opengl using shaders - texas a&m university–corpus...
TRANSCRIPT
OPENGL – USING
SHADERS
OpenGL.org
• Definitely a good place to look for hints on OpenGL
• Download the language spec Reference Card for the
version you are using. Very helpful. Can print and
laminate.
COSC 4328/5327 Computer Graphics 2
Specifying Objects
• All primitives are made up of vertices
• We will use a vertex stream to define our objects
• How do vertices differ?
• Attributes
• Position, normal, order, color, or whatever you need to draw they way
the application wants to draw
• We can specify the objects by sending the vertices in order
• We can also send the vertices and then specify the order
by using indices (later)
COSC 4328/5327 Computer Graphics 3
Our Example
• We are going to have vertices with two attributes
• Position – the location in world space
• Color – the color of the vertex
• We will store the attributes in their own Buffer Objects
• vertex shader will pass color & position to the fragment shader
• Col – input stream to vertex shader with color of vertex
• Pos – input stream to vertex shader with position of vertex
• clr – output stream that sends color to fragment shader
• The fragment shader will then send that color to the framebuffer
COSC 4328/5327 Computer Graphics 4
Vertex Array Objects
• The VAO holds the state that specifies the vertex data
• The format of the vertices
• The source of the vertex arrays
• Not the actual arrays, just where they are
• They are actually stored in Buffer Objects (VBO)
• glGenVertexArrays - create
• glDeleteVertexArrays – destroy
• glBindVertexArray – bind
• glEnableVertexAttribArray – enable arrays for drawing
COSC 4328/5327 Computer Graphics 5
Vertex Array Objects
• glGenVertexArrays(GLsizei n, Gluint *arrays)
• Create n arrays, store their names in arrays
• glDeleteVertexArrays(Glsizei n, const Gluint *arrays)
• When you are done this will destroy the arrays
• glBindVertexArray(GLuint array)
• Enables all of the arrays store in the VAO, turns them on
• glEnableVertexAttribArray(GLuint index)
• Enables the generic vertex attribute specified by index for use in
drawing
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
COSC 4328/5327 Computer Graphics 6
Vertex Buffer Objects
• Buffer Objects store the array data for the vertex attributes
• You can have one or multiple buffers
• Which is best depends upon the use and the platform
• For our purposes, it won’t matter
• glGenBuffers(num, namearray) – same as Array Object
• glBindBuffer(target, buffer) – to bind it (enable)
• VAOs don’t have an explicit target, but buffer objects do
• The target to use is GL_ARRAY_BUFFER
• glVertexAttribPointer() – specify format of a VBO, put that
information in the VAO, and hook it to a stream for the
shader.
COSC 4328/5327 Computer Graphics 7
Vertex Buffer Objects
• glGenBuffers(GLsizei n, Gluint *arrays) • Create n buffers, store their names in arrays
• glBindBuffer(GLenum target, GLuint buffer) • binds buffer to target, enables it
• glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer); GLuint VBO[2];
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
loadShaders(); // Set up shaders
GLuint loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*) (0) );
COSC 4328/5327 Computer Graphics 8
Shaders
• Shaders do the critical work of rendering
• At the minimum you must have a vertex shader and a
fragment shader
COSC 4328/5327 Computer Graphics 9
Program Object
• A program object holds all the shaders
• glCreateProgram() – generate a program object
• glAttachShader() – attach a shader to program object
• glComipleShader() – compile shader source
• glLinkProgram() – link the shaders to the right programmable processor. Also set up varying and uniform variables for use.
• glUseProgram() – set a program object for use in rendering in subsequently rendered objects • Only one at a time, but can render same object more than one time
with a different program
• glDeleteProgram() – destroy the object when done with it
• glBindAttribLocation() – bind a vertex attribute to a variable
COSC 4328/5327 Computer Graphics 10
Program Object
• GLuint glCreateProgram(); - returns the name of a program object that you can attach shaders to • GLuint program = glCreateProgram();
• GLuint glCreateShader(GLenum shaderType); • Creates a shader object of type shaderType
• GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, …
• GLuint shader = glCreateShader(GL_VERTEX_SHADER);
• glShaderSource(GLuint shader, GLsizei count, const GLchar ** string, const GLint * length); • Loads the source code contained in string, into the shader object
shader. The source is made up of count strings with the individual string lengths stored in length;
• glShaderSource(shader, 1, (const GLchar**)
&source, NULL )
COSC 4328/5327 Computer Graphics 11
A Convenience Function GLuint InitShader(const char* source, GLenum type)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1,(const GLchar**)&source, NULL);
glCompileShader(shader);
GLint compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if ( !compiled ) {
fprintf(stderr, "Failed to compiler shader!\n");
exit(EXIT_FAILURE);
}
return shader;
}
// Call with
GLuint shader = InitShader(vert, GL_VERTEX_SHADER);
glAttachShader(program, shader);
COSC 4328/5327 Computer Graphics 12
Another Function Gluint InitShaders(const char* vert, const char *frag) {
GLuint program = glCreateProgram();
GLuint shader;
shader = InitShader(vert, GL_VERTEX_SHADER);
glAttachShader( program, shader );
shader = InitShader(frag, GL_FRAGMENT_SHADER);
glAttachShader( program, shader );
glLinkProgram(program);
/* link and error check */
GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
fprintf(stderr, "Shaders failed to link!\n");
exit( EXIT_FAILURE );
}
glUseProgram(program); // Or do this call in rendering
return program;
}
COSC 4328/5327 Computer Graphics 13
The Big Picture
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
COSC 4328/5327 Computer Graphics 14
COSC 4328/5327 Computer Graphics 15
The Big Picture
COSC 4328/5327 Computer Graphics 16
// Set up the points array
// Set up the colors array
The Big Picture
COSC 4328/5327 Computer Graphics 17
VAO
Frame
Buffer
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
VBO[0] -
The Big Picture
COSC 4328/5327 Computer Graphics 18
VAO
Buffer 1:
VBO[0] - Positions
Frame
Buffer
GLuint VBO[2];
glGenBuffers(2, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(points), points, GL_STATIC_DRAW);
The Big Picture
COSC 4328/5327 Computer Graphics 19
VAO
Buffer 1:
Buffer 2:
VBO[0] - Positions
VBO[0] - Colors
Frame
Buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(colors), colors,
GL_STATIC_DRAW);
The Big Picture
COSC 4328/5327 Computer Graphics 20
VAO
Buffer 1:
Buffer 2:
in Col
in Pos
out clr
clr =
Col;
VBO[0] - Positions
VBO[0] - Colors
Program
Geom Vert Tess Frag
Frame
Buffer
GLuint program = glCreateProgram();
GLuint Shader = CreateShader(GL_VERTEX_SHADER);
glShaderSource(shader,1,(const GLchar**) &vert,NULL);
glCompilerShader(shader);
glAttachShader( program, shader );
The Big Picture
COSC 4328/5327 Computer Graphics 21
VAO
Buffer 1:
Buffer 2:
in Col
in Pos
out clr
clr =
Col;
VBO[0] - Positions
VBO[0] - Colors
Program
Geom Vert Tess Frag
in clr
out fclr
fclr = clr;
Frame
Buffer
shader = InitShader(frag,GL_FRAGMENT_SHADER);
glAttachShader( program, shader );
glLinkProgram(program);
The Big Picture
COSC 4328/5327 Computer Graphics 22
char *vert = “#version 150\n …";
char *frag = "#version 150\n …";
GLuint program = InitShaders(vert,frag);
glUseProgram(program);
VAO
Buffer 1:
Buffer 2:
in Col
in Pos
out clr
clr =
Col;
VBO[0] - Positions
VBO[0] - Colors
Program
Geom Vert Tess Frag
in clr
out fclr
fclr = clr;
Frame
Buffer
The Shaders
Vertex Shader
#version 150
in vec4 Pos;
in vec3 Col;
out vec3 clr;
void main(){
clr = Col;
gl_Position = Pos;
};
Fragment Shader
#version 150
in vec3 clr;
out vec4 fclr;
void main() {
fclr =
vec4(clr,1.0);
}
COSC 4328/5327 Computer Graphics 23
The Big Picture
COSC 4328/5327 Computer Graphics 24
VAO
Buffer 1: GL_FLOAT[3], tight, index 0
Buffer 2:
in Col
in Pos
out clr
clr =
Col;
VBO[0] - Positions
VBO[0] - Colors
Program
Geom Vert Tess Frag
in clr
out fclr
fclr = clr;
Frame
Buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
GLuint loc = glGetAttribLocation(program, “Pos");
glEnableVertexAttribArray(loc);
printf("vPosition is in %d\n", loc);
glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE,
0, (GLvoid*) (0));
The Big Picture
COSC 4328/5327 Computer Graphics 25
VAO
Buffer 1: GL_FLOAT[3], tight, index 0
Buffer 2: GL_FLOAT[3], tight, index 1
in Col
in Pos
out clr
clr =
Col;
VBO[0] - Positions
VBO[0] - Colors
Program
Geom Vert Tess Frag
in clr
out fclr
fclr = clr;
Frame
Buffer
glBindBuffer(GL_ARRARY_BUFFER, VBO[1]);
loc = glGetAttribLocation(program, "vColor");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE,
0, (GLvoid*) (0) )
The Big Picture
COSC 4328/5327 Computer Graphics 26
VAO
Buffer 1: GL_FLOAT[3], tight, index 0
Buffer 2: GL_FLOAT[3], tight, index 1
in Col
in Pos
out clr
clr =
Col;
VBO[0] - Positions
VBO[0] - Colors
Program
Geom Vert Tess Frag
in clr
out fclr
fclr = clr;
Frame
Buffer
// To draw (in display function)
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_LINE_STRIP, 0, NumPoints);
glFlush();
Frame
Buffer
INDEXING
COSC 4328/5327 Computer Graphics 27
Binding Indexed Primitive
#define reportError(s) _ReportError(__LINE__, (s)
void bindiPrimitive(IndexedPrimitive *obj) {
glBindBuffer(GL_ARRAY_BUFFER, obj->VBO);
reportError("bindiPrimitive glBindBuffer");
glVertexAttribPointer(glGetAttribLocation(phongShaders, "vPosition"), 3,
GL_FLOAT, GL_FALSE, 0, (GLvoid*) (0) );
glVertexAttribPointer(glGetAttribLocation(phongShaders, "vNormal"), 3,
GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (obj->NPts * sizeof(*obj->pts)));
glVertexAttribPointer(glGetAttribLocation(phongShaders, "vTex"), 2,
GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (obj->NPts * (sizeof(*obj->pts)+sizeof(*obj->normals) )));
reportError("bindiPrimitive glVertexAttribPointer");
COSC 4328/5327 Computer Graphics 28
Uniform Variable Example
GLint angleParam;
angleParam = glGetUniformLocation(myProgObj,
"angle");
/* angle defined in shader */
/* my_angle set in application */
GLfloat my_angle;
my_angle = 5.0 /* or some other value */
glUniform1f(angleParam, my_angle);
COSC 4328/5327 Computer Graphics 29