drawing/rendering 使用 openGL、C++ 的替代方法
Alternative ways of drawing/rendering using openGL, C++
我正在尝试使用 Pointer 方法绘制我的对象,因为在我渲染的那一刻,当我有多个对象时,由于循环遍历顶点等。我听说使用指针方法会加快处理速度并使帧速率更好,因为它加载得更快。
这就是我现在正在使用的,我不能生成超过 3 个对象而不会导致游戏严重滞后。
for (int j = 0; j < mesh->objectParts.size(); j++) {//loop through each object part
glBindTexture(GL_TEXTURE_2D, textures[j]->getId());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBegin(GL_TRIANGLES);
for (int i = 0; i < mesh->objectParts[j]->faces[0].size(); i++) {
glTexCoord2fv(&mesh->textureCoords[mesh->objectParts[j]->faces[1][i]]->u);
glNormal3fv(&mesh->normals[mesh->objectParts[j]->faces[2][i]]->x);
glVertex3fv(&mesh->indexedVertices[mesh->objectParts[j]->faces[0][i]]->x);
}
glEnd();
这是转换为指针方法的尝试
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
for (int i = 0; i < mesh->objectParts.size(); i++) {//loop through the amount of parts
glBindTexture(GL_TEXTURE_2D, textures[i]->getId());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glVertexPointer(3, GL_FLOAT, 0, &mesh->indexedVertices[0]->x);
glNormalPointer(GL_FLOAT, 0, &mesh->normals[0]->x);
glTexCoordPointer(2, GL_FLOAT, 0, &mesh->textureCoords[0]->u);
for (int j = 0; j < 3; j++)
glDrawElements(GL_TRIANGLES, mesh->objectParts[i]->faceCount(), GL_UNSIGNED_SHORT, &mesh->objectParts[i]->faces[j][0]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
我不确定后者是如何工作的,它肯定是不正确的,因为它在绘制任何对象之前就崩溃了。
编辑:
我确实在我的旧 post
上试过这个答案
C++ .obj parser, issue with parsing, or drawing using OpenGL
我删除了索引列表,并在解析文件时存储了顶点、法线和纹理的所有数据。然后我将它们直接传递给指针方法并使用 glDrawArrays 进行绘制。然而,它使我的对象变形,并且它绝对不会像工作渲染代码那样出现。
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, &mesh->unindexedVertices[0]->x);
glNormalPointer(GL_FLOAT, 0, &mesh->unindexedNormals[0]->x);
glTexCoordPointer(2, GL_FLOAT, 0, &mesh->unindexedTextureCoords[0]->u);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
这是删除索引列表后的绘制方式,结果如下:
谁能帮我把上面的代码转换成下面的代码?
更改为指针方法可能不会有太大帮助,因为这里最大的问题是您每帧都发送顶点数据。
如果您的网格是静态的,您可以使用 VBO 和 VAO:您只需要将顶点数据发送到 OpenGL 实现一次并使用它进行绘制,您只需要为您的网格绑定 VAO然后调用适当的绘图调用。这是 "modern" 方法。您可以在这里阅读更多相关内容:https://www.opengl.org/wiki/Vertex_Specification
如果您无法使用 VBO,那么您可以尝试 display lists。
我正在尝试使用 Pointer 方法绘制我的对象,因为在我渲染的那一刻,当我有多个对象时,由于循环遍历顶点等。我听说使用指针方法会加快处理速度并使帧速率更好,因为它加载得更快。
这就是我现在正在使用的,我不能生成超过 3 个对象而不会导致游戏严重滞后。
for (int j = 0; j < mesh->objectParts.size(); j++) {//loop through each object part
glBindTexture(GL_TEXTURE_2D, textures[j]->getId());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBegin(GL_TRIANGLES);
for (int i = 0; i < mesh->objectParts[j]->faces[0].size(); i++) {
glTexCoord2fv(&mesh->textureCoords[mesh->objectParts[j]->faces[1][i]]->u);
glNormal3fv(&mesh->normals[mesh->objectParts[j]->faces[2][i]]->x);
glVertex3fv(&mesh->indexedVertices[mesh->objectParts[j]->faces[0][i]]->x);
}
glEnd();
这是转换为指针方法的尝试
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
for (int i = 0; i < mesh->objectParts.size(); i++) {//loop through the amount of parts
glBindTexture(GL_TEXTURE_2D, textures[i]->getId());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glVertexPointer(3, GL_FLOAT, 0, &mesh->indexedVertices[0]->x);
glNormalPointer(GL_FLOAT, 0, &mesh->normals[0]->x);
glTexCoordPointer(2, GL_FLOAT, 0, &mesh->textureCoords[0]->u);
for (int j = 0; j < 3; j++)
glDrawElements(GL_TRIANGLES, mesh->objectParts[i]->faceCount(), GL_UNSIGNED_SHORT, &mesh->objectParts[i]->faces[j][0]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
我不确定后者是如何工作的,它肯定是不正确的,因为它在绘制任何对象之前就崩溃了。
编辑:
我确实在我的旧 post
上试过这个答案C++ .obj parser, issue with parsing, or drawing using OpenGL
我删除了索引列表,并在解析文件时存储了顶点、法线和纹理的所有数据。然后我将它们直接传递给指针方法并使用 glDrawArrays 进行绘制。然而,它使我的对象变形,并且它绝对不会像工作渲染代码那样出现。
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, &mesh->unindexedVertices[0]->x);
glNormalPointer(GL_FLOAT, 0, &mesh->unindexedNormals[0]->x);
glTexCoordPointer(2, GL_FLOAT, 0, &mesh->unindexedTextureCoords[0]->u);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
这是删除索引列表后的绘制方式,结果如下:
谁能帮我把上面的代码转换成下面的代码?
更改为指针方法可能不会有太大帮助,因为这里最大的问题是您每帧都发送顶点数据。
如果您的网格是静态的,您可以使用 VBO 和 VAO:您只需要将顶点数据发送到 OpenGL 实现一次并使用它进行绘制,您只需要为您的网格绑定 VAO然后调用适当的绘图调用。这是 "modern" 方法。您可以在这里阅读更多相关内容:https://www.opengl.org/wiki/Vertex_Specification
如果您无法使用 VBO,那么您可以尝试 display lists。