srender: added API to render custom meshes.

master
Martin Felis 2021-11-05 14:03:07 +01:00
parent be54fe31e7
commit 890ea713db
1 changed files with 152 additions and 42 deletions

View File

@ -6,25 +6,45 @@ extern "C" {
#endif
#include <stdbool.h>
#include <stdio.h>
#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;