【问题标题】:C++: OpenGL orthographic depthC++:OpenGL正交深度
【发布时间】:2016-01-06 06:05:46
【问题描述】:

我遇到了一个让我很头疼的问题。我正在构建一个 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 日更新: 在考虑了更多关于这个问题之后,我假设它可能是我正在使用的窗口 API(GLFW)所以我改变了我的窗口类以适应 SDL2(这很容易,去模块化代码)并且问题仍然存在所以它归结为我的代码。

【问题讨论】:

  • camera_matrix 的值是多少?
  • @Reto Koradi Camera_matrix 是使用 glm::ortho(0.0f, width, 0.0f, height, -1.0f, 1.0); 创建的
  • 至少对于这里显示的矩形,第一个绘制在顶部看起来是正确的,因为它的深度更小。或者它总是第一个,即使你交换了绘制调用的顺序?那会很奇怪。
  • @RetoKoradi 交换抽签顺序会改变谁在前面。
  • 一个可能的问题是您没有深度缓冲区。您如何请求取决于您用于设置 OpenGL 绘图的框架/工具包,但它通常发生在您创建上下文时。

标签: c++ opengl depth-buffer


【解决方案1】:

因此,在进一步研究问题后,我忘记了您可以通过检查值并在满足条件时输出某种颜色来“调试”着色器。因此,我更改了两个着色器以将位置传递给片段并测试了内置变量 gl_FragDepth 并发现它没有设置(这很明显,尽管我假设这是自动设置的,如果我错了,请纠正我) .当使用 z 坐标设置该值时,整个问题都得到了解决。 这是更新的着色器:

// 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;
}

现在我可以继续这个项目了

【讨论】:

    【解决方案2】:

    我会将此作为评论,但没有足够的声誉。你用过代码吗 glEnable(GL_DEPTH_TEST) 在你的程序早期?没有这个,最后绘制的将在顶部。

    【讨论】:

    • 它在问题中说OP启用了深度测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 2011-05-17
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多