【问题标题】:Using different texture types in same texture unit at the same time in shader在着色器中同时在同一纹理单元中使用不同的纹理类型
【发布时间】:2013-06-07 17:58:54
【问题描述】:

当我尝试在我的着色器中为不同的纹理类型(即普通的 2D 纹理和立方体贴图)使用相同的纹理单元(编号 0)时,我在程序中遇到了一个令人讨厌的问题。看起来,GL 在第一次 glDrawArrays 调用后发出 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 uniform):

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 统一确定的:

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

会有什么问题?是不是真的不是一件有效的事?

【问题讨论】:

    标签: c++ opengl glsl textures opengl-3


    【解决方案1】:

    是的,这是非常不合理的做法。

    您应该完全忘记 OpenGL 甚至允许您将不同的纹理目标绑定到同一个纹理单元。使用此功能绝对没有任何用处。如果您需要绑定纹理来修改它,请在之后取消绑定。如果您需要绑定纹理以使用它进行渲染,则不应将任何其他内容绑定到该纹理单元。

    无论如何,你的绘图函数应该得到GL_INVALID_OPERATION,因为同一程序/管道中的两个采样器引用同一纹理单元,但使用不同的采样器类型是非法的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-07
      • 2017-04-24
      • 2020-09-06
      • 1970-01-01
      • 2018-12-01
      相关资源
      最近更新 更多