提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
看来我的useProgram没有绑定着色器,所以我无法为其设置统一。 但是,当我在着色器的编译代码中使用GlUseProgram时,我可以设置制服。 我正在使用一个资源管理器来处理着色器和纹理,并使用一个Game文件来处理着色器/文本器/游戏设置。
Shader.h:
class Shader
{
Shader() {};
void Compile(const std::string& vertexSource, const std::string& fragmentSource, const char* geometrySource = nullptr);
Shader &Use();
}
Shader.cpp
Shader & Shader::Use()
}
glUseProgram(this->ID);
return *this;
{
void Shader::Compile(const std::string& vertexSource, const std::string&
fragmentSource, const char* geometrySource)
{
unsigned int vShader, fShader, gShader;
const char* src1 = vertexSource.c_str();
const char* src2 = fragmentSource.c_str();
vShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vShader, 1, &src1, NULL);
glCompileShader(vShader);
checkCompileErrors(vShader, "VERTEX");
fShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fShader, 1, &src2, NULL);
glCompileShader(fShader);
checkCompileErrors(fShader, "FRAGMENT");
if (geometrySource != nullptr)
{
gShader = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(gShader, 1, &geometrySource, NULL);
glCompileShader(gShader);
checkCompileErrors(gShader, "error");
}
this->ID = glCreateProgram();
glAttachShader(this->ID, vShader);
glAttachShader(this->ID, fShader);
if (geometrySource != nullptr)
{
glAttachShader(this->ID, gShader);
}
glLinkProgram(this->ID);
checkCompileErrors(this->ID, "PROGRAM");
//glUseProgram(this->ID);
glDeleteShader(vShader);
glDeleteShader(fShader);
if (geometrySource != nullptr)
{
glDeleteShader(gShader);
}
}
您可以看到我在哪里注释掉了GlUseProgram。 如果我不对其进行注释,则着色器将正常工作,但如果对它进行注释,则它将不起作用。
ResourceManager.h:
class ResourceManager
{
public:
// Resource storage
static std::unordered_map<std::string, Shader> shader;
static Shader loadShader(const std::string& vShaderSource, std::string filename);
static Shader getShader(std::string name);
static Shader loadShaderFromFile(const std::string& vShaderFile);
ResourceManager.cpp
std::unordered_map<std::string, Shader> ResourceManager::shader;
Shader ResourceManager::loadShader(const std::string& vShaderSource, std::string filename)
{
shader[filename] = loadShaderFromFile(vShaderSource);
return shader[filename];
}
Shader ResourceManager::getShader(std::string filename)
{
return shader[filename];
}
Shader ResourceManager::loadShaderFromFile(const std::string& vShaderFile)
{
enum class ShaderType
{
none = -1, vertex = 0, fragment = 1
};
std::fstream path(vShaderFile);
std::stringstream ss[2];
std::string string;
ShaderType type = ShaderType::none;
while (std::getline(path, string))
{
if (string.find("shader") != std::string::npos)
{
if (string.find("vertex") != std::string::npos)
{
type = ShaderType::vertex;
}
if (string.find("fragment") != std::string::npos)
{
type = ShaderType::fragment;
}
}
else
ss[(int)type] << string << "\n";
}
std::string vertexCode = ss[0].str();
std::string fragmentCode = ss[1].str();
const char* geomtryCode = nullptr;
Shader shader;
shader.Compile(vertexCode, fragmentCode);
return shader;
}
最后。 Game.cpp:
void Game::Init()
{
ResourceManager::loadShader("res/Shader/shader.shader", "sprite");
ResourceManager::getShader("sprite").Use().setUniform1i("image", 0);
ResourceManager::getShader("sprite").setUniformMatrix4fv("projection", projection);
}
有人可以解释为什么它似乎不起作用吗?
在4.6规范 7.1节中有关DeleteShader()
它仅表示:
如果着色器未附加到任何程序对象,则将其立即删除。 否则,着色器将标记为删除,并且在不再附加到任何程序对象时将被删除。
在7.3节中,关于UseProgram()
如果程序尚未成功链接,则会生成INVALID_OPERATION错误。 当前渲染状态未修改。
和
使用程序对象时,应用程序可以自由修改附加的着色器对象,编译附加的着色器对象,附加其他着色器对象以及分离着色器对象。 这些操作不会影响程序对象的链接状态或可执行代码。
您会看到,显然,在成功链接之后,您可以在任何地方调用glUseProgram()
。
如果对您不起作用,则可能是gfx卡驱动程序中的错误。
但是请再次阅读并注意它会告诉您分离着色器,而不是删除着色器。
简而言之,请先删除着色器( glDetachShader
),然后再将其删除( glDeleteShader
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.