C++ 片段着色器将面绘制在彼此的顶部,即使它不应该';T
我正在用OpenGL编写一个简单的3D世界,可以渲染各种东西。我对OpenGL比较陌生,可能没有注意到什么,但是(我猜)片段着色器有一个很大的问题 它所做的是忽略z值并按索引缓冲区给定的顺序绘制面。我的意思是,例如,如果有条件索引缓冲区,它包含三角形1、三角形2和三角形3,它们在相机前面排成一行,那么三角形3,不管它的z值是多少,都会被画在其他两个的上面,因为它是最后一个。 结果,我变成了这样: 这张图片正好显示了我的意思。相对于相邻侧,正面的行为就像是透明的,但就透明度而言,它忽略了平行侧,因为它们是按这样的顺序绘制的 我的相机代码:C++ 片段着色器将面绘制在彼此的顶部,即使它不应该';T,c++,opengl,glfw,glm-math,C++,Opengl,Glfw,Glm Math,我正在用OpenGL编写一个简单的3D世界,可以渲染各种东西。我对OpenGL比较陌生,可能没有注意到什么,但是(我猜)片段着色器有一个很大的问题 它所做的是忽略z值并按索引缓冲区给定的顺序绘制面。我的意思是,例如,如果有条件索引缓冲区,它包含三角形1、三角形2和三角形3,它们在相机前面排成一行,那么三角形3,不管它的z值是多少,都会被画在其他两个的上面,因为它是最后一个。 结果,我变成了这样: 这张图片正好显示了我的意思。相对于相邻侧,正面的行为就像是透明的,但就透明度而言,它忽略了平行侧,
PCamera::PCamera(GLFWwindow* projectWindow, float windowWidth, float windowHeight)
{
window = projectWindow;
wWidth = windowWidth;
wHeight = windowHeight;
Position = glm::vec3(0.f, 0.f, -10.f);
Rotation = glm::vec3(0.f, glm::pi<float>(), 0.f);
if (glfwRawMouseMotionSupported())
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
glfwGetCursorPos(window, &xposnormal, &yposnormal);
}
PCamera::~PCamera()
{
}
glm::mat4 PCamera::NavigateCamera()
{
double xpos, ypos;
int state;
glfwGetCursorPos(window, &xpos, &ypos);
state = glfwGetKey(window, GLFW_KEY_ESCAPE);
if (state == GLFW_PRESS)
{
bMouseControl = false;
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}
state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
if ((state == GLFW_PRESS) && (bMouseControl == false))
{
bMouseControl = true;
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
glfwGetCursorPos(window, &xposnormal, &yposnormal);
}
if (bMouseControl)
{
glfwGetCursorPos(window, &xpos, &ypos);
Rotation.x += (float)(yposnormal - ypos) / -300.f;
Rotation.y += (float)(xposnormal - xpos) / -300.f;
glfwSetCursorPos(window, xposnormal, yposnormal);
}
glm::mat4 RTSMatrix = glm::rotate(UnitMatrix, Rotation.x, glm::vec3(1.f, 0.f, 0.f)) * glm::rotate(UnitMatrix, Rotation.y, glm::vec3(0.f, 1.f, 0.f));
glm::vec3 DeltaPosition(0.f, 0.f, 0.f);
state = glfwGetKey(window, GLFW_KEY_W);
if (state == GLFW_PRESS) DeltaPosition.z += 0.01f;
state = glfwGetKey(window, GLFW_KEY_S);
if (state == GLFW_PRESS) DeltaPosition.z -= 0.01f;
state = glfwGetKey(window, GLFW_KEY_A);
if (state == GLFW_PRESS) DeltaPosition.x += 0.01f;
state = glfwGetKey(window, GLFW_KEY_D);
if (state == GLFW_PRESS) DeltaPosition.x -= 0.01f;
state = glfwGetKey(window, GLFW_KEY_LEFT_SHIFT);
if (state == GLFW_PRESS) DeltaPosition.y -= 0.01f;
state = glfwGetKey(window, GLFW_KEY_SPACE);
if (state == GLFW_PRESS) DeltaPosition.y += 0.01f;
glm::vec4 D4Position(Position, 0.f);
glm::mat4 InverseRTSMatrix = glm::rotate(UnitMatrix, -Rotation.y, glm::vec3(0.f, 1.f, 0.f)) * glm::rotate(UnitMatrix, -Rotation.x, glm::vec3(1.f, 0.f, 0.f));
D4Position -= InverseRTSMatrix*glm::vec4(DeltaPosition, 0.0);
Position.x = D4Position.x;
Position.y = D4Position.y;
Position.z = D4Position.z;
RTSMatrix = RTSMatrix * glm::translate(UnitMatrix, -Position);
return RTSMatrix;
}
void PCamera::UpdateProjectionMatrix(float Angle, float windowWidth, float windowHeight)
{
ProjectionMatrix = glm::perspective(Angle, (GLfloat)windowWidth / (GLfloat)windowHeight, -1.0f, 1.0f);
}
我的主执行文件的代码:
PProject::PProject(PRenderer * Renderer)
{
ProjectRenderer = Renderer;
}
PProject::~PProject()
{
}
int PProject::Launch()
{
GLFWwindow* window;
if (!glfwInit()) return -1;
window = glfwCreateWindow(640, 480, "PhysMaker", NULL, NULL);
if (!window) { glfwTerminate(); return -1; }
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) return -1;
float pos[] =
{
-0.5, -0.5, -0.5, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 1.0, 0.0,
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
-0.5, 0.5, -0.5, 1.0, 0.0, 1.0,
0.5, 0.5, 0.5, 1.0, 0.0, 1.0,
0.5, -0.5, 0.5, 1.0, 1.0, 0.0,
0.5, -0.5, -0.5, 1.0, 0.0, 0.0,
0.5, 0.5, -0.5, 0.0, 1.0, 1.0,
0.5, -0.5, 0.5, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 1.0, 0.0,
0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
-0.5, 0.5, 0.5, 1.0, 0.0, 0.0
};
unsigned int ind[]
{
0, 1, 2,
2, 3, 0,
6, 5, 4,
4, 7, 6,
8, 9, 10,
9, 11, 10
};
PShader NewShader("Source/Shaders/Vertex.shader","Source/Shaders/Fragment.shader");
NewShader.Bind();
glfwGetWindowSize(window, &windowWidth, &windowHeight);
PCamera MainCamera(window, windowWidth, windowHeight);
PObject NewObject(pos, 24, ind, 18, 0);
ProjectRenderer->SceneObjects.insert(ProjectRenderer->SceneObjects.end(), &NewObject);
while (!glfwWindowShouldClose(window))
{
glfwGetWindowSize(window, &windowWidth, &windowHeight);
glViewport(0, 0, windowWidth, windowHeight);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
MainCamera.UpdateProjectionMatrix(45.f, windowWidth, windowHeight);
glm::mat4 translation = MainCamera.ProjectionMatrix * MainCamera.NavigateCamera();
glUniformMatrix4fv(glGetUniformLocation(NewShader.Shader_ID, "u_MVP"), 1, GL_FALSE, &translation[0][0]);
ProjectRenderer->Draw(&NewObject);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
片段和顶点着色器:
#FRAGMENT
#version 330 core
out vec4 color;
in vec3 vertexColor;
void main()
{
color = vec4(vertexColor, 1.0);;
}
#VERTEX
#version 330 core
in layout(location = 0) vec3 position;
in layout(location = 1) vec3 Color;
out vec3 vertexColor;
uniform mat4 u_MVP;
void main()
{
gl_Position = (u_MVP * vec4(position, 1.f));
vertexColor = Color;
}
也许是透视法有问题?我应该使用深度吗?如何使用?我以前用过,但没用。好像是投影矩阵的问题。那么,怎么了?您必须启用。如果启用了深度测试,则根据所写入样本的深度测试片段的深度。如果失败,该片段将被丢弃。深度测试是一种全局状态。在应用程序循环之前启用一次就足够了
glEnable(GL_深度_测试);
启用深度测试后,还必须清除深度缓冲区:(见附件)
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
您必须启用。但是如果我启用了深度,它根本不会渲染任何东西,我得到的只是灰色屏幕:(@NicolasIceberg我已经扩展了答案。glClear(GL\u COLOR\u BUFFER\u BIT | GL\u depth\u BUFFER\u BIT);
)哦,谢谢你。它帮助将情况改变为稍微不同的情况(它仍然是错误的,但它是正确的)。现在向后的面总是在前面渲染。我尝试了glDepthFunc(GL_LEQUAL),但当时没有帮助all@NicolasIceberg投影矩阵错误。在透视投影时,近平面和远平面必须为正值(0ProjectionMatrix=glm::perspective(Angle,(GLfloat)windowWidth/(GLfloat)窗高,0.01f,1.0f);
非常感谢您,您帮了我很多忙。我真的很感谢您的努力,我很抱歉您花了这么多时间解决我的问题。祝您玩得愉快)
#FRAGMENT
#version 330 core
out vec4 color;
in vec3 vertexColor;
void main()
{
color = vec4(vertexColor, 1.0);;
}
#VERTEX
#version 330 core
in layout(location = 0) vec3 position;
in layout(location = 1) vec3 Color;
out vec3 vertexColor;
uniform mat4 u_MVP;
void main()
{
gl_Position = (u_MVP * vec4(position, 1.f));
vertexColor = Color;
}