Opengl 使用GLSL着色器时亮度不起作用
我的程序的目标是使用GLSL着色器渲染由光点照亮的简单立方体。问题是我的立方体保持黑色,就好像禁用了照明属性一样。 几个小时以来我一直在寻找解决办法,但都没有成功。我有两个缓冲区,一个用于位置顶点,另一个用于法线顶点。这两个缓冲区是由Blender生成的。我以前在一个使用顶点数组的基本OpenGL程序中使用过它们,它工作得非常好。现在我只想做同样的事情,但这次使用GLSL着色器Opengl 使用GLSL着色器时亮度不起作用,opengl,glsl,shader,opengl-3,vertex-shader,Opengl,Glsl,Shader,Opengl 3,Vertex Shader,我的程序的目标是使用GLSL着色器渲染由光点照亮的简单立方体。问题是我的立方体保持黑色,就好像禁用了照明属性一样。 几个小时以来我一直在寻找解决办法,但都没有成功。我有两个缓冲区,一个用于位置顶点,另一个用于法线顶点。这两个缓冲区是由Blender生成的。我以前在一个使用顶点数组的基本OpenGL程序中使用过它们,它工作得非常好。现在我只想做同样的事情,但这次使用GLSL着色器 这是我的C++代码的一部分: static GLfloat LightPosition[4] = {0.0f, 10.
这是我的C++代码的一部分:
static GLfloat LightPosition[4] = {0.0f, 10.0f, 10.0f, 1.0f};
static GLfloat Kd[3] = {0.9f, 0.5f, 0.3f};
static GLfloat Ld[3] = {1.0f, 1.0f, 1.0f};
[...]
tatic GLuint initShaders(char const *vertShaderSrc, char const *fragShaderSrc)
{
GLuint vertShaderID = 0, fragShaderID = 0;
compileShader(vertShaderID, GL_VERTEX_SHADER, vertShaderSrc);
compileShader(fragShaderID, GL_FRAGMENT_SHADER, fragShaderSrc);
GLuint programID = glCreateProgram();
glAttachShader(programID, vertShaderID);
glAttachShader(programID, fragShaderID);
glBindAttribLocation(programID, 0, "VertexPosition");
glBindAttribLocation(programID, 1, "VertexNormal");
glUniform3f(glGetUniformLocation(programID, "Kd"), Kd[0], Kd[1], Kd[2]);
glUniform3f(glGetUniformLocation(programID, "Ld"), Ld[0], Ld[1], Ld[2]);
glLinkProgram(programID);
GLint errorLink = 0;
glGetProgramiv(programID, GL_LINK_STATUS, &errorLink);
if (errorLink != GL_TRUE)
{
GLint sizeError = 0;
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &sizeError);
char *erreur = new char[sizeError + 1];
glGetShaderInfoLog(programID, sizeError, &sizeError, erreur);
erreur[sizeError] = '\0';
std::cout << erreur << std::endl;
delete[] erreur;
glDeleteProgram(programID);
}
return (programID);
}
int main(int ac, char **av)
{
bool continuer = true;
SDL_Event event;
GLuint vboID[2];
GLuint textureID = 0;
GLuint programID = 0;
//SDL window initialization
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Test", NULL);
SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
//Viewport initialization
glViewport(0, 0, WIDTH, HEIGHT);
//Glew init component
glewInit();
//VBO initialization
initVBO(vboID);
//Shaders initialization
programID = initShaders("Box.vert", "Box.frag");
//Main loop
while (continuer)
{
eventListener(&event, &continuer);
glClearDepth(1.0f);
glClearColor(0.13f, 0.12f, 0.13f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
//Projection matrix
glm::mat4 ProjectionMatrix = glm::perspective(45.0f, 500.0f / 500.0f, 0.1f, 100.0f);
//View matrix
glm::mat4 ViewMatrix = glm::lookAt(glm::vec3(0.0f, 0.0f, 8.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
//Model matrix
glm::mat4 ModelMatrix = glm::mat4(1.0f);
ModelMatrix = glm::translate(ModelMatrix, glm::vec3(0.0f, 0.0f, 0.0f));
ModelMatrix = glm::rotate(ModelMatrix, angle, glm::vec3(1.0f, 1.0f, 1.0f));
ModelMatrix = glm::scale(ModelMatrix, glm::vec3(1.0f, 1.0f, 1.0f));
//Prepare matrix
glm::mat4 ModelViewMatrix = ViewMatrix * ModelMatrix;
glm::mat3 NormalMatrix = glm::mat3(glm::vec3(ModelViewMatrix[0]), glm::vec3(ModelViewMatrix[1]), glm::vec3(ModelViewMatrix[2]));
glm::mat4 ModelViewProjectionMatrix = ProjectionMatrix * ModelViewMatrix;
glm::vec4 LightPositionVec = ViewMatrix * glm::vec4(LightPosition[0], LightPosition[1], LightPosition[2], LightPosition[3]);
//Send matrix
glUniform4f(glGetUniformLocation(programID, "LightPosition"), LightPositionVec[0], LightPositionVec[1], LightPositionVec[2], LightPositionVec[3]);
glUniformMatrix4fv(glGetUniformLocation(programID, "ProjectionMatrix"), 1, GL_FALSE, glm::value_ptr(ProjectionMatrix));
glUniformMatrix3fv(glGetUniformLocation(programID, "NormalMatrix"), 1, GL_FALSE, glm::value_ptr(NormalMatrix));
glUniformMatrix4fv(glGetUniformLocation(programID, "ModelViewMatrix"), 1, GL_FALSE, glm::value_ptr(ModelViewMatrix));
glUniformMatrix4fv(glGetUniformLocation(programID, "MVP"), 1, GL_FALSE, glm::value_ptr(ModelViewProjectionMatrix));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(0));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, vboID[1]);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(0));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
glUseProgram(0);
angle += 0.010f;
glFlush();
SDL_GL_SwapBuffers();
}
SDL_Quit();
return (0);
}
片段着色器代码:
#version 330
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
uniform vec4 LightPosition;
uniform vec3 Kd;
uniform vec3 Ld;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform mat4 MVP;
out vec3 LightIntensity;
void main()
{
vec3 tnorm = normalize( NormalMatrix * VertexNormal);
vec4 eyeCoords = ModelViewMatrix * vec4(VertexPosition,1.0);
vec3 s = normalize(vec3(LightPosition - eyeCoords));
LightIntensity = Ld * Kd * max( dot( s, tnorm ), 0.0 );
gl_Position = MVP * vec4(VertexPosition,1.0);
}
#version 330
in vec3 LightIntensity;
layout (location = 0) out vec4 FragColor;
void main() {
FragColor = vec4(LightIntensity, 1.0f);
}
这是我的应用程序的屏幕:
如您所见,照明属性似乎已禁用。有人能帮我吗
glUniform3f(glGetUniformLocation(programID, "Kd"), Kd[0], Kd[1], Kd[2]);
glUniform3f(glGetUniformLocation(programID, "Ld"), Ld[0], Ld[1], Ld[2]);
这两行位于错误的位置,在链接和绑定着色器之前无法执行此操作。将它们向下移动到所有其他glUniform调用的位置
每次交换着色器或查看统一块时,都需要重置统一
这两行位于错误的位置,在链接和绑定着色器之前无法执行此操作。将它们向下移动到所有其他glUniform调用的位置
每次交换着色器或查看统一块时,都需要重置统一。好的,我现在更了解了。非常感谢你的回答。拜拜。虽然这个答案是正确的,但每次交换着色器时都需要重置制服,因为着色器不完全正确。当然,如果不使用glprogrammuniform,则只能更改当前使用的程序的统一,但这些统一将与程序一起存储,甚至跨glUseProgram调用。因此,如果这些制服没有改变,您只能在启动时设置一次,您只需确保程序已链接并正在使用,如您所写。感谢您提供完整的答案。实际上,它也工作得很好,而且更好,因为灯光数据不需要像矩阵一样进行更改。谢谢再见。好的,我现在更明白了。非常感谢你的回答。拜拜。虽然这个答案是正确的,但每次交换着色器时都需要重置制服,因为着色器不完全正确。当然,如果不使用glprogrammuniform,则只能更改当前使用的程序的统一,但这些统一将与程序一起存储,甚至跨glUseProgram调用。因此,如果这些制服没有改变,您只能在启动时设置一次,您只需确保程序已链接并正在使用,如您所写。感谢您提供完整的答案。实际上,它也工作得很好,而且更好,因为灯光数据不需要像矩阵一样进行更改。谢谢再见