opengl_learn

Step-by-step introduction to OpenGL
git clone https://0xdd.org/code/opengl_learn.git
Log | Files | Refs | README | LICENSE

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