我认为我已完成移植我的应用程序以使用GL 3.3和#version 330着色器。 但是,我得到一个黑屏(来自glClear()),但没有看到任何错误。我将尝试通过我的代码进行演练。
这是我的渲染功能:
void render() {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
applyCameraPerspective();
glUseProgram(prog);
setUniforms();
for (ObjectList::iterator it = objectList.begin(); it != objectList.end(); it++) {
GLuint usedTexture = glTextureList.find((*it)->getTextureName())->second;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, usedTexture);
glUniform1ui(textureLoc, 0);
(*it)->render();
//glBindTexture(GL_TEXTURE_2D, 0);
}
glPopMatrix();
frameCount++;
}
usedTexture是GLuint纹理索引。
*它是RenderObject类的一个对象,它的render()函数如下所示:
void render() {
if (totalTriangleCount > 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_NORMAL_ARRAY);
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glVertexPointer(3, GL_FLOAT, 32, BUFFER_OFFSET(0));
//glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(12));
//glTexCoordPointer(2, GL_FLOAT, 32, BUFFER_OFFSET(24));
glDrawArrays(GL_TRIANGLES, 0, totalTriangleCount * 3);
//glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_NORMAL_ARRAY);
//glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
你可以在这里看到glXXXPointer() - 被删除的函数和客户端状态切换以使用新版本。当我取消注释它们时,奇怪的是,我会渲染几何体,但看起来像是未插入的纹理坐标。但是,布局限定符(请参阅下面的内容)的要点应该是不再需要这些调用。
对象有一个initToGL() - 事先调用的函数,如下所示:
void initToGL(GLuint positionLoc, GLuint normalLoc, GLuint texCoordLoc) {
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
totalTriangleCount = 0;
for (FaceList::iterator it = faceList.begin(); it != faceList.end(); it++) {
totalTriangleCount += (*it)->getTriangleCount();
}
// Per triangle: 36 bytes for position, 36 for normal, 24 for texture coordinates (32 per vertex)
UINT bytesNeeded = 3 * (12 + 12 + 8) * totalTriangleCount;
glBufferData(GL_ARRAY_BUFFER, bytesNeeded, NULL, GL_STATIC_DRAW_ARB);
glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(0)); // Position
glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_TRUE, 32, BUFFER_OFFSET(12)); // Normal
glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(24)); // Texture coordinates
GLintptr currentOffset = 0;
for (FaceList::iterator fIt = faceList.begin(); fIt != faceList.end(); fIt++) {
std::list<std::vector<UINT>> indicesList = (*fIt)->getTriangleVertexIndices();
for (std::list<std::vector<UINT>>::iterator triIt = indicesList.begin(); triIt != indicesList.end(); triIt++) {
// Get Vertex positions
Vector3f vertex1 = (*fIt)->getVertex(triIt->at(0));
Vector3f vertex2 = (*fIt)->getVertex(triIt->at(1));
Vector3f vertex3 = (*fIt)->getVertex(triIt->at(2));
// Calculate normal; keep in mind these vertices are clockwise!
Vector3f normal = (vertex3 - vertex1).crossProduct(vertex2 - vertex1).normalize();
// Get texture coordinates
Vector2f textureCoordinate1 = (*fIt)->getTextureCoordinates(triIt->at(0));
Vector2f textureCoordinate2 = (*fIt)->getTextureCoordinates(triIt->at(1));
Vector2f textureCoordinate3 = (*fIt)->getTextureCoordinates(triIt->at(2));
// Vertex 1
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 12, (GLvoid*) &vertex1);
currentOffset += 12;
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 12, (GLvoid*) &normal);
currentOffset += 12;
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 8, (GLvoid*) &textureCoordinate1);
currentOffset += 8;
// Vertex 2
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 12, (GLvoid*) &vertex2);
currentOffset += 12;
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 12, (GLvoid*) &normal);
currentOffset += 12;
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 8, (GLvoid*) &textureCoordinate2);
currentOffset += 8;
// Vertex 3
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 12, (GLvoid*) &vertex3);
currentOffset += 12;
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 12, (GLvoid*) &normal);
currentOffset += 12;
glBufferSubData(GL_ARRAY_BUFFER, currentOffset, 8, (GLvoid*) &textureCoordinate3);
currentOffset += 8;
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
此处,为此函数提供的参数与从着色器中检索的参数相同(请参见下文)。 这里唯一的变化是增加了对glVertexAttribPointer()的3次调用。
applyCameraPerspective():
void applyCameraPerspective() {
glRotatef(cam->getPitch(), 1.0f, 0.0f, 0.0f);
glRotatef(cam->getRoll(), 0.0f, 0.0f, 1.0f);
glRotatef(cam->getYaw(), 0.0f, 1.0f, 0.0f);
glTranslatef(-cam->x(), -cam->y(), -cam->z());
}
这仍然依赖于OpenGL的矩阵堆栈。
setUniforms():
void setUniforms() {
GLfloat m[16];
glGetFloatv(GL_PROJECTION_MATRIX, &m[0]);
glUniformMatrix4fv(projectionMatrixLoc, 1, GL_FALSE, &m[0]);
glGetFloatv(GL_MODELVIEW_MATRIX, &m[0]);
//for (int y = 0; y < 4; y++) {
// for (int x = 0; x < 4; x++) {
// std::cout << std::showpoint << m[4 * x + y] << std::noshowpoint << " " ;
// }
// std::cout << std::endl;
//}
glUniformMatrix4fv(modelViewMatrixLoc, 1, GL_FALSE, &m[0]);
// Error: GL_NORMAL_MATRIX is not a thing. :-(
//glGetFloatv(GL_NORMAL_MATRIX, 1, GL_FALSE, &m[0]);
// HACKHACK: As long as we don't do scale transformations (which we don't) we will be fine doing just this.
m[12] = 0;
m[13] = 0;
m[14] = 0;
glUniformMatrix4fv(normalMatrixLoc, 1, GL_FALSE, &m[0]);
}
你可以在这里看到我添加了输出来测试模型视图矩阵的正确性。这是预期的。
我加载纹理的代码没有改变。我在上传对象之前执行了加载着色器程序的代码,如下所示:
bool setupShader() {
bool success = true;
// Vertex shader
vs = glCreateShader(GL_VERTEX_SHADER);
std::string vsString = TextFileReader().readWhole("Shader/basic_fog.vert");
const char* vsChars = vsString.c_str();
glShaderSource(vs, 1, &vsChars, NULL);
std::cout << "Compiling vertex shader." << std::endl;
glCompileShader(vs);
success &= printShaderInfo(vs);
// Fragment shader
fs = glCreateShader(GL_FRAGMENT_SHADER);
std::string fsString = TextFileReader().readWhole("Shader/basic_fog.frag");
const char* fsChars = fsString.c_str();
glShaderSource(fs, 1, &fsChars, NULL);
std::cout << "Compiling fragment shader." << std::endl;
glCompileShader(fs);
success &= printShaderInfo(fs);
// Bundle them into a program
prog = glCreateProgram();
glAttachShader(prog, vs);
glAttachShader(prog, fs);
glBindFragDataLocation(prog, 0, "fragColor");
glLinkProgram(prog);
success &= printProgramInfo(prog);
if (success) {
// These all are GLuints
positionLoc = glGetAttribLocation(prog, "position");
normalLoc = glGetAttribLocation(prog, "normal");
texCoordLoc = glGetAttribLocation(prog, "texCoordinates");
projectionMatrixLoc = glGetUniformLocation(prog, "projectionMatrix");
modelViewMatrixLoc = glGetUniformLocation(prog, "modelViewMatrix");
normalMatrixLoc = glGetUniformLocation(prog, "normalMatrix");
textureLoc = glGetUniformLocation(prog, "colorTexture");
}
return success;
}
请注意,我从不glBindAttribLocation(),因为我使用布局限定符(见下文)。 对于我使用的以下着色器代码,此函数返回true。
顶点着色器:
#version 330
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 position;
layout(location = 0) out vec3 fragPosition;
layout(location = 1) in vec3 normal;
layout(location = 1) out vec3 fragNormal;
layout(location = 2) in vec2 texCoordinates;
layout(location = 2) out vec2 fragTexCoordinates;
uniform mat4 modelViewMatrix, projectionMatrix, normalMatrix;
void main() {
fragPosition = (modelViewMatrix * vec4(position, 1)).xyz;
fragNormal = (normalMatrix * vec4(normal, 1)).xyz;
fragTexCoordinates = vec2(texCoordinates);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1);
}
片段着色器:
#version 330
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 textureCoordinates;
layout(location = 0) out vec4 fragColor;
uniform sampler2D colorTexture;
void main() {
fragColor = texture2D(colorTexture, textureCoordinates);
}
我尝试将fragColor设置为红色:没有结果。没有一个像素穿过片段着色器。
这是很多代码。我非常感谢有人看一看,特别是关于简单地使用某些功能的问题。
答案 0 :(得分:4)
您的代码最明显的问题之一是不推荐使用的OpenGL混乱,如固定函数矩阵堆栈和自定义统一等现代功能。像这样的东西:
glGetFloatv(GL_PROJECTION_MATRIX, &m[0]);
glUniformMatrix4fv(projectionMatrixLoc, 1, GL_FALSE, &m[0]);
表示您正在使用旧式FFP矩阵函数来计算矩阵,从OpenGL查询并将其反馈为统一。你真的不应该这样做。使用真实的矩阵数学库,如GLM或Eigen。
然后当然glEnableClientState
将不适用于现代通用顶点属性。我没有看到对glEnableVertexAttribArray
的任何调用,所以如果缺少这些调用,那么注意到它就不足为奇了。