我使用OpenGL,GLEW和GLFW拍摄同一网格的多个图像。每个镜头中的网格(三角形)不会改变,只有ModelViewMatrix
会改变。
这是我的主循环的重要代码:
for (int i = 0; i < number_of_images; i++) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* set GL_MODELVIEW matrix depending on i */
glBegin(GL_TRIANGLES);
for (Triangle &t : mesh) {
for (Point &p : t) {
glVertex3f(p.x, p.y, p.z);
}
}
glReadPixels(/*...*/) // get picture and store it somewhere
glfwSwapBuffers();
}
如您所见,我为每个要拍摄的镜头设置/传输三角形顶点。有没有解决方案,我只需要转移一次?我的网格非常大,所以这种转移需要相当长的时间。
答案 0 :(得分:5)
在2016年,您不得使用glBegin
/ glEnd
。没门。请改用Vertex Array Obejcts;并使用自定义vertex和/或geometry着色器重新定位和修改顶点数据。使用这些技术,您可以将数据上传到GPU一次,然后您就可以使用各种变换绘制相同的网格。
以下是您的代码的外观大纲:
// 1. Initialization.
// Object handles:
GLuint vao;
GLuint verticesVbo;
// Generate and bind vertex array object.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Generate a buffer object.
glGenBuffers(1, &verticesVbo);
// Enable vertex attribute number 0, which
// corresponds to vertex coordinates in older OpenGL versions.
const GLuint ATTRIBINDEX_VERTEX = 0;
glEnableVertexAttribArray(ATTRIBINDEX_VERTEX);
// Bind buffer object.
glBindBuffer(GL_ARRAY_BUFFER, verticesVbo);
// Mesh geometry. In your actual code you probably will generate
// or load these data instead of hard-coding.
// This is an example of a single triangle.
GLfloat vertices[] = {
0.0f, 0.0f, -9.0f,
0.0f, 0.1f, -9.0f,
1.0f, 1.0f, -9.0f
};
// Determine vertex data format.
glVertexAttribPointer(ATTRIBINDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Pass actual data to the GPU.
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*3*3, vertices, GL_STATIC_DRAW);
// Initialization complete - unbinding objects.
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// 2. Draw calls.
while(/* draw calls are needed */) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao);
// Set transformation matrix and/or other
// transformation parameters here using glUniform* calls.
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0); // Unbinding just as an example in case if some other code will bind something else later.
}
顶点着色器可能如下所示:
layout(location=0) in vec3 vertex_pos;
uniform mat4 viewProjectionMatrix; // Assuming you set this before glDrawArrays.
void main(void) {
gl_Position = viewProjectionMatrix * vec4(vertex_pos, 1.0f);
}
另请查看this page以获得优质的现代加速图形书。
答案 1 :(得分:0)
@BDL已经评论过你应该放弃立即模式绘制调用(glBegin ... glEnd)并切换到从顶点缓冲对象(VBO)获取数据的顶点数组绘图(glDrawElements,glDrawArrays)。 @Sergey在他的回答中提到了顶点数组对象,但这些实际上是VBO的状态容器。
你必须要理解的一件非常重要的事情 - 以及你提出问题的方式,显然你还不知道的事情是,OpenGL不处理&#34;网格& #34;,&#34;场景&#34;等等。 OpenGL只是一个绘图API。它绘制点......线......和三角形......一次一个......它们之间没有任何联系。就是这样。因此,当您显示&#34;相同&#34;的多个视图时事情,你必须 画出几次。没有办法解决这个问题。
最新版本的OpenGL支持多视口渲染,但仍需要几何着色器将几何体相乘成几个要绘制的部分。