first person camera

This commit is contained in:
Zack Buhman 2026-03-08 18:04:07 -05:00
parent a0e922975a
commit c987c0330b
4 changed files with 57 additions and 20 deletions

View File

@ -5,6 +5,7 @@ extern "C" {
#endif #endif
void load(); void load();
void draw_hud();
void draw(); void draw();
void update(float lx, float ly, float rx, float ry, float tl, float tr, void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right); int up, int down, int left, int right);

View File

@ -7,6 +7,7 @@ function init()
ffi.cdef[[ ffi.cdef[[
void load(); void load();
void draw(); void draw();
void draw_hud();
void update(float lx, float ly, float rx, float ry, float tl, float tr, void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right); int up, int down, int left, int right);
]] ]]
@ -33,6 +34,7 @@ end
local draw = function() local draw = function()
test.draw() test.draw()
test.draw_hud()
end end
function love.run() function love.run()

View File

@ -133,20 +133,17 @@ namespace font {
int i = 0; int i = 0;
while (s[i] != 0) { while (s[i] != 0) {
char c = s[i]; char c = s[i++];
if (c <= 0x20 || c > 0x7f) if (!(c <= 0x20 || c > 0x7f)) {
continue;
XMFLOAT4X4 transform = glyph_transform(font, x, y); XMFLOAT4X4 transform = glyph_transform(font, x, y);
glUniformMatrix4fv(location.uniform.transform, 1, GL_FALSE, (float *)&transform); glUniformMatrix4fv(location.uniform.transform, 1, GL_FALSE, (float *)&transform);
XMFLOAT2 glyph = glyph_coordinate(font, c); XMFLOAT2 glyph = glyph_coordinate(font, c);
glUniform2fv(location.uniform.glyph, 1, (float *)&glyph); glUniform2fv(location.uniform.glyph, 1, (float *)&glyph);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0); glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
}
x += font.desc->glyph_width; x += font.desc->glyph_width;
i += 1;
} }
} }
} }

View File

@ -241,8 +241,10 @@ extern "C" {
struct view_state { struct view_state {
XMVECTOR up; XMVECTOR up;
XMVECTOR eye; XMVECTOR eye;
XMVECTOR forward;
XMVECTOR direction; XMVECTOR direction;
float fov; float fov;
float pitch;
}; };
view_state view_state; view_state view_state;
@ -260,9 +262,11 @@ void load()
view_state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); view_state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
view_state.eye = XMVectorSet(0, 0, 0, 1); view_state.eye = XMVectorSet(0, 0, 0, 1);
view_state.direction = XMVectorSet(1, 0, 0, 0); view_state.forward = XMVectorSet(1, 0, 0, 0);
view_state.direction = view_state.forward;
view_state.pitch = 0.0;
view_state.fov = 1.0; view_state.fov = 1.5;
//load_texture_shader_storage(); //load_texture_shader_storage();
@ -279,18 +283,30 @@ void load()
ter_8x16 = font::load_font(font::ter_8x16); ter_8x16 = font::load_font(font::ter_8x16);
} }
float _ry = 0.0;
void update(float lx, float ly, float rx, float ry, float tl, float tr, void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right) int up, int down, int left, int right)
{ {
//view_state.yaw += rx; //view_state.yaw += rx;
XMMATRIX mrz = XMMatrixRotationZ(rx * -0.035); XMMATRIX mrz = XMMatrixRotationZ(rx * -0.035);
XMMATRIX mry = XMMatrixRotationY(ry * -0.035);
view_state.direction = XMVector3Transform(view_state.direction, mrz * mry);
XMVECTOR normal = XMVector3Cross(view_state.direction, view_state.up); view_state.forward = XMVector3Transform(view_state.forward, mrz);
view_state.eye += view_state.direction * -ly + normal * lx + view_state.up * (tl - tr); XMVECTOR normal = XMVector3NormalizeEst(XMVector3Cross(view_state.forward, view_state.up));
view_state.fov += 0.01 * up + -0.01 * down; view_state.pitch += ry * -0.035;
if (view_state.pitch > 1.5f) view_state.pitch = 1.5f;
if (view_state.pitch < -1.5f) view_state.pitch = -1.5f;
XMMATRIX mrn = XMMatrixRotationAxis(normal, view_state.pitch);
view_state.direction = XMVector3Transform(view_state.forward, mrn);
view_state.eye += view_state.forward * -ly + normal * lx + view_state.up * (tl - tr);
float new_fov = view_state.fov + 0.01 * up + -0.01 * down;
if (new_fov > 0.00001f) {
view_state.fov = new_fov;
}
} }
static inline int popcount(int x) static inline int popcount(int x)
@ -298,6 +314,29 @@ static inline int popcount(int x)
return __builtin_popcount(x); return __builtin_popcount(x);
} }
void asdf(char * const buf, char const * const label, char const * const format, float value)
{
const int label_length = strlen(label);
memcpy(buf, label, label_length);
int len = snprintf(&buf[label_length], 511 - label_length, format, value);
buf[label_length + len] = 0;
}
void draw_hud()
{
char buf[512];
float y = 10.0f;
asdf(buf, "fov: ", "%.3f", view_state.fov);
font::draw_string(ter_8x16, buf, 10, y);
y += ter_8x16.desc->glyph_height;
asdf(buf, "pitch: ", "%.9f", view_state.pitch);
font::draw_string(ter_8x16, buf, 10, y);
y += ter_8x16.desc->glyph_height;
}
void draw() void draw()
{ {
XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction); XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction);
@ -368,6 +407,4 @@ void draw()
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count, base_instance); glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count, base_instance);
} }
} }
font::draw_string(ter_8x16, "test", 10, 10);
} }