summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-08-29 07:11:23 +0200
committerBad Diode <bd@badd10de.dev>2022-08-29 07:11:23 +0200
commit107b03f9019ec79324e9ef23b5ec9f4aa7e04f75 (patch)
treebb56f6936c062e418d5b9134813f1ac5b12e560d
parent94c36fb2f2c8f1c90752df4df96f7f65d7ade9b0 (diff)
downloadogl-monotext-107b03f9019ec79324e9ef23b5ec9f4aa7e04f75.tar.gz
ogl-monotext-107b03f9019ec79324e9ef23b5ec9f4aa7e04f75.zip
Refactor update/render functions to use the context
-rw-r--r--src/main.c210
1 files changed, 122 insertions, 88 deletions
diff --git a/src/main.c b/src/main.c
index 543ef86..98b9764 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,6 +7,8 @@
7 7
8#include "shorthand.h" 8#include "shorthand.h"
9 9
10#define TEXT_OVERLAY_SIZE 5
11
10// 12//
11// Callbacks. 13// Callbacks.
12// 14//
@@ -27,6 +29,13 @@ glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
27 } 29 }
28} 30}
29 31
32// Letter for a the monospace text overlay layer.
33struct Letter {
34 f32 x;
35 f32 y;
36 f32 idx;
37};
38
30typedef struct Context { 39typedef struct Context {
31 GLFWwindow *window; 40 GLFWwindow *window;
32 u32 gl_version_major; 41 u32 gl_version_major;
@@ -41,6 +50,20 @@ typedef struct Context {
41 f64 elapsed; 50 f64 elapsed;
42 size_t n_frames; 51 size_t n_frames;
43 } frame_time; 52 } frame_time;
53
54 struct {
55 u32 program;
56 u32 tex_id;
57 u32 vao;
58 u32 vbo;
59 u32 ebo;
60
61 struct Letter letters[2048];
62 u32 cur_x;
63 u32 cur_y;
64 u32 n_chars;
65 u32 size;
66 } text_overlay;
44} Context; 67} Context;
45 68
46u32 69u32
@@ -133,53 +156,6 @@ init_context(Context *ctx) {
133 156
134void 157void
135init_debug_overlay(Context *ctx) { 158init_debug_overlay(Context *ctx) {
136 // TODO: Add debug text to context and initialize here
137 (void)ctx;
138}
139
140void
141setup_callbacks(Context *ctx) {
142 glfwSetErrorCallback(glfw_error_callback);
143 glfwSetKeyCallback(ctx->window, glfw_key_callback);
144}
145
146void
147update_frame_time(Context *ctx) {
148 // Measure frame times and fps.
149 f64 cur_time = glfwGetTime();
150 f64 delta_time = cur_time - ctx->frame_time.prev;
151 ctx->frame_time.elapsed += delta_time;
152 ctx->frame_time.n_frames++;
153 if (ctx->frame_time.elapsed >= 1.0) {
154 f64 fps = 0;
155 fps = ctx->frame_time.n_frames / ctx->frame_time.elapsed;
156 ctx->frame_time.elapsed = 0;
157 ctx->frame_time.n_frames = 0;
158
159 // Update title with timing data.
160 char title_buf[256 * 2];
161 sprintf(title_buf,
162 "%s [%.2fms, %.2f FPS]",
163 ctx->win_title, delta_time * 1000, fps);
164 glfwSetWindowTitle(ctx->window, title_buf);
165 }
166 ctx->frame_time.prev = cur_time;
167}
168
169void
170update(Context *ctx) {
171 update_frame_time(ctx);
172}
173
174void
175render(Context *ctx) {
176 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
177 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
178
179 glfwGetFramebufferSize(ctx->window, &ctx->win_width, &ctx->win_height);
180 glViewport(0, 0, ctx->win_width, ctx->win_height);
181
182 // TODO: Only need to be done once on the initialization function.
183 // Prepare quad rendering. 159 // Prepare quad rendering.
184 f32 vertices[] = { 160 f32 vertices[] = {
185 // position // tex_coords 161 // position // tex_coords
@@ -194,9 +170,8 @@ render(Context *ctx) {
194 }; 170 };
195 171
196 // Vertex array object. 172 // Vertex array object.
197 u32 vao; 173 glGenVertexArrays(1, &ctx->text_overlay.vao);
198 glGenVertexArrays(1, &vao); 174 glBindVertexArray(ctx->text_overlay.vao);
199 glBindVertexArray(vao);
200 175
201 // Vertex buffer object setup. 176 // Vertex buffer object setup.
202 u32 vbo; 177 u32 vbo;
@@ -208,33 +183,19 @@ render(Context *ctx) {
208 glEnableVertexAttribArray(1); 183 glEnableVertexAttribArray(1);
209 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(f32), (void*)(2 * sizeof(f32))); 184 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(f32), (void*)(2 * sizeof(f32)));
210 185
211 // NOTE: This should be a dynamic array of offsets and index into the 186 glGenBuffers(1, &ctx->text_overlay.vbo);
212 // texture atlas. 187 glBindBuffer(GL_ARRAY_BUFFER, ctx->text_overlay.vbo);
213 struct Letter {
214 f32 x;
215 f32 y;
216 f32 idx;
217 };
218 struct Letter letters[] = {
219 {0, 0.0, 0},
220 {1, 0.0, 1},
221 {2, 0.0, 2},
222 };
223 u32 offset_vbo;
224 glGenBuffers(1, &offset_vbo);
225 glBindBuffer(GL_ARRAY_BUFFER, offset_vbo);
226 glBufferData(GL_ARRAY_BUFFER, sizeof(letters), letters, GL_STATIC_DRAW);
227 glEnableVertexAttribArray(2); 188 glEnableVertexAttribArray(2);
228 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(f32), (void*)0); 189 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(f32), (void*)0);
229 glVertexAttribDivisor(2, 1); 190 glVertexAttribDivisor(2, 1);
230 191
231 // Element buffer object setup. 192 // Element buffer object setup.
232 u32 ebo; 193 glGenBuffers(1, &ctx->text_overlay.ebo);
233 glGenBuffers(1, &ebo); 194 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ctx->text_overlay.ebo);
234 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
235 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 195 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
236 196
237 // Texture atlas. 197 // Texture atlas.
198 // TODO: Full 256 ascii font.
238 u8 texture[] = { 199 u8 texture[] = {
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 201 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
@@ -245,9 +206,8 @@ render(Context *ctx) {
245 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 206 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 }; 208 };
248 u32 tex_id; 209 glGenTextures(1, &ctx->text_overlay.tex_id);
249 glGenTextures(1, &tex_id); 210 glBindTexture(GL_TEXTURE_2D, ctx->text_overlay.tex_id);
250 glBindTexture(GL_TEXTURE_2D, tex_id);
251 glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 8 * 3, 8, 0, GL_RED, 211 glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 8 * 3, 8, 0, GL_RED,
252 GL_UNSIGNED_BYTE, &texture); 212 GL_UNSIGNED_BYTE, &texture);
253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -266,21 +226,24 @@ render(Context *ctx) {
266"layout (location = 1) in vec2 tex_coords;\n" 226"layout (location = 1) in vec2 tex_coords;\n"
267"layout (location = 2) in vec3 offset;\n" 227"layout (location = 2) in vec3 offset;\n"
268"out vec2 tex;\n" 228"out vec2 tex;\n"
269"void main() {\n"
270// TODO: Uniforms
271" float w = 800;\n"
272" float h = 600;\n"
273" float size = 5;\n"
274" float N = 3;\n"
275 229
230"uniform float w;\n"
231"uniform float h;\n"
232"uniform float size;\n"
233
234"void main() {\n"
235" float N = 3;\n" // TODO: should be 256 for the full font.
276" float idx = offset.z;\n" 236" float idx = offset.z;\n"
277" float m = 1.0 / N;\n" 237" float m = 1.0 / N;\n"
278" float k = m * idx;\n" 238" float k = m * idx;\n"
239
279// TODO: Only 8x8 monospace fonts for now 240// TODO: Only 8x8 monospace fonts for now
280" float font_w = 8;\n" 241" float font_w = 8;\n"
281" float font_h = 8;\n" 242" float font_h = 8;\n"
243
282// NOTE: This makes sures that the fonts have the right size. 244// NOTE: This makes sures that the fonts have the right size.
283" vec2 scalar = vec2(font_w / w, font_h / h) * size;\n" 245" vec2 scalar = vec2(font_w / w, font_h / h) * size;\n"
246
284" vec2 pos = tex_coords * scalar;\n" 247" vec2 pos = tex_coords * scalar;\n"
285" pos += vec2(0.0, 1.0 - scalar.y);\n" 248" pos += vec2(0.0, 1.0 - scalar.y);\n"
286" pos += scalar * offset.xy;\n" 249" pos += scalar * offset.xy;\n"
@@ -300,14 +263,87 @@ render(Context *ctx) {
300" frag = vec4(val, val, val, 1.0);\n" 263" frag = vec4(val, val, val, 1.0);\n"
301"}\n"; 264"}\n";
302 265
303 u32 program = compile_program(ctx, vert_src, frag_src); 266 ctx->text_overlay.program = compile_program(ctx, vert_src, frag_src);
267 ctx->text_overlay.cur_x = 0;
268 ctx->text_overlay.cur_y = 0;
269 ctx->text_overlay.n_chars = 0;
270 ctx->text_overlay.size = TEXT_OVERLAY_SIZE;
271}
272
273void
274setup_callbacks(Context *ctx) {
275 glfwSetErrorCallback(glfw_error_callback);
276 glfwSetKeyCallback(ctx->window, glfw_key_callback);
277}
278
279void
280update_frame_time(Context *ctx) {
281 // Measure frame times and fps.
282 f64 cur_time = glfwGetTime();
283 f64 delta_time = cur_time - ctx->frame_time.prev;
284 ctx->frame_time.elapsed += delta_time;
285 ctx->frame_time.n_frames++;
286 if (ctx->frame_time.elapsed >= 1.0) {
287 f64 fps = 0;
288 fps = ctx->frame_time.n_frames / ctx->frame_time.elapsed;
289 ctx->frame_time.elapsed = 0;
290 ctx->frame_time.n_frames = 0;
291
292 // Update title with timing data.
293 char title_buf[256 * 2];
294 sprintf(title_buf,
295 "%s [%.2fms, %.2f FPS]",
296 ctx->win_title, delta_time * 1000, fps);
297 glfwSetWindowTitle(ctx->window, title_buf);
298 }
299 ctx->frame_time.prev = cur_time;
300}
301
302void
303update_text(Context *ctx) {
304 // TODO: Test with the full font atlas and characters.
305 // TODO: add_text function for setting up letters[] based on a char* + n_chars.
306 ctx->text_overlay.letters[0].x = 0;
307 ctx->text_overlay.letters[0].y = 0;
308 ctx->text_overlay.letters[0].idx = 0;
309 ctx->text_overlay.letters[1].x = 1;
310 ctx->text_overlay.letters[1].y = 0;
311 ctx->text_overlay.letters[1].idx = 1;
312 ctx->text_overlay.letters[2].x = 2;
313 ctx->text_overlay.letters[2].y = 0;
314 ctx->text_overlay.letters[2].idx = 2;
315 ctx->text_overlay.n_chars = 3;
316 glBindBuffer(GL_ARRAY_BUFFER, ctx->text_overlay.vbo);
317 glBufferData(GL_ARRAY_BUFFER,
318 sizeof(struct Letter) * ctx->text_overlay.n_chars,
319 ctx->text_overlay.letters,
320 GL_STATIC_DRAW);
321}
322
323void
324update(Context *ctx) {
325 update_frame_time(ctx);
326 update_text(ctx);
327}
328
329void
330render(Context *ctx) {
331 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
332 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
333
334 glfwGetFramebufferSize(ctx->window, &ctx->win_width, &ctx->win_height);
335 glViewport(0, 0, ctx->win_width, ctx->win_height);
336
337 glUseProgram(ctx->text_overlay.program);
338 glBindVertexArray(ctx->text_overlay.vao);
339 glBindTexture(GL_TEXTURE_2D, ctx->text_overlay.tex_id);
304 340
305 glUseProgram(program); 341 // Update uniforms.
306 glBindVertexArray(vao); 342 glUniform1f(glGetUniformLocation(ctx->text_overlay.program, "w"), ctx->win_width);
307 glBindTexture(GL_TEXTURE_2D, tex_id); 343 glUniform1f(glGetUniformLocation(ctx->text_overlay.program, "h"), ctx->win_height);
344 glUniform1f(glGetUniformLocation(ctx->text_overlay.program, "size"), ctx->text_overlay.size);
308 345
309 // TODO: How to pass the parameters for each box? 346 // TODO: Which blend mode to use?
310 // NOTE: We want to render the text as a single draw call if possible.
311 // glEnable(GL_BLEND); 347 // glEnable(GL_BLEND);
312 // glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 348 // glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
313 // // glBlendFunc(GL_ONE, GL_ONE); 349 // // glBlendFunc(GL_ONE, GL_ONE);
@@ -322,10 +358,8 @@ render(Context *ctx) {
322 // // glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); 358 // // glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
323 // // glBlendEquation(GL_FUNC_ADD); 359 // // glBlendEquation(GL_FUNC_ADD);
324 // 360 //
325 // glBindTexture(GL_TEXTURE_2D, text_tex); // TODO: Bind the texture atlas. 361 glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0,
326 // TODO: Send the number of instances as a uniform or see if you can query 362 ctx->text_overlay.n_chars);
327 // it from the GLSL for N. In this case N == 3.
328 glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, 3);
329 // glDisable(GL_BLEND); 363 // glDisable(GL_BLEND);
330 364
331 glfwSwapBuffers(ctx->window); 365 glfwSwapBuffers(ctx->window);