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, ¤tChannels, 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);
}
}
无论你的纹理有什么问题,它都不是统一的位置。
对于我的 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, ¤tChannels, 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); } }
无论你的纹理有什么问题,它都不是统一的位置。