mirror of
https://github.com/IllusionMan1212/C2048.git
synced 2026-10-24 02:12:31 +00:00
zephr/game: textures, icons, and buttons
- zephr: correctly set cursor when hovering button - zephr: added texture loading and displaying - zephr: added icon button - game: added help and settings icon buttons
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glad/glx.h>
|
||||
#include <stb_image.h>
|
||||
|
||||
#include "shader.h"
|
||||
#include "zephr.h"
|
||||
@@ -171,6 +172,14 @@ void apply_alignment(Alignment align, UIConstraints *constraints, Vec2f *pos, Si
|
||||
}
|
||||
}
|
||||
|
||||
bool inside_rect(Rect *rect, Vec2 *point) {
|
||||
if (point->x >= rect->pos.x && point->x <= rect->pos.x + rect->size.width &&
|
||||
point->y >= rect->pos.y && point->y <= rect->pos.y + rect->size.height) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void draw_quad(UIConstraints *constraints, const Color color, float border_radius, Alignment align) {
|
||||
use_shader(ui_shader);
|
||||
|
||||
@@ -245,6 +254,10 @@ void draw_triangle(UIConstraints *constraints, const Color color, Alignment alig
|
||||
apply_constraints(constraints, &pos, &size);
|
||||
apply_alignment(align, constraints, &pos, size);
|
||||
|
||||
// set the positions after applying alignment so children can use them
|
||||
constraints->x = pos.x;
|
||||
constraints->y = pos.y;
|
||||
|
||||
Matrix4x4 model = identity();
|
||||
apply_translation(&model, (Vec2f){-size.width / 2.f, -size.height / 2.f});
|
||||
apply_rotation(&model, to_radians(constraints->rotation));
|
||||
@@ -271,12 +284,61 @@ void draw_triangle(UIConstraints *constraints, const Color color, Alignment alig
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
bool inside_rect(Rect *rect, Vec2 *point) {
|
||||
if (point->x >= rect->pos.x && point->x <= rect->pos.x + rect->size.width &&
|
||||
point->y >= rect->pos.y && point->y <= rect->pos.y + rect->size.height) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
void draw_texture(UIConstraints *constraints, const TextureId texture_id, const Color color, f32 radius, Alignment align) {
|
||||
use_shader(ui_shader);
|
||||
|
||||
set_vec4f(ui_shader, "aColor", color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f);
|
||||
set_float(ui_shader, "uiWidth", constraints->width);
|
||||
set_float(ui_shader, "uiHeight", constraints->height);
|
||||
set_float(ui_shader, "borderRadius", radius);
|
||||
set_bool(ui_shader, "hasTexture", true);
|
||||
|
||||
set_mat4f(ui_shader, "projection", (float *)zephr_ctx->projection.m);
|
||||
|
||||
Vec2f pos = { 0.f, 0.f };
|
||||
Sizef size = { 0.f, 0.f };
|
||||
|
||||
apply_constraints(constraints, &pos, &size);
|
||||
apply_alignment(align, constraints, &pos, size);
|
||||
|
||||
// set the positions after applying alignment so children can use them
|
||||
constraints->x = pos.x;
|
||||
constraints->y = pos.y;
|
||||
|
||||
Matrix4x4 model = identity();
|
||||
apply_translation(&model, (Vec2f){-size.width / 2.f, -size.height / 2.f});
|
||||
apply_rotation(&model, to_radians(constraints->rotation));
|
||||
apply_translation(&model, (Vec2f){size.width / 2.f, size.height / 2.f});
|
||||
|
||||
apply_translation(&model, pos);
|
||||
|
||||
set_mat4f(ui_shader, "model", (float *)model.m);
|
||||
|
||||
glBindVertexArray(ui_vao);
|
||||
|
||||
float vertices[6][4] = {
|
||||
// bottom left tri
|
||||
{0, 0 + size.height, 0.0, 1.0},
|
||||
{0, 0, 0.0, 0.0},
|
||||
{0 + size.width, 0, 1.0, 0.0},
|
||||
|
||||
// top right tri
|
||||
{0, 0 + size.height, 0.0, 1.0},
|
||||
{0 + size.width, 0, 1.0, 0.0},
|
||||
{0 + size.width, 0 + size.height, 1.0, 1.0},
|
||||
};
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ui_vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
glBindVertexArray(0);
|
||||
set_bool(ui_shader, "hasTexture", false);
|
||||
}
|
||||
|
||||
bool draw_button(UIConstraints *constraints, const Color color, const char *text, f32 radius, Alignment align) {
|
||||
@@ -285,10 +347,13 @@ bool draw_button(UIConstraints *constraints, const Color color, const char *text
|
||||
apply_constraints(constraints, &rect.pos, &rect.size);
|
||||
apply_alignment(align, constraints, &rect.pos, rect.size);
|
||||
|
||||
if (inside_rect(&rect, &zephr_ctx->mouse.pos)) {
|
||||
bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos);
|
||||
bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
|
||||
|
||||
if (is_hovered) {
|
||||
zephr_set_cursor(ZEPHR_CURSOR_HAND);
|
||||
|
||||
if (zephr_ctx->mouse.pressed) {
|
||||
if (left_mouse_pressed) {
|
||||
Color new_color = mult_color(color, 0.8f);
|
||||
draw_quad(constraints, new_color, radius, align);
|
||||
} else {
|
||||
@@ -296,7 +361,6 @@ bool draw_button(UIConstraints *constraints, const Color color, const char *text
|
||||
draw_quad(constraints, new_color, radius, align);
|
||||
}
|
||||
} else {
|
||||
zephr_set_cursor(ZEPHR_CURSOR_ARROW);
|
||||
draw_quad(constraints, color, radius, align);
|
||||
}
|
||||
|
||||
@@ -306,22 +370,65 @@ bool draw_button(UIConstraints *constraints, const Color color, const char *text
|
||||
set_parent_constraint(&text_constraints, constraints);
|
||||
set_x_constraint(&text_constraints, 0, UI_CONSTRAINT_RELATIVE_PIXELS);
|
||||
set_y_constraint(&text_constraints, 0, UI_CONSTRAINT_RELATIVE_PIXELS);
|
||||
set_width_constraint(&text_constraints, 1.5, UI_CONSTRAINT_RELATIVE_PIXELS);
|
||||
set_width_constraint(&text_constraints, 1.0, UI_CONSTRAINT_RELATIVE_PIXELS);
|
||||
|
||||
u8 font_size = (u8)(constraints->width * 0.2 / text_constraints.width * 0.2 * 100.f);
|
||||
u8 font_size = (u8)((constraints->width) / (text_constraints.width * 0.1 * 65.f));
|
||||
|
||||
// TODO: need to adjust the font size based on the text height
|
||||
|
||||
draw_text(text, font_size, text_constraints, COLOR_BLACK, ALIGN_CENTER);
|
||||
}
|
||||
|
||||
if (inside_rect(&rect, &zephr_ctx->mouse.pos) && zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) {
|
||||
if (is_hovered && zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool draw_icon_button(UIConstraints *constraints, Color btn_color, const TextureId icon_tex_id, f32 radius, Alignment align) {
|
||||
CORE_DEBUG_ASSERT(icon_tex_id, "draw_icon_button() requires that you provide an icon texture");
|
||||
|
||||
Rect rect = {0};
|
||||
Color icon_color = COLOR_WHITE;
|
||||
|
||||
apply_constraints(constraints, &rect.pos, &rect.size);
|
||||
apply_alignment(align, constraints, &rect.pos, rect.size);
|
||||
|
||||
bool is_hovered = inside_rect(&rect, &zephr_ctx->mouse.pos);
|
||||
bool left_mouse_pressed = zephr_ctx->mouse.pressed && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT;
|
||||
|
||||
if (is_hovered) {
|
||||
zephr_set_cursor(ZEPHR_CURSOR_HAND);
|
||||
|
||||
if (left_mouse_pressed) {
|
||||
btn_color = mult_color(btn_color, 0.8f);
|
||||
icon_color = mult_color(icon_color, 0.8f);
|
||||
} else {
|
||||
btn_color = mult_color(btn_color, 0.9f);
|
||||
icon_color = mult_color(icon_color, 0.9f);
|
||||
}
|
||||
}
|
||||
|
||||
draw_quad(constraints, btn_color, radius, align);
|
||||
|
||||
UIConstraints icon_constraints = {0};
|
||||
|
||||
set_parent_constraint(&icon_constraints, constraints);
|
||||
set_x_constraint(&icon_constraints, 0, UI_CONSTRAINT_RELATIVE_PIXELS);
|
||||
set_y_constraint(&icon_constraints, 0, UI_CONSTRAINT_RELATIVE_PIXELS);
|
||||
set_width_constraint(&icon_constraints, constraints->width * 0.8f, UI_CONSTRAINT_FIXED);
|
||||
set_height_constraint(&icon_constraints, constraints->height * 0.8f, UI_CONSTRAINT_FIXED);
|
||||
draw_texture(&icon_constraints, icon_tex_id, icon_color, 0, ALIGN_CENTER);
|
||||
|
||||
if (is_hovered && zephr_ctx->mouse.released && zephr_ctx->mouse.button == ZEPHR_MOUSE_BUTTON_LEFT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* enum Element { */
|
||||
/* Rect, */
|
||||
/* Circle, */
|
||||
|
||||
Reference in New Issue
Block a user