6

シェーダーで異なるテクスチャ タイプ (通常の 2D テクスチャとキューブ マップ) に同じテクスチャ ユニット (番号 0) を使用しようとしたときに、プログラムで厄介な問題に遭遇しました。最初の 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);

問題は何でしょうか?本当に有効なことではありませんか?

4

1 に答える 1

6

はい、それは非常に有効なことではありません。

OpenGL では、異なるテクスチャ ターゲットを同じテクスチャ ユニットにバインドすることもできることを完全に忘れてください。この能力でできることは絶対にありません。テクスチャをバインドして変更する必要がある場合は、後でバインドを解除します。テクスチャをレンダリングに使用するためにバインドする必要がある場合は、そのテクスチャ ユニットに他に何もバインドしないでください。

いずれにGL_INVALID_OPERATIONしても、同じプログラム/パイプライン内の 2 つのサンプラーが同じテクスチャ ユニットを参照するのに異なるサンプラー タイプを使用することは違法であるため、描画関数は を取得する必要があります。

于 2013-06-07T18:12:32.737 に答える