c++ - 任何人都知道为什么这个特定的对象被渲染在另一个对象的前面,尽管它的 z 坐标?
问题描述
我正在使用 OpenGL 重新创建 3D 的 2D 场景。我的目标是用显示器、塔、键盘和鼠标重新创建一张桌子的图像。到目前为止,我已经为监视器渲染了监视器和屏幕。显示器(灰色框)的 z 坐标最初大于纯白屏幕的 z 坐标,因为屏幕应该在它的前面。但是,当它呈现时,会发生与您期望的完全相反的情况。屏幕呈现在矩形立方体的后面。我可以告诉我何时对我的旋转矩阵应用 180 度旋转。因此,当我调整 z 坐标以使屏幕大于显示器时,它会出现在前面。但是随着 z 坐标的增加,物体应该会越来越远,所以这真的很奇怪。
这是屏幕 z 坐标大于显示器 z 坐标时的屏幕截图:
这是旋转 45 度的相同两个对象:
当然,这就是它应该看起来的样子,但前提是屏幕的坐标小于监视器的坐标。这里有一些相关的代码可以帮助你理解我在说什么。我留下了一些我认为不相关的代码。如果您需要我提供更多代码,请告诉我。
void uCreateScreenMesh(GLMesh& mesh) {
GLfloat vertices[] = {
-0.25f, 0.95f, 0.81f, 1.0f, 1.0f, 1.0f, 1.0f, //0
-0.25f, 0.65f, 0.81f, 1.0f, 1.0f, 1.0f, 1.0f, //1
0.25f, 0.65f, 0.81f, 1.0f, 1.0f, 1.0f, 1.0f, //2
0.25f, 0.95f, 0.81f, 1.0f, 1.0f, 1.0f, 1.0f //3
};
GLushort indices[] = {
0, 1, 2,
0, 3, 2
};
const GLuint floatsPerVertex = 3;
const GLuint floatsPerColor = 4;
const GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
mesh.nIndices = sizeof(indices) / sizeof(indices[0]);
glGenVertexArrays(1, &mesh.vao);
glBindVertexArray(mesh.vao);
glGenBuffers(2, mesh.vbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbo[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//create vertex attribute pointers
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
glEnableVertexAttribArray(1);
}
void uCreateMonitorMesh(GLMesh& mesh)
{
GLfloat vertices[] = {
//monitor (rectangle)
-0.3f, 1.0f, 0.75f, 0.5f, 0.5f, 0.5f, 1.0f, //0
-0.3f, 1.0f, 0.8f, 0.5f, 0.5f, 0.5f, 1.0f, //1
-0.3f, 0.6f, 0.75f, 0.5f, 0.5f, 0.5f, 1.0f, //2
-0.3f, 0.6f, 0.8f, 0.5f, 0.5f, 0.5f, 1.0f, //3
0.3f, 0.6f, 0.75f, 0.5f, 0.5f, 0.5f, 1.0f, //4
0.3f, 0.6f, 0.8f, 0.5f, 0.5f, 0.5f, 1.0f, //5
0.3f, 1.0f, 0.75f, 0.5f, 0.5f, 0.5f, 1.0f, //6
0.3f, 1.0f, 0.8f, 0.5f, 0.5f, 0.5f, 1.0f //7
};
GLushort indices[] = {
//monitor front
0, 2, 4,
0, 6, 4,
//top
0, 1, 7,
0, 6, 7,
//left side
0, 3, 1,
0, 2, 1,
//bottom side
2, 3, 5,
2, 5, 4,
//right side
4, 5, 6,
4, 7, 6,
//monitor back
1, 3, 5,
1, 7, 5
};
const GLuint floatsPerVertex = 3;
const GLuint floatsPerColor = 4;
const GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
mesh.nIndices = sizeof(indices) / sizeof(indices[0]);
glGenVertexArrays(1, &mesh.vao);
glBindVertexArray(mesh.vao);
glGenBuffers(2, mesh.vbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbo[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//create vertex attribute pointers
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
glEnableVertexAttribArray(1);
}
void uRender()
{
//enable z-depth
glEnable(GL_DEPTH_TEST);
//clear frame and z buffers
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 scale = glm::scale(glm::vec3(1.2f, 1.2f, 1.2f));
glm::mat4 rotation = glm::rotate(glm::radians(0.f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));
glm::mat4 model = translation * rotation * scale;
glm::mat4 view = glm::translate(glm::vec3(0.0f, 0.0f, -3.5f));
glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);
glUseProgram(programId);
GLint modelLoc = glGetUniformLocation(programId, "model");
GLint viewLoc = glGetUniformLocation(programId, "view");
GLint projLoc = glGetUniformLocation(programId, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(screenMesh.vao);
glDrawElements(GL_TRIANGLES, screenMesh.nIndices, GL_UNSIGNED_SHORT, NULL);
glBindVertexArray(monitorMesh.vao);
glDrawElements(GL_TRIANGLES, monitorMesh.nIndices, GL_UNSIGNED_SHORT, NULL);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
我尝试更改顶点数组对象的绑定顺序,但正如我所料,这并没有改变任何东西。
感谢所有帮助,谢谢。
解决方案
推荐阅读
- mysql - 构建此数据库的提示
- vba - 查找并替换具有相反值的特定列中的字符串,一次一行
- javascript - 如何在 Slick carousel 上制作黑色背景过渡?
- c# - Visual Studio 找不到 Microsoft.AspNetCore.DataProtection 的 PersistKeysToRedis 方法
- mysql - MySQL:仅选择仅具有某些值的组
- url-masking - 是否可以使用谷歌域来转发用端口屏蔽的子域并将其屏蔽?
- android - Android - ExpandableListView 内容在屏幕底部被截断
- r - 在 `dplyr` 的 `mutate()` 中应用函数
- angular - 在页面加载时加载 MDBootstrap 模式
- grails - 带有 SAML 的 Grails 3 - 身份验证失败