opengl_learn

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

04-lighting.c (10133B)


      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/beginners-tutorials/tutorial-5-a-textured-cube/ */
      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, 1, "04 - lighting");
     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 	ogl_mat4f_identity(&MVP_model);
     91 
     92 	struct ogl_mat4f MVP;
     93 	ogl_mat4f_identity(&MVP);
     94 	ogl_mat4f_multiply(MVP, MVP_projection, &MVP);
     95 	ogl_mat4f_multiply(MVP, MVP_view,       &MVP);
     96 	ogl_mat4f_multiply(MVP, MVP_model,      &MVP);
     97 
     98 	static const GLfloat cube_vertexbuffer_data[] = { 
     99 		-1.0f,-1.0f,-1.0f,  -1.0f,-1.0f, 1.0f,  -1.0f, 1.0f, 1.0f,
    100 		 1.0f, 1.0f,-1.0f,  -1.0f,-1.0f,-1.0f,  -1.0f, 1.0f,-1.0f,
    101 		 1.0f,-1.0f, 1.0f,  -1.0f,-1.0f,-1.0f,   1.0f,-1.0f,-1.0f,
    102 		 1.0f, 1.0f,-1.0f,   1.0f,-1.0f,-1.0f,  -1.0f,-1.0f,-1.0f,
    103 		-1.0f,-1.0f,-1.0f,  -1.0f, 1.0f, 1.0f,  -1.0f, 1.0f,-1.0f,
    104 		 1.0f,-1.0f, 1.0f,  -1.0f,-1.0f, 1.0f,  -1.0f,-1.0f,-1.0f,
    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 	};
    112 	static const size_t cube_vertexbuffer_data_size     = sizeof(cube_vertexbuffer_data);
    113 	static const size_t cube_vertexbuffer_data_vertexes = (sizeof(cube_vertexbuffer_data) / sizeof(*cube_vertexbuffer_data)) / 3;
    114 	GLuint cube_vertexbuffer_ID = ogl_arraybuffer_load(cube_vertexbuffer_data, cube_vertexbuffer_data_size);
    115 
    116 	#define _TRIPLICATE(x, y, z) x, y, z,  x, y, z,  x, y, z
    117 	static const GLfloat cube_normalbuffer_data[] = { 
    118 		_TRIPLICATE(-1.0f, 0.0f, 0.0f),
    119 		_TRIPLICATE( 0.0f, 0.0f,-1.0f),
    120 		_TRIPLICATE( 0.0f,-1.0f, 0.0f),
    121 		_TRIPLICATE( 0.0f, 0.0f,-1.0f),
    122 		_TRIPLICATE(-1.0f, 0.0f, 0.0f),
    123 		_TRIPLICATE( 0.0f,-1.0f, 0.0f),
    124 		_TRIPLICATE( 0.0f, 0.0f, 1.0f),
    125 		_TRIPLICATE( 1.0f, 0.0f, 0.0f),
    126 		_TRIPLICATE( 1.0f, 0.0f, 0.0f),
    127 		_TRIPLICATE( 0.0f, 1.0f, 0.0f),
    128 		_TRIPLICATE( 0.0f, 1.0f, 0.0f),
    129 		_TRIPLICATE( 0.0f, 0.0f, 1.0f),
    130 	};
    131 	#undef _TRIPLICATE
    132 	static const size_t cube_normalbuffer_data_size = sizeof(cube_normalbuffer_data);
    133 	GLuint cube_normalbuffer_ID = ogl_arraybuffer_load(cube_normalbuffer_data, cube_normalbuffer_data_size);
    134 
    135 	static const GLfloat cube_colorbuffer_data[] = {
    136 		0.583f,0.771f,0.014f,  0.609f,0.115f,0.436f,  0.327f,0.483f,0.844f,
    137 		0.822f,0.569f,0.201f,  0.435f,0.602f,0.223f,  0.310f,0.747f,0.185f,
    138 		0.597f,0.770f,0.761f,  0.559f,0.436f,0.730f,  0.359f,0.583f,0.152f,
    139 		0.483f,0.596f,0.789f,  0.559f,0.861f,0.639f,  0.195f,0.548f,0.859f,
    140 		0.014f,0.184f,0.576f,  0.771f,0.328f,0.970f,  0.406f,0.615f,0.116f,
    141 		0.676f,0.977f,0.133f,  0.971f,0.572f,0.833f,  0.140f,0.616f,0.489f,
    142 		0.997f,0.513f,0.064f,  0.945f,0.719f,0.592f,  0.543f,0.021f,0.978f,
    143 		0.279f,0.317f,0.505f,  0.167f,0.620f,0.077f,  0.347f,0.857f,0.137f,
    144 		0.055f,0.953f,0.042f,  0.714f,0.505f,0.345f,  0.783f,0.290f,0.734f,
    145 		0.722f,0.645f,0.174f,  0.302f,0.455f,0.848f,  0.225f,0.587f,0.040f,
    146 		0.517f,0.713f,0.338f,  0.053f,0.959f,0.120f,  0.393f,0.621f,0.362f,
    147 		0.673f,0.211f,0.457f,  0.820f,0.883f,0.371f,  0.982f,0.099f,0.879f,
    148 	};
    149 	static const size_t cube_colorbuffer_data_size = sizeof(cube_colorbuffer_data);
    150 	GLuint cube_colorbuffer_ID = ogl_arraybuffer_load(cube_colorbuffer_data, cube_colorbuffer_data_size);
    151 
    152 	uint32_t cube_texture_data[] = {
    153 		htobe32(0x00000000),  htobe32(0x0000FFFF),
    154 		htobe32(0xFF0000FF),  htobe32(0x00FF00FF),
    155 	};
    156 	const size_t cube_texture_data_width  = 2;
    157 	const size_t cube_texture_data_height = 2;
    158 	GLuint cube_texture_ID = 0;
    159 	glGenTextures(1, &cube_texture_ID);
    160 	glBindTexture(GL_TEXTURE_2D, cube_texture_ID);
    161 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cube_texture_data_width, cube_texture_data_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, cube_texture_data);
    162 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    163 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    164 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    165 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    166 	glBindTexture(GL_TEXTURE_2D, 0);
    167 
    168 	const GLfloat cube_texture_UVbuffer_data[] = {
    169 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    170 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,  /* right face, upper   triangle */
    171 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    172 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,  /* right face, lower   triangle */
    173 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    174 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    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,  /* left  face, upper   triangle */
    177 		0.0f,1.0f,  0.0f,0.0f,  1.0f,1.0f,  /* left  face, lower   triangle */
    178 		0.0f,0.0f,  0.0f,4.0f,  4.0f,4.0f,  /* top   face, closer  triangle */
    179 		0.0f,0.0f,  4.0f,4.0f,  0.0f,4.0f,  /* top   face, farther triangle */
    180 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    181 	};
    182 	const GLsizeiptr cube_texture_UVbuffer_data_size = sizeof(cube_texture_UVbuffer_data);
    183 	GLuint cube_texture_UVbuffer_ID = ogl_arraybuffer_load(cube_texture_UVbuffer_data, cube_texture_UVbuffer_data_size);
    184 
    185 	do {
    186 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    187 
    188 		glUseProgram(program_ID);
    189 
    190 		ogl_program_uniform_set_mat4f(program_ID, "vu_vertex_MVP", MVP);
    191 
    192 		glActiveTexture(GL_TEXTURE0);
    193 		glBindTexture(GL_TEXTURE_2D, cube_texture_ID);
    194 		glUniform1i(program_fu_texture_sampler_ID, 0);
    195 
    196 		glUniform3f(program_fu_light_ID, 1.0f, 0.6f, -1.0f);
    197 
    198 		glEnableVertexAttribArray(program_va_vertex_position_ID);
    199 		glBindBuffer(GL_ARRAY_BUFFER, cube_vertexbuffer_ID);
    200 		glVertexAttribPointer(program_va_vertex_position_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
    201 
    202 		glEnableVertexAttribArray(program_va_vertex_normal_ID);
    203 		glBindBuffer(GL_ARRAY_BUFFER, cube_normalbuffer_ID);
    204 		glVertexAttribPointer(program_va_vertex_normal_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
    205 
    206 		glEnableVertexAttribArray(program_va_texture_UV_ID);
    207 		glBindBuffer(GL_ARRAY_BUFFER, cube_texture_UVbuffer_ID);
    208 		glVertexAttribPointer(program_va_texture_UV_ID, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
    209 
    210 		glEnableVertexAttribArray(program_va_vertex_color_ID);
    211 		glBindBuffer(GL_ARRAY_BUFFER, cube_colorbuffer_ID);
    212 		glVertexAttribPointer(program_va_vertex_color_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
    213 
    214 		glDrawArrays(GL_TRIANGLES, 0, cube_vertexbuffer_data_vertexes);
    215 
    216 		glDisableVertexAttribArray(program_va_vertex_position_ID);
    217 		glDisableVertexAttribArray(program_va_vertex_normal_ID);
    218 		glDisableVertexAttribArray(program_va_texture_UV_ID);
    219 		//glDisableVertexAttribArray(program_va_vertex_color_ID);
    220 
    221 		glfwSwapBuffers(window);
    222 		glfwPollEvents();
    223 	}
    224 	while (
    225 		(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS)
    226 		&&
    227 		(glfwWindowShouldClose(window) == 0)
    228 	);
    229 
    230 	glDeleteBuffers(1, &cube_vertexbuffer_ID);
    231 	glDeleteBuffers(1, &cube_texture_UVbuffer_ID);
    232 	glDeleteBuffers(1, &cube_colorbuffer_ID);
    233 	glDeleteProgram(program_ID);
    234 	//glDeleteTextures(1, &program_uniform_texturesampler_ID);
    235 
    236 	glfwTerminate();
    237 
    238 	return 0;
    239 }
    240