在同一屏幕上显示两个不同的对象
Displaying two different objects on same screen
我试图在同一屏幕上显示一个球体和一个环面,但 "glutInitDisplayMode" 似乎是导致我只显示一个的原因。
当我将它保持为 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA |GLUT_DEPTH)
时,圆环显示。
当我将其保持为 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
时,球体会显示。我该怎么做才能显示两者?
渲染代码如下:
static void render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// clear the identity matrix.
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
glColor3f(0.0, 0.0, 0.0);
glRotatef(zRotated, 0.0, 0.0, 1.0);
// scaling transfomation
glScalef(1.0, 1.0, 1.0);
// built-in (glut library) function , draw you a sphere.
glutSolidTorus(innerRadius, outerRadius, sides, rings);
// Flush buffers to screen
glFlush();
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// activate our shader program
glUseProgram(programId);
// turn on depth buffering
glEnable(GL_DEPTH_TEST);
float aspectRatio = (float)width / (float)height;
glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 1000.0f);
// view matrix - orient everything around our preferred view
glm::mat4 view = glm::lookAt(
glm::vec3(40,30,30), // eye/camera location
glm::vec3(0,0,0), // where to look
glm::vec3(0,1,0) // up
);
// model matrix: translate, scale, and rotate the model
glm::vec3 rotationAxis(0,1,0);
glm::mat4 model = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(angle), glm::vec3(0, 1, 0)); // rotate about the y-axis
model = glm::scale(model, glm::vec3(25.0f, 25.0f, 25.0f));
// model-view-projection matrix
glm::mat4 mvp = projection * view * model;
GLuint mvpMatrixId = glGetUniformLocation(programId, "MVP");
glUniformMatrix4fv(mvpMatrixId, 1, GL_FALSE, &mvp[0][0]);
// texture sampler - a reference to the texture we've previously created
// send the texture id to the texture sampler
GLuint textureUniformId = glGetUniformLocation(programId, "textureSampler");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
glUniform1i(textureUniformId, 0);
// find the names (ids) of each vertex attribute
GLint positionAttribId = glGetAttribLocation(programId, "position");
GLint colourAttribId = glGetAttribLocation(programId, "colour");
GLint textureCoordsAttribId = glGetAttribLocation(programId, "textureCoords");
GLint normalAttribId = glGetAttribLocation(programId, "normal");
// provide the vertex positions to the shaders
glBindBuffer(GL_ARRAY_BUFFER, positions_vbo);
glEnableVertexAttribArray(positionAttribId);
glVertexAttribPointer(positionAttribId, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// provide the vertex texture coordinates to the shaders
glBindBuffer(GL_ARRAY_BUFFER, textureCoords_vbo);
glEnableVertexAttribArray(textureCoordsAttribId);
glVertexAttribPointer(textureCoordsAttribId, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
// provide the vertex normals to the shaders
glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
glEnableVertexAttribArray(normalAttribId);
glVertexAttribPointer(normalAttribId, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// draw the triangles
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, (void*)0);
// disable the attribute arrays
glDisableVertexAttribArray(positionAttribId);
glDisableVertexAttribArray(textureCoordsAttribId);
glDisableVertexAttribArray(normalAttribId);
glDisableVertexAttribArray(colourAttribId);
// make the draw buffer to display buffer (i.e. display what we have drawn)
glutSwapBuffers();
}
glutSolidTorus
draws a torus, by the use of the fixed function attributes. For this a compatibility profile OpenGL Context缺一不可。
glutSolidTorus
与您的着色器程序不兼容。使当前安装的程序无效,在 glutSolidTorus
:
之前
glUseProgram(0);
glutSolidTorus(innerRadius, outerRadius, sides, rings);
请注意,OpenGL 是一个状态引擎。如果安装了一个程序,它会一直保留,直到安装另一个程序或它失效,甚至超出框架。在你的情况下,第一帧不是问题,但它仍会安装在第二帧的开头,当 glutSolidTorus
被调用时。
如果您使用双缓冲 window (GLUT_DOUBLE
),则必须调用 glutSwapBuffers
。 glutSwapBuffers
交换缓冲区。 window 中 显示 的缓冲区。 show int eh window 缓冲区已准备好在下一帧中绘制。
在单个缓冲中 window 你可以做到 glFlush
。这会强制 OpenGL 完成 绘图。由于绘制到的缓冲区与显示在 window 上的相同,这导致绘制到缓冲区的所有内容立即显示在 window.
中
将 glFlush
调用从 render
函数的中间移动到它的末尾,就在 glutSwapBuffers
:
之前
void render()
{
// ...
glUseProgram(0);
glutSolidTorus(innerRadius, outerRadius, sides, rings);
// glFlush(); <---- delete
// ...
glUseProgram(programId);
// ...
glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, (void*)0);
// ...
glFlush();
glutSwapBuffers();
}
我试图在同一屏幕上显示一个球体和一个环面,但 "glutInitDisplayMode" 似乎是导致我只显示一个的原因。
当我将它保持为 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA |GLUT_DEPTH)
时,圆环显示。
当我将其保持为 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
时,球体会显示。我该怎么做才能显示两者?
渲染代码如下:
static void render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// clear the identity matrix.
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
glColor3f(0.0, 0.0, 0.0);
glRotatef(zRotated, 0.0, 0.0, 1.0);
// scaling transfomation
glScalef(1.0, 1.0, 1.0);
// built-in (glut library) function , draw you a sphere.
glutSolidTorus(innerRadius, outerRadius, sides, rings);
// Flush buffers to screen
glFlush();
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// activate our shader program
glUseProgram(programId);
// turn on depth buffering
glEnable(GL_DEPTH_TEST);
float aspectRatio = (float)width / (float)height;
glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 1000.0f);
// view matrix - orient everything around our preferred view
glm::mat4 view = glm::lookAt(
glm::vec3(40,30,30), // eye/camera location
glm::vec3(0,0,0), // where to look
glm::vec3(0,1,0) // up
);
// model matrix: translate, scale, and rotate the model
glm::vec3 rotationAxis(0,1,0);
glm::mat4 model = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(angle), glm::vec3(0, 1, 0)); // rotate about the y-axis
model = glm::scale(model, glm::vec3(25.0f, 25.0f, 25.0f));
// model-view-projection matrix
glm::mat4 mvp = projection * view * model;
GLuint mvpMatrixId = glGetUniformLocation(programId, "MVP");
glUniformMatrix4fv(mvpMatrixId, 1, GL_FALSE, &mvp[0][0]);
// texture sampler - a reference to the texture we've previously created
// send the texture id to the texture sampler
GLuint textureUniformId = glGetUniformLocation(programId, "textureSampler");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
glUniform1i(textureUniformId, 0);
// find the names (ids) of each vertex attribute
GLint positionAttribId = glGetAttribLocation(programId, "position");
GLint colourAttribId = glGetAttribLocation(programId, "colour");
GLint textureCoordsAttribId = glGetAttribLocation(programId, "textureCoords");
GLint normalAttribId = glGetAttribLocation(programId, "normal");
// provide the vertex positions to the shaders
glBindBuffer(GL_ARRAY_BUFFER, positions_vbo);
glEnableVertexAttribArray(positionAttribId);
glVertexAttribPointer(positionAttribId, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// provide the vertex texture coordinates to the shaders
glBindBuffer(GL_ARRAY_BUFFER, textureCoords_vbo);
glEnableVertexAttribArray(textureCoordsAttribId);
glVertexAttribPointer(textureCoordsAttribId, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
// provide the vertex normals to the shaders
glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
glEnableVertexAttribArray(normalAttribId);
glVertexAttribPointer(normalAttribId, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// draw the triangles
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, (void*)0);
// disable the attribute arrays
glDisableVertexAttribArray(positionAttribId);
glDisableVertexAttribArray(textureCoordsAttribId);
glDisableVertexAttribArray(normalAttribId);
glDisableVertexAttribArray(colourAttribId);
// make the draw buffer to display buffer (i.e. display what we have drawn)
glutSwapBuffers();
}
glutSolidTorus
draws a torus, by the use of the fixed function attributes. For this a compatibility profile OpenGL Context缺一不可。
glutSolidTorus
与您的着色器程序不兼容。使当前安装的程序无效,在 glutSolidTorus
:
glUseProgram(0);
glutSolidTorus(innerRadius, outerRadius, sides, rings);
请注意,OpenGL 是一个状态引擎。如果安装了一个程序,它会一直保留,直到安装另一个程序或它失效,甚至超出框架。在你的情况下,第一帧不是问题,但它仍会安装在第二帧的开头,当 glutSolidTorus
被调用时。
如果您使用双缓冲 window (GLUT_DOUBLE
),则必须调用 glutSwapBuffers
。 glutSwapBuffers
交换缓冲区。 window 中 显示 的缓冲区。 show int eh window 缓冲区已准备好在下一帧中绘制。
在单个缓冲中 window 你可以做到 glFlush
。这会强制 OpenGL 完成 绘图。由于绘制到的缓冲区与显示在 window 上的相同,这导致绘制到缓冲区的所有内容立即显示在 window.
将 glFlush
调用从 render
函数的中间移动到它的末尾,就在 glutSwapBuffers
:
void render()
{
// ...
glUseProgram(0);
glutSolidTorus(innerRadius, outerRadius, sides, rings);
// glFlush(); <---- delete
// ...
glUseProgram(programId);
// ...
glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, (void*)0);
// ...
glFlush();
glutSwapBuffers();
}