add timer

This commit is contained in:
Zack Buhman 2025-12-05 11:28:35 -06:00
parent 5c535bc176
commit 724383a8c0
10 changed files with 190 additions and 10 deletions

View File

@ -105,6 +105,7 @@ MAIN_OBJS = \
src/render.o \ src/render.o \
src/collision.o \ src/collision.o \
src/update.o \ src/update.o \
src/unparse.o \
$(patsubst %.glsl,%.glsl.o,$(wildcard src/shader/*.glsl)) \ $(patsubst %.glsl,%.glsl.o,$(wildcard src/shader/*.glsl)) \
$(patsubst %.data,%.data.o,$(wildcard src/level/*.data)) \ $(patsubst %.data,%.data.o,$(wildcard src/level/*.data)) \
$(patsubst %.data,%.data.o,$(wildcard src/font/*.data)) \ $(patsubst %.data,%.data.o,$(wildcard src/font/*.data)) \

View File

@ -31,7 +31,9 @@ extern "C" {
uint attrib_texture, uint attrib_texture,
uint attrib_normal, uint attrib_normal,
uint uniform_trans, uint uniform_trans,
uint uniform_texture0); uint uniform_texture_trans,
uint uniform_texture0,
struct game_state * state);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -12,6 +12,9 @@ extern "C" {
float ball_y; float ball_y;
float ball_dx; float ball_dx;
float ball_dy; float ball_dy;
double start_time;
double remaining;
}; };
#ifdef __cplusplus #ifdef __cplusplus

14
include/unparse.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int unparse_base10_64(char * s, int64_t n, int len);
int unparse_double(double num, int whole_pad, int fract_pad, char * dst);
#ifdef __cplusplus
}
#endif

View File

@ -139,6 +139,7 @@ int main()
uint font__attrib_texture = glGetAttribLocation(font_program, "_texture"); uint font__attrib_texture = glGetAttribLocation(font_program, "_texture");
uint font__attrib_normal = glGetAttribLocation(font_program, "normal"); uint font__attrib_normal = glGetAttribLocation(font_program, "normal");
uint font__uniform_trans = glGetUniformLocation(font_program, "trans"); uint font__uniform_trans = glGetUniformLocation(font_program, "trans");
uint font__uniform_texture_trans = glGetUniformLocation(font_program, "texture_trans");
uint font__uniform_texture0 = glGetUniformLocation(font_program, "texture0"); uint font__uniform_texture0 = glGetUniformLocation(font_program, "texture0");
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -150,6 +151,7 @@ int main()
256, 256,
256, 256,
GL_RED); GL_RED);
(void)terminus_font;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// main loop // main loop
@ -171,11 +173,12 @@ int main()
state.ball_dx = 0.1; state.ball_dx = 0.1;
state.ball_dy = 0.1; state.ball_dy = 0.1;
state.start_time = glfwGetTime();
while(!glfwWindowShouldClose(window)) { while(!glfwWindowShouldClose(window)) {
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, true);
glEnable(GL_DEPTH_TEST);
glClearDepth(-1000.0f); glClearDepth(-1000.0f);
glClearColor(0.1, 0.2, 0.3, 1.0); glClearColor(0.1, 0.2, 0.3, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -215,6 +218,8 @@ int main()
state.paddle_x = 12 - extent; state.paddle_x = 12 - extent;
update(&state); update(&state);
double time = glfwGetTime();
state.remaining = 20.0 - (time - state.start_time);
if ((state.ball_x + state.ball_dx * 0.4) > 12.25f) { if ((state.ball_x + state.ball_dx * 0.4) > 12.25f) {
state.ball_x = 12.25f; state.ball_x = 12.25f;
@ -232,6 +237,7 @@ int main()
state.ball_dy = -state.ball_dy; state.ball_dy = -state.ball_dy;
} }
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER); glDepthFunc(GL_GREATER);
glUseProgram(program); glUseProgram(program);
@ -247,6 +253,7 @@ int main()
uniform_light_pos, uniform_light_pos,
&state); &state);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS); glDepthFunc(GL_ALWAYS);
glUseProgram(font_program); glUseProgram(font_program);
@ -255,8 +262,9 @@ int main()
font__attrib_texture, font__attrib_texture,
font__attrib_normal, font__attrib_normal,
font__uniform_trans, font__uniform_trans,
font__uniform_texture0 font__uniform_texture_trans,
); font__uniform_texture0,
&state);
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();

View File

@ -4,6 +4,7 @@
#include "glad/glad.h" #include "glad/glad.h"
#include "unparse.h"
#include "collision.hpp" #include "collision.hpp"
#include "render.hpp" #include "render.hpp"
#include "math/float_types.hpp" #include "math/float_types.hpp"
@ -266,12 +267,43 @@ void render(mesh paddle_mesh,
} }
} }
const int grid_width = 16;
const int grid_height = 32;
const int grid_stride = 256 / grid_width;
const int first_character = 0x20;
const float grid_scale = 1.0f / 256.0f;
static inline mat4x4 char_tex_trans(char c)
{
int cc = c - first_character;
int x = cc % grid_stride;
int y = cc / grid_stride;
mat4x4 tex_t = translate(vec3((float)(x * grid_width) * grid_scale,
(float)(y * grid_height) * grid_scale,
0));
mat4x4 tex_s = scale(vec3(grid_width * grid_scale, grid_height * grid_scale, 1.0f));
mat4x4 texture_trans = tex_t * tex_s;
return texture_trans;
}
static inline int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
void render_font(struct mesh plane_mesh, void render_font(struct mesh plane_mesh,
uint attrib_position, uint attrib_position,
uint attrib_texture, uint attrib_texture,
uint attrib_normal, uint attrib_normal,
uint uniform_trans, uint uniform_trans,
uint uniform_texture0) uint uniform_texture_trans,
uint uniform_texture0,
struct game_state * state)
{ {
glBindBuffer(GL_ARRAY_BUFFER, plane_mesh.vtx); glBindBuffer(GL_ARRAY_BUFFER, plane_mesh.vtx);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, plane_mesh.idx); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, plane_mesh.idx);
@ -301,12 +333,29 @@ void render_font(struct mesh plane_mesh,
glEnableVertexAttribArray(attrib_texture); glEnableVertexAttribArray(attrib_texture);
glEnableVertexAttribArray(attrib_normal); glEnableVertexAttribArray(attrib_normal);
float aspect = (float)vp_height / (float)vp_width;
mat4x4 a = scale(vec3(aspect, 1.0f, 1.0f));
mat4x4 s = scale(vec3(1, 2, 1));
mat4x4 r = rotate_y(PI / 1.0f) * rotate_z(PI / 1.0f) * rotate_x(PI / 2.0f); mat4x4 r = rotate_y(PI / 1.0f) * rotate_z(PI / 1.0f) * rotate_x(PI / 2.0f);
mat4x4 trans = scale(0.5f) * r;
glUniform4fv(uniform_trans, 4, &trans[0][0]);
glUniform1i(uniform_texture0, 0); glUniform1i(uniform_texture0, 0);
glDrawElements(GL_TRIANGLES, plane_mesh.length, GL_UNSIGNED_INT, 0); char dst[64];
int len = unparse_double(state->remaining, 4, 3, dst);
int advance = 0;
for (int i = 0; i < len; i++) {
if (dst[i] != ' ') {
mat4x4 texture_trans = char_tex_trans(dst[i]);
mat4x4 char_t = translate(vec3(advance / 8.0f, -8.0f * aspect, 0));
mat4x4 trans = a * scale(32.0f / vp_height) * s * char_t * r;
glUniform4fv(uniform_trans, 4, &trans[0][0]);
glUniform4fv(uniform_texture_trans, 4, &texture_trans[0][0]);
glDrawElements(GL_TRIANGLES, plane_mesh.length, GL_UNSIGNED_INT, 0);
}
advance += grid_width;
}
} }

View File

@ -8,6 +8,9 @@ void main()
{ {
vec4 c = texture2D(texture0, fp_texture); vec4 c = texture2D(texture0, fp_texture);
if (c.x == 0)
discard;
float i = c.x == 0 ? 0.0 : 1.0; float i = c.x == 0 ? 0.0 : 1.0;
gl_FragColor = vec4(i, i, i, 1.0); gl_FragColor = vec4(i, i, i, 1.0);

View File

@ -5,8 +5,10 @@ attribute vec2 _texture;
attribute vec3 normal; attribute vec3 normal;
varying vec2 fp_texture; varying vec2 fp_texture;
varying vec2 fp_texture_trans;
uniform vec4 trans[4]; uniform vec4 trans[4];
uniform vec4 texture_trans[4];
vec4 transform4(vec4 v) vec4 transform4(vec4 v)
{ {
@ -16,11 +18,20 @@ vec4 transform4(vec4 v)
dot(trans[3], v)); dot(trans[3], v));
} }
vec4 transform4t(vec4 v)
{
return vec4(dot(texture_trans[0], v),
dot(texture_trans[1], v),
dot(texture_trans[2], v),
dot(texture_trans[3], v));
}
void main() void main()
{ {
vec4 pos = transform4(vec4(position, 1)); vec4 pos = transform4(vec4(position, 1));
vec4 tt = transform4t(vec4(_texture, 0, 1));
fp_texture = _texture; fp_texture = tt.xy;
gl_Position = pos; gl_Position = pos;
} }

88
src/unparse.c Normal file
View File

@ -0,0 +1,88 @@
#include <math.h>
#include "unparse.h"
static inline int digits_base10_64(uint64_t n)
{
if (n >= 10000000000000000000ull) return 20;
if (n >= 1000000000000000000ull) return 19;
if (n >= 100000000000000000ull) return 18;
if (n >= 10000000000000000ull) return 17;
if (n >= 1000000000000000ull) return 16;
if (n >= 100000000000000ull) return 15;
if (n >= 10000000000000ull) return 14;
if (n >= 1000000000000ull) return 13;
if (n >= 100000000000ull) return 12;
if (n >= 10000000000ull) return 11;
if (n >= 1000000000ull) return 10;
if (n >= 100000000ull) return 9;
if (n >= 10000000ull) return 8;
if (n >= 1000000ull) return 7;
if (n >= 100000ull) return 6;
if (n >= 10000ull) return 5;
if (n >= 1000ull) return 4;
if (n >= 100ull) return 3;
if (n >= 10ull) return 2;
return 1;
}
static inline int min(int a, int b)
{
if (a < b)
return a;
else
return b;
}
int unparse_base10_64(char * s, int64_t n, int len)
{
int digits = 0;
if (n < 0) {
digits += 1;
n = -n;
}
digits += digits_base10_64(n);
len = min(digits, len);
int ret = len;
while (len > 0) {
const uint32_t digit = n % 10;
n = n / 10;
s[--len] = digit + 48;
}
return ret;
}
int unparse_double(double num, int whole_pad, int fract_pad, char * dst)
{
bool negative = num < 0;
double n = negative ? -num : num;
double whole = floor(n);
double fract = n - whole;
int64_t wholei = whole;
int64_t fracti = fract * pow(10.0, fract_pad);
char wbuf[20];
int wret = unparse_base10_64(wbuf, wholei, 20);
char fbuf[20];
int fret = unparse_base10_64(fbuf, fracti, 20);
int ix = 0;
for (int i = 0; i < whole_pad - wret; i++) {
dst[ix++] = ' ';
}
dst[ix++] = negative ? '-' : ' ';
for (int i = 0; i < wret; i++) {
dst[ix++] = wbuf[i];
}
dst[ix++] = '.';
for (int i = 0; i < fract_pad - fret; i++) {
dst[ix++] = '0';
}
for (int i = 0; i < fret; i++) {
dst[ix++] = fbuf[i];
}
return ix;
}

View File

@ -13,4 +13,5 @@
void update(struct game_state * state) void update(struct game_state * state)
{ {
} }