Pushing Geometry to the GPU

advertisement
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
Download