Basic UI system, font

This commit is contained in:
2025-06-05 19:18:21 +02:00
parent 376c26aae6
commit 6652194f2f
31 changed files with 424 additions and 84 deletions
+4 -3
View File
@@ -1,7 +1,8 @@
SRC=src/main.c src/program.c src/resources.c src/camera.c src/chunk/chunk.c \
src/chunk/chunkmesh.c src/flags.c src/texture.c src/chunk/chunkman.c \
SRC=src/main.c src/gl/program.c src/resources.c src/camera.c src/chunk/chunk.c \
src/chunk/chunkmesh.c src/flags.c src/gl/texture.c src/chunk/chunkman.c \
src/event/manager.c src/event/handlers.c src/state.c src/graphics.c \
src/entity/meshes.c src/entity/entman.c src/entity/templates.c
src/gl/mesh.c src/entity/entman.c src/entity/templates.c src/ui/uielement.c \
src/ui/uiman.c
OBJ=$(SRC:.c=.o)
CFLAGS=-g -pg -Werror -Wextra -Wall `pkg-config --cflags sdl3 sdl3-image cglm gl glib-2.0`
+1 -1
View File
@@ -8,7 +8,7 @@ varying vec2 f_uv;
void main ()
{
if(texture2D (texture, f_uv).a < 0.2)
if(texture2D (texture, f_uv).a < 0.5)
{
discard;
}
+14
View File
@@ -0,0 +1,14 @@
#version 100
precision mediump float;
uniform vec3 color;
uniform sampler2D texture;
varying vec2 f_uv;
void main ()
{
vec4 tex_color = texture2D (texture, f_uv);
gl_FragColor = tex_color * vec4 (color, 1.0);
}
+31
View File
@@ -0,0 +1,31 @@
#version 100
attribute vec4 position;
attribute vec2 uv;
uniform mat4 model;
uniform float time;
uniform float character;
varying vec2 f_uv;
void main ()
{
float tex_w = 128.0;
float tex_h = 128.0;
float char_w = 8.0;
float char_h = 16.0;
float chars_per_row = tex_w / char_w;
float x = mod (character, chars_per_row);
float y = floor (character / chars_per_row);
vec2 char_offset = vec2 (x * char_w / tex_w, y * char_h / tex_h);
vec2 char_size = vec2 (char_w / tex_w, char_h / tex_h);
f_uv = char_offset + uv * char_size;
gl_Position = model * position;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+7 -5
View File
@@ -106,10 +106,10 @@ chunkman_init ()
chunk, to save frame time. */
void
chunkman_update (vec3 camera_position)
chunkman_update (vec3 position)
{
int cx, cz;
chunkman_world_to_chunk (camera_position[0], camera_position[2], &cx, &cz);
chunkman_world_to_chunk (position[0], position[2], &cx, &cz);
for (int z = cz - RENDER_DISTANCE - 1; z <= cz + RENDER_DISTANCE + 1; ++z)
{
@@ -135,10 +135,11 @@ chunkman_update (vec3 camera_position)
}
void
chunkman_render (vec3 camera_position, int program)
chunkman_render (vec3 position)
{
int cx = 0, cz = 0;
chunkman_world_to_chunk (camera_position[0], camera_position[2], &cx, &cz);
chunkman_world_to_chunk (position[0], position[2], &cx, &cz);
program_use (RESPRG ("chunk"));
for (int z = cz - RENDER_DISTANCE; z <= cz + RENDER_DISTANCE; ++z)
{
@@ -153,7 +154,7 @@ chunkman_render (vec3 camera_position, int program)
bound = true;
}
program_set_vec3 (program, "chunk_position", x * CHUNK_DIM, 0.0, z * CHUNK_DIM);
program_set_vec3 (RESPRG ("chunk"), "chunk_position", x * CHUNK_DIM, 0.0, z * CHUNK_DIM);
ChunkMesh_render (mesh);
}
}
@@ -200,6 +201,7 @@ chunkman_generate_Chunk_at (int cx, int cz)
tree->position[1] = chunk->heightmap [INDEX (x, z)];
tree->position[2] = z + zoffset;
tree->rotation[1] = rand () % 180;
tree->scale[1] = (rand() % 5) + 5;
ENTADD (tree);
}
+3 -3
View File
@@ -5,15 +5,15 @@
#include "chunk.h"
#include "chunkmesh.h"
#include "../program.h"
#include "../gl/program.h"
#include "../entity/entman.h"
#include "../entity/templates.h"
#define RENDER_DISTANCE 4
void chunkman_init ();
void chunkman_update (vec3 camera_position);
void chunkman_render (vec3 camera_position, int program);
void chunkman_update (vec3 position);
void chunkman_render (vec3 position);
float chunkman_get_height_at (float x, float z);
+7 -7
View File
@@ -10,7 +10,7 @@ extern int last_time;
Entity *player_entity, *sky_entity;
static GSequence *entities;
static EntityMesh mesh_quad1, mesh_quad2, mesh_quad_x;
static SimpleMesh mesh_quad1, mesh_quad2, mesh_quad_x;
static unsigned int last_program = -1;
static unsigned int last_type = -1;
static unsigned int last_texture = -1;
@@ -25,9 +25,9 @@ void
entman_init ()
{
entities = g_sequence_new (NULL);
mesh_quad1 = EntityMesh_make_quad1 ();
mesh_quad2 = EntityMesh_make_quad2 ();
mesh_quad_x = EntityMesh_make_quad_x ();
mesh_quad1 = SimpleMesh_make_quad1 ();
mesh_quad2 = SimpleMesh_make_quad2 ();
mesh_quad_x = SimpleMesh_make_quad_x ();
player_entity = malloc (sizeof (Entity));
*player_entity = (Entity) {
@@ -111,7 +111,7 @@ entman_render_internal (gpointer data, gpointer userdata)
}
#endif
EntityMesh to_render;
SimpleMesh to_render;
unsigned int render_type = entity->render_type;
switch (entity->mesh_type)
@@ -201,13 +201,13 @@ entman_render_internal (gpointer data, gpointer userdata)
if (entity->mesh_type != last_type)
{
EntityMesh_bind (&to_render);
SimpleMesh_bind (&to_render);
}
last_program = entity->program;
last_type = entity->mesh_type;
last_texture = entity->texture;
EntityMesh_render (&to_render);
SimpleMesh_render (&to_render);
}
void
+1 -1
View File
@@ -4,7 +4,7 @@
#include <cglm/cglm.h>
#include "entity.h"
#include "meshes.h"
#include "../gl/mesh.h"
#include "../util.h"
#include "../resources.h"
#include "../state.h"
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include <SDL3/SDL_opengles2.h>
#include <cglm/cglm.h>
#include "../flags.h"
typedef struct EntityMesh
{
size_t indices_len;
unsigned int pbo;
unsigned int uvbo;
unsigned int ebo;
} EntityMesh;
void EntityMesh_bind (EntityMesh *mesh);
void EntityMesh_render (EntityMesh *mesh);
EntityMesh EntityMesh_make_quad1 ();
EntityMesh EntityMesh_make_quad2 ();
EntityMesh EntityMesh_make_quad_x ();
+1 -1
View File
@@ -6,7 +6,7 @@
#include "manager.h"
#include "../camera.h"
#include "../flags.h"
#include "../program.h"
#include "../gl/program.h"
#include "../state.h"
void evt_handlers_init ();
+12 -12
View File
@@ -1,4 +1,4 @@
#include "meshes.h"
#include "mesh.h"
/* TODO: Theoretically, we could fit all the transforms into one
vec4. The caveat? It would be for every vertex. There seems to be a
@@ -6,7 +6,7 @@
every subsequent vertex. */
void
EntityMesh_bind (EntityMesh *mesh)
SimpleMesh_bind (SimpleMesh *mesh)
{
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
glEnableVertexAttribArray (0);
@@ -20,7 +20,7 @@ EntityMesh_bind (EntityMesh *mesh)
}
void
EntityMesh_render (EntityMesh *mesh)
SimpleMesh_render (SimpleMesh *mesh)
{
if (flags_get ("wireframe_enabled"))
{
@@ -32,8 +32,8 @@ EntityMesh_render (EntityMesh *mesh)
}
}
EntityMesh
EntityMesh_make_quad1 ()
SimpleMesh
SimpleMesh_make_quad1 ()
{
/* The positions are trivial. */
float positions[12] = {
@@ -54,7 +54,7 @@ EntityMesh_make_quad1 ()
1.0, 0.0,
};
EntityMesh mesh;
SimpleMesh mesh;
mesh.indices_len = 6;
glGenBuffers (1, &mesh.pbo);
glGenBuffers (1, &mesh.uvbo);
@@ -77,8 +77,8 @@ EntityMesh_make_quad1 ()
return mesh;
}
EntityMesh
EntityMesh_make_quad2 ()
SimpleMesh
SimpleMesh_make_quad2 ()
{
/* The positions are trivial. */
float positions[12] = {
@@ -100,7 +100,7 @@ EntityMesh_make_quad2 ()
1.0, 0.0,
};
EntityMesh mesh;
SimpleMesh mesh;
mesh.indices_len = 12;
glGenBuffers (1, &mesh.pbo);
glGenBuffers (1, &mesh.uvbo);
@@ -123,8 +123,8 @@ EntityMesh_make_quad2 ()
return mesh;
}
EntityMesh
EntityMesh_make_quad_x ()
SimpleMesh
SimpleMesh_make_quad_x ()
{
/* The positions are trivial. */
float positions[24] = {
@@ -158,7 +158,7 @@ EntityMesh_make_quad_x ()
1.0, 0.0
};
EntityMesh mesh;
SimpleMesh mesh;
mesh.indices_len = 24;
glGenBuffers (1, &mesh.pbo);
glGenBuffers (1, &mesh.uvbo);
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <SDL3/SDL_opengles2.h>
#include <cglm/cglm.h>
#include "../flags.h"
typedef struct SimpleMesh
{
size_t indices_len;
unsigned int pbo;
unsigned int uvbo;
unsigned int ebo;
} SimpleMesh;
void SimpleMesh_bind (SimpleMesh *mesh);
void SimpleMesh_render (SimpleMesh *mesh);
SimpleMesh SimpleMesh_make_quad1 ();
SimpleMesh SimpleMesh_make_quad2 ();
SimpleMesh SimpleMesh_make_quad_x ();
+1 -1
View File
@@ -3,7 +3,7 @@
#include <SDL3/SDL_opengles2.h>
#include <cglm/cglm.h>
#include "util.h"
#include "../util.h"
/* Just for clarity sake. */
#define program_use glUseProgram
+46
View File
@@ -0,0 +1,46 @@
#include "quad.h"
EntityMesh
EntityMesh_make_quad1 ()
{
/* The positions are trivial. */
float positions[12] = {
-1.0, -1.0, 0.0,
+1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
+1.0, 1.0, 0.0
};
unsigned int indices[12] = {
3, 2, 0, 0, 1, 3,
};
float uvs[8] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
};
EntityMesh mesh;
mesh.indices_len = 6;
glGenBuffers (1, &mesh.pbo);
glGenBuffers (1, &mesh.uvbo);
glGenBuffers (1, &mesh.ebo);
glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 12, positions, GL_STATIC_DRAW);
glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (float) * 3, 0);
glBindBuffer (GL_ARRAY_BUFFER, mesh.uvbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 8, uvs, GL_STATIC_DRAW);
glEnableVertexAttribArray (1);
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo);
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * mesh.indices_len, indices, GL_STATIC_DRAW);
return mesh;
}
+15 -1
View File
@@ -11,7 +11,21 @@ texture_create (int width, int height, unsigned char *data)
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, 0);
return texture;
}
unsigned int
texture_create_no_interp (int width, int height, unsigned char *data)
{
unsigned int texture;
glGenTextures (1, &texture);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap (GL_TEXTURE_2D);
return texture;
}
@@ -3,3 +3,4 @@
#include <SDL3/SDL_opengles2.h>
unsigned int texture_create (int width, int height, unsigned char *data);
unsigned int texture_create_no_interp (int width, int height, unsigned char *data);
+16 -15
View File
@@ -5,6 +5,9 @@ extern vec3 camera_position;
static SDL_Window *sdl_window;
static SDL_GLContext gl_context;
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
void
graphics_init ()
{
@@ -13,7 +16,7 @@ graphics_init ()
FATAL ("Couldn't initialize SDL: %s", SDL_GetError ());
}
sdl_window = SDL_CreateWindow (GAME_NAME, 640, 480, SDL_WINDOW_OPENGL);
sdl_window = SDL_CreateWindow (GAME_NAME, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL);
if (!sdl_window)
{
@@ -21,7 +24,9 @@ graphics_init ()
}
/* We use OpenGL ES 2.0. It should support everything, and it's more
than enough for the game. */
than enough for the game. Note that regardless of what you set,
the version returned by glGetString can differ. Doesn't
matter. */
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
@@ -41,7 +46,7 @@ graphics_init ()
INFO ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
INFO ("Max vertex attributes: %d", GL_MAX_VERTEX_ATTRIBS);
glViewport (0, 0, 640, 480);
glViewport (0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glClearColor (0, 0.3, 0.8, 1);
glEnable (GL_CULL_FACE);
@@ -54,12 +59,11 @@ graphics_render ()
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mat4 projection, view;
camera_get_projection (640.0 / 480.0, projection);
camera_get_projection (WINDOW_WIDTH / WINDOW_HEIGHT, projection);
camera_get_view (view);
program_use (RESPRG ("chunk"));
program_set_mat4 (RESPRG ("chunk"), "projection", projection);
program_set_mat4 (RESPRG ("chunk"), "view", view);
resources_programs_set_projection (projection);
resources_programs_set_view (view);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain0"));
@@ -72,16 +76,13 @@ graphics_render ()
glActiveTexture (GL_TEXTURE4);
glBindTexture (GL_TEXTURE_2D, RESTEX ("terrain4"));
chunkman_render (camera_position, RESPRG ("chunk"));
program_use (RESPRG ("clouds"));
program_set_mat4 (RESPRG ("clouds"), "projection", projection);
program_set_mat4 (RESPRG ("clouds"), "view", view);
program_use (RESPRG ("default"));
program_set_mat4 (RESPRG ("default"), "projection", projection);
program_set_mat4 (RESPRG ("default"), "view", view);
chunkman_render (camera_position);
entman_render (view);
glDisable (GL_DEPTH_TEST);
uiman_render ();
glEnable (GL_DEPTH_TEST);
SDL_GL_SwapWindow (sdl_window);
}
+2 -1
View File
@@ -3,11 +3,12 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_opengles2.h>
#include "util.h"
#include "ui/uiman.h"
#include "chunk/chunkman.h"
#include "entity/entman.h"
#include "state.h"
#include "resources.h"
#include "util.h"
void graphics_init ();
void graphics_render ();
+2
View File
@@ -7,6 +7,7 @@
#include "event/handlers.h"
#include "chunk/chunkman.h"
#include "entity/templates.h"
#include "ui/uiman.h"
#include "state.h"
#include "resources.h"
#include "graphics.h"
@@ -22,6 +23,7 @@ SDL_AppInit (void **appstate, int argc, char **argv)
graphics_init ();
evt_handlers_init ();
resources_init ();
uiman_init ();
chunkman_init ();
entman_init ();
ent_templates_init ();
+62 -11
View File
@@ -55,6 +55,21 @@ resources_load_texture (const char *path)
return texture;
}
unsigned int
resources_load_texture_no_interp (const char *path)
{
SDL_Surface *surface = IMG_Load (path);
if (surface == NULL)
{
WARN ("Failed to load texture from path %s: %s", path, SDL_GetError ());
return 0;
}
unsigned int texture = texture_create_no_interp (surface->w, surface->h, surface->pixels);
return texture;
}
static inline void
resources_add_program (char *key, unsigned int program)
{
@@ -85,6 +100,38 @@ resources_get_texture (char *key)
return GPOINTER_TO_INT (g_hash_table_lookup (textures, key));
}
void
res_proj_internal (gpointer key, gpointer value, gpointer userdata)
{
UNUSED (key);
unsigned int program = GPOINTER_TO_INT (value);
mat4 *projection = userdata;
program_use (program);
program_set_mat4 (program, "projection", *projection);
}
void
res_view_internal (gpointer key, gpointer value, gpointer userdata)
{
UNUSED (key);
unsigned int program = GPOINTER_TO_INT (value);
mat4 *view = userdata;
program_use (program);
program_set_mat4 (program, "view", *view);
}
void
resources_programs_set_projection (mat4 projection)
{
g_hash_table_foreach (programs, res_proj_internal, projection);
}
void
resources_programs_set_view (mat4 view)
{
g_hash_table_foreach (programs, res_view_internal, view);
}
void
resources_init ()
{
@@ -95,19 +142,23 @@ resources_init ()
#define RLP resources_load_program
#define RAT resources_add_texture
#define RLT resources_load_texture
#define RLTNI resources_load_texture_no_interp
RAP ("default", RLP ("res/shaders/default.vert", "res/shaders/default.frag"));
RAP ("chunk", RLP ("res/shaders/chunk.vert", "res/shaders/chunk.frag"));
RAP ("clouds", RLP ("res/shaders/clouds.vert", "res/shaders/clouds.frag"));
RAP ("default", RLP ("res/shaders/default.vert", "res/shaders/default.frag"));
RAP ("chunk", RLP ("res/shaders/chunk.vert", "res/shaders/chunk.frag"));
RAP ("clouds", RLP ("res/shaders/clouds.vert", "res/shaders/clouds.frag"));
RAP ("uielement", RLP ("res/shaders/uielement.vert", "res/shaders/uielement.frag"));
RAT ("terrain0", RLT ("res/textures/dirt.png"));
RAT ("terrain1", RLT ("res/textures/drygrass.png"));
RAT ("terrain2", RLT ("res/textures/grass.png"));
RAT ("terrain3", RLT ("res/textures/rock_cement.png"));
RAT ("terrain4", RLT ("res/textures/asphalt_gravel.png"));
RAT ("tree0", RLT ("res/textures/tree.png"));
RAT ("grass0", RLT ("res/textures/grass0.png"));
RAT ("clouds", RLT ("res/textures/clouds.png"));
RAT ("terrain0", RLT ("res/textures/dirt.png"));
RAT ("terrain1", RLT ("res/textures/drygrass.png"));
RAT ("terrain2", RLT ("res/textures/grass.png"));
RAT ("terrain3", RLT ("res/textures/rock_cement.png"));
RAT ("terrain4", RLT ("res/textures/asphalt_gravel.png"));
RAT ("tree0", RLT ("res/textures/tree.png"));
RAT ("grass0", RLT ("res/textures/grass0.png"));
RAT ("clouds", RLT ("res/textures/clouds.png"));
RAT ("font0", RLTNI ("res/textures/font.png"));
#undef RAP
#undef RLP
+5 -2
View File
@@ -2,13 +2,16 @@
#include <SDL3_image/SDL_image.h>
#include <glib-2.0/glib.h>
#include <cglm/cglm.h>
#include "program.h"
#include "texture.h"
#include "gl/program.h"
#include "gl/texture.h"
#define RESPRG(key) (resources_get_program (key))
#define RESTEX(key) (resources_get_texture (key))
void resources_programs_set_projection (mat4 projection);
void resources_programs_set_view (mat4 view);
unsigned int resources_get_program (char *key);
unsigned int resources_get_texture (char *key);
void resources_init ();
+10
View File
@@ -1,7 +1,9 @@
#include "state.h"
extern vec3 camera_position;
extern vec3 camera_rotation;
extern Entity *player_entity, *sky_entity;
extern UIElement *player_pos;
float delta_time;
int last_time;
@@ -21,8 +23,16 @@ game_state_tick (int ticks)
glm_vec3_copy (player_entity->position, camera_position);
camera_position[1] += player_entity->scale[1] - 0.2;
player_entity->rotation[1] = camera_rotation[1];
sky_entity->position[0] = camera_position[0];
sky_entity->position[2] = camera_position[2];
/* Put the player position into the UI. */
char *buf = malloc (sizeof (char) * 32);
snprintf (buf, 32, "X:%2.1f Y:%2.1f Z:%2.1f", player_entity->position[0],
player_entity->position[1], player_entity->position[2]);
player_pos->text = buf;
if (flags_get ("moving_forward"))
{
+1
View File
@@ -3,6 +3,7 @@
#include "camera.h"
#include "flags.h"
#include "entity/entity.h"
#include "ui/uielement.h"
void game_state_init (int ticks);
void game_state_tick (int ticks);
+83
View File
@@ -0,0 +1,83 @@
#include "uielement.h"
/* TODO: Convert to mat3's and 2D affine transformations. */
static SimpleMesh quad;
void
ui_element_mesh_init ()
{
quad = SimpleMesh_make_quad1 ();
}
void
UIElement_add_child (UIElement *parent, UIElement *child)
{
g_sequence_append (parent->children, child);
}
void
uiel_render_internal (gpointer data, gpointer userdata)
{
UNUSED (userdata);
UIElement *element = data;
UIElement_render (element);
}
void
UIElement_render (UIElement *element)
{
if (element->parent == NULL)
{
SimpleMesh_bind (&quad);
program_use (RESPRG ("uielement"));
}
if (element->visible)
{
/* First, we render the background as a quad of
`background_color'. */
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, 0);
mat4 model = GLM_MAT4_IDENTITY_INIT;
glm_translate (model, element->position);
glm_scale (model, element->scale);
program_set_mat4 (RESPRG ("uielement"), "model", model);
/* TODO: rename this function to vec3_individual or
something. */
program_set_vec3 (RESPRG ("uielement"), "color",
element->background_color[0], element->background_color[1],
element->background_color[2]);
SimpleMesh_render (&quad);
/* Now, the tedious, boring, and so on task of rendering the
text, the worst fate of an OpenGL programmer. */
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, RESTEX ("font0"));
program_set_vec3 (RESPRG ("uielement"), "color",
element->text_color[0], element->text_color[1],
element->text_color[2]);
for (size_t i = 0; i < strlen (element->text); ++i)
{
vec3 pos;
float x = -element->scale[0] + (element->scale[1] / 2) + (element->scale[1] * i);
glm_vec3_add (element->position, (vec3) { x, 0.0, 0.0 }, pos);
glm_mat4_copy (GLM_MAT4_IDENTITY, model);
glm_translate (model, pos);
glm_scale (model, (vec3) { element->scale[1] / 2, element->scale[1], 1.0 });
program_set_mat4 (RESPRG ("uielement"), "model", model);
program_set_float (RESPRG ("uielement"), "character", element->text[i]);
SimpleMesh_render (&quad);
}
}
if (element->children != NULL)
{
g_sequence_foreach (element->children, uiel_render_internal, NULL);
}
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
/* TODO: Patch up with GLib's GTree */
#include <stdbool.h>
#include <glib-2.0/glib.h>
#include <cglm/cglm.h>
#include "../util.h"
#include "../resources.h"
#include "../gl/mesh.h"
#include "../gl/program.h"
typedef struct UIElement
{
struct UIElement *parent;
GSequence *children;
void (*on_left_click) (struct UIElement *self);
void (*on_right_click) (struct UIElement *self);
bool visible;
vec3 text_color;
vec3 background_color;
vec3 position;
vec3 scale;
char *text; /* Maybe switch to GString? */
} UIElement;
void ui_element_mesh_init ();
void UIElement_render (UIElement *element);
void UIElement_add_child (UIElement *parent, UIElement *child);
+37
View File
@@ -0,0 +1,37 @@
#include "uiman.h"
UIElement *player_pos;
static UIElement ui_root;
void
uiman_init ()
{
ui_root = (UIElement) {
.parent = NULL,
.children = g_sequence_new (NULL),
.visible = false,
};
player_pos = malloc (sizeof (UIElement));
*player_pos = (UIElement) {
.parent = &ui_root,
.children = NULL,
.visible = true,
.background_color = { 0.0, 0.0, 0.0 },
.text_color = { 1.0, 1.0, 1.0 },
.position = { -0.65, 0.92, 0.0 },
.scale = { 0.3, 0.03, 1.0 },
.text = "POSITION: 0,0,0"
};
UIElement_add_child (&ui_root, player_pos);
ui_element_mesh_init ();
}
void
uiman_render ()
{
UIElement_render (&ui_root);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "uielement.h"
void uiman_init ();
void uiman_render ();