在 3D 空间中使用 GLSL 绘制 2D 网格

Rea*_*ion 2 opengl glsl

我希望使用 OpenGL 4.0 在 X 轴上的有限空间内绘制 2D 网格。

我希望使用 GLSL 使用 vert/frag 着色器等来渲染光线(使它们出现)。

它可以使用较旧的 OpenGL 2.0 方法通过最简单的代码来完成,但当然它不使用照明/着色器来为它们着色:

    void Draw_Grid()
    {
     for(float i = -500; i <= 500; i += 5)
        {
         glBegin(GL_LINES);
            glColor3ub(150, 190, 150);
            glVertex3f(-500, 0, i);
            glVertex3f(500, 0, i);
            glVertex3f(i, 0,-500);
            glVertex3f(i, 0, 500);
         glEnd();
        }
    }
Run Code Online (Sandbox Code Playgroud)

但除了这个教程之外,我找不到任何教程,因为我不太理解这些教程,无法将图形转换为 3D 空间中的简单 2D 网格。

joz*_*yqk 6

是的,您可以仅使用着色器来生成几何体......

  1. 不要绑定任何VBO。
  2. 称呼glDrawArrays()
  3. gl_VertexID在顶点着色器或gl_PrimitiveID几何着色器中使用来按程序生成您的东西。

它可以更快,因为没有顶点属性或输入数据。更不用说节省的空间和初始化时间几乎为零。

下面是一个顶点着色器的示例,它使用以下命令绘制网格GL_TRIANGLES

#version 150

uniform mat4 modelviewMat;
uniform mat3 normalMat;
uniform mat4 projectionMat;

uniform ivec2 dim;

out vec3 esNorm;

const vec2 triOffset[] = vec2[](
    vec2(0,0),
    vec2(0,1),
    vec2(1,1),
    vec2(0,0),
    vec2(1,1),
    vec2(1,0));

void main()
{
    int triVert = gl_VertexID % 6;
    int gridIndex = gl_VertexID / 6;
    vec2 coord = vec2(gridIndex / dim.x, gridIndex % dim.x);
    coord = (coord + triOffset[triVert]) / vec2(dim);
    vec4 esVert = modelviewMat * vec4(coord * 2.0 - 1.0, 0.0, 1.0);
    gl_Position = projectionMat * esVert;
    esNorm = normalMat * vec3(0.0, 0.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

在我古老的 ATI 卡上没有绑定 VBO 的情况下,我在绘图时确实遇到了一些麻烦。这种方法在我的带有新驱动程序的 Nvidia 卡上运行良好。此处进一步讨论:Opengl, DrawArrays without binding VBO,其中glDrawArraysInstanced/gl_InstanceID被建议作为替代方案。

进一步说明。我注意到%在某些情况下模运算可能会有点慢。使用更简单的按位运算或其他技巧可能会加快速度。