srender: added API to render custom meshes.
parent
be54fe31e7
commit
890ea713db
194
src/srender.h
194
src/srender.h
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue