PUSHIN’ GEO TO THE GPU As well as colors, normals, and other vertex data JEFF CHASTINE 1 This is what we want to make JEFF CHASTINE 2 (-1, 1) (0, 1) (1, 1) Normalized Device Coordinate System (-1, 0) (-1, -1) JEFF CHASTINE (0, 0) (0, -1) (1, 0) (1, -1) 3 Coordinates of our triangle (0.0f, 0.5f, 0.0f) (-0.5f, -0.5f, 0.0f) JEFF CHASTINE (0.5f, -0.5f, 0.0f) 4 QUICK! COLOR THEORY! • Represent almost any color by adding red, green and blue • Alpha is the transparency • Called the primary colors (RGB or RGBA) • 0.0 means “all the way off” • 1.0 means “all the way on” • Examples: • Red (1.0, 0.0, 0.0, 1.0) • White (1.0, 1.0, 1.0, 1.0) • Blue (0.0, 0.0, 1.0, 1.0) • Black (0.0, 0.0, 0.0, 1.0) • Purple (1.0, 0.0, 1.0, 1.0) • Grey (0.5, 0.5, 0.5, 1.0) • Yellow (1.0, 1.0, 0.0, 1.0) • Brown (0.7, 0.5, 0.1, 1.0) JEFF CHASTINE 5 Colors of our triangle* (0.0f, 0.0f, 1.0f, 1.0f) (1.0f, 0.0f, 0.0f, 1.0f) (0.0f, 1.0f, 0.0f, 1.0f) *Note the beautiful interpolation of color! JEFF CHASTINE 6 BASIC PROBLEM • Get the geometry and color to the GPU • Typically also need a normal and texture coordinate for each vertex! • Ask the OpenGL driver to create a buffer object • This is just a chunk of memory (e.g. array) • Nothing to be afraid of! • Located on the GPU (probably) JEFF CHASTINE 7 WORKING WITH BUFFERS • To create a buffer ID: // This will be the ID of the buffer GLuint buffer; // Ask OpenGL to generate exactly 1 unique ID glGenBuffers(1, &buffer); • To set this buffer as the active one and specify which buffer we’re referring to: glBindBuffer(GL_ARRAY_BUFFER, buffer); • Notes: • That buffer is now bound and active! • Any “drawing” will come from that buffer • Any “loading” goes into that buffer JEFF CHASTINE 8 TWO APPROACHES TO LOADING THE BUFFER WITH DATA • Assume everything is in GLfloat* (called data) • One-shot call to load the buffer with data: glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); • Other drawing types GL_X_Y: • X • STREAM for infrequent use and changes • STATIC for frequent use and infrequent change • DYNAMIC for frequent use and frequent change • Y could be DRAW, READ or COPY JEFF CHASTINE 9 HOW WE’LL DO IT • Process • Create the buffer and pass no data • Load the geometry • Load the colors (if any) after that • Load the normals after that… • Note: some like to interlace their vertex data… JEFF CHASTINE 10 A SIDE-BY-SIDE COMPARISON • Show the relationship between client code and shader code • Assume we’re still trying to draw 1 triangle… • numVertices – the number of vertices (will be 3 - duh!) • verts – the position information of each vertex (XYZ - array of GLfloats) • colors – the color information of each vertex (RGBA - array of GLfloats) JEFF CHASTINE 11 GLuint buffer; buffer glGenBuffers(1, &buffer); Note: buffer “lives” on the graphics card in a nice, two-bedroom loft… JEFF CHASTINE 12 Hey – I’m active now GLuint buffer; buffer glGenBuffers(1, &buffer); glBindBuffer (GL_ARRAY_BUFFER, buffer); JEFF CHASTINE 13 Now I know how big I am! buffer GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer (GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, numVertices*7*sizeof(GLfloat), NULL, GL_STATIC_DRAW); Allocate how much space (in bytes) we need Where’d the 7 come from? JEFF CHASTINE 14 Now I know how big I am! buffer GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer (GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, numVertices*7*sizeof(GLfloat), NULL, GL_STATIC_DRAW); Allocate how much space (in bytes) we need Where’d the 7 come from? (x, y, z) + (r, g, b, a) = 7 JEFF CHASTINE 15 Now I’m putting verts at the beginning GLuint buffer; buffer glGenBuffers(1, &buffer); verts glBindBuffer (GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, numVertices*7*sizeof(GLfloat), NULL, GL_STATIC_DRAW); glBufferSubData (GL_ARRAY_BUFFER, 0, numVertices*3*sizeof(GLfloat), verts); glBufferSubData (GL_ARRAY_BUFFER, numVertices*3*sizeof(GLfloat), numVertices*4*sizeof(GLfloat), colors); JEFF CHASTINE Put verts at 0… it’s pretty big though… 16 I’m putting colors next GLuint buffer; buffer glGenBuffers(1, &buffer); verts colors glBindBuffer (GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, numVertices*7*sizeof(GLfloat), NULL, GL_STATIC_DRAW); glBufferSubData (GL_ARRAY_BUFFER, 0, numVertices*3*sizeof(GLfloat), verts); glBufferSubData (GL_ARRAY_BUFFER, numVertices*3*sizeof(GLfloat), numVertices*4*sizeof(GLfloat), colors); JEFF CHASTINE Put colors starting right after that! It’s pretty big too… 17 WHAT WE HAVE SO FAR… • We have a buffer with an ID • That buffer lives on the graphics card • That buffer is full of vertex position/color data • How do we get that info to our shader? JEFF CHASTINE 18 HOW TO LINK TO THE SHADER • Query the shader program for its variables • The code below goes into the shader program and gets the “vPosition” ID GLuint vpos; vpos = glGetAttribLocation (programID, “vPosition”); • In OpenGL, we have to enable things (attributes, in this case): glEnableVertexAttribArray(vpos); // turn on vPosition • Finally, we set the location and tell it the format of the data in the buffer glVertexAttribPointer(vpos, 3, GL_FLOAT, GL_FALSE, 0, 0); void glVertexAttribPointer(GLuint index, GLint size, Glenum type, GLboolean normalized, GLsizei stride, const GLvoid* offset); JEFF CHASTINE 19 GLuint loc = glGetAttribLocation(shaderProgramID, "vPosition"); Find the variable “vPosition” inside the shader #version 130 in vec4 vPosition; in vec4 vColor; out vec4 color; void main () { color = vColor; gl_Position = vPosition; } JEFF CHASTINE 20 GLuint loc = glGetAttribLocation(shaderProgramID, "vPosition"); glEnableVertexAttribArray(loc); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0); Guys! I’m still active, remember? buffer verts colors #version 130 in vec4 vPosition; in vec4 vColor; out vec4 color; void main () { color = vColor; gl_Position = vPosition; } JEFF CHASTINE 21 Tell vColor where to find its data in me… buffer verts colors GLuint loc2 = glGetAttribLocation(shaderProgramID, "vColor"); glEnableVertexAttribArray(loc2); glVertexAttribPointer(loc2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertices*3*sizeof(GLfloat))); #version 130 in vec4 vPosition; in vec4 vColor; out vec4 color; void main () { color = vColor; gl_Position = vPosition; } JEFF CHASTINE 22 GLuint loc = glGetAttribLocation(shaderProgramID, "vPosition"); glEnableVertexAttribArray(loc); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0); GLuint loc2 = glGetAttribLocation(shaderProgramID, "vColor"); glEnableVertexAttribArray(loc2); glVertexAttribPointer(loc2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertices*3*sizeof(GLfloat))); #version 130 in vec4 vPosition; in vec4 vColor; out vec4 color; void main () { color = vColor; gl_Position = vPosition; } JEFF CHASTINE 23 ONE LAST THING • Vertex Array Objects (VAOs) • “Pure State” - it remembers almost everything about buffers • Set it up once, then just call it before drawing! • glVertexAttribPointer… • Doesn’t bind the VBO though… • Creating a vertex array object: // This will be the ID of the VAO GLuint vao; // Ask the driver for exactly 1 unique ID glGenVertexArrays(1, &vao); // Everything after this will be part of the VAO glBindVertexArray(vao); JEFF CHASTINE 24 // Create the "remember all" glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Create a buffer and bind it as active glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); // Create space and load the buffer glBufferData(GL_ARRAY_BUFFER, 7*3*sizeof(GLfloat), NULL, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, 3*3*sizeof(GLfloat), vertices); glBufferSubData(GL_ARRAY_BUFFER, 3*3*sizeof(GLfloat),3*4*sizeof(GLfloat), colors); // Find the positions of the variables in the shader positionID = glGetAttribLocation(shaderProgramID, "vPosition"); colorID = glGetAttribLocation(shaderProgramID, "vColor"); // Tell the shader variables where to find their data glVertexAttribPointer(positionID, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(colorID, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(3*3*sizeof(GLfloat))); glUseProgram(shaderProgramID); glEnableVertexAttribArray(positionID); glEnableVertexAttribArray(colorID); JEFF CHASTINE 25 END WITH A UTAH TEAPOT! JEFF CHASTINE 26