我的程序的目标是使用 GLSL 着色器渲染一个由光点照亮的简单立方体。问题是我的立方体保持黑色,就好像照明属性被禁用一样。几个小时以来,我一直在寻找解决方案。我有两个缓冲区(一个用于位置顶点,另一个用于正常顶点)。这两个缓冲区是由 Blender 生成的。我以前在使用顶点数组的基本 OpenGL 程序中使用它们,它运行良好。现在我只想做同样的事情,但这次使用 GLSL 着色器。
这是我的 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);
}
这是我的应用程序的屏幕:
如您所见,照明属性似乎被禁用。有人可以帮助我吗?