openGL统一属性位置无效

openGL uniform attribute location invalid

对于我的 2D opengl/sdl 游戏,我目前 运行 一个 opengl 日志文件,它打印出以下 openGL 程序属性:

GL_LINK_STATUS = SUCCESS
GL_ATTACHED_SHADERS = 0
GL_ACTIVE_ATTRIBUTES = 2
 - 0) type:vec2 name:textCoord location 1
 - 1) type:vec3 name:vertexPosition location 0
GL_ACTIVE_UNIFORMS = 1
 - 0) type:sampler2D name:basicTexture location -1

如您所见,我的位置和纹理坐标属性都处于活动状态并且有效,但我的 1 统一属性显示的位置为 -1(我假设这意味着位置无效)。我正在尝试让我的第一个纹理正确加载。在尝试显示纹理之前,我能够在屏幕上显示一个彩色框,因此假设包含在函数中的所有其他 opengl 代码都正常工作。这就是我设置纹理属性的原因:

main.cpp

int main(int agrc, char** argv)
{
    window.Initialize();
    playerSprite.Init(-1.0f, -1.0f, 1.0f, 1.0f);

    GameState gamestate{ GameState::PLAY };

    SDL_Event evnt;

    int32 x, y, currentChannels;
    int32 forceChannels = 4;
    uchar8* imageData = 0;
    imageData = stbi_load("CharImage.png", &x, &y, &currentChannels, forceChannels);

    if (imageData == nullptr)
    {
        LOG("ERROR: Could not load image file!");
    };

    Blz::OpenGL::ShaderProgram colorShaderProgram;
    colorShaderProgram.Compile();
    colorShaderProgram.Link();
    colorShaderProgram.Bind();

    GLuint texture;
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);

    GLuint uniformLocation = glGetUniformLocation(colorShaderProgram.programID, "basicTexture");
    glUniform1i(uniformLocation, 0);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    //Where I am logging to the openGL file
    Blz::OpenGL::LogShaderProgramProperties(colorShaderProgram.programID);

    while (gamestate != GameState::EXIT)
    {
        unsigned int startTime = SDL_GetTicks();

        //Game Logic Update
        while (SDL_PollEvent(&evnt))
        {
            switch (evnt.type)
            {
            case SDL_QUIT:
                gamestate = GameState::EXIT;

            default:
                break;
            }
        }

        window.ClearBuffers();

        playerSprite.Draw();

        window.SwapBuffers();
    }

    return 0;
}

这是我用来设置统一变量的着色器:

Veretx 着色器

#version 430

layout(location=0) in vec3 vertexPosition;
layout(location=1) in vec2 textCoord;

out vec2 TextureCoord;

void main()
{
    gl_Position = vec4(vertexPosition, 1.0f);
    TextureCoord = textCoord;
};

片段着色器

#version 430

out vec4 daColor;
in vec2 TextureCoord;

uniform sampler2D basicTexture;

void main()
{
    vec4 texel = texture(basicTexture, TextureCoord);
    daColor = texel;
};

从上面的代码来看,是否有任何问题会导致我的统一变量位置在日志文件中打印 -1?

编辑:

打印日志信息的代码如下:

void LogShaderProgramProperties(GLuint shaderProgramID)
        {
            //Header
            OpenGL::LogToFile("-------------------------------------------------\n");
            OpenGL::LogToFile("Shader program %i\n", shaderProgramID);
            OpenGL::LogToFile("-------------------------------------------------\n\n");

            int32 result = -1;
            glGetProgramiv(shaderProgramID, GL_LINK_STATUS, &result);
            OpenGL::LogToFile("GL_LINK_STATUS = %s\n", (result == GL_TRUE) ? "SUCCESS" : "FAILURE");

            glGetProgramiv(shaderProgramID, GL_ATTACHED_SHADERS, &result);
            OpenGL::LogToFile("GL_ATTACHED_SHADERS = %i\n", result);

            glGetProgramiv(shaderProgramID, GL_ACTIVE_ATTRIBUTES, &result);
            OpenGL::LogToFile("GL_ACTIVE_ATTRIBUTES = %i\n", result);

            //Will log all current active attributes for program/shader
            for (GLuint i = 0; i < (GLuint)result; ++i)
            {
                char8 name[64];
                int32 maxLength = 64;
                int32 actualLength = 0;
                int32 size = 0;
                GLenum type;

                glGetActiveAttrib(shaderProgramID, i, maxLength, &actualLength, &size, &type, name);
                if (size > 1)
                {
                    //Sometimes an attribute will contain an array of other attributes for which this
                    //loop will catch and print all contained variables
                    for (int j = 0; j < size; j++)
                    {
                        char8 longName[64];
                        sprintf(longName, "%s[%i]", name, j);
                        int32 location = glGetAttribLocation(shaderProgramID, longName);
                        OpenGL::LogToFile(" - %i) type:%s name:%s location: %i\n", i, GLTypeToString(type), name, location);
                    }
                }
                else
                {
                    //Just print single attribute information
                    int32 location = glGetAttribLocation(shaderProgramID, name);
                    OpenGL::LogToFile(" - %i) type:%s name:%s location %i\n", i, GLTypeToString(type), name, location);
                }
            }

            glGetProgramiv(shaderProgramID, GL_ACTIVE_UNIFORMS, &result);
            LogToFile("GL_ACTIVE_UNIFORMS = %i\n", result);

            //Will log all current active attributes for program/shader
            for (GLuint i = 0; i < (GLuint)result; ++i)
            {
                char8 name[64];
                int32 maxLength = 64;
                int32 actualLength = 0;
                int32 size = 0;
                GLenum type;

                glGetActiveUniform(shaderProgramID, i, maxLength, &actualLength, &size, &type, name);
                if (size > 1)
                {
                    //In case a uniform contains an array of other variables/uniforms
                    for (int j = 0; j < size; j++)
                    {
                        char8 longName[64];
                        sprintf(longName, "%s[%i]", name, j);
                        int32 location = glGetUniformLocation(shaderProgramID, longName);
                        OpenGL::LogToFile(" - %i) type:%s name:%s location: %i\n", i, GLTypeToString(type), longName, location);
                    }
                }
                else
                {
                    //Just print single uniform variable 
                    int32 location = glGetAttribLocation(shaderProgramID, name);
                    OpenGL::LogToFile(" - %i) type:%s name:%s location %i\n", i, GLTypeToString(type), name, location);
                }
            }

            int32 maxLength = 2048;
            int32 actualLength = 0;
            char8 log[2048];
            glGetProgramInfoLog(shaderProgramID, maxLength, &actualLength, log);
            OpenGL::LogToFile("Program info log for GL index %u:\n%s", shaderProgramID, log);
        }

您尝试通过 glGetAttribLocation 查询 uniform 位置,当然没有具有该名称的属性:

         else
            {
                //Just print single uniform variable 
                int32 location = glGetAttribLocation(shaderProgramID, name);
                OpenGL::LogToFile(" - %i) type:%s name:%s location %i\n", i, GLTypeToString(type), name, location);
            }
        }

无论你的纹理有什么问题,它都不是统一的位置。