Initial code for UV Spheres
parent
d7a5507774
commit
0622c53d29
137
src/srender.h
137
src/srender.h
|
@ -17,7 +17,6 @@ typedef enum {
|
|||
SRndrCmdTypeFrame = 0,
|
||||
SRndrCmdTypeGrid,
|
||||
SRndrCmdTypeCube,
|
||||
SRndrCmdTypeLight,
|
||||
SRndrCmdTypeSphere
|
||||
} SRndrCmdType;
|
||||
|
||||
|
@ -131,6 +130,7 @@ typedef struct srmeshdata {
|
|||
static srmeshdata gCoordFrameMesh = {0};
|
||||
static srmeshdata gGridMesh = {0};
|
||||
static srmeshdata gCubeMesh = {0};
|
||||
static srmeshdata gUVSphereMesh = {0};
|
||||
|
||||
typedef struct srshader {
|
||||
const char* vert_fname;
|
||||
|
@ -502,6 +502,119 @@ void init_debug_meshes() {
|
|||
gCubeMesh.mode = GL_TRIANGLES;
|
||||
gCubeMesh.count = 36;
|
||||
|
||||
//
|
||||
// UVSphere
|
||||
//
|
||||
gUVSphereMesh.vao_id = gDebugShapesVAId;
|
||||
gUVSphereMesh.vb_id = gDebugShapesVBOId;
|
||||
|
||||
// loosely based on http://www.songho.ca/opengl/gl_sphere.html
|
||||
int stack_count = 4;
|
||||
int sector_count = 4;
|
||||
gUVSphereMesh.nvertices = (stack_count + 1) * (sector_count + 1);
|
||||
gLog("UVsphere vertices: %d", gUVSphereMesh.nvertices);
|
||||
|
||||
srvrtxdata* uvsphere_vertices =
|
||||
calloc(sizeof(srvrtxdata), gUVSphereMesh.nvertices);
|
||||
|
||||
float sector_step = 2.f * M_PI / sector_count;
|
||||
float stack_step = M_PI / stack_count;
|
||||
float sector_angle, stack_angle;
|
||||
|
||||
for (int i = 0; i <= stack_count; ++i) {
|
||||
stack_angle = M_PI / 2 - i * stack_step; // starting from pi/2 to -pi/2
|
||||
float xy = cosf(stack_angle); // r * cos(u)
|
||||
float z = sinf(stack_angle); // r * sin(u)
|
||||
|
||||
// add (sector_count+1) vertices per stack
|
||||
// the first and last vertices have same position and normal, but different tex coords
|
||||
for (int j = 0; j <= sector_count; ++j) {
|
||||
int vertex_index = (i * (sector_count + 1)) + j;
|
||||
gLog("vertex_index %d", vertex_index);
|
||||
srvrtxdata* vertex = &uvsphere_vertices[vertex_index];
|
||||
sector_angle = j * sector_step; // starting from 0 to 2pi
|
||||
|
||||
// vertex position (x, y, z)
|
||||
vertex->x = xy * cosf(sector_angle); // r * cos(u) * cos(v)
|
||||
vertex->y = xy * sinf(sector_angle); // r * cos(u) * sin(v)
|
||||
vertex->z = z;
|
||||
vertex->w = 1.f;
|
||||
|
||||
// normalized vertex normal (nx, ny, nz)
|
||||
vertex->nx = vertex->x;
|
||||
vertex->ny = vertex->y;
|
||||
vertex->nz = vertex->z;
|
||||
|
||||
// vertex tex coord (s, t) range between [0, 1]
|
||||
vertex->s = (float)j / sector_count;
|
||||
vertex->t = (float)i / stack_count;
|
||||
|
||||
vertex->r = 128;
|
||||
vertex->g = 128;
|
||||
vertex->b = 128;
|
||||
vertex->a = 255;
|
||||
}
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gDebugShapesVBOId);
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
dbg_vbuf_offset,
|
||||
sizeof(srvrtxdata) * gUVSphereMesh.nvertices,
|
||||
uvsphere_vertices);
|
||||
dbg_vbuf_offset += sizeof(srvrtxdata) * gUVSphereMesh.nvertices;
|
||||
free(uvsphere_vertices);
|
||||
|
||||
gUVSphereMesh.nindices =
|
||||
stack_count * sector_count * 3 * 2 - sector_count * 2 * 3;
|
||||
GLuint* uvsphere_indices = calloc(sizeof(GLuint), gUVSphereMesh.nindices);
|
||||
|
||||
gLog("nindices = %d", gUVSphereMesh.nindices);
|
||||
// generate CCW index list of sphere triangles
|
||||
int k1, k2;
|
||||
GLuint tri_index = 0;
|
||||
for (int i = 0; i < stack_count; ++i) {
|
||||
k1 = i * (sector_count + 1); // beginning of current stack
|
||||
k2 = k1 + sector_count + 1; // beginning of next stack
|
||||
|
||||
for (int j = 0; j < sector_count; ++j, ++k1, ++k2) {
|
||||
// 2 triangles per sector excluding first and last stacks
|
||||
// k1 => k2 => k1+1
|
||||
if (i != 0) {
|
||||
uvsphere_indices[++tri_index] = k1;
|
||||
uvsphere_indices[++tri_index] = k2;
|
||||
uvsphere_indices[++tri_index] = k1 + 1;
|
||||
}
|
||||
|
||||
// k1+1 => k2 => k2+1
|
||||
if (i != (stack_count - 1)) {
|
||||
uvsphere_indices[++tri_index] = k1 + 1;
|
||||
uvsphere_indices[++tri_index] = k2;
|
||||
uvsphere_indices[++tri_index] = k2 + 1;
|
||||
}
|
||||
|
||||
gLog("tri_index = %d", tri_index);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < gUVSphereMesh.nindices; i++) {
|
||||
uvsphere_indices[i] +=
|
||||
gCoordFrameMesh.nvertices + gGridMesh.nvertices + gCubeMesh.nvertices;
|
||||
}
|
||||
|
||||
glGenBuffers(1, &gUVSphereMesh.idb_id);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gUVSphereMesh.idb_id);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
sizeof(GLuint) * gUVSphereMesh.nindices,
|
||||
uvsphere_indices,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
free(uvsphere_indices);
|
||||
|
||||
gUVSphereMesh.mode = GL_TRIANGLES;
|
||||
gUVSphereMesh.count = gUVSphereMesh.nindices;
|
||||
|
||||
glBindVertexArray(0);
|
||||
};
|
||||
|
||||
|
@ -668,6 +781,20 @@ void srndr_run_cube_command(const srcmd* cmd) {
|
|||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void srndr_run_sphere_command(const srcmd* cmd) {
|
||||
glBindVertexArray(gCubeMesh.vao_id);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gUVSphereMesh.idb_id);
|
||||
glDrawElements(
|
||||
gUVSphereMesh.mode,
|
||||
gUVSphereMesh.count,
|
||||
GL_UNSIGNED_INT,
|
||||
(void*)0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sview->mFrameBufferId);
|
||||
|
||||
|
@ -675,9 +802,8 @@ void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) {
|
|||
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// glEnable(GL_CULL_FACE);
|
||||
// glCullFace(GL_BACK);
|
||||
|
||||
glUseProgram(gDefaultShader.program_id);
|
||||
GLint view_mat_loc =
|
||||
|
@ -708,6 +834,9 @@ void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) {
|
|||
case SRndrCmdTypeCube:
|
||||
srndr_run_cube_command(cmd);
|
||||
break;
|
||||
case SRndrCmdTypeSphere:
|
||||
srndr_run_sphere_command(cmd);
|
||||
break;
|
||||
default:
|
||||
gLog("Invalid command type %d at index %d", cmd->type, i);
|
||||
break;
|
||||
|
|
|
@ -165,7 +165,7 @@ void DoRender() {
|
|||
simd4x4f view;
|
||||
simd4x4f proj;
|
||||
simd4x4f_translation(&view, 0.1f, 0.1f, -0.5f);
|
||||
simd4f eye = simd4f_create (2.f * sin(gTimer->mCurrentTime), 1.f, 2.f * cos (gTimer->mCurrentTime), 1.f);
|
||||
simd4f eye = simd4f_create (2.f * sin(gTimer->mCurrentTime), sin(gTimer->mCurrentTime * 0.5f), 2.f * cos (gTimer->mCurrentTime), 1.f);
|
||||
simd4x4f_lookat(
|
||||
&view,
|
||||
eye,
|
||||
|
@ -197,10 +197,6 @@ void DoRender() {
|
|||
rcmd.type = SRndrCmdTypeFrame;
|
||||
srcmdbuf_add(gRndrCmds, &rcmd);
|
||||
|
||||
rcmd.type = SRndrCmdTypeGrid;
|
||||
srcmdbuf_add(gRndrCmds, &rcmd);
|
||||
|
||||
|
||||
rcmd.type = SRndrCmdTypeGrid;
|
||||
simd4x4f_translation(&rcmd.mat, 10.f, 0.f, 10.f);
|
||||
srcmdbuf_add(gRndrCmds, &rcmd);
|
||||
|
@ -224,7 +220,7 @@ void DoRender() {
|
|||
srcmdbuf_add(gRndrCmds, &rcmd);
|
||||
|
||||
srcmd_clear(&rcmd);
|
||||
rcmd.type = SRndrCmdTypeCube;
|
||||
rcmd.type = SRndrCmdTypeSphere;
|
||||
srcmdbuf_add(gRndrCmds, &rcmd);
|
||||
|
||||
// Perform the actual render
|
||||
|
|
Loading…
Reference in New Issue