pxl8/src/gfx/pxl8_mesh.c

123 lines
3.6 KiB
C
Raw Normal View History

#include "pxl8_mesh.h"
#include <stdlib.h>
#include <string.h>
pxl8_mesh* pxl8_mesh_create(u32 vertex_capacity, u32 index_capacity) {
if (vertex_capacity > PXL8_MESH_MAX_VERTICES) vertex_capacity = PXL8_MESH_MAX_VERTICES;
if (index_capacity > PXL8_MESH_MAX_INDICES) index_capacity = PXL8_MESH_MAX_INDICES;
pxl8_mesh* mesh = calloc(1, sizeof(pxl8_mesh));
if (!mesh) return NULL;
mesh->vertices = calloc(vertex_capacity, sizeof(pxl8_vertex));
mesh->indices = calloc(index_capacity, sizeof(u16));
if (!mesh->vertices || !mesh->indices) {
free(mesh->vertices);
free(mesh->indices);
free(mesh);
return NULL;
}
mesh->vertex_capacity = vertex_capacity;
mesh->index_capacity = index_capacity;
mesh->vertex_count = 0;
mesh->index_count = 0;
return mesh;
}
void pxl8_mesh_destroy(pxl8_mesh* mesh) {
if (!mesh) return;
free(mesh->vertices);
free(mesh->indices);
free(mesh);
}
void pxl8_mesh_clear(pxl8_mesh* mesh) {
if (!mesh) return;
mesh->vertex_count = 0;
mesh->index_count = 0;
}
u16 pxl8_mesh_push_vertex(pxl8_mesh* mesh, pxl8_vertex v) {
if (!mesh || mesh->vertex_count >= mesh->vertex_capacity) return 0;
u16 idx = (u16)mesh->vertex_count;
mesh->vertices[mesh->vertex_count++] = v;
return idx;
}
void pxl8_mesh_push_triangle(pxl8_mesh* mesh, u16 i0, u16 i1, u16 i2) {
if (!mesh || mesh->index_count + 3 > mesh->index_capacity) return;
mesh->indices[mesh->index_count++] = i0;
mesh->indices[mesh->index_count++] = i1;
mesh->indices[mesh->index_count++] = i2;
}
void pxl8_mesh_push_quad(pxl8_mesh* mesh, u16 i0, u16 i1, u16 i2, u16 i3) {
pxl8_mesh_push_triangle(mesh, i0, i1, i2);
pxl8_mesh_push_triangle(mesh, i0, i2, i3);
}
void pxl8_mesh_push_box(pxl8_mesh* mesh, pxl8_vec3 center, pxl8_vec3 half, u8 color) {
pxl8_mesh_push_box_uv(mesh, center, half, color, 1.0f, 1.0f);
}
void pxl8_mesh_push_box_uv(pxl8_mesh* mesh, pxl8_vec3 center, pxl8_vec3 half, u8 color, f32 u_scale, f32 v_scale) {
if (!mesh) return;
pxl8_vec3 corners[8] = {
{center.x - half.x, center.y - half.y, center.z - half.z},
{center.x + half.x, center.y - half.y, center.z - half.z},
{center.x + half.x, center.y + half.y, center.z - half.z},
{center.x - half.x, center.y + half.y, center.z - half.z},
{center.x - half.x, center.y - half.y, center.z + half.z},
{center.x + half.x, center.y - half.y, center.z + half.z},
{center.x + half.x, center.y + half.y, center.z + half.z},
{center.x - half.x, center.y + half.y, center.z + half.z},
};
pxl8_vec3 normals[6] = {
{ 0, 0, -1}, // front
{ 0, 0, 1}, // back
{-1, 0, 0}, // left
{ 1, 0, 0}, // right
{ 0, -1, 0}, // bottom
{ 0, 1, 0}, // top
};
i32 faces[6][4] = {
{0, 1, 2, 3}, // front
{5, 4, 7, 6}, // back
{4, 0, 3, 7}, // left
{1, 5, 6, 2}, // right
{4, 5, 1, 0}, // bottom
{3, 2, 6, 7}, // top
};
f32 uvs[4][2] = {
{0, v_scale},
{u_scale, v_scale},
{u_scale, 0},
{0, 0},
};
for (i32 face = 0; face < 6; face++) {
u16 base = (u16)mesh->vertex_count;
for (i32 v = 0; v < 4; v++) {
pxl8_vertex vert = {
.position = corners[faces[face][v]],
.normal = normals[face],
.u = uvs[v][0],
.v = uvs[v][1],
.color = color,
.light = 255,
};
pxl8_mesh_push_vertex(mesh, vert);
}
pxl8_mesh_push_quad(mesh, base, base + 1, base + 2, base + 3);
}
}