GLSL Tutorial – Hello World
Prev: OpenGL skeleton | Next: Color Example |
In programming languages the hello world program is the simplest thing we can write that provides some result, there is even a wikipedia page about it!. Traditionally this program outputs “Hello World”, but since we’re talking about shaders we’re just going to output some geometry instead.
Our pipeline is going to have a vertex and a fragment shader. The vertex shader will receive a vertex position, in local space, and transform it to clip space, see section on Spaces and Matrices. To perform this transformation it will use the projection-view-model matrix.
The processed vertices will then be interpolated using the built-in variable gl_Position
, see the section on Vertex Shader.
The rasterization then produces fragments that will be processed in the fragment shader. This shader will only output a single color for each fragment that it processes.
The vertex shader starts with the version declaration
#version 330
Then we declare the uniform variables. In this case we have a 4×4 matrix to store the projection-view-model matrix called pvm
. We’re going to use a uniform block to store the matrix. This is probably overkill for a single matrix but in future tutorials this block will grow to accommodate more matrices.
layout (std140) uniform Matrices { mat4 pvm; } ;
Next we declare our input vertex attribute. In this case we only require the vertex coordinates, which is a vec4
.
in vec4 position;
Finally we can write the main function. The only thing this function will do is to compute the built-in variable gl_Position
, multiplying the pvm
matrix by our vertex coordinates.
void main() { gl_Position = pvm * position ; }
The full vertex shader is as follows:
#version 330 layout (std140) uniform Matrices { mat4 pvm; } ; in vec4 position; out vec4 color; void main() { gl_Position = pvm * position ; }
The fragment shader is even simpler. It also starts with the version number, it declares an output variable, which will by default be the color we’ll see on the screen, and it writes a constant color to that variable.
#version 330 out vec4 outputF; void main() { outputF = vec4(1.0, 0.0, 0.0, 1.0); }
And that’s it. The end result, a constant colored cube, is not very exciting, but this is the starting point for most of the shaders we’ll have in this tutorial.
Full source code and a VS2010 project can be downloaded in here.
Prev: OpenGL skeleton | Next: Color Example |
6 Responses to “GLSL Tutorial – Hello World”
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Hi there! First, I’d like to thank you for having a really nice-looking and complete tutorial here.
I’m currently trying to experiment with shader-based coloring, and I decided to copy these two shaders since, it seems to me, they will essentially turn my object flat and red (since 1,0,0,1 is red, right?).
Unfortunately, the resulting object is white rather than red, and if I go further into your tutorials, the object stays red (position-based coloring, for instance, doesn’t work either – it just stays white). I am rendering my object as follows:
glBindBuffer(GL_ARRAY_BUFFER, m_WorldBuffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), 0);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 6 * sizeof(float), (void*)12);
glDrawArrays(GL_TRIANGLES, 0, m_ArraySize/6);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Any idea why my object is white?
Oops, I meant to say it stays white, no matter what I do.
Hi Garrick,
If the object has the right shape, then coloring should work fine. Are you sure you are loading the correct shaders? Have you tried to run the downloadable code in the page?
I tried that, but unfortunately I can’t get the code to compile; MinGW complains about an “unrecognized option ‘-static-libstdc++'”, and if I remove that opion I get collect2: 1 exit status returned.
I’ve been using SFML for my OpenGL context rather than GLUT; it works fine, and my old shaders do display color when it is included in the VBO as a vertex attribute. The old fragment shader is simply
void main()
{
gl_FragColor = gl_Color;
}
Hm… I’m trying this on another computer now (I was first trying it on an older PC at work, which might have had an integrated graphics card now that I think of it), and your fragment shader seems to be working. I’ll implement your vertex shader properly and get back to you on that. Perhaps it was simply a case of the hardware not supporting modern GLSL. That would be embarassing…
Try GLView to check which version is supported on your hardware.