260 likes | 362 Views
Pushin ’ Geo to the GPU. As well as colors, normals , and other vertex data. This is what we want to make. (-1, 1). (0, 1). (1, 1). Normalized Device Coordinate System. (-1, 0). (1, 0). (0, 0). (1, -1). (-1, -1). (0, -1). Coordinates of our triangle. (0.0f, 0.5f, 0.0f).
E N D
Pushin’ Geo to the GPU As well as colors, normals, and other vertex data Jeff Chastine
This is what we want to make Jeff Chastine
(-1, 1) (0, 1) (1, 1) Normalized Device Coordinate System (-1, 0) (1, 0) (0, 0) (1, -1) (-1, -1) (0, -1) Jeff Chastine
Coordinates of our triangle (0.0f, 0.5f, 0.0f) (-0.5f, -0.5f, 0.0f) (0.5f, -0.5f, 0.0f) Jeff Chastine
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) • Blue (0.0, 0.0, 1.0, 1.0) • Purple (1.0, 0.0, 1.0, 1.0) • Yellow (1.0, 1.0, 0.0, 1.0) • White (1.0, 1.0, 1.0, 1.0) • Black (0.0, 0.0, 0.0, 1.0) • Grey (0.5, 0.5, 0.5, 1.0) • Brown (0.7, 0.5, 0.1, 1.0) Jeff Chastine
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
Basic Problem • Get the geometry and color to the GPU • Typically also need a normal and texture coordinatefor 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
Working with Buffers • To create a buffer ID: // This will be the ID of the bufferGLuint buffer; // Ask OpenGL to generate exactly 1 unique IDglGenBuffers(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
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
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
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
buffer GLuintbuffer; glGenBuffers(1, &buffer); Note: buffer “lives” on the graphics card in a nice, two-bedroom loft… Jeff Chastine
Hey – I’m active now buffer GLuintbuffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); Jeff Chastine
Now I know how big I am! buffer GLuintbuffer; 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
Now I know how big I am! buffer GLuintbuffer; 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
Now I’m putting verts at the beginning buffer verts GLuintbuffer; glGenBuffers(1, &buffer); 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); Put verts at 0… it’s pretty bigthough… Jeff Chastine
I’m putting colors next buffer verts colors GLuintbuffer; glGenBuffers(1, &buffer); 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); Put colors startingright after that! It’s pretty bigtoo… Jeff Chastine
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
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 GLuintvpos;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, constGLvoid* offset); Jeff Chastine
GLuintloc = glGetAttribLocation(shaderProgramID, "vPosition"); #version 130 in vec4 vPosition; in vec4 vColor; out vec4 color; void main () { color = vColor; gl_Position = vPosition; } Find the variable “vPosition” inside the shader Jeff Chastine
Guys! I’m still active, remember? buffer GLuintloc = glGetAttribLocation(shaderProgramID, "vPosition");glEnableVertexAttribArray(loc);glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0); #version 130 in vec4 vPosition; in vec4 vColor; out vec4 color; void main () { color = vColor; gl_Position = vPosition; } verts colors Jeff Chastine
Tell vColor where to find its data in me… buffer verts colors GLuintloc2 = 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
GLuintloc = glGetAttribLocation(shaderProgramID, "vPosition");glEnableVertexAttribArray(loc);glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0); GLuintloc2 = 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
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 VAOGLuintvao; // Ask the driver for exactly 1 unique IDglGenVertexArrays(1, &vao); // Everything after this will be part ofthe VAOglBindVertexArray(vao); Jeff Chastine
// 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
END WITH A UTAH TEAPOT! Jeff Chastine