diff --git a/libc3/window/sdl2/demo/window_sdl2_demo.c b/libc3/window/sdl2/demo/window_sdl2_demo.c
index f6d76e8..84f504c 100644
--- a/libc3/window/sdl2/demo/window_sdl2_demo.c
+++ b/libc3/window/sdl2/demo/window_sdl2_demo.c
@@ -149,6 +149,7 @@ bool window_sdl2_demo_load (s_window_sdl2 *window)
}
if (! gl_ortho_init(&g_ortho))
return false;
+ gl_ortho_resize(&g_ortho, 0, window->w, 0, window->h, -1, 1);
if (! gl_font_init(&g_font_courier_new,
"fonts/Courier New/Courier New.ttf"))
return false;
@@ -204,6 +205,9 @@ static void render_text (s_gl_text *text, f64 x, f64 y)
assert(glGetError() == GL_NO_ERROR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
+ glEnable(GL_BLEND);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+ GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
assert(glGetError() == GL_NO_ERROR);
gl_matrix_4d_init_identity(&g_ortho.model_matrix);
gl_matrix_4d_translate(&g_ortho.model_matrix, x - 1.0, y - 1.0, 0.0);
@@ -251,6 +255,7 @@ bool window_sdl2_demo_render (s_window_sdl2 *window, void *context)
if (! window_animate((s_window *) window))
return false;
seq = window->sequence + window->sequence_pos;
+ gl_matrix_4d_init_identity(&g_ortho.model_matrix);
gl_ortho_render(&g_ortho);
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
@@ -285,6 +290,7 @@ bool window_sdl2_demo_render (s_window_sdl2 *window, void *context)
s8 fps[32];
snprintf(fps, sizeof(fps), "%.1f", (f64) seq->frame / seq->t);
gl_text_update_1(&g_text_fps, fps);
+ glEnable(GL_BLEND);
render_text(&g_text_fps, 20, window->h - 30);
gl_ortho_render_end(&g_ortho);
return true;
diff --git a/libc3/window/sdl2/gl_matrix_4d.c b/libc3/window/sdl2/gl_matrix_4d.c
index 1fa3096..d96bd5e 100644
--- a/libc3/window/sdl2/gl_matrix_4d.c
+++ b/libc3/window/sdl2/gl_matrix_4d.c
@@ -129,9 +129,10 @@ s_gl_matrix_4d * gl_matrix_4d_ortho (s_gl_matrix_4d *m, f64 x1, f64 x2,
ortho.xx = 2.0 / dx;
ortho.yy = 2.0 / dy;
ortho.zz = -2.0 / dz;
- ortho.tx = -((x1 + x2) / dx);
- ortho.ty = -((y1 + y2) / dy);
- ortho.tz = -((clip_z_near + clip_z_far) / dz);
+ ortho.tx = -(x1 + x2) / dx;
+ ortho.ty = -(y1 + y2) / dy;
+ ortho.tz = -(clip_z_near + clip_z_far) / dz;
+ ortho.tt = 1.0;
gl_matrix_4d_product(m, &ortho);
return m;
}
diff --git a/libc3/window/sdl2/gl_ortho.c b/libc3/window/sdl2/gl_ortho.c
index b8002e2..3422cf2 100644
--- a/libc3/window/sdl2/gl_ortho.c
+++ b/libc3/window/sdl2/gl_ortho.c
@@ -40,7 +40,6 @@ void gl_ortho_delete (s_gl_ortho *ortho)
s_gl_ortho * gl_ortho_init (s_gl_ortho *ortho)
{
- GLenum error;
GLint success;
u32 vertex_shader;
assert(ortho);
@@ -77,24 +76,13 @@ s_gl_ortho * gl_ortho_init (s_gl_ortho *ortho)
assert(glGetError() == GL_NO_ERROR);
ortho->gl_projection_matrix_loc =
glGetUniformLocation(ortho->gl_shader_program, "projection_matrix");
- glUniformMatrix4dv(ortho->gl_projection_matrix_loc, 1, GL_FALSE,
- &ortho->view_matrix.xx);
- if ((error = glGetError()) != GL_NO_ERROR) {
- err_write_1("gl_ortho_init: glUniformMatrix4dv: ");
- err_puts((const s8 *) glewGetErrorString(error));
- assert(! "gl_ortho_init: glUniformMatrix4dv");
- return NULL;
- }
+ assert(glGetError() == GL_NO_ERROR);
ortho->gl_view_matrix_loc =
glGetUniformLocation(ortho->gl_shader_program, "view_matrix");
- glUniformMatrix4dv(ortho->gl_view_matrix_loc, 1, GL_FALSE,
- &ortho->view_matrix.xx);
+ assert(glGetError() == GL_NO_ERROR);
ortho->gl_model_matrix_loc =
glGetUniformLocation(ortho->gl_shader_program, "model_matrix");
assert(glGetError() == GL_NO_ERROR);
- glUniformMatrix4dv(ortho->gl_model_matrix_loc, 1, GL_FALSE,
- &ortho->model_matrix.xx);
- assert(glGetError() == GL_NO_ERROR);
glUseProgram(0);
assert(glGetError() == GL_NO_ERROR);
return ortho;
@@ -117,10 +105,25 @@ s_gl_ortho * gl_ortho_new (void)
void gl_ortho_render (s_gl_ortho *ortho)
{
+ GLenum error;
assert(ortho);
assert(glGetError() == GL_NO_ERROR);
glUseProgram(ortho->gl_shader_program);
assert(glGetError() == GL_NO_ERROR);
+ glUniformMatrix4dv(ortho->gl_projection_matrix_loc, 1, GL_FALSE,
+ &ortho->projection_matrix.xx);
+ if ((error = glGetError()) != GL_NO_ERROR) {
+ err_write_1("gl_ortho_render: glUniformMatrix4dv: ");
+ err_puts((const s8 *) glewGetErrorString(error));
+ assert(! "gl_ortho_render: glUniformMatrix4dv");
+ }
+ assert(glGetError() == GL_NO_ERROR);
+ glUniformMatrix4dv(ortho->gl_view_matrix_loc, 1, GL_FALSE,
+ &ortho->view_matrix.xx);
+ assert(glGetError() == GL_NO_ERROR);
+ glUniformMatrix4dv(ortho->gl_model_matrix_loc, 1, GL_FALSE,
+ &ortho->model_matrix.xx);
+ assert(glGetError() == GL_NO_ERROR);
}
void gl_ortho_resize (s_gl_ortho *ortho, f64 x1, f64 x2, f64 y1, f64 y2,
diff --git a/libc3/window/sdl2/gl_square.h b/libc3/window/sdl2/gl_square.h
new file mode 100644
index 0000000..be793c5
--- /dev/null
+++ b/libc3/window/sdl2/gl_square.h
@@ -0,0 +1,32 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef GL_SQUARE_H
+#define GL_SQUARE_H
+
+#include "types.h"
+
+/* Stack-allocation compatible functions, call gl_square_clean after
+ use. */
+void gl_square_clean (s_gl_square *square);
+s_gl_square * gl_square_init (s_gl_square *square, uw segments_u,
+ uw segments_v);
+
+/* Heap-allocation functions, call gl_square_delete after use. */
+void gl_square_delete (s_gl_square *square);
+s_gl_square * gl_square_new (uw segments_u, uw segments_v);
+
+/* Observers. */
+void gl_square_render (const s_gl_square *square);
+void gl_square_render_wireframe (const s_gl_square *square);
+
+#endif /* GL_SQUARE_H */
diff --git a/libc3/window/sdl2/types.h b/libc3/window/sdl2/types.h
index 0d366f6..0b655f0 100644
--- a/libc3/window/sdl2/types.h
+++ b/libc3/window/sdl2/types.h
@@ -36,6 +36,7 @@ typedef struct gl_ortho s_gl_ortho;
typedef struct gl_point_2d s_gl_point_2d;
typedef struct gl_point_3d s_gl_point_3d;
typedef struct gl_sphere s_gl_sphere;
+typedef struct gl_square s_gl_square;
typedef struct gl_text s_gl_text;
typedef struct gl_triangle s_gl_triangle;
typedef struct gl_vertex s_gl_vertex;
@@ -234,6 +235,12 @@ struct gl_sphere {
uw segments_v;
};
+struct gl_square {
+ s_gl_object object;
+ uw segments_u;
+ uw segments_v;
+};
+
struct gl_vertex {
s_gl_point_3d position;
s_gl_point_3d normal;