I understand vaos

This commit is contained in:
Ciro Santilli 2016-11-15 22:52:57 +00:00
parent 5360e3ba28
commit e35c7bbf14
8 changed files with 134 additions and 98 deletions

View File

@ -155,3 +155,7 @@ E.g. Vertex Array Object is a container <https://www.opengl.org/wiki/Vertex_Spec
TODO.
<http://stackoverflow.com/questions/6682771/gldrawelements-vs-gldrawarray-efficiency>
If the last argument of glDrawElements is null, it takes the currently bound:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

View File

@ -51,12 +51,16 @@ int main(void) {
attribute_position = glGetAttribLocation(program, "position");
attribute_vertColor = glGetAttribLocation(program, "vertColor");
/* Buffer setup. */
glGenVertexArrays(1, &vao);
/* vbo */
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Buffer setup. */
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(
attribute_position,
3,

View File

@ -46,6 +46,7 @@ int main(void) {
program,
texture,
uvbo,
vao,
vbo
;
unsigned int
@ -66,7 +67,6 @@ int main(void) {
coord2d_location = glGetAttribLocation(program, "coord2d");
vertexUv_location = glGetAttribLocation(program, "vertexUv");
myTextureSampler_location = glGetUniformLocation(program, "myTextureSampler");
glUseProgram(program);
/* vbo */
glGenBuffers(1, &vbo);
@ -85,9 +85,13 @@ int main(void) {
texture_image = common_texture_get_image(texture_width, texture_height);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glActiveTexture(GL_TEXTURE0);
/* Specify data for current texture unit specified by glActiveTexture. */
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_width,
0, GL_BGR, GL_UNSIGNED_BYTE, texture_image);
/* glTexParameter specifies parameters for the current texture unit. */
/* Cheap. filtering. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -102,42 +106,25 @@ int main(void) {
free(texture_image);
}
/* vbo */
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(
coord2d_location,
2,
GL_FLOAT,
GL_FALSE,
0,
0
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* uvbo */
glVertexAttribPointer(coord2d_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(coord2d_location);
glBindBuffer(GL_ARRAY_BUFFER, uvbo);
glVertexAttribPointer(
vertexUv_location,
2,
GL_FLOAT,
GL_FALSE,
0,
0
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribPointer(vertexUv_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vertexUv_location);
glBindVertexArray(0);
/* Draw. */
glViewport(0, 0, WIDTH, HEIGHT);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
/* Sampler will sample from GL_TEXTURE0. TODO example that changes this. */
glUniform1i(myTextureSampler_location, 0);
glEnableVertexAttribArray(coord2d_location);
glEnableVertexAttribArray(vertexUv_location);
glUseProgram(program);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(coord2d_location);
glDisableVertexAttribArray(vertexUv_location);
glBindVertexArray(0);
glfwSwapBuffers(window);
/* Main loop. */
@ -148,6 +135,7 @@ int main(void) {
/* Cleanup. */
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &uvbo);
glDeleteVertexArrays(1, &vao);
glDeleteTextures(1, &texture);
glDeleteProgram(program);
glfwTerminate();

View File

@ -57,28 +57,33 @@ int main(void) {
glewExperimental = GL_TRUE;
glewInit();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, WIDTH, HEIGHT);
/* Shaders. */
/* Shader program. */
program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
vColor_location = glGetAttribLocation(program, "vColor");
position_location = glGetAttribLocation(program, "position");
transform_location = glGetUniformLocation(program, "transform");
glUseProgram(program);
/* Buffers. */
glGenVertexArrays(1, &vao);
/* vbo */
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
/* Position attribute */
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Buffers. */
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
/* Color attribute */
glEnableVertexAttribArray(position_location);
glVertexAttribPointer(vColor_location, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(vColor_location);
glBindVertexArray(0);
/* Global draw calls. */
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, WIDTH, HEIGHT);
/* Main loop. */
common_fps_init();
while (!glfwWindowShouldClose(window)) {
@ -92,11 +97,7 @@ int main(void) {
glUniformMatrix4fv(transform_location, 1, GL_FALSE, transform);
glBindVertexArray(vao);
glEnableVertexAttribArray(position_location);
glEnableVertexAttribArray(vColor_location);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(position_location);
glDisableVertexAttribArray(vColor_location);
glBindVertexArray(0);
glfwSwapBuffers(window);

View File

@ -18,11 +18,20 @@ Looks like a way to bind a bunch of things at once:
> stores all of the state needed to supply vertex data (with one minor exception noted below).
It stores the format of the vertex data as well as the Buffer Objects
What is stores:
- glBind calls
- glVertexAttribPointer and glEnableVertexAttribArray calls TODO: why not store shaders as well then, since those are bound to shaders?
VAO is a container object: it contains other objects.
https://www.opengl.org/wiki/Vertex_Specification#Vertex_Array_Object
Adapted from
https://github.com/JoeyDeVries/LearnOpenGL/blob/d5c3be70ab2b884cf2b2c94cbf73a31f632fbf47/src/1.getting_started/2.hello_triangle/hellotriangle2.cpp
Tood explanations:
- http://www.learnopengl.com/#!Getting-Started/Hello-Triangle
*/
#include "common.h"
@ -60,25 +69,28 @@ int main(void) {
glfwMakeContextCurrent(window);
glewInit();
/* Shader. */
program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
attribute_position = glGetAttribLocation(program, "position");
/* Buffer setup. */
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Buffer setup. */
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(attribute_position, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
/* Draw. */
glUseProgram(program);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, WIDTH, HEIGHT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

View File

@ -63,7 +63,12 @@ int main(void) {
*/
/* vertices[0] = 1.0; */
/* Set currently bound GL_ARRAY_BUFFER as the vertex shader input. */
/*
Set currently bound GL_ARRAY_BUFFER as the vertex shader input.
- argument 2: size. Can only be 1, 2, 3, or 4. Each one of those maps to a
vec1, 2, 3 or 4 argument in the shader.
*/
glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0);
/* Unbind GL_ARRAY_BUFFER. */

View File

@ -4,8 +4,8 @@ Reuse vertices on multiple triangles via vertex indices.
#include "common.h"
static const GLuint WIDTH = 800;
static const GLuint HEIGHT = 600;
static const GLuint WIDTH = 500;
static const GLuint HEIGHT = 500;
/* ourColor is passed on to the fragment shader. */
static const GLchar *vertex_shader_source =
"#version 330 core\n"
@ -46,7 +46,6 @@ int main(void) {
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, __FILE__, NULL, NULL);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
/* Shader program. */
@ -54,20 +53,23 @@ int main(void) {
attribute_position = glGetAttribLocation(program, "position");
attribute_color = glGetAttribLocation(program, "color");
/* Buffer setup. */
glGenVertexArrays(1, &vao);
/* vbo */
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* ebo */
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
/*
Position attribute.
- 3: length
- 6: how many bytes to skip until next one == 3 (position) + 3 (color)
*/
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
/* Buffer setup. */
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(attribute_position, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(attribute_position);
/* Color attribute */

View File

@ -130,7 +130,7 @@ static const GLchar *fragment_shader_source2 =
/*" color = texture(myTextureSampler, fragmentUv.yx ).rgb;\n"*/
/*"// Inverter\n"*/
/*" color = 1.0 - texture(myTextureSampler, fragmentUv.yx ).rgb;\n"*/
" color = 1.0 - texture(myTextureSampler, fragmentUv.yx ).rgb;\n"
/*"// Swapper\n"*/
/*" color = texture(myTextureSampler, fragmentUv.yx ).gbr;\n"*/
@ -154,17 +154,17 @@ static const GLchar *fragment_shader_source2 =
/*" color /= blur_width;\n"*/
/*"// Square linear blur. Good GPU bogger since n^2.\n"*/
" int blur_width = 23;\n"
" int blur_width_half = blur_width / 2;\n"
" color = vec3(0.0, 0.0, 0.0);\n"
" for (int i = -blur_width_half; i <= blur_width_half; ++i) {\n"
" for (int j = -blur_width_half; j <= blur_width_half; ++j) {\n"
" color += texture(\n"
" myTextureSampler, fragmentUv.yx + ivec2(i, j) * pixD\n"
" ).rgb;\n"
" }\n"
" }\n"
" color /= (blur_width * blur_width);\n"
/*" int blur_width = 23;\n"*/
/*" int blur_width_half = blur_width / 2;\n"*/
/*" color = vec3(0.0, 0.0, 0.0);\n"*/
/*" for (int i = -blur_width_half; i <= blur_width_half; ++i) {\n"*/
/*" for (int j = -blur_width_half; j <= blur_width_half; ++j) {\n"*/
/*" color += texture(\n"*/
/*" myTextureSampler, fragmentUv.yx + ivec2(i, j) * pixD\n"*/
/*" ).rgb;\n"*/
/*" }\n"*/
/*" }\n"*/
/*" color /= (blur_width * blur_width);\n"*/
"}\n";
@ -186,7 +186,8 @@ int main(int argc, char **argv) {
program2,
texture,
vbo,
vao
vao,
vao2
;
unsigned int
cpu,
@ -240,23 +241,37 @@ int main(int argc, char **argv) {
myTextureSampler_location2 = glGetUniformLocation(program2, "myTextureSampler");
pixD_location2 = glGetUniformLocation(program2, "pixD");
/* Buffer setup. */
glGenVertexArrays(1, &vao);
/* Create vbo. */
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Create ebo. */
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
/* vao. */
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(coord2d_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(vertices[0]), (GLvoid*)0);
glVertexAttribPointer(coord2d_location2, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(vertices[0]), (GLvoid*)0);
glEnableVertexAttribArray(coord2d_location);
/* TODO this likely makes no sense. Do we need 2 vaos? */
glEnableVertexAttribArray(coord2d_location2);
glVertexAttribPointer(vertexUv_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(vertices[0])));
glVertexAttribPointer(vertexUv_location2, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(vertices[0])));
glEnableVertexAttribArray(vertexUv_location);
glBindVertexArray(0);
/* vao2. */
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(coord2d_location2, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(vertices[0]), (GLvoid*)0);
glEnableVertexAttribArray(coord2d_location2);
glVertexAttribPointer(vertexUv_location2, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(vertices[0])));
glEnableVertexAttribArray(vertexUv_location2);
glBindVertexArray(0);
@ -279,21 +294,18 @@ int main(int argc, char **argv) {
CommonV4l2_updateImage(&common_v4l2);
image = CommonV4l2_getImage(&common_v4l2);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
/* Original. */
glUseProgram(program);
glUniform1i(myTextureSampler_location, 0);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGB, GL_UNSIGNED_BYTE, image
);
glUseProgram(program);
glUniform1i(myTextureSampler_location, 0);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
/* Modified. */
glUseProgram(program2);
glUniform1i(myTextureSampler_location2, 0);
glUniform2f(pixD_location2, 1.0 / width, 1.0 / height);
/* Optional CPU modification to compare with GPU shader speed. */
if (cpu) {
image2 = realloc(image2, 3 * width * height * sizeof(image2[0]));
@ -302,16 +314,17 @@ int main(int argc, char **argv) {
size_t index = 3 * (i * width + j);
/* Inverter. */
/*image2[index + 0] = 255U - image[index + 0];*/
/*image2[index + 1] = 255U - image[index + 1];*/
/*image2[index + 2] = 255U - image[index + 2];*/
image2[index + 0] = 1.0 - (image[index + 0] / 255.0);
image2[index + 1] = 1.0 - (image[index + 1] / 255.0);
image2[index + 2] = 1.0 - (image[index + 2] / 255.0);
/* Swapper. */
/*image2[index + 0] = image[index + 1];*/
/*image2[index + 1] = image[index + 2];*/
/*image2[index + 2] = image[index + 0];*/
/*image2[index + 0] = image[index + 1] / 255.0;*/
/*image2[index + 1] = image[index + 2] / 255.0;*/
/*image2[index + 2] = image[index + 0] / 255.0;*/
/* Square linear blur. */
/*
int blur_width = 5;
int blur_width_half = blur_width / 2;
int blur_width2 = (blur_width * blur_width);
@ -334,6 +347,7 @@ int main(int argc, char **argv) {
image2[index + 0] /= (blur_width2 * 255.0);
image2[index + 1] /= (blur_width2 * 255.0);
image2[index + 2] /= (blur_width2 * 255.0);
*/
}
}
glTexImage2D(
@ -341,9 +355,15 @@ int main(int argc, char **argv) {
0, GL_RGB, GL_FLOAT, image2
);
}
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
/* Modified. */
glUseProgram(program2);
glUniform1i(myTextureSampler_location2, 0);
glUniform2f(pixD_location2, 1.0 / width, 1.0 / height);
glBindVertexArray(vao2);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
common_fps_print();