当我尝试在我的着色器中使用相同的纹理单元(数字0)用于不同的纹理类型(即普通的2D纹理和立方体贴图)时,我在程序中遇到了一个令人讨厌的问题。在第一次glDrawArrays调用之后,GL似乎发出了502H(无效操作)。 在我的应用程序代码中,我将纹理加载到不同的纹理目标:
void setup_textures()
{
unsigned int width, height;
int components;
unsigned int format;
float param[8];
vector<unsigned char> pngData;
GLenum texture_target;
glGenTextures(2, textures);
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, param);
for(int i = 0; i < 2; i++) {
texture_target = (i == 0) ? (GL_TEXTURE_CUBE_MAP) : (GL_TEXTURE_2D); // The first texture is the cube map
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture_target, textures[i]);
glTexParameterf(texture_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, param[0]);
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_REPEAT);
if(texture_target == GL_TEXTURE_CUBE_MAP) glTexParameteri(texture_target, GL_TEXTURE_WRAP_R, GL_REPEAT);
loadPNG(pngData, width, height, PNGFile[i], LCT_RGBA, 8) // PNGFile[0] is my 2D texture file and PNGFile[1] is the cube texture
if(texture_target == GL_TEXTURE_CUBE_MAP) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pngData[0]);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pngData[0]);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pngData[0]);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pngData[0]);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pngData[0]);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pngData[0]);
} else if(texture_target == GL_TEXTURE_2D)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pngData[0]);
glGenerateMipmap(texture_target);
}
return;
}
在我的渲染功能中,我将纹理绑定到相应的目标,并告诉着色器使用哪种纹理类型(通过bool制服):
void render(HDC hdc)
{
GLenum texture_target;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
for(int i = 0; i < 2; i++) {
texture_target = (i == 0) ? (GL_TEXTURE_CUBE_MAP) : (GL_TEXTURE_2D);
glBindVertexArray(objVertexArray[i]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture_target, textures[i]);
glUniform1i(uniIsCubeMap, texture_target == GL_TEXTURE_CUBE_MAP); // Tell the shader the texture type
glDrawArrays(GL_TRIANGLES, 0, nVertices[i]);
}
SwapBuffers(hdc);
return;
}
在片段着色器中,纹理类型基于is_cube_map uniform:
确定#version 330 core
uniform sampler2D texture_map;
uniform samplerCube texture_map_cube;
uniform bool is_cube_map;
smooth in vec3 texcoords;
out vec4 fragcolor;
void main(void)
{
vec4 texel;
if(is_cube_map) {
texel = textureCube(texture_map_cube, texcoords.stp);
} else {
texel = texture(texture_map, texcoords.st);
}
fragcolor = texel;
}
我还在我的应用程序代码中将两个纹理采样器制服设置为0(纹理单元编号0):
glUniform1iARB(uniTextureMap, 0);
glUniform1iARB(uniTextureMapCube, 0);
会出现什么问题?真的不是一件有效的事吗?
答案 0 :(得分:6)
是的,这不是一件有效的事情。
你应该完全忘记OpenGL甚至允许你将不同的纹理目标绑定到同一个纹理单元。对于这种能力,你无能为力。如果需要绑定纹理以对其进行修改,请在之后取消绑定。如果需要绑定纹理以将其用于渲染,则不应该将任何其他内容绑定到该纹理单元。
在任何情况下,您的绘图函数都应该得到GL_INVALID_OPERATION
,因为同一程序/管道中的两个采样器引用相同的纹理单元,但使用不同的采样器类型是非法的。