summaryrefslogtreecommitdiff
path: root/themes/Renderer3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'themes/Renderer3d.cpp')
-rw-r--r--themes/Renderer3d.cpp168
1 files changed, 164 insertions, 4 deletions
diff --git a/themes/Renderer3d.cpp b/themes/Renderer3d.cpp
index ded364d..771d778 100644
--- a/themes/Renderer3d.cpp
+++ b/themes/Renderer3d.cpp
@@ -1,8 +1,10 @@
#include "Renderer3d.h"
#include "Shader.h"
+#include "list.h"
#include "mathlib.h"
#include "WebglContext.h"
#include "Logger.h"
+#include <cstdio>
// Note: In the 'transform' attribute, the transform.x is the scale,
// transform.y is the rotation, and transform.zw is the translatiob.
@@ -10,10 +12,11 @@ const char* vertexShader =
"attribute vec4 position; \n"
"attribute vec4 color; \n"
"uniform mat4 projection; \n"
+"uniform mat4 view; \n"
"uniform mat4 model; \n"
"varying lowp vec4 VertexColor; \n"
"void main() { \n"
-" vec4 fragmentPosition = projection * model * position; \n"
+" vec4 fragmentPosition = projection * view * model * position; \n"
" gl_Position = fragmentPosition; \n"
" VertexColor = color; \n"
"}";
@@ -45,8 +48,10 @@ void Renderer3D::load(WebglContext* inContext) {
attributes.position = getShaderAttribute(shader, "position");
attributes.color = getShaderAttribute(shader, "color");
uniforms.projection = getShaderUniform(shader, "projection");
+ uniforms.view = getShaderUniform(shader, "view");
uniforms.model = getShaderUniform(shader, "model");
- projection = Mat4x4().getPerspectiveProjection(0.1, 100.f, DEG_TO_RAD(60.f), static_cast<f32>(context->width) / static_cast<f32>(context->height));
+ projection = Mat4x4().getPerspectiveProjection(0.1, 1000.f, 0.872f, static_cast<f32>(context->width) / static_cast<f32>(context->height));
+ view = Mat4x4().getLookAt({ 0, 25, 25 }, { 0, 0, 0 }, { 0, 1, 0 });
logger_info("Renderer2d shader compiled.\n");
@@ -64,6 +69,7 @@ void Renderer3D::render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
useShader(shader);
setShaderMat4(uniforms.projection, projection);
+ setShaderMat4(uniforms.view, view);
}
void Renderer3D::unload() {
@@ -72,10 +78,164 @@ void Renderer3D::unload() {
glDeleteProgram(shader);
}
-Mesh3d Mesh3d_fromObj(std::string content) {
+enum LineType {
+ LineType_None,
+ LineType_Comment,
+ LineType_mtl,
+ LineType_v,
+ LineType_f,
+ LineType_Unsupported
+};
+
+struct LineItem {
+ LineType type = LineType_None;
+
+ i32 idx = 0;
+
+ union {
+ f32 vertices[3];
+ i32 indices[3];
+ } v;
+};
+
+inline i32 readPastSpaces(i32 i, const char* content) {
+ while (content[i] == ' ') i++;
+ return i;
+}
+
+inline i32 readPastLine(i32 i, const char* content) {
+ while (content[i] != '\n' && content[i] != '\0') i++;
+ return i;
+}
+
+inline i32 readToken(i32 i, const char* content, char* output) {
+ i32 tidx = 0;
+ i = readPastSpaces(i, content);
+ while (content[i] != ' ' && content[i] != '\n' && content[i] != '\0') {
+ output[tidx] = content[i];
+ i++;
+ tidx++;
+ }
+ output[tidx] = '\0';
+ return i;
+}
+
+Mesh3d Mesh3d_fromObj(Renderer3D* renderer, const char* content, const i32 len) {
Mesh3d result;
+ result.vertices.allocate(2048);
+ result.indices.allocate(2048);
-
+ LineItem lt;
+ lt.type = LineType_None;
+ i32 lineNumber = 0;
+ i32 i = 0;
+ while (content[i] != '\0') {
+ i = readPastSpaces(i, content);
+ if (lt.type == LineType_None) {
+ lineNumber++;
+ char type[32];
+ i = readToken(i, content, type);
+
+ if (strncmp(type, "#", 1) == 0) {
+ lt.type = LineType_Comment;
+ }
+ else if (strncmp(type, "mtllib", 6) == 0) {
+ lt.type = LineType_mtl;
+ }
+ else if (strncmp(type, "v", 1) == 0) {
+ lt.type = LineType_v;
+ }
+ else if (strncmp(type, "f", 1) == 0) {
+ lt.type = LineType_f;
+ }
+ else {
+ i++;
+ //lt.type = LineType_Unsupported;
+ //logger_error("Unknown type %s, %d", type, lineNumber);
+ }
+ }
+ else {
+ char buffer[32];
+ switch (lt.type) {
+ case LineType_mtl:
+ i = readToken(i, content, buffer);
+ break;
+ case LineType_v:
+ while (content[i] != '\n' && content[i] != '\0') {
+ i = readToken(i, content, buffer);
+ lt.v.vertices[lt.idx] = atof(buffer);
+ lt.idx++;
+ }
+ result.vertices.add({
+ Vector4(lt.v.vertices[0], lt.v.vertices[1], lt.v.vertices[2], 1.f),
+ Vector4(randomFloatBetween(0, 1), randomFloatBetween(0, 1), randomFloatBetween(0, 1), 1)
+ });
+ break;
+ case LineType_f:
+ while (content[i] != '\n' && content[i] != '\0') {
+ i = readToken(i, content, buffer);
+ lt.v.indices[lt.idx] = atoi(buffer);
+ lt.idx++;
+ }
+ result.indices.add(lt.v.indices[0] - 1);
+ result.indices.add(lt.v.indices[1] - 1);
+ result.indices.add(lt.v.indices[2] - 1);
+ break;
+ case LineType_Comment:
+ i = readPastLine(i, content);
+ break;
+ case LineType_Unsupported:
+ i = readPastLine(i, content);
+ break;
+ default:
+ break;
+ }
+
+ lt = LineItem();
+ }
+ }
+ printf("Completed Mesh3d loading.\n");
+ result.load(renderer);
return result;
+}
+
+void Mesh3d::load(Renderer3D* renderer) {
+ glGenVertexArrays(1, &vao);
+ glGenBuffers(1, &vbo);
+ glGenBuffers(1, &ebo);
+
+ glBindVertexArray(vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, vertices.numElements * sizeof(Vertex3d), &vertices.data[0], GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.numElements * sizeof(GLuint), &indices.data[0], GL_STATIC_DRAW);
+
+ // Position
+ glEnableVertexAttribArray(renderer->attributes.position);
+ glVertexAttribPointer(renderer->attributes.position, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)0);
+
+ // Normal
+ glEnableVertexAttribArray(renderer->attributes.color);
+ glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)offsetof(Vertex3d, color));
+
+ glBindVertexArray(0);
+}
+
+void Mesh3d::unload() {
+ if (vao) glDeleteVertexArrays(1, &vao);
+ if (vbo) glDeleteBuffers(1, &vbo);
+ if (ebo) glDeleteBuffers(1, &ebo);
+ vertices.deallocate();
+ indices.deallocate();
+}
+
+void Mesh3d::render(Renderer3D* renderer) {
+ setShaderMat4(renderer->uniforms.model, model);
+
+ glBindVertexArray(vao);
+ glDrawElements(GL_TRIANGLES, indices.numElements, GL_UNSIGNED_INT, 0);
+ glBindVertexArray(0);
} \ No newline at end of file