From 890ea713db22b82eae3a0580e531dc821a1f705c Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Fri, 5 Nov 2021 14:03:07 +0100 Subject: [PATCH] srender: added API to render custom meshes. --- src/srender.h | 194 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 152 insertions(+), 42 deletions(-) diff --git a/src/srender.h b/src/srender.h index 0222ced..0de46fc 100644 --- a/src/srender.h +++ b/src/srender.h @@ -6,25 +6,45 @@ extern "C" { #endif #include +#include #include "vectorial/simd4x4f.h" typedef struct srndr srndr; typedef struct srview srview; typedef struct srcmdbuf srcmdbuf; +typedef union srvrtxdata srvrtxdata; +typedef struct srmeshdata srmeshdata; +extern GLuint* srDefaultVAId; typedef enum { SRndrCmdTypeFrame = 0, SRndrCmdTypeGrid, SRndrCmdTypeCube, SRndrCmdTypeSphere, - SrndrCmdTypePoint, + SrndrCmdTypeMesh, } SRndrCmdType; +// +// Simple Mesh Data +// +typedef struct srmeshdata { + int nvertices; + int nindices; + + GLuint vao_id; + GLuint vb_id; + GLuint idb_id; + + GLuint count; + GLenum mode; +} srmeshdata; + typedef struct srcmd { simd4x4f mat; simd4f color; SRndrCmdType type; + srmeshdata* meshdata; } srcmd; // @@ -56,6 +76,112 @@ srcmd* srcmd_create(srcmdbuf* cmdbuf); void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf); +// +// Vertex Data +// +typedef union srvrtxdata { + struct { + float x, y, z, w; + float nx, ny, nz; + float s, t; + GLubyte r, g, b, a; + }; + struct { + float pos[4]; + float n[3]; + float uv[2]; + GLubyte color[4]; + }; +} srvrtxdata; + +inline srmeshdata* srmesh_create( + srvrtxdata* vrtxdata, + int nvertices, + GLuint* idxdata, + int nindices, + GLenum prim_mode, + GLuint count) { + srmeshdata* result = (srmeshdata*)calloc(sizeof(srmeshdata), 1); + + result->nvertices = nvertices; + result->nindices = nindices; + result->mode = prim_mode; + result->count = count; + + glGenVertexArrays(1, &result->vao_id); + glBindVertexArray(result->vao_id); + + glGenBuffers(1, &result->vb_id); + glBindBuffer(GL_ARRAY_BUFFER, result->vb_id); + + glEnableVertexAttribArray(0); + glVertexAttribPointer( + 0, + 4, + GL_FLOAT, + GL_FALSE, + (sizeof(srvrtxdata)), + (void*)0); + + glEnableVertexAttribArray(1); + glVertexAttribPointer( + 1, + 3, + GL_FLOAT, + GL_FALSE, + (sizeof(srvrtxdata)), + (void*)(sizeof(float) * 4)); + + // Attribute 2: texture coordinates + glEnableVertexAttribArray(2); + glVertexAttribPointer( + 2, + 2, + GL_FLOAT, + GL_FALSE, + (sizeof(srvrtxdata)), + (void*)(sizeof(float) * 7)); + + // Attribute 3: color + glEnableVertexAttribArray(3); + glVertexAttribPointer( + 3, + 4, + GL_UNSIGNED_BYTE, + GL_TRUE, + (sizeof(srvrtxdata)), + (void*)(sizeof(float) * 9)); + + glBufferData( + GL_ARRAY_BUFFER, + sizeof(srvrtxdata) * nvertices, + vrtxdata, + GL_DYNAMIC_DRAW); + + glGenBuffers(1, &result->idb_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result->idb_id); + for (int i = 0; i < nindices; i++) { + printf ("idx %2d: %d\n", i, idxdata[i]); + } + glBufferData( + GL_ELEMENT_ARRAY_BUFFER, + sizeof(GLuint) * nindices, + idxdata, + GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glBindVertexArray(0); + + return result; +} + +inline void srmesh_destroy(srmeshdata* mesh) { + glDeleteVertexArrays(1, &mesh->vao_id); + glDeleteBuffers(1, &mesh->vb_id); + glDeleteBuffers(1, &mesh->idb_id); + free(mesh); +} + // // srender Implementation // @@ -94,45 +220,12 @@ typedef struct srcmdbuf { srcmd* cmds; } srcmdbuf; -// -// Vertex Data -// -typedef union srvrtxdata { - struct { - float x, y, z, w; - float nx, ny, nz; - float s, t; - GLubyte r, g, b, a; - }; - struct { - float pos[4]; - float n[4]; - float uv[2]; - GLubyte color[4]; - }; -} srvrtxdata; - // // Vertex Buffer Object for all debug objects (coord frame, grid, cube, ...) // const GLint DEBUG_VBO_SIZE = 1024; -GLuint gDebugShapesVBOId = 0; GLuint gDebugShapesVAId = 0; - -// -// Simple Mesh Data -// -typedef struct srmeshdata { - int nvertices; - int nindices; - - GLuint vao_id; - GLuint vb_id; - GLuint idb_id; - - GLuint count; - GLenum mode; -} srmeshdata; +GLuint gDebugShapesVBOId = 0; static srmeshdata gCoordFrameMesh = {0}; static srmeshdata gGridMesh = {0}; @@ -422,7 +515,7 @@ void init_debug_meshes() { glBufferSubData( GL_ARRAY_BUFFER, dbg_vbuf_offset, - sizeof(srvrtxdata) * 44, + sizeof(union srvrtxdata) * 44, grid_vertices); dbg_vbuf_offset += sizeof(srvrtxdata) * 44; @@ -494,9 +587,9 @@ void init_debug_meshes() { glBufferSubData( GL_ARRAY_BUFFER, dbg_vbuf_offset, - sizeof(srvrtxdata) * 24, + sizeof(srvrtxdata) * gCubeMesh.nvertices, cube_vertices); - dbg_vbuf_offset += sizeof(srvrtxdata) * 24; + dbg_vbuf_offset += sizeof(srvrtxdata) * gCubeMesh.nvertices; GLuint cube_indices[] = { // clang-format off @@ -551,7 +644,7 @@ void init_debug_meshes() { float theta = -M_PI + j * sector_step; float x = cos(theta) * cos(phi); float z = -sin(theta) * cos(phi); -// gLog ("idx: %d # phi: %f, theta %f, p = %f, %f, %f", vert_index, phi * 180 / M_PI, theta * 180 / M_PI, x, y, z); + // gLog ("idx: %d # phi: %f, theta %f, p = %f, %f, %f", vert_index, phi * 180 / M_PI, theta * 180 / M_PI, x, y, z); srvrtxdata* vertex = &uvsphere_vertices[vert_index++]; vertex->x = x * 0.5; @@ -624,8 +717,6 @@ void init_debug_meshes() { gUVSphereMesh.count = gUVSphereMesh.nindices; glBindVertexArray(0); - - gLog ("Debug Mesh Vertices: %d", dbg_vbuf_offset / sizeof(union srvrtxdata)); }; // @@ -807,6 +898,22 @@ void srndr_run_sphere_command(const srcmd* cmd) { glBindVertexArray(0); } +void srndr_run_mesh_command(const srcmd* cmd) { + glBindVertexArray(cmd->meshdata->vao_id); + + glBindBuffer(GL_ARRAY_BUFFER, cmd->meshdata->vb_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cmd->meshdata->idb_id); + glDrawElements( + cmd->meshdata->mode, + cmd->meshdata->count, + GL_UNSIGNED_INT, + (void*)0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sview->mFrameBufferId); @@ -817,7 +924,7 @@ void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) { glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); -// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glUseProgram(gDefaultShader.program_id); GLint view_mat_loc = @@ -851,6 +958,9 @@ void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) { case SRndrCmdTypeSphere: srndr_run_sphere_command(cmd); break; + case SrndrCmdTypeMesh: + srndr_run_mesh_command(cmd); + break; default: gLog("Invalid command type %d at index %d", cmd->type, i); break;