2

I'm hoping to draw a 2D Grid within a finite space on the X axis using OpengGL 4.0.

I wish to use GLSL using vert/frag shaders etc for rending the light (making them appear).

It can be done with the simplest code using older OpenGL 2.0 methods but then of course it doesn't use lighting/shaders to colour them:

    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();
        }
    }

But I can'd find any tutorials other than this one which I don't understand well enough to convert from a graph to a simple 2D Grid in 3D space.

Reanimation
  • 2,911
  • 10
  • 46
  • 82

2 Answers2

5

Yes, you can use just shaders to generate your geometry...

  1. Don't bind any VBOs.
  2. Call glDrawArrays()
  3. Use gl_VertexID in the vertex shader or gl_PrimitiveID in the geometry shader to procedurally generate your stuff.

It can be faster exactly because there are no vertex attributes or input data. Not to mention the space saved and initialization time is next to nothing.

Here's an example of a vertex shader that draws a grid with 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);
}

I did have some trouble drawing without VBOs bound on my ancient ATI card. This approach works fine on my Nvidia cards with new drivers. Discussed further here: Opengl, DrawArrays without binding VBO, where glDrawArraysInstanced/gl_InstanceID is suggested as an alternative.

A further note. I've noticed modulo % arithmetic can be a little slow in some cases. Using simpler bitwise operations or other tricks may speed things up.

Community
  • 1
  • 1
jozxyqk
  • 15,424
  • 12
  • 80
  • 168
-1

GLSL is not meant for doing things like that. GLSL is meant for writing shaders which:

  • tesselate simple geometries into slightly more complex ones
  • transform simple primitives in abstract space into clip space
  • control the fragment rasterization process

GLSL isn't intended to be used for actually making draw calls. Yes, you can use shaders for procedural geometry generation, but you always start off with geometry and draw calls made on the client side.

Mike G
  • 748
  • 5
  • 19
datenwolf
  • 155,162
  • 12
  • 177
  • 284
  • Yeh, I'm hoping to draw them in openGL 4.0+ using VBO's and using GLSL for lighting/shading. That's why the code I copied into my question doesn't work because it's OpenGL 2.0. I'm not sure how to implement a grid like object using lines in 4.0 and unsure how to render them using .vert and .frag files. – Reanimation Nov 09 '13 at 21:28
  • 1
    @Reanimation: Then I suggest you work through Nicol Bolas excellent modern OpenGL tutorial, which explains everything of that http://arcsynthesis.org/gltut – when it comes to create a grid, it's just a matter of putting the vertices into an array (in sequence) and tell OpenGL do draw that from element 0 … N. – datenwolf Nov 09 '13 at 21:50