working rotation and zoom. pan bad
This commit is contained in:
120
src/body.cpp
Normal file
120
src/body.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <cassert>
|
||||
#include <glad/glad.h>
|
||||
#include "util.hpp"
|
||||
#include "body.hpp"
|
||||
#include "shaders.hpp"
|
||||
|
||||
enum class ParserState {
|
||||
PREFIX,
|
||||
VERTEX,
|
||||
FACE,
|
||||
FACE_SKIP,
|
||||
};
|
||||
|
||||
bool load_body(body* out_body, const char* obj_filepath) {
|
||||
array<char> source;
|
||||
if (!read_file(&source, obj_filepath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t num_verts = 0;
|
||||
size_t num_faces = 0;
|
||||
for (int i = 1; i < source.len; i++) {
|
||||
if (source[i] == ' ' && source[i - 1] == 'v') {
|
||||
num_verts++;
|
||||
} else if (source[i] == ' ' && source[i - 1] == 'f') {
|
||||
num_faces++;
|
||||
}
|
||||
}
|
||||
|
||||
array<float> verts = { (float*)malloc(sizeof(float) * num_verts * 3), num_verts * 3 };
|
||||
array<int> faces = { (int*)malloc(sizeof(int) * num_faces * 3), num_faces*3 };
|
||||
|
||||
// Get ready for the parsing loop
|
||||
ParserState state = ParserState::PREFIX;
|
||||
int vert_i = 0;
|
||||
int face_i = 0;
|
||||
int start = 0;
|
||||
|
||||
for (int i = 1; i < source.len; i++) {
|
||||
if (source[i] == '\n') {
|
||||
state = ParserState::PREFIX;
|
||||
continue;
|
||||
}
|
||||
switch (state) {
|
||||
case ParserState::PREFIX:
|
||||
if (source[i - 1] == 'v' && source[i] == ' ') {
|
||||
state = ParserState::VERTEX;
|
||||
start = i + 1;
|
||||
} else if (i > 0 && source[i - 1] == 'f' && source[i] == ' ') {
|
||||
state = ParserState::FACE;
|
||||
start = i + 1;
|
||||
}
|
||||
break;
|
||||
case ParserState::VERTEX:
|
||||
if (source[i] == ' ' || source[i] == '\r' || source[i] == '\n') {
|
||||
verts[vert_i] = atof(&source[start])/1.5;
|
||||
vert_i++;
|
||||
start = i + 1;
|
||||
}
|
||||
break;
|
||||
case ParserState::FACE:
|
||||
if (source[i] == '/') {
|
||||
state = ParserState::FACE_SKIP;
|
||||
faces[face_i] = atoi(&source[start]) - 1;
|
||||
face_i++;
|
||||
}
|
||||
break;
|
||||
case ParserState::FACE_SKIP:
|
||||
if (source[i] == ' ') {
|
||||
state = ParserState::FACE;
|
||||
start = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need a good validation check here. This is a stand in.
|
||||
if (verts.len == 0 || faces.len == 0) {
|
||||
printf(
|
||||
"Obj file appears incomplete or corrupted. Num verts %zu. Num Faces %zu.\n", verts.len, faces.len);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint vao, vbo, ebo;
|
||||
|
||||
glGenVertexArrays(1, &vao);
|
||||
glGenBuffers(1, &vbo);
|
||||
glGenBuffers(1, &ebo);
|
||||
|
||||
glBindVertexArray(vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, verts.len * sizeof(float), verts.data, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces.len * sizeof(int), faces.data, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
*out_body = { .pose = glm::mat4(1),
|
||||
.ebo = ebo,
|
||||
.vao = vao,
|
||||
.vbo = vbo,
|
||||
.shader = 0,
|
||||
.verts = verts,
|
||||
.faces = faces,
|
||||
.color = glm::vec4(0.5, 0.5, 0.5, 1)
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void draw_body(const body& b) {
|
||||
use_shader(b.shader);
|
||||
set_uniform(b.shader, "global_t", b.pose);
|
||||
set_uniform(b.shader, "color", b.color);
|
||||
glBindVertexArray(b.vao);
|
||||
glDrawElements(GL_TRIANGLES, b.faces.len, GL_UNSIGNED_INT, 0);
|
||||
//glDisableVertexAttribArray(0);
|
||||
}
|
||||
Reference in New Issue
Block a user