User Tools

Site Tools


tutorials:pfopengl_shaders

Getting Started with Shaders

The main details of this were covered in class, so referencing your notes is a good idea. However, we'll do a brief recap.

Recall that the programmable pipeline requires us to write two programs that are external to our main PyOpenGL program. These programs, called shader programs, are written in a C-like programming language called GLSL (GL Shader Language). The first of these two shader programs is our vertex shader program. This program operates on a single vertex at a time. This means that it will execute for each vertex in your geometry. This is typically where you will apply transformations to your vertices. A very basic vertex shader program is shown below. There are certain built-in incoming and outgoing variables. Incoming variables pass information from your main program into the shader (examples include gl_Vertex, gl_Normal, gl_Color, gl_ModelViewMatrix, and gl_ProjectionMatrix). Outgoing variables are those that are passed along to the next phase of the rendering pipeline. gl_Position is an outgoing variable that defines the 2D position of a vertex in OpenGL screen coordinates after having been transformed by the ModelView and Projection matrices.

void main()
{
   //multiplies the current vertex by the modelview and projection matrices
   gl_Position = gl_ModelViewMatrix * gl_ProjectionMatrix * gl_Vertex;
}

The second shader program you will be working with the our fragment shader program. This shader is applied on a pixel-per-pixel basis on your geometry. Pretty much the primary purpose of this shader is set the color of a single fragment (or proto-pixel). A very basic fragment shader is shown below. gl_FragColor is an outgoing variable that specifies the final color of a fragment.

void main()
{
   //set the fragment color to white
   gl_FragColor=vec4( 1.0, 1.0, 1.0, 1.0 );
}

A common place to store your vertex and fragment shaders in files named vert.glsl and frag.glsl respectively. To use these shaders in your PyOpenGL program. You will need to add some code to your init() function. This code will read in your shaders programs compile them individually and then compile them into one payload that can be delivered to the GPU. This generally works as follows:

        vs_source=open("vert.glsl", "r")
        vs_source=vs_source.read()
        VERTEX_SHADER=shaders.compileShader(vs_source, GL_VERTEX_SHADER)                                            
 
        fs_source=open("frag.glsl", "r")
        fs_source=fs_source.read()
        FRAGMENT_SHADER=shaders.compileShader(fs_source,GL_FRAGMENT_SHADER)
 
        self.shader=shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)

The fixed pipeline shaders will remain active, however, until you activate your newly compiled shaders. To activate the shaders you simply need to make the following call.

shaders.glUseProgram(self.shader)

Recall that you can switch back to the fixed pipeline shaders by making a similar call but instead specifying that you want to use shader 0. Shader 0 will always be the fixed pipeline shaders.

shaders.glUseProgram(self.shader)
tutorials/pfopengl_shaders.txt · Last modified: 2021/08/01 00:54 by jones