aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-01-26 09:25:04 +0100
committerBad Diode <bd@badd10de.dev>2021-01-26 10:34:46 +0100
commit21924d5e08814cc9028dc3866d8b97d8422807f4 (patch)
tree2e185715bdb0521be5c67633defa51fd64c03713
parent71ab55ad22abd7ba8d6c41fa4c9ff5aa69db8284 (diff)
downloadmic-opengl-example-21924d5e08814cc9028dc3866d8b97d8422807f4.tar.gz
mic-opengl-example-21924d5e08814cc9028dc3866d8b97d8422807f4.zip
Add triangle rendering w/ shader recompilation
-rw-r--r--Makefile3
-rw-r--r--shaders/triangle.frag5
-rw-r--r--shaders/triangle.vert5
-rw-r--r--src/app.c113
-rw-r--r--src/app.h4
5 files changed, 123 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index e7770ac..d1d5630 100644
--- a/Makefile
+++ b/Makefile
@@ -3,10 +3,13 @@
3 3
4# Source code location and files to watch for changes. 4# Source code location and files to watch for changes.
5SRC_DIR := src 5SRC_DIR := src
6SHADERS_DIR := shaders
6SRC_MAIN := $(SRC_DIR)/main.c 7SRC_MAIN := $(SRC_DIR)/main.c
7SRC_APP := $(SRC_DIR)/app.c 8SRC_APP := $(SRC_DIR)/app.c
8WATCH_SRC := $(wildcard $(SRC_DIR)/*.c) 9WATCH_SRC := $(wildcard $(SRC_DIR)/*.c)
9WATCH_SRC += $(wildcard $(SRC_DIR)/*.h) 10WATCH_SRC += $(wildcard $(SRC_DIR)/*.h)
11WATCH_SRC += $(wildcard $(SHADERS_DIR)/*.vert)
12WATCH_SRC += $(wildcard $(SHADERS_DIR)/*.frag)
10 13
11# Output library names and executables. 14# Output library names and executables.
12BIN_NAME := app 15BIN_NAME := app
diff --git a/shaders/triangle.frag b/shaders/triangle.frag
new file mode 100644
index 0000000..e8bde66
--- /dev/null
+++ b/shaders/triangle.frag
@@ -0,0 +1,5 @@
1#version 330 core
2out vec4 frag_col;
3void main() {
4 frag_col = vec4(0.8f, 0.8f, 0.8f, 1.0f);
5}
diff --git a/shaders/triangle.vert b/shaders/triangle.vert
new file mode 100644
index 0000000..d5168a8
--- /dev/null
+++ b/shaders/triangle.vert
@@ -0,0 +1,5 @@
1#version 330 core
2layout (location = 0) in vec3 vertex;
3void main() {
4 gl_Position = vec4(vertex.x, vertex.y, vertex.z, 1.0);
5}
diff --git a/src/app.c b/src/app.c
index 99f5cff..08ca7f2 100644
--- a/src/app.c
+++ b/src/app.c
@@ -1,6 +1,62 @@
1#include "app.h" 1#include "app.h"
2#include "platform.h" 2#include "platform.h"
3 3
4bool
5compile_shaders(const char *vert, const char *frag, u32 *handle,
6 PlatformAPI platform) {
7 int success = 0;
8 char memory[MB(1)] = {0}; // Memory for reading shader files
9
10 // Initialize shader handles.
11 u32 vert_handle = glCreateShader(GL_VERTEX_SHADER);
12 u32 frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
13
14 // Vertex shader.
15 {
16 platform.read_file(vert, memory);
17 const char * source = memory;
18 glShaderSource(vert_handle, 1, &source, NULL);
19 glCompileShader(vert_handle);
20 glGetShaderiv(vert_handle, GL_COMPILE_STATUS, &success);
21 if (!success) {
22 glDeleteShader(vert_handle);
23 glDeleteShader(frag_handle);
24 return false;
25 }
26 }
27
28 // Fragment shader.
29 {
30 platform.read_file(frag, memory);
31 const char * source = memory;
32 glShaderSource(frag_handle, 1, &source, NULL);
33 glCompileShader(frag_handle);
34 glGetShaderiv(frag_handle, GL_COMPILE_STATUS, &success);
35 if (!success) {
36 glDeleteShader(vert_handle);
37 glDeleteShader(frag_handle);
38 return false;
39 }
40 }
41
42 // Program linkage.
43 *handle = glCreateProgram();
44 glAttachShader(*handle, vert_handle);
45 glAttachShader(*handle, frag_handle);
46 glLinkProgram(*handle);
47 glGetProgramiv(*handle, GL_LINK_STATUS, &success);
48 if(!success) {
49 glDeleteProgram(*handle);
50 glDeleteShader(vert_handle);
51 glDeleteShader(frag_handle);
52 return false;
53 }
54 glDeleteShader(vert_handle);
55 glDeleteShader(frag_handle);
56
57 return true;
58}
59
4static inline bool 60static inline bool
5app_init(AppState *state, PlatformAPI platform) { 61app_init(AppState *state, PlatformAPI platform) {
6 platform.log("INIT"); 62 platform.log("INIT");
@@ -14,7 +70,7 @@ app_init(AppState *state, PlatformAPI platform) {
14 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 70 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
15 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 71 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
16 72
17 // // Initialize window. 73 // Initialize window.
18 GLFWwindow* window = glfwCreateWindow(400, 300, "Hello MIC", NULL, NULL); 74 GLFWwindow* window = glfwCreateWindow(400, 300, "Hello MIC", NULL, NULL);
19 if (window == NULL) { 75 if (window == NULL) {
20 platform.log("ERROR: failed to create GLFW window"); 76 platform.log("ERROR: failed to create GLFW window");
@@ -33,8 +89,47 @@ app_init(AppState *state, PlatformAPI platform) {
33 // Initialize viewport. 89 // Initialize viewport.
34 glViewport(0, 0, 400, 300); 90 glViewport(0, 0, 400, 300);
35 91
92 // Initialize vertex data.
93 state->vertices[0] = -0.5f;
94 state->vertices[1] = -0.5f;
95 state->vertices[2] = 0.0f;
96 state->vertices[3] = 0.5f;
97 state->vertices[4] = -0.5f;
98 state->vertices[5] = 0.0f;
99 state->vertices[6] = 0.0f;
100 state->vertices[7] = 0.5f;
101 state->vertices[8] = 0.0f;
102
103 // Initialize Vertex Buffer Object (VBO) and Vertex Array Object (VAO).
104 u32 VBO;
105 glGenBuffers(1, &VBO);
106 u32 VAO;
107 glGenVertexArrays(1, &VAO);
108
109 // Bind the VAO before any other binding.
110 glBindVertexArray(VAO);
111
112 // Send vertex data to VBO.
113 glBindBuffer(GL_ARRAY_BUFFER, VBO);
114 glBufferData(GL_ARRAY_BUFFER, sizeof(state->vertices), state->vertices,
115 GL_STATIC_DRAW);
116
117 // Set vertex attribute pointers.
118 glEnableVertexAttribArray(0);
119 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
120
121 // Compile shader program.
122 const char *vert = "shaders/triangle.vert";
123 const char *frag = "shaders/triangle.frag";
124 if (!compile_shaders(vert, frag, &state->shader_program, platform)) {
125 platform.log("WARNING: failed to compile shader program");
126 }
127
36 // Initialize application state. 128 // Initialize application state.
37 state->window = window; 129 state->window = window;
130 state->VBO = VBO;
131 state->VAO = VAO;
132
38 return true; 133 return true;
39} 134}
40 135
@@ -46,8 +141,12 @@ app_destroy(AppState *state, PlatformAPI platform) {
46 141
47static inline void 142static inline void
48app_reload(AppState *state, PlatformAPI platform) { 143app_reload(AppState *state, PlatformAPI platform) {
49 (void)state; // Unused parameter.
50 platform.log("RELOAD"); 144 platform.log("RELOAD");
145 const char *vert = "shaders/triangle.vert";
146 const char *frag = "shaders/triangle.frag";
147 if (!compile_shaders(vert, frag, &state->shader_program, platform)) {
148 platform.log("WARNING: failed to compile shader program");
149 }
51} 150}
52 151
53static inline void 152static inline void
@@ -58,13 +157,13 @@ app_unload(AppState *state, PlatformAPI platform) {
58 157
59static inline bool 158static inline bool
60app_step(AppState *state, PlatformAPI platform) { 159app_step(AppState *state, PlatformAPI platform) {
61 (void)platform; // Unused parameter. 160 (void)platform; // Unused parameter
62 if (glfwWindowShouldClose(state->window)) {
63 return false;
64 }
65 161
66 glClearColor(1.0f, 0.0f, 0.4f, 1.0f); 162 glClearColor(0.8f, 0.0f, 0.4f, 1.0f);
67 glClear(GL_COLOR_BUFFER_BIT); 163 glClear(GL_COLOR_BUFFER_BIT);
164 glUseProgram(state->shader_program);
165 glBindVertexArray(state->VAO);
166 glDrawArrays(GL_TRIANGLES, 0, 3);
68 167
69 glfwSwapBuffers(state->window); 168 glfwSwapBuffers(state->window);
70 glfwPollEvents(); 169 glfwPollEvents();
diff --git a/src/app.h b/src/app.h
index 613360f..16dc8a5 100644
--- a/src/app.h
+++ b/src/app.h
@@ -10,6 +10,10 @@
10typedef struct AppState { 10typedef struct AppState {
11 // OpenGL 11 // OpenGL
12 GLFWwindow *window; 12 GLFWwindow *window;
13 f32 vertices[12];
14 u32 VBO;
15 u32 VAO;
16 u32 shader_program;
13} AppState; 17} AppState;
14 18
15// Function pointers for the AppAPI. 19// Function pointers for the AppAPI.