opengl_learn

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

03-texture.c (8411B)


      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, "03 - texture");
     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 		"uniform   mat4 vu_vertex_MVP;" "\n"       /* uniforms are inputs to vertex and fragment shaders that don't change per-vertex */
     33 		"attribute vec3 va_vertex_position;" "\n"  /* attributes are inputs to vertex shaders */
     34 		"attribute vec3 va_vertex_color;" "\n"
     35 		"attribute vec2 va_texture_UV;" "\n"
     36 		"varying   vec4 fv_vertex_color;" "\n"     /* varyings are outputs of vertex shaders and inputs to fragment shaders */
     37 		"varying   vec2 fv_texture_UV;" "\n"
     38 		"void main(){" "\n"
     39 		"	gl_Position = vu_vertex_MVP * vec4(va_vertex_position,1);" "\n"
     40 		"\n"
     41 		"	fv_vertex_color = vec4(va_vertex_color,1);" "\n"
     42 		"	fv_texture_UV   = va_texture_UV;" "\n"
     43 		"}" "\n"
     44 	;
     45 	const char * program_fragment_source =
     46 		"#version 100" "\n"
     47 		"precision lowp float;" "\n"
     48 		"uniform sampler2D fu_texture_sampler;" "\n"
     49 		"varying vec2      fv_texture_UV;" "\n"
     50 		"varying vec4      fv_vertex_color;" "\n"
     51 		"void main() {" "\n"
     52 		"	vec4 texel = texture2D(fu_texture_sampler, fv_texture_UV);" "\n"
     53 		"	gl_FragColor = mix(texel, fv_vertex_color, 1.0-texel.a);" "\n"
     54 		"}" "\n"
     55 	;
     56 	GLuint program_ID = ogl_program_build(program_vertex_source, program_fragment_source);
     57 	GLint program_va_vertex_position_ID = glGetAttribLocation( program_ID, "va_vertex_position");
     58 	GLint program_va_vertex_color_ID    = glGetAttribLocation( program_ID, "va_vertex_color");
     59 	GLint program_va_texture_UV_ID      = glGetAttribLocation( program_ID, "va_texture_UV");
     60 	GLint program_fu_texture_sampler_ID = glGetUniformLocation(program_ID, "fu_texture_sampler");
     61 
     62 	struct ogl_mat4f MVP_projection;
     63 	ogl_perspective(45.0f, 0.1f, 100.0f, &MVP_projection);
     64 
     65 	struct ogl_mat4f MVP_view;
     66 	struct ogl_vec3f MVP_view_eye    = { .x= 4.0f,  .y= 3.0f,  .z= 3.0f };
     67 	struct ogl_vec3f MVP_view_center = { .x= 0.0f,  .y= 0.0f,  .z= 0.0f };
     68 	struct ogl_vec3f MVP_view_up     = { .x= 0.0f,  .y= 1.0f,  .z= 0.0f };
     69 	ogl_lookat(MVP_view_eye, MVP_view_center, MVP_view_up, &MVP_view);
     70 
     71 	struct ogl_mat4f MVP_model;
     72 	ogl_mat4f_identity(&MVP_model);
     73 
     74 	struct ogl_mat4f MVP;
     75 	ogl_mat4f_identity(&MVP);
     76 	ogl_mat4f_multiply(MVP, MVP_projection, &MVP);
     77 	ogl_mat4f_multiply(MVP, MVP_view,       &MVP);
     78 	ogl_mat4f_multiply(MVP, MVP_model,      &MVP);
     79 
     80 	static const GLfloat cube_vertexbuffer_data[] = { 
     81 		-1.0f,-1.0f,-1.0f,  -1.0f,-1.0f, 1.0f,  -1.0f, 1.0f, 1.0f,
     82 		 1.0f, 1.0f,-1.0f,  -1.0f,-1.0f,-1.0f,  -1.0f, 1.0f,-1.0f,
     83 		 1.0f,-1.0f, 1.0f,  -1.0f,-1.0f,-1.0f,   1.0f,-1.0f,-1.0f,
     84 		 1.0f, 1.0f,-1.0f,   1.0f,-1.0f,-1.0f,  -1.0f,-1.0f,-1.0f,
     85 		-1.0f,-1.0f,-1.0f,  -1.0f, 1.0f, 1.0f,  -1.0f, 1.0f,-1.0f,
     86 		 1.0f,-1.0f, 1.0f,  -1.0f,-1.0f, 1.0f,  -1.0f,-1.0f,-1.0f,
     87 		-1.0f, 1.0f, 1.0f,  -1.0f,-1.0f, 1.0f,   1.0f,-1.0f, 1.0f,
     88 		 1.0f, 1.0f, 1.0f,   1.0f,-1.0f,-1.0f,   1.0f, 1.0f,-1.0f,
     89 		 1.0f,-1.0f,-1.0f,   1.0f, 1.0f, 1.0f,   1.0f,-1.0f, 1.0f,
     90 		 1.0f, 1.0f, 1.0f,   1.0f, 1.0f,-1.0f,  -1.0f, 1.0f,-1.0f,
     91 		 1.0f, 1.0f, 1.0f,  -1.0f, 1.0f,-1.0f,  -1.0f, 1.0f, 1.0f,
     92 		 1.0f, 1.0f, 1.0f,  -1.0f, 1.0f, 1.0f,   1.0f,-1.0f, 1.0f,
     93 	};
     94 	static const size_t cube_vertexbuffer_data_size     = sizeof(cube_vertexbuffer_data);
     95 	static const size_t cube_vertexbuffer_data_vertexes = (sizeof(cube_vertexbuffer_data) / sizeof(*cube_vertexbuffer_data)) / 3;
     96 	GLuint cube_vertexbuffer_ID = ogl_arraybuffer_load(cube_vertexbuffer_data, cube_vertexbuffer_data_size);
     97 
     98 	static const GLfloat cube_colorbuffer_data[] = {
     99 		0.583f,0.771f,0.014f,  0.609f,0.115f,0.436f,  0.327f,0.483f,0.844f,
    100 		0.822f,0.569f,0.201f,  0.435f,0.602f,0.223f,  0.310f,0.747f,0.185f,
    101 		0.597f,0.770f,0.761f,  0.559f,0.436f,0.730f,  0.359f,0.583f,0.152f,
    102 		0.483f,0.596f,0.789f,  0.559f,0.861f,0.639f,  0.195f,0.548f,0.859f,
    103 		0.014f,0.184f,0.576f,  0.771f,0.328f,0.970f,  0.406f,0.615f,0.116f,
    104 		0.676f,0.977f,0.133f,  0.971f,0.572f,0.833f,  0.140f,0.616f,0.489f,
    105 		0.997f,0.513f,0.064f,  0.945f,0.719f,0.592f,  0.543f,0.021f,0.978f,
    106 		0.279f,0.317f,0.505f,  0.167f,0.620f,0.077f,  0.347f,0.857f,0.137f,
    107 		0.055f,0.953f,0.042f,  0.714f,0.505f,0.345f,  0.783f,0.290f,0.734f,
    108 		0.722f,0.645f,0.174f,  0.302f,0.455f,0.848f,  0.225f,0.587f,0.040f,
    109 		0.517f,0.713f,0.338f,  0.053f,0.959f,0.120f,  0.393f,0.621f,0.362f,
    110 		0.673f,0.211f,0.457f,  0.820f,0.883f,0.371f,  0.982f,0.099f,0.879f,
    111 	};
    112 	static const size_t cube_colorbuffer_data_size = sizeof(cube_colorbuffer_data);
    113 	GLuint cube_colorbuffer_ID = ogl_arraybuffer_load(cube_colorbuffer_data, cube_colorbuffer_data_size);
    114 
    115 	uint32_t cube_texture_data[] = {
    116 		htobe32(0x00000000),  htobe32(0x0000FFFF),
    117 		htobe32(0xFF0000FF),  htobe32(0x00FF00FF),
    118 	};
    119 	const size_t cube_texture_data_width  = 2;
    120 	const size_t cube_texture_data_height = 2;
    121 	GLuint cube_texture_ID = 0;
    122 	glGenTextures(1, &cube_texture_ID);
    123 	glBindTexture(GL_TEXTURE_2D, cube_texture_ID);
    124 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cube_texture_data_width, cube_texture_data_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, cube_texture_data);
    125 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    126 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    127 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    128 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    129 	glBindTexture(GL_TEXTURE_2D, 0);
    130 
    131 	const GLfloat cube_texture_UVbuffer_data[] = {
    132 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    133 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,  /* right face, upper   triangle */
    134 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    135 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,  /* right face, lower   triangle */
    136 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    137 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    138 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    139 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,  /* left  face, upper   triangle */
    140 		0.0f,1.0f,  0.0f,0.0f,  1.0f,1.0f,  /* left  face, lower   triangle */
    141 		0.0f,0.0f,  0.0f,4.0f,  4.0f,4.0f,  /* top   face, closer  triangle */
    142 		0.0f,0.0f,  4.0f,4.0f,  0.0f,4.0f,  /* top   face, farther triangle */
    143 		0.0f,0.0f,  0.0f,1.0f,  1.0f,1.0f,
    144 	};
    145 	const GLsizeiptr cube_texture_UVbuffer_data_size = sizeof(cube_texture_UVbuffer_data);
    146 	GLuint cube_texture_UVbuffer_ID = ogl_arraybuffer_load(cube_texture_UVbuffer_data, cube_texture_UVbuffer_data_size);
    147 
    148 	do {
    149 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    150 
    151 		glUseProgram(program_ID);
    152 		ogl_program_uniform_set_mat4f(program_ID, "vu_vertex_MVP", MVP);
    153 		glActiveTexture(GL_TEXTURE0);
    154 		glBindTexture(GL_TEXTURE_2D, cube_texture_ID);
    155 		glUniform1i(program_fu_texture_sampler_ID, 0);
    156 
    157 		glEnableVertexAttribArray(program_va_vertex_position_ID);
    158 		glBindBuffer(GL_ARRAY_BUFFER, cube_vertexbuffer_ID);
    159 		glVertexAttribPointer(program_va_vertex_position_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
    160 
    161 		glEnableVertexAttribArray(program_va_texture_UV_ID);
    162 		glBindBuffer(GL_ARRAY_BUFFER, cube_texture_UVbuffer_ID);
    163 		glVertexAttribPointer(program_va_texture_UV_ID, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
    164 
    165 		glEnableVertexAttribArray(program_va_vertex_color_ID);
    166 		glBindBuffer(GL_ARRAY_BUFFER, cube_colorbuffer_ID);
    167 		glVertexAttribPointer(program_va_vertex_color_ID, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0);
    168 
    169 		glDrawArrays(GL_TRIANGLES, 0, cube_vertexbuffer_data_vertexes);
    170 
    171 		glBindBuffer(GL_ARRAY_BUFFER, 0);
    172 		glDisableVertexAttribArray(program_va_vertex_position_ID);
    173 		glDisableVertexAttribArray(program_va_texture_UV_ID);
    174 		//glDisableVertexAttribArray(program_va_vertex_color_ID);
    175 
    176 		glfwSwapBuffers(window);
    177 		glfwPollEvents();
    178 	}
    179 	while (
    180 		(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS)
    181 		&&
    182 		(glfwWindowShouldClose(window) == 0)
    183 	);
    184 
    185 	glDeleteBuffers(1, &cube_vertexbuffer_ID);
    186 	glDeleteBuffers(1, &cube_texture_UVbuffer_ID);
    187 	glDeleteBuffers(1, &cube_colorbuffer_ID);
    188 	glDeleteProgram(program_ID);
    189 	//glDeleteTextures(1, &program_uniform_texturesampler_ID);
    190 
    191 	glfwTerminate();
    192 
    193 	return 0;
    194 }
    195