commit 1741e4821b6f7d372b7491cf686f3e354b7125f8
parent 775644701cd394b129ac2605f9ae2a229f4207e4
Author: David DiPaola <DavidDiPaola@users.noreply.github.com>
Date: Sat, 6 Oct 2018 14:45:15 -0400
06: initial commit of performance measurement example
Diffstat:
3 files changed, 286 insertions(+), 2 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -5,6 +5,7 @@
03-texture
04-lighting
05-geometrytransforms
+06-performance
.*.swp
diff --git a/06-performance.c b/06-performance.c
@@ -0,0 +1,276 @@
+/*
+2018 David DiPaola
+licensed under CC0 (public domain, see https://creativecommons.org/publicdomain/zero/1.0/)
+*/
+
+/* followed this tutorial: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/ */
+
+#define _DEFAULT_SOURCE
+#define _BSD_SOURCE
+#include <endian.h>
+#undef _DEFAULT_SOURCE
+#undef _BSD_SOURCE
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include <GL/glew.h>
+
+#include <GLFW/glfw3.h>
+
+#include "ogl/ogl.h"
+
+int
+main() {
+ GLFWwindow * window = ogl_init(400, 240, 0, "06 - performance");
+
+ /* vu: vertex shader uniform, va: vertex shader attribute, fu: fragment shader uniform, fv: fragment shader varying */
+ const char * program_vertex_source =
+ "#version 100" "\n"
+ "precision highp float;" "\n"
+ "\n"
+ "uniform mat4 vu_vertex_MVP;" "\n" /* uniforms are inputs to vertex and fragment shaders that don't change per-vertex */
+ "\n"
+ "attribute vec3 va_vertex_position;" "\n" /* attributes are inputs to vertex shaders */
+ "attribute vec3 va_vertex_color;" "\n"
+ "attribute vec2 va_texture_UV;" "\n"
+ "attribute vec3 va_vertex_normal;" "\n"
+ "\n"
+ "varying vec4 fv_vertex_color;" "\n" /* varyings are outputs of vertex shaders and inputs to fragment shaders */
+ "varying vec2 fv_texture_UV;" "\n"
+ "varying vec3 fv_vertex_normal;" "\n"
+ "\n"
+ "void main(){" "\n"
+ " gl_Position = vu_vertex_MVP * vec4(va_vertex_position,1);" "\n"
+ "\n"
+ " fv_vertex_color = vec4(va_vertex_color,1);" "\n"
+ " fv_texture_UV = va_texture_UV;" "\n"
+ " fv_vertex_normal = va_vertex_normal;" "\n"
+ "}" "\n"
+ ;
+ const char * program_fragment_source =
+ "#version 100" "\n"
+ "precision lowp float;" "\n"
+ "\n"
+ "uniform sampler2D fu_texture_sampler;" "\n"
+ "uniform vec3 fu_light;" "\n"
+ "\n"
+ "varying vec4 fv_vertex_color;" "\n"
+ "varying vec2 fv_texture_UV;" "\n"
+ "varying vec3 fv_vertex_normal;" "\n"
+ "\n"
+ "void main() {" "\n"
+ " vec4 texel = texture2D(fu_texture_sampler, fv_texture_UV);" "\n"
+ " vec4 fragcolor = mix(texel, fv_vertex_color, 1.0-texel.a);" "\n"
+ " float light_ambient = 0.1;" "\n"
+ " float light_diffuse = clamp(dot(fv_vertex_normal, fu_light), 0.0, 1.0);" "\n"
+ " float light = clamp(light_ambient + light_diffuse, 0.0, 1.0);" "\n"
+ " gl_FragColor = fragcolor * light;" "\n"
+ "}" "\n"
+ ;
+ GLuint program_ID = ogl_program_build(program_vertex_source, program_fragment_source);
+ GLint program_va_vertex_position_ID = glGetAttribLocation( program_ID, "va_vertex_position");
+ GLint program_va_vertex_normal_ID = glGetAttribLocation( program_ID, "va_vertex_normal");
+ GLint program_va_vertex_color_ID = glGetAttribLocation( program_ID, "va_vertex_color");
+ GLint program_va_texture_UV_ID = glGetAttribLocation( program_ID, "va_texture_UV");
+ GLint program_fu_texture_sampler_ID = glGetUniformLocation(program_ID, "fu_texture_sampler");
+ GLint program_fu_light_ID = glGetUniformLocation(program_ID, "fu_light");
+
+ struct ogl_mat4f MVP_projection;
+ ogl_perspective(45.0f, 0.1f, 100.0f, &MVP_projection);
+
+ struct ogl_mat4f MVP_view;
+ struct ogl_vec3f MVP_view_eye = { .x= 4.0f, .y= 3.0f, .z= 3.0f };
+ struct ogl_vec3f MVP_view_center = { .x= 0.0f, .y= 0.0f, .z= 0.0f };
+ struct ogl_vec3f MVP_view_up = { .x= 0.0f, .y= 1.0f, .z= 0.0f };
+ ogl_lookat(MVP_view_eye, MVP_view_center, MVP_view_up, &MVP_view);
+
+ struct ogl_mat4f MVP_model;
+ struct ogl_vec3f MVP_model_translation = { .x= 0.0f, .y= 0.0f, .z=-1.0f };
+ struct ogl_quat MVP_model_rotation = { .angle= 3.14f/3.0f, .axis={ .x= 0.0f, .y= 1.0f, .z= 0.0f } };
+ struct ogl_vec3f MVP_model_scale = { .x= 2.0f, .y= 2.0f, .z= 2.0f };
+ ogl_mat4f_identity( &MVP_model);
+ ogl_mat4f_translate(MVP_model, MVP_model_translation, &MVP_model);
+ ogl_mat4f_rotate( MVP_model, MVP_model_rotation, &MVP_model);
+ ogl_mat4f_scale( MVP_model, MVP_model_scale, &MVP_model);
+
+ struct ogl_mat4f MVP;
+ ogl_mat4f_identity(&MVP);
+ ogl_mat4f_multiply(MVP, MVP_projection, &MVP);
+ ogl_mat4f_multiply(MVP, MVP_view, &MVP);
+ ogl_mat4f_multiply(MVP, MVP_model, &MVP);
+
+ static const GLfloat cube_vertexbuffer_data[] = {
+ -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f,
+ 1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, 1.0f,-1.0f,-1.0f,
+ 1.0f, 1.0f,-1.0f, 1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f,
+ -1.0f,-1.0f,-1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f,
+ 1.0f,-1.0f, 1.0f, -1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f,
+ -1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f,
+ 1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f,-1.0f,
+ 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f,
+ };
+ static const size_t cube_vertexbuffer_data_size = sizeof(cube_vertexbuffer_data);
+ static const size_t cube_vertexbuffer_data_vertexes = (sizeof(cube_vertexbuffer_data) / sizeof(*cube_vertexbuffer_data)) / 3;
+ GLuint cube_vertexbuffer_ID = ogl_arraybuffer_load(cube_vertexbuffer_data, cube_vertexbuffer_data_size);
+
+ #define _TRIPLICATE(x, y, z) x, y, z, x, y, z, x, y, z
+ static const GLfloat cube_normalbuffer_data[] = {
+ _TRIPLICATE(-1.0f, 0.0f, 0.0f),
+ _TRIPLICATE( 0.0f, 0.0f,-1.0f),
+ _TRIPLICATE( 0.0f,-1.0f, 0.0f),
+ _TRIPLICATE( 0.0f, 0.0f,-1.0f),
+ _TRIPLICATE(-1.0f, 0.0f, 0.0f),
+ _TRIPLICATE( 0.0f,-1.0f, 0.0f),
+ _TRIPLICATE( 0.0f, 0.0f, 1.0f),
+ _TRIPLICATE( 1.0f, 0.0f, 0.0f),
+ _TRIPLICATE( 1.0f, 0.0f, 0.0f),
+ _TRIPLICATE( 0.0f, 1.0f, 0.0f),
+ _TRIPLICATE( 0.0f, 1.0f, 0.0f),
+ _TRIPLICATE( 0.0f, 0.0f, 1.0f),
+ };
+ #undef _TRIPLICATE
+ static const size_t cube_normalbuffer_data_size = sizeof(cube_normalbuffer_data);
+ GLuint cube_normalbuffer_ID = ogl_arraybuffer_load(cube_normalbuffer_data, cube_normalbuffer_data_size);
+
+ static const GLfloat cube_colorbuffer_data[] = {
+ 0.583f,0.771f,0.014f, 0.609f,0.115f,0.436f, 0.327f,0.483f,0.844f,
+ 0.822f,0.569f,0.201f, 0.435f,0.602f,0.223f, 0.310f,0.747f,0.185f,
+ 0.597f,0.770f,0.761f, 0.559f,0.436f,0.730f, 0.359f,0.583f,0.152f,
+ 0.483f,0.596f,0.789f, 0.559f,0.861f,0.639f, 0.195f,0.548f,0.859f,
+ 0.014f,0.184f,0.576f, 0.771f,0.328f,0.970f, 0.406f,0.615f,0.116f,
+ 0.676f,0.977f,0.133f, 0.971f,0.572f,0.833f, 0.140f,0.616f,0.489f,
+ 0.997f,0.513f,0.064f, 0.945f,0.719f,0.592f, 0.543f,0.021f,0.978f,
+ 0.279f,0.317f,0.505f, 0.167f,0.620f,0.077f, 0.347f,0.857f,0.137f,
+ 0.055f,0.953f,0.042f, 0.714f,0.505f,0.345f, 0.783f,0.290f,0.734f,
+ 0.722f,0.645f,0.174f, 0.302f,0.455f,0.848f, 0.225f,0.587f,0.040f,
+ 0.517f,0.713f,0.338f, 0.053f,0.959f,0.120f, 0.393f,0.621f,0.362f,
+ 0.673f,0.211f,0.457f, 0.820f,0.883f,0.371f, 0.982f,0.099f,0.879f,
+ };
+ static const size_t cube_colorbuffer_data_size = sizeof(cube_colorbuffer_data);
+ GLuint cube_colorbuffer_ID = ogl_arraybuffer_load(cube_colorbuffer_data, cube_colorbuffer_data_size);
+
+ uint32_t cube_texture_data[] = {
+ htobe32(0x00000000), htobe32(0x0000FFFF),
+ htobe32(0xFF0000FF), htobe32(0x00FF00FF),
+ };
+ const size_t cube_texture_data_width = 2;
+ const size_t cube_texture_data_height = 2;
+ GLuint cube_texture_ID = 0;
+ glGenTextures(1, &cube_texture_ID);
+ glBindTexture(GL_TEXTURE_2D, cube_texture_ID);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cube_texture_data_width, cube_texture_data_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, cube_texture_data);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ const GLfloat cube_texture_UVbuffer_data[] = {
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f,
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, /* right face, upper triangle */
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f,
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, /* right face, lower triangle */
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f,
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f,
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f,
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, /* left face, upper triangle */
+ 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f, /* left face, lower triangle */
+ 0.0f,0.0f, 0.0f,4.0f, 4.0f,4.0f, /* top face, closer triangle */
+ 0.0f,0.0f, 4.0f,4.0f, 0.0f,4.0f, /* top face, farther triangle */
+ 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f,
+ };
+ const GLsizeiptr cube_texture_UVbuffer_data_size = sizeof(cube_texture_UVbuffer_data);
+ GLuint cube_texture_UVbuffer_ID = ogl_arraybuffer_load(cube_texture_UVbuffer_data, cube_texture_UVbuffer_data_size);
+
+ double time_best = 999.0;
+ double time_worst = -1.0;
+ double time_total = 0.0;
+ int framecount = 0;
+
+ do {
+ double time = glfwGetTime();
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glUseProgram(program_ID);
+
+ ogl_program_uniform_set_mat4f(program_ID, "vu_vertex_MVP", MVP);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, cube_texture_ID);
+ glUniform1i(program_fu_texture_sampler_ID, 0);
+
+ glUniform3f(program_fu_light_ID, 1.0f, 0.6f, -1.0f);
+
+ glEnableVertexAttribArray(program_va_vertex_position_ID);
+ glBindBuffer(GL_ARRAY_BUFFER, cube_vertexbuffer_ID);
+ glVertexAttribPointer(program_va_vertex_position_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
+
+ glEnableVertexAttribArray(program_va_vertex_normal_ID);
+ glBindBuffer(GL_ARRAY_BUFFER, cube_normalbuffer_ID);
+ glVertexAttribPointer(program_va_vertex_normal_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
+
+ glEnableVertexAttribArray(program_va_texture_UV_ID);
+ glBindBuffer(GL_ARRAY_BUFFER, cube_texture_UVbuffer_ID);
+ glVertexAttribPointer(program_va_texture_UV_ID, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
+
+ glEnableVertexAttribArray(program_va_vertex_color_ID);
+ glBindBuffer(GL_ARRAY_BUFFER, cube_colorbuffer_ID);
+ glVertexAttribPointer(program_va_vertex_color_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
+
+ glDrawArrays(GL_TRIANGLES, 0, cube_vertexbuffer_data_vertexes);
+
+ glDisableVertexAttribArray(program_va_vertex_position_ID);
+ glDisableVertexAttribArray(program_va_vertex_normal_ID);
+ glDisableVertexAttribArray(program_va_texture_UV_ID);
+ //glDisableVertexAttribArray(program_va_vertex_color_ID);
+
+ time = glfwGetTime() - time;
+ if (time < time_best) {
+ time_best = time;
+ }
+ else if (time > time_worst) {
+ time_worst = time;
+ }
+ time_total += time;
+
+ framecount++;
+
+ glfwSwapBuffers(window);
+ glfwPollEvents();
+ }
+ while (
+ (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS)
+ &&
+ (glfwWindowShouldClose(window) == 0)
+ );
+
+ glDeleteBuffers(1, &cube_vertexbuffer_ID);
+ glDeleteBuffers(1, &cube_texture_UVbuffer_ID);
+ glDeleteBuffers(1, &cube_colorbuffer_ID);
+ glDeleteProgram(program_ID);
+ //glDeleteTextures(1, &program_uniform_texturesampler_ID);
+
+ glfwTerminate();
+
+ printf(
+ "performance:" "\n"
+ "\t" "frames drawn: %i" "\n"
+ "\t" "best: %fms" "\n"
+ "\t" "worst: %fms" "\n"
+ "\t" "average: %fms" "\n",
+ framecount,
+ time_best * 1000,
+ time_worst * 1000,
+ (time_total / framecount) * 1000
+ );
+
+ return 0;
+}
+
diff --git a/Makefile b/Makefile
@@ -24,6 +24,10 @@ OGL_BIN = ogl/ogl.a
05_OBJ = $(05_SRC:.c=.o) $(OGL_BIN)
05_BIN = 05-geometrytransforms
+06_SRC = 06-performance.c
+06_OBJ = $(06_SRC:.c=.o) $(OGL_BIN)
+06_BIN = 06-performance
+
CFLAGS ?= -std=c99 -Wall -fwrapv -g
@@ -31,7 +35,7 @@ LIB_CFLAGS += $(shell pkg-config --cflags glew gl glfw3)
LIB_LDFLAGS += $(shell pkg-config --libs glew gl glfw3) -lm
.PHONY: all
-all: $(00_BIN) $(01_BIN) $(02_BIN) $(03_BIN) $(04_BIN) $(05_BIN)
+all: $(00_BIN) $(01_BIN) $(02_BIN) $(03_BIN) $(04_BIN) $(05_BIN) $(06_BIN)
.PHONY: clean
clean:
@@ -41,7 +45,8 @@ clean:
$(02_OBJ) $(02_BIN) \
$(03_OBJ) $(03_BIN) \
$(04_OBJ) $(04_BIN) \
- $(05_OBJ) $(05_BIN)
+ $(05_OBJ) $(05_BIN) \
+ $(06_OBJ) $(06_BIN)
$(MAKE) --directory=./ogl/ clean
$(00_BIN): $(00_OBJ)
@@ -56,6 +61,8 @@ $(04_BIN): $(04_OBJ)
$(05_BIN): $(05_OBJ)
+$(06_BIN): $(06_OBJ)
+
.PHONY: $(OGL_BIN)
$(OGL_BIN):
$(MAKE) --directory=./ogl/ all