#ifndef RENDER_MESH_H #define RENDER_MESH_H /* * GPU mesh plus a CPU-side builder. * Vertex layout: position (loc 0), normal (loc 1), color (loc 2). */ #include #include #include "core/gl.h" #include "math/linalg.h" typedef struct { Vec3 position; Vec3 normal; Vec3 color; } Vertex; typedef struct { GLuint vao; GLuint vbo; GLuint ebo; GLsizei index_count; Vec3 center; /* bounding sphere (model space): what isn't in view isn't drawn */ float radius; } Mesh; typedef struct { Vertex *vertices; size_t vertex_count, vertex_capacity; GLuint *indices; size_t index_count, index_capacity; bool out_of_memory; } MeshBuilder; void MeshBuilder_init(MeshBuilder *b); void MeshBuilder_free(MeshBuilder *b); /* Appends a vertex and returns its index. */ GLuint MeshBuilder_vertex(MeshBuilder *b, Vec3 position, Vec3 normal, Vec3 color); /* * Triangles are always stored counter-clockwise as seen from the side their * vertex normals point to, so the given index order does not matter. */ void MeshBuilder_triangle(MeshBuilder *b, GLuint i0, GLuint i1, GLuint i2); /* Two triangles: (i0, i1, i2) and (i2, i3, i0). */ void MeshBuilder_quad(MeshBuilder *b, GLuint i0, GLuint i1, GLuint i2, GLuint i3); /* * Flat quad (corners in order around the edge) or triangle, subdivided into * cells of at most cell_size so the surface can bend in the vertex shader. */ void MeshBuilder_gridQuad(MeshBuilder *b, Vec3 p0, Vec3 p1, Vec3 p2, Vec3 p3, Vec3 normal, Vec3 color, float cell_size); void MeshBuilder_gridTriangle(MeshBuilder *b, Vec3 p0, Vec3 p1, Vec3 p2, Vec3 normal, Vec3 color, float cell_size); /* Number of segments needed to split a length into cells of cell_size. */ int MeshBuilder_segments(float length, float cell_size); /* Uploads the builder to the GPU and frees it. Returns an empty mesh on error. */ Mesh Mesh_fromBuilder(MeshBuilder *b); void Mesh_draw(const Mesh *mesh); void Mesh_destroy(Mesh *mesh); #endif /* RENDER_MESH_H */