The simultaneous use of different types of textures in one texture unit in the shader

There was an unpleasant problem in my program when I tried to use the same texture (number 0) for different types of textures (i.e. normal 2D texture and cube map) in my shader. It appeared so that GL returns 502H (Invalid Operation) after the first call to glDrawArrays. In my application code, I load textures into different texture targets:

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; } 

In my rendering function, I bind the texture to its corresponding target and tell the shader which type of texture to use (using a unified 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; } 

In the fragment shader, the texture type is determined based on the is_cube_map uniformity:

 #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; } 

I also set both forms of the texture sampler to 0 (texture unit number 0) in my application code:

 glUniform1iARB(uniTextureMap, 0); glUniform1iARB(uniTextureMapCube, 0); 

What is the problem? Is this really implausible?

+4
source share
1 answer

Yes, this is very implausible.

You must completely forget that OpenGL even allows you to bind different texture objects to the same texture unit. There is absolutely nothing useful you can do with this ability. If you need to bind a texture to change it, untie it later. If you need to bind a texture in order to use it for rendering, then nothing should be tied to this texture unit.

In any case, your drawing function should have received GL_INVALID_OPERATION , because two GL_INVALID_OPERATION in the same program / pipeline cannot refer to the same texture structure, but they use different types of samplers.

+6
source

Source: https://habr.com/ru/post/1485092/


All Articles