UI system improvements, event handling
This commit is contained in:
@@ -206,7 +206,7 @@ chunkman_render (vec3 position, vec4 planes[6])
|
||||
}
|
||||
|
||||
program_set_vec3_ind (RESPRG ("chunk"), "chunk_position", x * CHUNK_DIM, 0.0, z * CHUNK_DIM);
|
||||
ChunkMesh_render (mesh);
|
||||
ChunkMesh_render (mesh, flags_get ("wireframe_enabled"));
|
||||
n_frame_chunks++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ ChunkMesh_bind (ChunkMesh *mesh)
|
||||
}
|
||||
|
||||
void
|
||||
ChunkMesh_render (ChunkMesh *mesh)
|
||||
ChunkMesh_render (ChunkMesh *mesh, bool wireframe)
|
||||
{
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
|
||||
glEnableVertexAttribArray (0);
|
||||
@@ -110,13 +110,6 @@ ChunkMesh_render (ChunkMesh *mesh)
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo);
|
||||
glEnableVertexAttribArray (1);
|
||||
glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, sizeof (float) * 4, 0);
|
||||
|
||||
if (flags_get ("wireframe_enabled"))
|
||||
{
|
||||
glDrawElements (GL_LINES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements (GL_TRIANGLES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
glDrawElements (wireframe ? GL_LINES : GL_TRIANGLES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <SDL3/SDL_opengles2.h>
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#include "../flags.h"
|
||||
#include "chunk.h"
|
||||
|
||||
#define TERRAIN_TEXTURES 5
|
||||
@@ -21,4 +20,4 @@ typedef struct ChunkMesh
|
||||
|
||||
ChunkMesh *ChunkMesh_build (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc);
|
||||
void ChunkMesh_bind (ChunkMesh *mesh);
|
||||
void ChunkMesh_render (ChunkMesh *mesh);
|
||||
void ChunkMesh_render (ChunkMesh *mesh, bool wireframe);
|
||||
|
||||
@@ -174,7 +174,7 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
|
||||
if (entity->program != last_program)
|
||||
{
|
||||
program_use (entity->program);
|
||||
last_program = program_use (entity->program);
|
||||
}
|
||||
|
||||
program_set_mat4 (entity->program, "model", model);
|
||||
@@ -183,19 +183,16 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
if (entity->texture != last_texture)
|
||||
{
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, entity->texture);
|
||||
last_texture = texture_use (entity->texture);
|
||||
}
|
||||
|
||||
if (entity->mesh_type != last_type)
|
||||
{
|
||||
SimpleMesh_bind (&to_render);
|
||||
last_type = entity->mesh_type;
|
||||
}
|
||||
|
||||
last_program = entity->program;
|
||||
last_type = entity->mesh_type;
|
||||
last_texture = entity->texture;
|
||||
SimpleMesh_render (&to_render);
|
||||
|
||||
SimpleMesh_render (&to_render, flags_get ("wireframe_enabled"));
|
||||
n_frame_ents++;
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -80,16 +80,16 @@ evtman_init ()
|
||||
evtman_add_handler (1, SDL_EVENT_MOUSE_WHEEL, evt_pred_flag, "ui_has_focus", uiman_cb_mouse_wheel, NULL);
|
||||
evtman_add_handler (1, SDL_EVENT_TEXT_INPUT, evt_pred_flag, "ui_has_focus", uiman_cb_text_input, NULL);
|
||||
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_W), evt_cb_flag_on, "moving_forward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_W), evt_cb_flag_off, "moving_forward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_S), evt_cb_flag_on, "moving_backward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_S), evt_cb_flag_off, "moving_backward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_A), evt_cb_flag_on, "moving_left");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_A), evt_cb_flag_off, "moving_left");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_D), evt_cb_flag_on, "moving_right");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_D), evt_cb_flag_off, "moving_right");
|
||||
evtman_add_handler (0, SDL_EVENT_MOUSE_MOTION, NULL, NULL, evt_cb_rotate_camera, NULL);
|
||||
evtman_add_handler (0, SDL_EVENT_MOUSE_BUTTON_DOWN, evt_pred_mouse, KEY (3), uiman_cb_switch_focus, NULL);
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_W), evt_cb_flag_on, "moving_forward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_W), evt_cb_flag_off, "moving_forward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_S), evt_cb_flag_on, "moving_backward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_S), evt_cb_flag_off, "moving_backward");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_A), evt_cb_flag_on, "moving_left");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_A), evt_cb_flag_off, "moving_left");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_D), evt_cb_flag_on, "moving_right");
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_D), evt_cb_flag_off, "moving_right");
|
||||
evtman_add_handler (0, SDL_EVENT_MOUSE_MOTION, NULL, NULL, evt_cb_rotate_camera, NULL);
|
||||
evtman_add_handler (0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_TAB), uiman_cb_switch_focus, NULL);
|
||||
|
||||
#undef KEY
|
||||
}
|
||||
|
||||
+2
-9
@@ -20,16 +20,9 @@ SimpleMesh_bind (SimpleMesh *mesh)
|
||||
}
|
||||
|
||||
void
|
||||
SimpleMesh_render (SimpleMesh *mesh)
|
||||
SimpleMesh_render (SimpleMesh *mesh, bool wireframe)
|
||||
{
|
||||
if (flags_get ("wireframe_enabled"))
|
||||
{
|
||||
glDrawElements (GL_LINES, mesh->indices_len, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements (GL_TRIANGLES, mesh->indices_len, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
glDrawElements (wireframe ? GL_LINES : GL_TRIANGLES, mesh->indices_len, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
SimpleMesh
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ typedef struct SimpleMesh
|
||||
} SimpleMesh;
|
||||
|
||||
void SimpleMesh_bind (SimpleMesh *mesh);
|
||||
void SimpleMesh_render (SimpleMesh *mesh);
|
||||
void SimpleMesh_render (SimpleMesh *mesh, bool wireframe);
|
||||
|
||||
SimpleMesh SimpleMesh_make_quad1 ();
|
||||
SimpleMesh SimpleMesh_make_quad2 ();
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
|
||||
#include "program.h"
|
||||
|
||||
unsigned int
|
||||
program_use (int program)
|
||||
{
|
||||
glUseProgram (program);
|
||||
return program;
|
||||
}
|
||||
|
||||
void
|
||||
shader_fail (int shader)
|
||||
{
|
||||
@@ -42,7 +49,7 @@ program_fail (int program)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
unsigned int
|
||||
program_create (const char *v_src, const char *f_src)
|
||||
{
|
||||
int success = 0;
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
|
||||
#include "../util.h"
|
||||
|
||||
/* Just for clarity sake. */
|
||||
#define program_use glUseProgram
|
||||
|
||||
unsigned int program_use (int program);
|
||||
void shader_fail (int shader);
|
||||
void program_fail (int program);
|
||||
int program_create (const char *v_src, const char *f_src);
|
||||
unsigned int program_create (const char *v_src, const char *f_src);
|
||||
void program_set_float (int program, const char *name, float value);
|
||||
void program_set_int_array (int program, const char *name, size_t count, int *value);
|
||||
void program_set_vec3 (int program, const char *name, vec3 value);
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
#include "texture.h"
|
||||
|
||||
unsigned int
|
||||
texture_use (unsigned int texture)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
texture_create (int width, int height, unsigned char *data)
|
||||
{
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
|
||||
#include <SDL3/SDL_opengles2.h>
|
||||
|
||||
unsigned int texture_use (unsigned int texture);
|
||||
unsigned int texture_create (int width, int height, unsigned char *data);
|
||||
|
||||
+10
-3
@@ -1,8 +1,5 @@
|
||||
#include "resources.h"
|
||||
|
||||
/* TODO: Warn if program doesn't exist, make program_use and
|
||||
texture_use return the textures/ */
|
||||
|
||||
static GHashTable *programs;
|
||||
static GHashTable *textures;
|
||||
|
||||
@@ -79,12 +76,22 @@ resources_add_texture (char *key, unsigned int texture)
|
||||
unsigned int
|
||||
resources_get_program (char *key)
|
||||
{
|
||||
if (!g_hash_table_contains (programs, key))
|
||||
{
|
||||
WARN ("Program `%s' does not exist. Careful!", key);
|
||||
}
|
||||
|
||||
return GPOINTER_TO_INT (g_hash_table_lookup (programs, key));
|
||||
}
|
||||
|
||||
unsigned int
|
||||
resources_get_texture (char *key)
|
||||
{
|
||||
if (!g_hash_table_contains (textures, key))
|
||||
{
|
||||
WARN ("Texture `%s' does not exist. Careful!", key);
|
||||
}
|
||||
|
||||
return GPOINTER_TO_INT (g_hash_table_lookup (textures, key));
|
||||
}
|
||||
|
||||
|
||||
+125
-23
@@ -1,7 +1,8 @@
|
||||
#include "uielement.h"
|
||||
|
||||
/* TODO: Convert to mat3's and 2D affine transformations. */
|
||||
/* TODO: Alpha blending. */
|
||||
/* TODO: Texture support in the uielement shader. */
|
||||
/* TODO: UTF-8 support */
|
||||
|
||||
static SimpleMesh quad;
|
||||
static unsigned int last_program;
|
||||
@@ -20,8 +21,6 @@ ui_el_new_internal (UIKind kind)
|
||||
UIElement *e = g_new0 (UIElement, 1);
|
||||
e->kind = kind;
|
||||
e->visible = true;
|
||||
glm_vec4_zero (e->background_color);
|
||||
glm_vec2_zero (e->position);
|
||||
glm_vec2_one (e->scale);
|
||||
e->children = g_array_new (false, false, sizeof (UIElement *));
|
||||
return e;
|
||||
@@ -47,7 +46,7 @@ UIElement_label_new (const char *text)
|
||||
{
|
||||
UIElement *e = ui_el_new_internal (UI_KIND_LABEL);
|
||||
e->label.text = g_string_new (text);
|
||||
glm_vec4_one (e->label.color);
|
||||
glm_vec4_one (e->label.text_color);
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -60,6 +59,39 @@ UIElement_set_on_tick (UIElement *element,
|
||||
element->userdata = userdata;
|
||||
}
|
||||
|
||||
void
|
||||
UIElement_set_on_left_click (UIElement *element,
|
||||
void (*on_left_click) (struct UIElement *self, void *userdata),
|
||||
void *userdata)
|
||||
{
|
||||
element->on_left_click = on_left_click;
|
||||
element->userdata = userdata;
|
||||
}
|
||||
|
||||
void
|
||||
UIElement_set_background_color (UIElement *element, float r, float g, float b, float a)
|
||||
{
|
||||
glm_vec4_copy ((vec4) { r, g, b, a }, element->background_color);
|
||||
}
|
||||
|
||||
void
|
||||
UIElement_set_hover_background_color (UIElement *element, float r, float g, float b, float a)
|
||||
{
|
||||
glm_vec4_copy ((vec4) { r, g, b, a }, element->hover_background_color);
|
||||
}
|
||||
|
||||
void
|
||||
UIElement_set_position (UIElement *element, float x, float y)
|
||||
{
|
||||
glm_vec2_copy ((vec2) { x, y }, element->position);
|
||||
}
|
||||
|
||||
void
|
||||
UIElement_set_scale (UIElement *element, float x, float y)
|
||||
{
|
||||
glm_vec2_copy ((vec2) { x, y }, element->scale);
|
||||
}
|
||||
|
||||
void
|
||||
UIElement_add_child (UIElement *parent, UIElement *child)
|
||||
{
|
||||
@@ -68,7 +100,7 @@ UIElement_add_child (UIElement *parent, UIElement *child)
|
||||
}
|
||||
|
||||
void
|
||||
UILabel_render_text (UIElement *element, mat3 parent_model)
|
||||
UIElement_label_render_text (UIElement *element, mat3 parent_model)
|
||||
{
|
||||
mat3 model;
|
||||
glm_mat3_copy (parent_model, model);
|
||||
@@ -86,16 +118,15 @@ UILabel_render_text (UIElement *element, mat3 parent_model)
|
||||
|
||||
if (last_program != RESPRG ("uitext"))
|
||||
{
|
||||
program_use (RESPRG ("uitext"));
|
||||
last_program = RESPRG ("uitext");
|
||||
last_program = program_use (RESPRG ("uitext"));
|
||||
}
|
||||
|
||||
for (guint i = 0; i < element->label.text->len; ++i)
|
||||
{
|
||||
program_set_mat3 (RESPRG ("uitext"), "model", model);
|
||||
program_set_float (RESPRG ("uitext"), "character", element->label.text->str[i]);
|
||||
program_set_vec4 (RESPRG ("uitext"), "color", element->label.color);
|
||||
SimpleMesh_render (&quad);
|
||||
program_set_vec4 (RESPRG ("uitext"), "color", element->label.text_color);
|
||||
SimpleMesh_render (&quad, false); /* UI always without wireframe. */
|
||||
glm_translate2d (model, (vec2) { 1.5f, 0.0f });
|
||||
}
|
||||
}
|
||||
@@ -139,8 +170,7 @@ UIElement_render_with_model (UIElement *element, mat3 parent_model)
|
||||
|
||||
if (last_program != RESPRG ("uielement"))
|
||||
{
|
||||
program_use (RESPRG ("uielement"));
|
||||
last_program = RESPRG ("uielement");
|
||||
last_program = program_use (RESPRG ("uielement"));
|
||||
}
|
||||
|
||||
mat3 model;
|
||||
@@ -156,18 +186,20 @@ UIElement_render_with_model (UIElement *element, mat3 parent_model)
|
||||
if (element->kind != UI_KIND_ROOT)
|
||||
{
|
||||
program_set_mat3 (RESPRG ("uielement"), "model", model);
|
||||
program_set_vec4 (RESPRG ("uielement"), "color", element->background_color);
|
||||
program_set_vec4 (RESPRG ("uielement"), "color",
|
||||
element->hovered ? element->hover_background_color
|
||||
: element->background_color);
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, element->image);
|
||||
texture_use (element->texture);
|
||||
|
||||
SimpleMesh_render (&quad);
|
||||
SimpleMesh_render (&quad, false);
|
||||
}
|
||||
|
||||
if (element->kind == UI_KIND_LABEL)
|
||||
{
|
||||
/* Here, we additionally render the text. */
|
||||
UILabel_render_text (element, model);
|
||||
UIElement_label_render_text (element, model);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < element->children->len; ++i)
|
||||
@@ -177,6 +209,45 @@ UIElement_render_with_model (UIElement *element, mat3 parent_model)
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
UIElement_hit_test (UIElement *element, mat3 parent_model, vec2 point)
|
||||
{
|
||||
mat3 model;
|
||||
glm_mat3_copy (parent_model, model);
|
||||
glm_translate2d (model, element->position);
|
||||
glm_scale2d (model, element->scale);
|
||||
|
||||
mat3 inv;
|
||||
glm_mat3_inv (model, inv);
|
||||
|
||||
vec3 local;
|
||||
glm_mat3_mulv (inv, (vec3) { point[0], point[1], 1.0 }, local);
|
||||
|
||||
return local[0] >= -1.0f && local[0] <= 1.0f && local[1] >= -1.0f && local[1] <= 1.0f;
|
||||
}
|
||||
|
||||
UIElement *
|
||||
UIElement_find_xy (UIElement *element, mat3 parent_model, vec2 mouse_ui_pos)
|
||||
{
|
||||
mat3 model;
|
||||
glm_mat3_copy (parent_model, model);
|
||||
glm_translate2d (model, element->position);
|
||||
glm_scale2d (model, element->scale);
|
||||
|
||||
for (int i = element->children->len - 1; i >= 0; --i)
|
||||
{
|
||||
UIElement *child = g_array_index (element->children, UIElement *, i);
|
||||
UIElement *hit = UIElement_find_xy (child, model, mouse_ui_pos);
|
||||
if (hit)
|
||||
return hit;
|
||||
}
|
||||
|
||||
if (element->kind != UI_KIND_ROOT && UIElement_hit_test (element, parent_model, mouse_ui_pos))
|
||||
return element;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
UIElement_tick (UIElement *element)
|
||||
{
|
||||
@@ -195,12 +266,12 @@ UIElement_tick (UIElement *element)
|
||||
void
|
||||
UIElement_render (UIElement *element)
|
||||
{
|
||||
last_program = -1;
|
||||
|
||||
if (element->kind == UI_KIND_ROOT && element->parent == NULL)
|
||||
{
|
||||
SimpleMesh_bind (&quad);
|
||||
program_use (RESPRG ("uielement"));
|
||||
last_program = RESPRG ("uielement");
|
||||
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, 0);
|
||||
|
||||
@@ -210,15 +281,46 @@ UIElement_render (UIElement *element)
|
||||
}
|
||||
|
||||
void
|
||||
UILabel_on_tick_show_int (UIElement *element, void *userdata)
|
||||
UIElement_label_set_text (UIElement *element, const char *text)
|
||||
{
|
||||
int *value = userdata;
|
||||
g_string_printf (element->label.text, "%d", *value);
|
||||
g_string_overwrite (element->label.text, 0, text);
|
||||
}
|
||||
|
||||
void
|
||||
UILabel_on_tick_show_float (UIElement *element, void *userdata)
|
||||
UIElement_label_printf (UIElement *element, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
g_string_vprintf (element->label.text, format, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_label_show_int (UIElement *element, void *userdata)
|
||||
{
|
||||
int *value = userdata;
|
||||
UIElement_label_printf (element, "%d", *value);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_label_show_float (UIElement *element, void *userdata)
|
||||
{
|
||||
float *value = userdata;
|
||||
g_string_printf (element->label.text, "%3.2f", *value);
|
||||
UIElement_label_printf (element, "%3.2f", *value);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_flag_switch (UIElement *element, void *userdata)
|
||||
{
|
||||
UNUSED (element);
|
||||
char *flag = userdata;
|
||||
flags_switch (flag);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_debug_print (UIElement *element, void *userdata)
|
||||
{
|
||||
UNUSED (element);
|
||||
char *text = userdata;
|
||||
INFO ("%s", text);
|
||||
}
|
||||
|
||||
+23
-6
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "../util.h"
|
||||
#include "../resources.h"
|
||||
#include "../flags.h"
|
||||
#include "../gl/mesh.h"
|
||||
#include "../gl/program.h"
|
||||
|
||||
@@ -14,7 +15,7 @@ typedef enum UIKind
|
||||
{
|
||||
UI_KIND_ROOT,
|
||||
UI_KIND_CONTAINER,
|
||||
UI_KIND_LABEL,
|
||||
UI_KIND_LABEL
|
||||
} UIKind;
|
||||
|
||||
typedef struct UIContainer
|
||||
@@ -24,7 +25,7 @@ typedef struct UIContainer
|
||||
|
||||
typedef struct UILabel
|
||||
{
|
||||
vec4 color;
|
||||
vec4 text_color;
|
||||
GString *text;
|
||||
} UILabel;
|
||||
|
||||
@@ -36,11 +37,13 @@ typedef struct UIElement
|
||||
|
||||
vec2 position;
|
||||
vec2 scale;
|
||||
vec4 background_color;
|
||||
unsigned int image;
|
||||
vec4 background_color, hover_background_color;
|
||||
unsigned int texture;
|
||||
bool visible;
|
||||
bool hovered;
|
||||
|
||||
void *userdata;
|
||||
bool ignores_events;
|
||||
|
||||
void (*on_left_click) (struct UIElement *self, void *userdata);
|
||||
void (*on_right_click) (struct UIElement *self, void *userdata);
|
||||
@@ -59,9 +62,23 @@ UIElement *UIElement_container_new (bool horizontal);
|
||||
UIElement *UIElement_label_new (const char *text);
|
||||
|
||||
void UIElement_add_child (UIElement *parent, UIElement *child);
|
||||
|
||||
void UIElement_set_on_left_click (UIElement *element, void (*on_left_click) (struct UIElement *self, void *userdata), void *userdata);
|
||||
void UIElement_set_on_tick (UIElement *element, void (*on_tick) (struct UIElement *self, void *userdata), void *userdata);
|
||||
void UIElement_set_background_color (UIElement *element, float r, float g, float b, float a);
|
||||
void UIElement_set_hover_background_color (UIElement *element, float r, float g, float b, float a);
|
||||
void UIElement_set_position (UIElement *element, float x, float y);
|
||||
void UIElement_set_scale (UIElement *element, float x, float y);
|
||||
|
||||
UIElement *UIElement_find_xy (UIElement *element, mat3 parent_model, vec2 mouse_ui_pos);
|
||||
void UIElement_tick (UIElement *element);
|
||||
void UIElement_render (UIElement *element);
|
||||
|
||||
void UILabel_on_tick_show_int (UIElement *element, void *userdata);
|
||||
void UILabel_on_tick_show_float (UIElement *element, void *userdata);
|
||||
void UIElement_label_set_text (UIElement *element, const char *text);
|
||||
void UIElement_label_printf (UIElement *element, const char *format, ...);
|
||||
|
||||
void uicb_label_show_int (UIElement *element, void *userdata);
|
||||
void uicb_label_show_float (UIElement *element, void *userdata);
|
||||
|
||||
void uicb_flag_switch (UIElement *element, void *userdata);
|
||||
void uicb_debug_print (UIElement *element, void *userdata);
|
||||
|
||||
+91
-12
@@ -3,8 +3,10 @@
|
||||
extern SDL_Window *sdl_window;
|
||||
extern float delta_time;
|
||||
extern int n_frame_ents, n_frame_chunks;
|
||||
extern vec3 camera_position;
|
||||
|
||||
static UIElement *ui_root;
|
||||
static UIElement *hovered_element;
|
||||
|
||||
void
|
||||
uiman_init ()
|
||||
@@ -13,26 +15,47 @@ uiman_init ()
|
||||
ui_root = UIElement_root_new ();
|
||||
|
||||
UIElement *container = UIElement_container_new (false);
|
||||
container->scale[0] = 0.4;
|
||||
container->scale[1] = 0.07;
|
||||
container->position[0] = -0.5;
|
||||
container->position[1] = 0.83;
|
||||
glm_vec3_copy ((vec4) { 1.0, 0.0, 0.0, 1.0 }, container->background_color);
|
||||
UIElement_set_position (container, -0.5, 0.75);
|
||||
UIElement_set_scale (container, 0.4, 0.15);
|
||||
UIElement_set_background_color (container, 1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
UIElement *frame_time = UIElement_label_new ("Frame time: ");
|
||||
UIElement *container2 = UIElement_container_new (true);
|
||||
UIElement_set_on_tick (frame_time, uicb_label_show_float, &delta_time);
|
||||
|
||||
UIElement *game_name = UIElement_label_new (NULL);
|
||||
UIElement_label_printf (game_name, "%s %s", GAME_NAME, GAME_VERSION);
|
||||
|
||||
UIElement *entities_rendered = UIElement_label_new ("Entities rendered: ");
|
||||
UIElement *chunks_rendered = UIElement_label_new ("Chunks rendered: ");
|
||||
UIElement_set_on_tick (entities_rendered, uicb_label_show_int, &n_frame_ents);
|
||||
UIElement_set_on_tick (chunks_rendered, uicb_label_show_int, &n_frame_chunks);
|
||||
|
||||
UIElement_set_on_tick (frame_time, UILabel_on_tick_show_float, &delta_time);
|
||||
UIElement_set_on_tick (entities_rendered, UILabel_on_tick_show_int, &n_frame_ents);
|
||||
UIElement_set_on_tick (chunks_rendered, UILabel_on_tick_show_int, &n_frame_chunks);
|
||||
|
||||
UIElement *container2 = UIElement_container_new (true);
|
||||
UIElement_add_child (container2, entities_rendered);
|
||||
UIElement_add_child (container2, chunks_rendered);
|
||||
|
||||
UIElement *pos_x = UIElement_label_new ("X: ");
|
||||
UIElement *pos_y = UIElement_label_new ("Y: ");
|
||||
UIElement *pos_z = UIElement_label_new ("Z: ");
|
||||
UIElement_set_on_tick (pos_x, uicb_label_show_float, &camera_position[0]);
|
||||
UIElement_set_on_tick (pos_y, uicb_label_show_float, &camera_position[1]);
|
||||
UIElement_set_on_tick (pos_z, uicb_label_show_float, &camera_position[2]);
|
||||
|
||||
UIElement *container3 = UIElement_container_new (true);
|
||||
UIElement_add_child (container3, pos_x);
|
||||
UIElement_add_child (container3, pos_y);
|
||||
UIElement_add_child (container3, pos_z);
|
||||
|
||||
UIElement *wireframe_button = UIElement_label_new ("Toggle wireframe");
|
||||
UIElement_set_background_color (wireframe_button, 0.2, 0.2, 0.2, 1.0);
|
||||
UIElement_set_hover_background_color (wireframe_button, 0.3, 0.3, 0.3, 1.0);
|
||||
UIElement_set_on_left_click (wireframe_button, uicb_flag_switch, "wireframe_enabled");
|
||||
|
||||
UIElement_add_child (container, game_name);
|
||||
UIElement_add_child (container, frame_time);
|
||||
UIElement_add_child (container, container2);
|
||||
UIElement_add_child (container, container3);
|
||||
UIElement_add_child (container, wireframe_button);
|
||||
|
||||
UIElement_add_child (ui_root, container);
|
||||
}
|
||||
@@ -49,6 +72,12 @@ uiman_render ()
|
||||
UIElement_render (ui_root);
|
||||
}
|
||||
|
||||
static inline void
|
||||
screen_to_ui_coords (int mouse_x, int mouse_y, int screen_w, int screen_h, vec2 out_coords) {
|
||||
out_coords[0] = (float) mouse_x / (float) screen_w * 2.0 - 1.0;
|
||||
out_coords[1] = 1.0 - (float) mouse_y / (float) screen_h * 2.0;
|
||||
}
|
||||
|
||||
bool
|
||||
uiman_cb_switch_focus (SDL_Event *event, void *data)
|
||||
{
|
||||
@@ -75,14 +104,64 @@ uiman_cb_key_up (SDL_Event *event, void *data)
|
||||
bool
|
||||
uiman_cb_mouse_motion (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
/* What even is in data at this point? No fucking idea. */
|
||||
UNUSED (data);
|
||||
int win_w, win_h;
|
||||
SDL_GetWindowSize (sdl_window, &win_w, &win_h);
|
||||
|
||||
vec2 ui_pos;
|
||||
screen_to_ui_coords (event->motion.x, event->motion.y, win_w, win_h, ui_pos);
|
||||
|
||||
UIElement *element = UIElement_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos);
|
||||
|
||||
if (element != hovered_element)
|
||||
{
|
||||
if (hovered_element)
|
||||
{
|
||||
hovered_element->hovered = false;
|
||||
}
|
||||
|
||||
if (element)
|
||||
{
|
||||
element->hovered = true;
|
||||
}
|
||||
|
||||
hovered_element = element;
|
||||
}
|
||||
|
||||
/* This callback always eats the event, because why would the game
|
||||
need mouse motion if the UI has stolen the focus? */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
uiman_cb_button_down (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
UNUSED (data);
|
||||
|
||||
int win_w, win_h;
|
||||
SDL_GetWindowSize (sdl_window, &win_w, &win_h);
|
||||
|
||||
vec2 ui_pos;
|
||||
screen_to_ui_coords (event->motion.x, event->motion.y, win_w, win_h, ui_pos);
|
||||
|
||||
UIElement *element = UIElement_find_xy (ui_root, GLM_MAT3_IDENTITY, ui_pos);
|
||||
|
||||
if (element)
|
||||
{
|
||||
if (event->button.button == SDL_BUTTON_LEFT && element->on_left_click)
|
||||
{
|
||||
element->on_left_click (element, element->userdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event->button.button == SDL_BUTTON_RIGHT && element->on_right_click)
|
||||
{
|
||||
element->on_right_click (element, element->userdata);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "uielement.h"
|
||||
#include "../flags.h"
|
||||
#include "../state.h"
|
||||
#include "../camera.h"
|
||||
|
||||
void uiman_init ();
|
||||
void uiman_tick ();
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GAME_NAME "Wschód"
|
||||
#define GAME_VERSION "0.1"
|
||||
#define GAME_NAME "Wschod"
|
||||
#define GAME_VERSION "0.2"
|
||||
|
||||
#define COLOR_BLUE "\x1B[34m"
|
||||
#define COLOR_RED "\x1B[31m"
|
||||
|
||||
Reference in New Issue
Block a user