Я пишу простой трехмерный мир в OpenGL, который может рендерить различные вещи. Я относительно новичок в OpenGL и, возможно, чего-то не замечаю, но есть действительно большая проблема с (я думаю) фрагментным шейдером.
Что он делает, так это игнорирует z-значение, и dr aws сталкивается с тем, чтобы они были заданы индексным буфером. Под этим я подразумеваю, что если есть, например, буфер условного индекса, и он содержит треугольник 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);
}
Код моего рендерера:
void PRenderer::Draw(PObject * Object)
{
Object->Bind();
glDrawElements(GL_TRIANGLES, Object->IBCount, GL_UNSIGNED_INT, nullptr);
}
Код моего основного исполняемого файла:
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;
}
Возможно что-то не так с перспективой? Должен ли я использовать глубину и как? Я использовал это раньше, но это не помогло. Кажется, что-то с матрицей проекции. Итак, что не так?