06-performance.c (11165B)
1 /* 2 2018 David DiPaola 3 licensed under CC0 (public domain, see https://creativecommons.org/publicdomain/zero/1.0/) 4 */ 5 6 /* followed this tutorial: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/ */ 7 8 #define _DEFAULT_SOURCE 9 #define _BSD_SOURCE 10 #include <endian.h> 11 #undef _DEFAULT_SOURCE 12 #undef _BSD_SOURCE 13 14 #include <stdio.h> 15 16 #include <stdlib.h> 17 18 #include <GL/glew.h> 19 20 #include <GLFW/glfw3.h> 21 22 #include "ogl/ogl.h" 23 24 int 25 main() { 26 GLFWwindow * window = ogl_init(400, 240, 0, "06 - performance"); 27 28 /* vu: vertex shader uniform, va: vertex shader attribute, fu: fragment shader uniform, fv: fragment shader varying */ 29 const char * program_vertex_source = 30 "#version 100" "\n" 31 "precision highp float;" "\n" 32 "\n" 33 "uniform mat4 vu_vertex_MVP;" "\n" /* uniforms are inputs to vertex and fragment shaders that don't change per-vertex */ 34 "\n" 35 "attribute vec3 va_vertex_position;" "\n" /* attributes are inputs to vertex shaders */ 36 "attribute vec3 va_vertex_color;" "\n" 37 "attribute vec2 va_texture_UV;" "\n" 38 "attribute vec3 va_vertex_normal;" "\n" 39 "\n" 40 "varying vec4 fv_vertex_color;" "\n" /* varyings are outputs of vertex shaders and inputs to fragment shaders */ 41 "varying vec2 fv_texture_UV;" "\n" 42 "varying vec3 fv_vertex_normal;" "\n" 43 "\n" 44 "void main(){" "\n" 45 " gl_Position = vu_vertex_MVP * vec4(va_vertex_position,1);" "\n" 46 "\n" 47 " fv_vertex_color = vec4(va_vertex_color,1);" "\n" 48 " fv_texture_UV = va_texture_UV;" "\n" 49 " fv_vertex_normal = va_vertex_normal;" "\n" 50 "}" "\n" 51 ; 52 const char * program_fragment_source = 53 "#version 100" "\n" 54 "precision lowp float;" "\n" 55 "\n" 56 "uniform sampler2D fu_texture_sampler;" "\n" 57 "uniform vec3 fu_light;" "\n" 58 "\n" 59 "varying vec4 fv_vertex_color;" "\n" 60 "varying vec2 fv_texture_UV;" "\n" 61 "varying vec3 fv_vertex_normal;" "\n" 62 "\n" 63 "void main() {" "\n" 64 " vec4 texel = texture2D(fu_texture_sampler, fv_texture_UV);" "\n" 65 " vec4 fragcolor = mix(texel, fv_vertex_color, 1.0-texel.a);" "\n" 66 " float light_ambient = 0.1;" "\n" 67 " float light_diffuse = clamp(dot(fv_vertex_normal, fu_light), 0.0, 1.0);" "\n" 68 " float light = clamp(light_ambient + light_diffuse, 0.0, 1.0);" "\n" 69 " gl_FragColor = fragcolor * light;" "\n" 70 "}" "\n" 71 ; 72 GLuint program_ID = ogl_program_build(program_vertex_source, program_fragment_source); 73 GLint program_va_vertex_position_ID = glGetAttribLocation( program_ID, "va_vertex_position"); 74 GLint program_va_vertex_normal_ID = glGetAttribLocation( program_ID, "va_vertex_normal"); 75 GLint program_va_vertex_color_ID = glGetAttribLocation( program_ID, "va_vertex_color"); 76 GLint program_va_texture_UV_ID = glGetAttribLocation( program_ID, "va_texture_UV"); 77 GLint program_fu_texture_sampler_ID = glGetUniformLocation(program_ID, "fu_texture_sampler"); 78 GLint program_fu_light_ID = glGetUniformLocation(program_ID, "fu_light"); 79 80 struct ogl_mat4f MVP_projection; 81 ogl_perspective(45.0f, 0.1f, 100.0f, &MVP_projection); 82 83 struct ogl_mat4f MVP_view; 84 struct ogl_vec3f MVP_view_eye = { .x= 4.0f, .y= 3.0f, .z= 3.0f }; 85 struct ogl_vec3f MVP_view_center = { .x= 0.0f, .y= 0.0f, .z= 0.0f }; 86 struct ogl_vec3f MVP_view_up = { .x= 0.0f, .y= 1.0f, .z= 0.0f }; 87 ogl_lookat(MVP_view_eye, MVP_view_center, MVP_view_up, &MVP_view); 88 89 struct ogl_mat4f MVP_model; 90 struct ogl_vec3f MVP_model_translation = { .x= 0.0f, .y= 0.0f, .z=-1.0f }; 91 struct ogl_quat MVP_model_rotation = { .angle= 3.14f/3.0f, .axis={ .x= 0.0f, .y= 1.0f, .z= 0.0f } }; 92 struct ogl_vec3f MVP_model_scale = { .x= 2.0f, .y= 2.0f, .z= 2.0f }; 93 ogl_mat4f_identity( &MVP_model); 94 ogl_mat4f_translate(MVP_model, MVP_model_translation, &MVP_model); 95 ogl_mat4f_rotate( MVP_model, MVP_model_rotation, &MVP_model); 96 ogl_mat4f_scale( MVP_model, MVP_model_scale, &MVP_model); 97 98 struct ogl_mat4f MVP; 99 ogl_mat4f_identity(&MVP); 100 ogl_mat4f_multiply(MVP, MVP_projection, &MVP); 101 ogl_mat4f_multiply(MVP, MVP_view, &MVP); 102 ogl_mat4f_multiply(MVP, MVP_model, &MVP); 103 104 static const GLfloat cube_vertexbuffer_data[] = { 105 -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 106 1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, 107 1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, 1.0f,-1.0f,-1.0f, 108 1.0f, 1.0f,-1.0f, 1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f, 109 -1.0f,-1.0f,-1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, 110 1.0f,-1.0f, 1.0f, -1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, 111 -1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 112 1.0f, 1.0f, 1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 113 1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 114 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f,-1.0f, 115 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 116 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 117 }; 118 static const size_t cube_vertexbuffer_data_size = sizeof(cube_vertexbuffer_data); 119 static const size_t cube_vertexbuffer_data_vertexes = (sizeof(cube_vertexbuffer_data) / sizeof(*cube_vertexbuffer_data)) / 3; 120 GLuint cube_vertexbuffer_ID = ogl_arraybuffer_load(cube_vertexbuffer_data, cube_vertexbuffer_data_size); 121 122 #define _TRIPLICATE(x, y, z) x, y, z, x, y, z, x, y, z 123 static const GLfloat cube_normalbuffer_data[] = { 124 _TRIPLICATE(-1.0f, 0.0f, 0.0f), 125 _TRIPLICATE( 0.0f, 0.0f,-1.0f), 126 _TRIPLICATE( 0.0f,-1.0f, 0.0f), 127 _TRIPLICATE( 0.0f, 0.0f,-1.0f), 128 _TRIPLICATE(-1.0f, 0.0f, 0.0f), 129 _TRIPLICATE( 0.0f,-1.0f, 0.0f), 130 _TRIPLICATE( 0.0f, 0.0f, 1.0f), 131 _TRIPLICATE( 1.0f, 0.0f, 0.0f), 132 _TRIPLICATE( 1.0f, 0.0f, 0.0f), 133 _TRIPLICATE( 0.0f, 1.0f, 0.0f), 134 _TRIPLICATE( 0.0f, 1.0f, 0.0f), 135 _TRIPLICATE( 0.0f, 0.0f, 1.0f), 136 }; 137 #undef _TRIPLICATE 138 static const size_t cube_normalbuffer_data_size = sizeof(cube_normalbuffer_data); 139 GLuint cube_normalbuffer_ID = ogl_arraybuffer_load(cube_normalbuffer_data, cube_normalbuffer_data_size); 140 141 static const GLfloat cube_colorbuffer_data[] = { 142 0.583f,0.771f,0.014f, 0.609f,0.115f,0.436f, 0.327f,0.483f,0.844f, 143 0.822f,0.569f,0.201f, 0.435f,0.602f,0.223f, 0.310f,0.747f,0.185f, 144 0.597f,0.770f,0.761f, 0.559f,0.436f,0.730f, 0.359f,0.583f,0.152f, 145 0.483f,0.596f,0.789f, 0.559f,0.861f,0.639f, 0.195f,0.548f,0.859f, 146 0.014f,0.184f,0.576f, 0.771f,0.328f,0.970f, 0.406f,0.615f,0.116f, 147 0.676f,0.977f,0.133f, 0.971f,0.572f,0.833f, 0.140f,0.616f,0.489f, 148 0.997f,0.513f,0.064f, 0.945f,0.719f,0.592f, 0.543f,0.021f,0.978f, 149 0.279f,0.317f,0.505f, 0.167f,0.620f,0.077f, 0.347f,0.857f,0.137f, 150 0.055f,0.953f,0.042f, 0.714f,0.505f,0.345f, 0.783f,0.290f,0.734f, 151 0.722f,0.645f,0.174f, 0.302f,0.455f,0.848f, 0.225f,0.587f,0.040f, 152 0.517f,0.713f,0.338f, 0.053f,0.959f,0.120f, 0.393f,0.621f,0.362f, 153 0.673f,0.211f,0.457f, 0.820f,0.883f,0.371f, 0.982f,0.099f,0.879f, 154 }; 155 static const size_t cube_colorbuffer_data_size = sizeof(cube_colorbuffer_data); 156 GLuint cube_colorbuffer_ID = ogl_arraybuffer_load(cube_colorbuffer_data, cube_colorbuffer_data_size); 157 158 uint32_t cube_texture_data[] = { 159 htobe32(0x00000000), htobe32(0x0000FFFF), 160 htobe32(0xFF0000FF), htobe32(0x00FF00FF), 161 }; 162 const size_t cube_texture_data_width = 2; 163 const size_t cube_texture_data_height = 2; 164 GLuint cube_texture_ID = 0; 165 glGenTextures(1, &cube_texture_ID); 166 glBindTexture(GL_TEXTURE_2D, cube_texture_ID); 167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cube_texture_data_width, cube_texture_data_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, cube_texture_data); 168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 172 glBindTexture(GL_TEXTURE_2D, 0); 173 174 const GLfloat cube_texture_UVbuffer_data[] = { 175 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 176 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, /* right face, upper triangle */ 177 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 178 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, /* right face, lower triangle */ 179 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 180 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 181 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 182 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, /* left face, upper triangle */ 183 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f, /* left face, lower triangle */ 184 0.0f,0.0f, 0.0f,4.0f, 4.0f,4.0f, /* top face, closer triangle */ 185 0.0f,0.0f, 4.0f,4.0f, 0.0f,4.0f, /* top face, farther triangle */ 186 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 187 }; 188 const GLsizeiptr cube_texture_UVbuffer_data_size = sizeof(cube_texture_UVbuffer_data); 189 GLuint cube_texture_UVbuffer_ID = ogl_arraybuffer_load(cube_texture_UVbuffer_data, cube_texture_UVbuffer_data_size); 190 191 double time_best = 999.0; 192 double time_worst = -1.0; 193 double time_total = 0.0; 194 int framecount = 0; 195 196 do { 197 double time = glfwGetTime(); 198 199 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 200 201 glUseProgram(program_ID); 202 203 ogl_program_uniform_set_mat4f(program_ID, "vu_vertex_MVP", MVP); 204 205 glActiveTexture(GL_TEXTURE0); 206 glBindTexture(GL_TEXTURE_2D, cube_texture_ID); 207 glUniform1i(program_fu_texture_sampler_ID, 0); 208 209 glUniform3f(program_fu_light_ID, 1.0f, 0.6f, -1.0f); 210 211 glEnableVertexAttribArray(program_va_vertex_position_ID); 212 glBindBuffer(GL_ARRAY_BUFFER, cube_vertexbuffer_ID); 213 glVertexAttribPointer(program_va_vertex_position_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0); 214 215 glEnableVertexAttribArray(program_va_vertex_normal_ID); 216 glBindBuffer(GL_ARRAY_BUFFER, cube_normalbuffer_ID); 217 glVertexAttribPointer(program_va_vertex_normal_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0); 218 219 glEnableVertexAttribArray(program_va_texture_UV_ID); 220 glBindBuffer(GL_ARRAY_BUFFER, cube_texture_UVbuffer_ID); 221 glVertexAttribPointer(program_va_texture_UV_ID, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0); 222 223 glEnableVertexAttribArray(program_va_vertex_color_ID); 224 glBindBuffer(GL_ARRAY_BUFFER, cube_colorbuffer_ID); 225 glVertexAttribPointer(program_va_vertex_color_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0); 226 227 glDrawArrays(GL_TRIANGLES, 0, cube_vertexbuffer_data_vertexes); 228 229 glDisableVertexAttribArray(program_va_vertex_position_ID); 230 glDisableVertexAttribArray(program_va_vertex_normal_ID); 231 glDisableVertexAttribArray(program_va_texture_UV_ID); 232 //glDisableVertexAttribArray(program_va_vertex_color_ID); 233 234 time = glfwGetTime() - time; 235 if (time < time_best) { 236 time_best = time; 237 } 238 else if (time > time_worst) { 239 time_worst = time; 240 } 241 time_total += time; 242 243 framecount++; 244 245 glfwSwapBuffers(window); 246 glfwPollEvents(); 247 } 248 while ( 249 (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS) 250 && 251 (glfwWindowShouldClose(window) == 0) 252 ); 253 254 glDeleteBuffers(1, &cube_vertexbuffer_ID); 255 glDeleteBuffers(1, &cube_texture_UVbuffer_ID); 256 glDeleteBuffers(1, &cube_colorbuffer_ID); 257 glDeleteProgram(program_ID); 258 //glDeleteTextures(1, &program_uniform_texturesampler_ID); 259 260 glfwTerminate(); 261 262 printf( 263 "performance:" "\n" 264 "\t" "frames drawn: %i" "\n" 265 "\t" "best: %fms" "\n" 266 "\t" "worst: %fms" "\n" 267 "\t" "average: %fms" "\n", 268 framecount, 269 time_best * 1000, 270 time_worst * 1000, 271 (time_total / framecount) * 1000 272 ); 273 274 return 0; 275 } 276