gpt4 book ai didi

c++ - 带有片段着色器的多个纹理单元不起作用

转载 作者:太空宇宙 更新时间:2023-11-04 16:28:16 25 4
gpt4 key购买 nike

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

来自零纹理的数据读取正确,导致黑色图像具有正确的 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
}

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

最佳答案

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

请参阅手册页中的相关文本:http://www.opengl.org/wiki/GLAPI/glGetUniformLocation

分配给统一变量的实际位置不是
直到程序对象被成功链接才知道。后
链接已经发生,命令
glGetUniformLocation 可以用来获取
统一变量的位置。统一的变量位置和值只能
如果链接成功,则在链接后查询。

在开发过程中,您应该始终至少每帧检查一次 glGetError 是否有 opengl 错误。在您必须上网寻求帮助之前,它会提醒您注意这些问题。

关于c++ - 带有片段着色器的多个纹理单元不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9879455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com