diff --git a/opengl/TODO.md b/opengl/TODO.md index 25526b5..a6eb0ff 100644 --- a/opengl/TODO.md +++ b/opengl/TODO.md @@ -155,3 +155,7 @@ E.g. Vertex Array Object is a container + +If the last argument of glDrawElements is null, it takes the currently bound: + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); diff --git a/opengl/glfw_color_array.c b/opengl/glfw_color_array.c index f566d40..ec2cf95 100644 --- a/opengl/glfw_color_array.c +++ b/opengl/glfw_color_array.c @@ -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, diff --git a/opengl/glfw_texture.c b/opengl/glfw_texture.c index cdcddf8..d8378e9 100644 --- a/opengl/glfw_texture.c +++ b/opengl/glfw_texture.c @@ -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(); diff --git a/opengl/glfw_transform.c b/opengl/glfw_transform.c index 510f1d9..0f96327 100644 --- a/opengl/glfw_transform.c +++ b/opengl/glfw_transform.c @@ -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); diff --git a/opengl/glfw_triangle_vao.c b/opengl/glfw_triangle_vao.c index 66a1677..490e403 100644 --- a/opengl/glfw_triangle_vao.c +++ b/opengl/glfw_triangle_vao.c @@ -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); diff --git a/opengl/glfw_triangle_vbo.c b/opengl/glfw_triangle_vbo.c index 261255a..987ac85 100644 --- a/opengl/glfw_triangle_vbo.c +++ b/opengl/glfw_triangle_vbo.c @@ -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. */ diff --git a/opengl/glfw_triangles.c b/opengl/glfw_triangles.c index c1ed0e9..531d186 100644 --- a/opengl/glfw_triangles.c +++ b/opengl/glfw_triangles.c @@ -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 */ diff --git a/opengl/glfw_webcam_image_process.c b/opengl/glfw_webcam_image_process.c index ef16ae8..f817ea1 100644 --- a/opengl/glfw_webcam_image_process.c +++ b/opengl/glfw_webcam_image_process.c @@ -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();