C++:OpenGL正交深度
C++: OpenGL orthographic depth
我 运行 遇到了一个让我很苦恼的问题。我正在构建一个 2D 游戏(使用正交投影,所有数学运算都是用 glm 完成的)并且我正在使用一个渲染器在一次调用中绘制原语(通过元素数组)。这会带来一个问题,因为事物是按照给定的顺序绘制的,而这不是我想要的。我试过使用 z 坐标进行深度测试。当我启用深度测试时,它仍然没有以正确的顺序绘制它们,而是相反的方式,第一个给渲染器的是在顶部,其余的在它后面。
这是一些代码:
// Vertex Shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
uniform mat4 camera_matrix;
out vec4 fragment_color;
void main()
{
gl_Position = camera_matrix * vec4(position, 1.0);
fragment_color = color;
{
// Fragment Shader
#version 330 core
layout (location = 0) out vec4 color;
in vec4 fragment_color;
void main()
{
color = fragment_color;
}
// Part of the rendering code
void render()
{
window.clear();
shader_program.begin();
renderer.drawRectangle(vec2(0, 0),
vec2(100, 100),
vec4(1, 0, 0, 1),
1.0f); // depth value
renderer.drawRectangle(vec2(50, 50),
vec2(100, 100),
vec4(0, 1, 0, 1),
-1.0f); // depth value
shader_program.end();
window.refresh();
}
// Renderer's code
void drawPolygon(const vec2* vertices, int count, const vec4& color, float depth)
{ // The drawRectangle just creates 4 vertices of the corners and passes them to this function
int first = m_offset;
m_vertices.emplace_back(vec3(vertices[0], depth), color);
m_vertices.emplace_back(vec3(vertices[1], depth), color);
m_offset += 2;
for (int i = 2; i < count; i++)
{
m_vertices.emplace_back(vec3(vertices[i], depth), color);
// Basically a triangle fan
m_indices.emplace_back(first);
m_indices.emplace_back(m_offset[1] - 1);
m_indices.emplace_back(m_offset[1]++);
}
}
// Draw call
void flush()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * m_vertices.size(), m_vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * m_indices.size(), m_indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
2016 年 1 月 6 日更新:
在考虑了更多问题之后,我假设它可能是我正在使用的 window API (GLFW) 所以我更改了我的 window class 以适应 SDL2(很简单,去模块化代码),问题仍然存在,所以这取决于我的代码。
我会把它作为评论,但没有足够的声誉。你用过代码吗
glEnable(GL_DEPTH_TEST)
在你的程序中更早?没有这个,最后画的都会在最上面。
因此,在进一步研究问题之后,我忘记了您可以 "debug" 着色器通过检查值并在满足条件时输出特定颜色。所以我改变了我的着色器以将位置传递给片段并测试了 built-in 变量 gl_FragDepth 以及发现它没有被设置(这很明显,虽然我假设这是自动设置的,纠正我如果我错了)。当使用 z-coord 设置该值时,整个问题都得到了解决。
这是更新的着色器:
// Vertex Shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
uniform mat4 camera_matrix = mat4(1.0);
out DATA
{
vec3 position;
vec3 color;
} fragment_out;
void main()
{
gl_Position = camera_matrix * vec4(position, 1.0);
fragment_out.position = position;
fragment_out.color = color;
}
//Fragment Shader
#version 330 core
layout (location = 0) out vec4 color;
in DATA
{
vec3 position;
vec3 color;
} fragment_in;
void main()
{
gl_FragDepth = fragment_in.position.z;
color.rgb = fragment_in.color;
}
现在我可以恢复这个项目了
我 运行 遇到了一个让我很苦恼的问题。我正在构建一个 2D 游戏(使用正交投影,所有数学运算都是用 glm 完成的)并且我正在使用一个渲染器在一次调用中绘制原语(通过元素数组)。这会带来一个问题,因为事物是按照给定的顺序绘制的,而这不是我想要的。我试过使用 z 坐标进行深度测试。当我启用深度测试时,它仍然没有以正确的顺序绘制它们,而是相反的方式,第一个给渲染器的是在顶部,其余的在它后面。
这是一些代码:
// Vertex Shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
uniform mat4 camera_matrix;
out vec4 fragment_color;
void main()
{
gl_Position = camera_matrix * vec4(position, 1.0);
fragment_color = color;
{
// Fragment Shader
#version 330 core
layout (location = 0) out vec4 color;
in vec4 fragment_color;
void main()
{
color = fragment_color;
}
// Part of the rendering code
void render()
{
window.clear();
shader_program.begin();
renderer.drawRectangle(vec2(0, 0),
vec2(100, 100),
vec4(1, 0, 0, 1),
1.0f); // depth value
renderer.drawRectangle(vec2(50, 50),
vec2(100, 100),
vec4(0, 1, 0, 1),
-1.0f); // depth value
shader_program.end();
window.refresh();
}
// Renderer's code
void drawPolygon(const vec2* vertices, int count, const vec4& color, float depth)
{ // The drawRectangle just creates 4 vertices of the corners and passes them to this function
int first = m_offset;
m_vertices.emplace_back(vec3(vertices[0], depth), color);
m_vertices.emplace_back(vec3(vertices[1], depth), color);
m_offset += 2;
for (int i = 2; i < count; i++)
{
m_vertices.emplace_back(vec3(vertices[i], depth), color);
// Basically a triangle fan
m_indices.emplace_back(first);
m_indices.emplace_back(m_offset[1] - 1);
m_indices.emplace_back(m_offset[1]++);
}
}
// Draw call
void flush()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * m_vertices.size(), m_vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * m_indices.size(), m_indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
2016 年 1 月 6 日更新: 在考虑了更多问题之后,我假设它可能是我正在使用的 window API (GLFW) 所以我更改了我的 window class 以适应 SDL2(很简单,去模块化代码),问题仍然存在,所以这取决于我的代码。
我会把它作为评论,但没有足够的声誉。你用过代码吗 glEnable(GL_DEPTH_TEST) 在你的程序中更早?没有这个,最后画的都会在最上面。
因此,在进一步研究问题之后,我忘记了您可以 "debug" 着色器通过检查值并在满足条件时输出特定颜色。所以我改变了我的着色器以将位置传递给片段并测试了 built-in 变量 gl_FragDepth 以及发现它没有被设置(这很明显,虽然我假设这是自动设置的,纠正我如果我错了)。当使用 z-coord 设置该值时,整个问题都得到了解决。 这是更新的着色器:
// Vertex Shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
uniform mat4 camera_matrix = mat4(1.0);
out DATA
{
vec3 position;
vec3 color;
} fragment_out;
void main()
{
gl_Position = camera_matrix * vec4(position, 1.0);
fragment_out.position = position;
fragment_out.color = color;
}
//Fragment Shader
#version 330 core
layout (location = 0) out vec4 color;
in DATA
{
vec3 position;
vec3 color;
} fragment_in;
void main()
{
gl_FragDepth = fragment_in.position.z;
color.rgb = fragment_in.color;
}
现在我可以恢复这个项目了