Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 碎片着色器不工作的多个纹理单元_C++_Opengl_Glsl - Fatal编程技术网

C++ 碎片着色器不工作的多个纹理单元

C++ 碎片着色器不工作的多个纹理单元,c++,opengl,glsl,C++,Opengl,Glsl,我需要显示一些索引的图形文件,它还具有每像素alpha通道。此外,我需要确保我可以随时更改调色板,并且生成的图像也会更改。为此,我首先使用了软件像素预计算,但这对于实时渲染来说太慢了,所以我决定编写一个着色器来处理GPU端的索引纹理。问题是第二个纹理(rec_颜色)没有加载(至少看起来是这样的-从该采样器读取的每个纹理看起来都是空的) 来自零纹理的数据读取正确,从而生成具有右alpha的黑色图像:) 着色器初始化相关代码: Application::Display->GetRC(); gl

我需要显示一些索引的图形文件,它还具有每像素alpha通道。此外,我需要确保我可以随时更改调色板,并且生成的图像也会更改。为此,我首先使用了软件像素预计算,但这对于实时渲染来说太慢了,所以我决定编写一个着色器来处理GPU端的索引纹理。问题是第二个纹理(rec_颜色)没有加载(至少看起来是这样的-从该采样器读取的每个纹理看起来都是空的)

来自零纹理的数据读取正确,从而生成具有右alpha的黑色图像:)

着色器初始化相关代码:

Application::Display->GetRC();
glewInit();
if(!GLEW_VERSION_2_0) return false;

char* code_frag = loadCode("shader.frag");
char* code_verx = loadCode("shader.verx");

aShader_palette = glCreateShader(GL_FRAGMENT_SHADER);
//glShaderSource(aShader_palette, 1, &aShaderProgram_palette, NULL);
glShaderSource(aShader_palette, 1, (const GLchar**)&code_frag, NULL);
glCompileShader(aShader_palette);

GLint compiled = 0;
glGetShaderiv(aShader_palette, GL_COMPILE_STATUS, &compiled);

if(!compiled)
{
    /* error-handling */
}

GLuint texloc = glGetUniformLocation(aShader_palette, "rec");
glUniform1i(texloc, 0);
texloc = glGetUniformLocation(aShader_palette, "rec_colors");
glUniform1i(texloc, 1);

glsl_palette_Program = glCreateProgram();
glAttachShader(glsl_palette_Program, aShader_palette);
glLinkProgram(glsl_palette_Program);
与渲染相关的:

glPushAttrib(GL_CURRENT_BIT);
glColor4ub(255, 255, 255, t_a); // t_a is overall alpha of sprite displayed
glUseProgram(glsl_palette_Program); // this one is a compiled/linked shader declared above
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->m_SpriteData[idx].texture);
glActiveTexture(GL_TEXTURE1); // at this point, it looks like texture unit is actually changed (I checked that via glGetIntegerv)
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->m_PaletteTex);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, palette); // update possibly changed palette on each render
glActiveTexture(GL_TEXTURE0);
glBegin(GL_QUADS);
    glTexCoord2i(0, 0);
    glVertex2i(x, y);
    glTexCoord2i(0, this->GetHeight(idx));
    glVertex2i(x, y+this->GetHeight(idx));
    glTexCoord2i(this->GetWidth(idx), this->GetHeight(idx));
    glVertex2i(x+this->GetWidth(idx), y+this->GetHeight(idx));
    glTexCoord2i(this->GetWidth(idx), 0);
    glVertex2i(x+this->GetWidth(idx), y);
glEnd();
glActiveTexture(GL_TEXTURE1);
glUnbindTexture(GL_TEXTURE_RECTANGLE_ARB); // custom macro
glActiveTexture(GL_TEXTURE0);
glUnbindTexture(GL_TEXTURE_RECTANGLE_ARB);
glUseProgram(0);
glPopAttrib();
着色器代码:

#extension GL_ARB_texture_rectangle : enable

uniform sampler2DRect rec;
uniform sampler2DRect rec_colors;

void main(void)
{
    vec4 oldcol = texture2DRect(rec, gl_TexCoord[0].st);
    vec4 newcol = texture2DRect(rec_colors, vec2(oldcol.r*255.0, 0.0)); // palette index should be*255 bcs rectangle coordinates aren't normalized
    gl_FragColor.rgb = newcol.rgb;
    gl_FragColor.a = oldcol.g; // alpha from green part
}

谷歌搜索了很多,我发现的任何类似帖子都是通过在glUniform1i调用中修复纹理单元ID来解决的,但对我来说,这看起来绝对正常(至少,TEXTURE0正确加载到rec中)。

你用
glGetError
检查任何地方的错误吗?我相信你做得不对
glGetUniformLocation
应该针对链接程序而不是着色器执行。在链接程序之前,您正在调用
glGetUniformLocation

请参阅手册页中的相关文本:

分配给统一变量的实际位置不是
直到程序对象成功链接为止。之后
发生链接时,命令
glGetUniformLocation可用于获取
均匀变量的位置。统一变量位置和值只能
如果链接成功,则在链接后查询。


在开发过程中,您至少应该使用
glGetError
每帧检查一次opengl错误。它会在你上网寻求帮助之前提醒你这些问题

是否使用
glGetError
检查任何地方的错误?我相信你做得不对
glGetUniformLocation
应该针对链接程序而不是着色器执行。在链接程序之前,您正在调用
glGetUniformLocation

请参阅手册页中的相关文本:

分配给统一变量的实际位置不是
直到程序对象成功链接为止。之后
发生链接时,命令
glGetUniformLocation可用于获取
均匀变量的位置。统一变量位置和值只能
如果链接成功,则在链接后查询。


在开发过程中,您至少应该使用
glGetError
每帧检查一次opengl错误。它会在你上网寻求帮助之前提醒你这些问题

您没有绑定纹理采样器。@kaoD我绑定纹理采样器:/GLuint texloc=glGetUniformLocation(aShader_调色板,“rec”);glUniform1i(texloc,0);texloc=glGetUniformLocation(aShader_调色板,“rec_颜色”);glUniform1i(texloc,1)/你也需要每帧调用一次glUniform。一旦你调用glUseProgram,你的状态可能会被重置。@kaoD:那是不正确的。如果取消绑定/重新绑定着色器,它们将保持统一状态。每个程序都有自己的内部统一状态,在解除绑定时保持不变。@Tim感谢您提供的信息。这就是为什么我没有把它作为一个答案,我只是猜测。无论如何,他不应该在程序已经链接和绑定的情况下设置制服吗?你没有绑定你的纹理采样器。@kaoD我绑定纹理采样器:/GLuint texloc=glGetUniformLocation(aShader_调色板,“rec”);glUniform1i(texloc,0);texloc=glGetUniformLocation(aShader_调色板,“rec_颜色”);glUniform1i(texloc,1)/你也需要每帧调用一次glUniform。一旦你调用glUseProgram,你的状态可能会被重置。@kaoD:那是不正确的。如果取消绑定/重新绑定着色器,它们将保持统一状态。每个程序都有自己的内部统一状态,在解除绑定时保持不变。@Tim感谢您提供的信息。这就是为什么我没有把它作为一个答案,我只是猜测。不管怎么说,他不应该在节目已经链接和绑定的情况下设置制服吗?