Fixed uv sphere generation.

master
Martin Felis 2020-10-31 22:40:51 +01:00
parent 1ef48039b5
commit cd1130afd3
2 changed files with 59 additions and 54 deletions

View File

@ -321,6 +321,7 @@ void init_debug_meshes() {
GL_FALSE,
(sizeof(srvrtxdata)),
(void*)(sizeof(float) * 7));
// Attribute 3: color
glEnableVertexAttribArray(3);
glVertexAttribPointer(
@ -377,7 +378,8 @@ void init_debug_meshes() {
srvrtxdata grid_vertices[44];
srvrtxdata grid_def_vertex =
{0.f, 0.f, 0.f, 1.f, 0.f, 1.f, 0.f, 0.f, 0.f, 255, 255, 255, 255};
// lines along parallel to x axis
// lines along parallel to z axis
for (int i = 0; i <= 10; i++) {
memcpy(&grid_vertices[2 * i], &grid_def_vertex, sizeof(srvrtxdata));
memcpy(&grid_vertices[2 * i + 1], &grid_def_vertex, sizeof(srvrtxdata));
@ -385,8 +387,14 @@ void init_debug_meshes() {
grid_vertices[2 * i].pos[2] = 5.0f;
grid_vertices[2 * i + 1].pos[0] = -5.0f + i * 1.0f;
grid_vertices[2 * i + 1].pos[2] = -5.0f;
if (i == 5) {
grid_vertices[2 * i].g = 0;
grid_vertices[2 * i].r = 0;
grid_vertices[2 * i + 1].g = 0;
grid_vertices[2 * i + 1].r = 0;
}
}
// lines parallel to z axis
// lines parallel to x axis
for (int i = 11; i <= 21; i++) {
memcpy(&grid_vertices[2 * i], &grid_def_vertex, sizeof(srvrtxdata));
memcpy(&grid_vertices[2 * i + 1], &grid_def_vertex, sizeof(srvrtxdata));
@ -394,6 +402,13 @@ void init_debug_meshes() {
grid_vertices[2 * i].pos[2] = -5.0f + (i - 11) * 1.0f;
grid_vertices[2 * i + 1].pos[0] = 5.0f;
grid_vertices[2 * i + 1].pos[2] = -5.0f + (i - 11) * 1.0f;
if (i == 16) {
grid_vertices[2 * i].g = 0;
grid_vertices[2 * i].b = 0;
grid_vertices[2 * i + 1].g = 0;
grid_vertices[2 * i + 1].b = 0;
}
}
glBindBuffer(GL_ARRAY_BUFFER, gDebugShapesVBOId);
@ -509,49 +524,44 @@ void init_debug_meshes() {
gUVSphereMesh.vb_id = gDebugShapesVBOId;
// loosely based on http://www.songho.ca/opengl/gl_sphere.html
int stack_count = 14;
int sector_count = 14;
int stack_count = 24;
int sector_count = 24;
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;
float sector_step = 2 * M_PI / sector_count;
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)
int vert_index = 0;
for (int i = 0; i < stack_count + 1; i++) {
float phi = -M_PI * 0.5 + i * stack_step;
float y = sin(phi);
// 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
for (int j = 0; j < sector_count + 1; j++) {
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);
// 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)
srvrtxdata* vertex = &uvsphere_vertices[vert_index++];
vertex->x = x;
vertex->y = y;
vertex->z = z;
vertex->w = 1.f;
vertex->w = 1.0f;
// normalized vertex normal (nx, ny, nz)
vertex->nx = vertex->x;
vertex->ny = vertex->y;
vertex->nz = vertex->z;
vertex->nx = x;
vertex->ny = y;
vertex->nz = z;
// vertex tex coord (s, t) range between [0, 1]
vertex->s = (float)j / sector_count;
vertex->t = (float)i / stack_count;
vertex->s = (theta + M_PI) / (2.f * M_PI);
vertex->t = (phi + M_PI * 0.5) / M_PI;
vertex->r = 228;
vertex->g = 228;
vertex->b = 228;
vertex->r = 192;
vertex->g = 192;
vertex->b = 192;
vertex->a = 255;
}
}
@ -569,31 +579,22 @@ void init_debug_meshes() {
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
int indices_index = 0;
for (int i = 0; i < stack_count; i++) {
GLuint k1 = i * (sector_count + 1);
GLuint k2 = k1 + sector_count + 1;
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 + 1;
uvsphere_indices[++tri_index] = k2;
uvsphere_indices[++tri_index] = k1;
uvsphere_indices[indices_index++] = k1;
uvsphere_indices[indices_index++] = k2 + 1;
uvsphere_indices[indices_index++] = k1 + 1;
}
// k1+1 => k2 => k2+1
if (i != (stack_count - 1)) {
uvsphere_indices[++tri_index] = k2 + 1;
uvsphere_indices[++tri_index] = k2;
uvsphere_indices[++tri_index] = k1 + 1;
if (i != stack_count - 1) {
uvsphere_indices[indices_index++] = k2 + 1;
uvsphere_indices[indices_index++] = k1;
uvsphere_indices[indices_index++] = k2;
}
gLog("tri_index = %d", tri_index);
}
}
@ -612,10 +613,12 @@ void init_debug_meshes() {
free(uvsphere_indices);
gUVSphereMesh.mode = GL_TRIANGLE_STRIP;
gUVSphereMesh.mode = GL_TRIANGLES;
gUVSphereMesh.count = gUVSphereMesh.nindices;
glBindVertexArray(0);
gLog ("Debug Mesh Vertices: %d", dbg_vbuf_offset / sizeof(union srvrtxdata));
};
//
@ -802,8 +805,10 @@ 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);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUseProgram(gDefaultShader.program_id);
GLint view_mat_loc =

View File

@ -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), sin(gTimer->mCurrentTime * 0.5f), 2.f * cos (gTimer->mCurrentTime), 1.f);
simd4f eye = simd4f_create (2.f * sin(gTimer->mCurrentTime), 2 *sin(gTimer->mCurrentTime * 0.5f), 2.f * cos (gTimer->mCurrentTime), 1.f);
simd4x4f_lookat(
&view,
eye,
@ -264,7 +264,7 @@ int main(void) {
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
gWindow = glfwCreateWindow(800, 600, "ProtoT", NULL, NULL);
gWindow = glfwCreateWindow(800, 600, "ViSimir", NULL, NULL);
assert(gWindow != NULL);
glfwMakeContextCurrent(gWindow);
glfwSwapInterval(1);