opengl_learn

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

commit 78e5d26707b1057f8392c0bf24a5fd82be0e6498
parent debe4ab718c941c356140b18a5c09c0d819220cf
Author: David DiPaola <DavidDiPaola@users.noreply.github.com>
Date:   Thu, 23 Aug 2018 07:26:15 -0400

04: initial commit of lighting example

Diffstat:
M.gitignore | 1+
A04-lighting.c | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MMakefile | 11+++++++++--
3 files changed, 250 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,6 +3,7 @@ 01-perspective 02-cube 03-texture +04-lighting .*.swp diff --git a/04-lighting.c b/04-lighting.c @@ -0,0 +1,240 @@ +/* +2018 David DiPaola +licensed under CC0 (public domain, see https://creativecommons.org/publicdomain/zero/1.0/) +*/ + +/* followed this tutorial: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/ */ + +#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, "03 - texture"); + + /* 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; + ogl_mat4f_identity(&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); + + do { + 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); + + 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(); + + return 0; +} + diff --git a/Makefile b/Makefile @@ -16,6 +16,10 @@ OGL_BIN = ogl/ogl.a 03_OBJ = $(03_SRC:.c=.o) $(OGL_BIN) 03_BIN = 03-texture +04_SRC = 04-lighting.c +04_OBJ = $(04_SRC:.c=.o) $(OGL_BIN) +04_BIN = 04-lighting + CFLAGS ?= -std=c99 -Wall -fwrapv -g @@ -23,7 +27,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) +all: $(00_BIN) $(01_BIN) $(02_BIN) $(03_BIN) $(04_BIN) .PHONY: clean clean: @@ -31,7 +35,8 @@ clean: $(00_OBJ) $(00_BIN) \ $(01_OBJ) $(01_BIN) \ $(02_OBJ) $(02_BIN) \ - $(03_OBJ) $(03_BIN) + $(03_OBJ) $(03_BIN) \ + $(04_OBJ) $(04_BIN) $(MAKE) --directory=./ogl/ clean $(00_BIN): $(00_OBJ) @@ -42,6 +47,8 @@ $(02_BIN): $(02_OBJ) $(03_BIN): $(03_OBJ) +$(04_BIN): $(04_OBJ) + .PHONY: $(OGL_BIN) $(OGL_BIN): $(MAKE) --directory=./ogl/ all