summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattkae <mattkae@protonmail.com>2022-05-01 21:44:04 -0400
committermattkae <mattkae@protonmail.com>2022-05-01 21:44:04 -0400
commit40a924db3664318615a9a3f11ee25c206cb77fe1 (patch)
tree3e4aacb8ea6c1f5fc6aea25dc6f7df489ea6d3dd
parentdfc387644939aada1edb69f8f730e62f116f1ae3 (diff)
Renderer3d basics
-rw-r--r--themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idxbin3404 -> 3400 bytes
-rw-r--r--themes/.cache/clangd/index/LeafParticleRender.h.A0C89D6CC01BA1D6.idxbin2398 -> 2388 bytes
-rw-r--r--themes/.cache/clangd/index/Renderer2d.cpp.DF430723818BC87C.idxbin2676 -> 2676 bytes
-rw-r--r--themes/.cache/clangd/index/Renderer2d.h.F1518A7EF7C2E747.idxbin1856 -> 1858 bytes
-rw-r--r--themes/.cache/clangd/index/Snowflake.cpp.3E4BE700DA4CDAC9.idxbin3612 -> 3608 bytes
-rw-r--r--themes/.cache/clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idxbin2620 -> 2606 bytes
-rw-r--r--themes/.cache/clangd/index/TreeShape.cpp.3271E9D39A039C82.idxbin4654 -> 4650 bytes
-rw-r--r--themes/.cache/clangd/index/TreeShape.h.68863A800A0A4201.idxbin3380 -> 3368 bytes
-rw-r--r--themes/.cache/clangd/index/list.h.94D5DE92B51D5CD7.idxbin0 -> 2590 bytes
-rw-r--r--themes/LeafParticleRender.cpp14
-rw-r--r--themes/LeafParticleRender.h6
-rw-r--r--themes/List.h222
-rw-r--r--themes/Renderer2d.cpp18
-rw-r--r--themes/Renderer2d.h6
-rw-r--r--themes/Renderer2d_Frag.glsl4
-rw-r--r--themes/Renderer2d_Vertex.glsl10
-rw-r--r--themes/Renderer3d.cpp73
-rw-r--r--themes/Renderer3d.h46
-rw-r--r--themes/Snowflake.cpp16
-rw-r--r--themes/Snowflake.h6
-rw-r--r--themes/TreeShape.cpp16
-rw-r--r--themes/TreeShape.h8
-rwxr-xr-xthemes/a.out.wasmbin26539 -> 0 bytes
-rwxr-xr-xthemes/dist/output.wasmbin85845 -> 89344 bytes
-rw-r--r--themes/list.h243
-rw-r--r--themes/main.cpp36
26 files changed, 428 insertions, 296 deletions
diff --git a/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx b/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx
index 6f82b75..1023991 100644
--- a/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx
+++ b/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/LeafParticleRender.h.A0C89D6CC01BA1D6.idx b/themes/.cache/clangd/index/LeafParticleRender.h.A0C89D6CC01BA1D6.idx
index 000789c..6578f1f 100644
--- a/themes/.cache/clangd/index/LeafParticleRender.h.A0C89D6CC01BA1D6.idx
+++ b/themes/.cache/clangd/index/LeafParticleRender.h.A0C89D6CC01BA1D6.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/Renderer2d.cpp.DF430723818BC87C.idx b/themes/.cache/clangd/index/Renderer2d.cpp.DF430723818BC87C.idx
index 85448f2..01bf4da 100644
--- a/themes/.cache/clangd/index/Renderer2d.cpp.DF430723818BC87C.idx
+++ b/themes/.cache/clangd/index/Renderer2d.cpp.DF430723818BC87C.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/Renderer2d.h.F1518A7EF7C2E747.idx b/themes/.cache/clangd/index/Renderer2d.h.F1518A7EF7C2E747.idx
index 99ffa12..d005647 100644
--- a/themes/.cache/clangd/index/Renderer2d.h.F1518A7EF7C2E747.idx
+++ b/themes/.cache/clangd/index/Renderer2d.h.F1518A7EF7C2E747.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/Snowflake.cpp.3E4BE700DA4CDAC9.idx b/themes/.cache/clangd/index/Snowflake.cpp.3E4BE700DA4CDAC9.idx
index ba4783e..16294ae 100644
--- a/themes/.cache/clangd/index/Snowflake.cpp.3E4BE700DA4CDAC9.idx
+++ b/themes/.cache/clangd/index/Snowflake.cpp.3E4BE700DA4CDAC9.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idx b/themes/.cache/clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idx
index 3f61437..2f0ad76 100644
--- a/themes/.cache/clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idx
+++ b/themes/.cache/clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/TreeShape.cpp.3271E9D39A039C82.idx b/themes/.cache/clangd/index/TreeShape.cpp.3271E9D39A039C82.idx
index aa36592..f531d9b 100644
--- a/themes/.cache/clangd/index/TreeShape.cpp.3271E9D39A039C82.idx
+++ b/themes/.cache/clangd/index/TreeShape.cpp.3271E9D39A039C82.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/TreeShape.h.68863A800A0A4201.idx b/themes/.cache/clangd/index/TreeShape.h.68863A800A0A4201.idx
index 39cf36c..dbbe718 100644
--- a/themes/.cache/clangd/index/TreeShape.h.68863A800A0A4201.idx
+++ b/themes/.cache/clangd/index/TreeShape.h.68863A800A0A4201.idx
Binary files differ
diff --git a/themes/.cache/clangd/index/list.h.94D5DE92B51D5CD7.idx b/themes/.cache/clangd/index/list.h.94D5DE92B51D5CD7.idx
new file mode 100644
index 0000000..0133a7f
--- /dev/null
+++ b/themes/.cache/clangd/index/list.h.94D5DE92B51D5CD7.idx
Binary files differ
diff --git a/themes/LeafParticleRender.cpp b/themes/LeafParticleRender.cpp
index 3ab46a0..0c6fbca 100644
--- a/themes/LeafParticleRender.cpp
+++ b/themes/LeafParticleRender.cpp
@@ -9,7 +9,7 @@ const i32 verticesPerLeaf = 6;
const f32 leafRadius = 3.f;
const i32 fallChanceMax = 100;
-inline void updateLeaf(Renderer2dVertex* vertices, Vector2 position, Vector4 color, f32 scale) {
+inline void updateLeaf(Vertex2D* vertices, Vector2 position, Vector4 color, f32 scale) {
f32 radius = scale * leafRadius;
Vector2 bottomLeft = Vector2(-radius, -radius) + position;
Vector2 bottomRight = Vector2(radius, -radius) + position;
@@ -31,7 +31,7 @@ void LeafParticleRender::load(Renderer2d *renderer, TreeShapeLoadResult* lr) {
numVertices = ld.numLeaves * verticesPerLeaf;
updateData = new LeafParticleUpdateData[numLeaves];
- vertices = new Renderer2dVertex[numVertices];
+ vertices = new Vertex2D[numVertices];
for (i32 leafIdx = 0; leafIdx < numLeaves; leafIdx++) {
i32 randomBranch = randomIntBetween(0, lr->numBranches);
@@ -50,17 +50,17 @@ void LeafParticleRender::load(Renderer2d *renderer, TreeShapeLoadResult* lr) {
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Renderer2dVertex), &vertices[0], GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex2D), &vertices[0], GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(renderer->attributes.position);
- glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)0);
+ glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)0);
glEnableVertexAttribArray(renderer->attributes.color);
- glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, color));
+ glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)offsetof(Vertex2D, color));
for (i32 idx = 0; idx < 4; idx++) {
glEnableVertexAttribArray(renderer->attributes.vMatrix + idx);
- glVertexAttribPointer(renderer->attributes.vMatrix + idx, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)(offsetof(Renderer2dVertex, vMatrix) + (idx * 16)));
+ glVertexAttribPointer(renderer->attributes.vMatrix + idx, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)(offsetof(Vertex2D, vMatrix) + (idx * 16)));
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -150,7 +150,7 @@ void LeafParticleRender::render(Renderer2d *renderer) {
setShaderMat4(renderer->uniforms.model, model);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Renderer2dVertex), &vertices[0]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Vertex2D), &vertices[0]);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
diff --git a/themes/LeafParticleRender.h b/themes/LeafParticleRender.h
index 230cee8..713d9f6 100644
--- a/themes/LeafParticleRender.h
+++ b/themes/LeafParticleRender.h
@@ -20,7 +20,7 @@ enum LeafParticleState {
struct LeafParticleUpdateData {
LeafParticleState state = LeafParticleState::Remerging;
- Renderer2dVertex* vertexToFollow = NULL;
+ Vertex2D* vertexToFollow = NULL;
Vector4 color = Vector4(1.f, 0.f, 0.f, 0.f);
f32 scale = 1.f;
@@ -32,7 +32,7 @@ struct LeafParticleUpdateData {
f32 resetTime = 0.f;
- Renderer2dVertex* vertexPtr = NULL;
+ Vertex2D* vertexPtr = NULL;
};
struct LeafParticleRender {
@@ -43,7 +43,7 @@ struct LeafParticleRender {
i32 numLeaves = 0;
LeafParticleUpdateData* updateData = NULL;
- Renderer2dVertex* vertices = NULL;
+ Vertex2D* vertices = NULL;
// Render data
u32 vao;
diff --git a/themes/List.h b/themes/List.h
deleted file mode 100644
index 00a466a..0000000
--- a/themes/List.h
+++ /dev/null
@@ -1,222 +0,0 @@
-#pragma once
-#include <cstdlib>
-#include <cstring>
-#include "Logger.h"
-
-#define FOREACH(list) \
- for (size_t idx = 0; idx < list.numElements; idx++) \
- if (auto value = list.getValue(idx)) \
-
-
-template <typename T>
-struct List {
- T* data = nullptr;
- size_t capacity = 0;
- size_t numElements = 0;
- bool growDynamically = true;
-
- void allocate(size_t size);
- void add(T* element);
- void add(T& element);
- void add(T&& element);
- bool grow(size_t newSize);
- void set(T* value, size_t index);
- void remove(size_t index);
- void clear();
- void deallocate();
- bool isEmpty() {
- return data == nullptr || numElements == 0;
- }
- T* getValue(int index) const;
- T& operator[](int idx) const;
- void binarySort(int (*f)(T *first, T* second));
- void setFromArray(T* arry, int size) {
- allocate(size);
- memcpy(data, arry, size * sizeof(T));
- numElements = size;
- }
- void remove(int index) {
- if (index >= numElements) {
- logger_error("Cannot remove element at index: %d", index);
- return;
- }
-
-
- if (index == numElements - 1) {
- numElements--;
- return;
- }
-
- memmove(data[index], data[index + 1], sizeof(T) * (numElements - index));
- numElements--;
- }
-};
-
-template <typename T>
-void List<T>::allocate(size_t size) {
- if (size == 0 || size == capacity) {
- numElements = 0;
- return;
- }
-
- if (data != nullptr) {
- deallocate();
- }
-
- data = static_cast<T*>(malloc(sizeof(T) * size));
- capacity = size;
- numElements = 0;
-}
-
-template <typename T>
-bool List<T>::grow(size_t newSize) {
- if (!growDynamically) {
- return false;
- }
-
- if (newSize == 0) {
- return false;
- }
-
- T* newData = static_cast<T*>(malloc(sizeof(T) * newSize));
-
- if (data != nullptr) {
- memcpy(newData, data, numElements * sizeof(T));
- delete data;
- }
-
- data = newData;
- capacity = newSize;
- return true;
-}
-
-template <typename T>
-void List<T>::set(T* value, size_t index) {
- if (index >= capacity && !grow(index * 2)) {
- return;
- }
-
- memcpy(&data[index], value, sizeof(T));
-}
-
-template <typename T>
-void List<T>::add(T* element) {
- if (data == nullptr) {
- allocate(2);
- }
-
- if (element == nullptr) {
- logger_error("Element not defined");
- return;
- }
-
- size_t newNumElements = numElements + 1;
- if (newNumElements > capacity) {
- if (!grow(2 * capacity)) {
- logger_error("Trying to add to list but unable to grow the array");
- return;
- }
- }
-
- memcpy(&data[numElements], element, sizeof(T));
- numElements = newNumElements;
-}
-
-template <typename T>
-void List<T>::add(T& element) {
- if (data == nullptr) {
- allocate(2);
- }
-
- size_t newNumElements = numElements + 1;
- if (newNumElements > capacity) {
- if (!grow(2 * capacity)) {
- logger_error("Trying to add to list but unable to grow the array");
- return;
- }
- }
-
- memcpy(&data[numElements], &element, sizeof(T));
- numElements = newNumElements;
-}
-
-template <typename T>
-void List<T>::add(T&& element) {
- if (data == nullptr) {
- allocate(2);
- }
-
- size_t newNumElements = numElements + 1;
- if (newNumElements > capacity) {
- if (!grow(2 * capacity)) {
- logger_error("Trying to add to list but unable to grow the array");
- return;
- }
- }
-
- memcpy(&data[numElements], &element, sizeof(T));
- numElements = newNumElements;
-}
-
-template <typename T>
-void List<T>::remove(size_t idx) {
- if (idx >= numElements) {
- logger_error("Index is outside of the list: %d >= %d", idx, numElements);
- return;
- }
-
- for (; idx < numElements - 1; idx++) {
- data[idx] = data[idx + 1];
- }
-
- numElements--;
-}
-
-template <typename T>
-void List<T>::deallocate() {
- if (data != nullptr) {
- free(data);
- data = nullptr;
- }
-
- capacity = 0;
- numElements = 0;
-}
-
-template <typename T>
-void List<T>::clear() {
- numElements = 0;
-}
-
-template <typename T>
-T* List<T>::getValue(int idx) const {
- return &data[idx];
-}
-
-template <typename T>
-T& List<T>::operator[](int idx) const {
- return data[idx];
-}
-
-template <typename T>
-void List<T>::binarySort(int (*f)(T *first, T* second)) {
- if (data == nullptr) {
- return;
- }
-
- for (size_t idx = 0; idx < numElements - 1; idx++) {
- int minIdx = idx;
- T firstValue = data[idx];
-
- for (int innerIdx = idx + 1; innerIdx < numElements; innerIdx++) {\
- T secondValue = data[innerIdx];
- if (f(&firstValue, &secondValue) > 0) {
- minIdx= innerIdx;
- }
- }
-
- T temp = data[minIdx];
- memmove(&data[minIdx], &data[idx], sizeof(T));
- memmove(&data[idx], &temp, sizeof(T));
- }
-}
diff --git a/themes/Renderer2d.cpp b/themes/Renderer2d.cpp
index 8c1af63..0d4eca2 100644
--- a/themes/Renderer2d.cpp
+++ b/themes/Renderer2d.cpp
@@ -6,7 +6,7 @@
// Note: In the 'transform' attribute, the transform.x is the scale,
// transform.y is the rotation, and transform.zw is the translatiob.
-const char* renderer2dVertexShader =
+const char* Vertex2DShader =
"attribute vec2 position; \n"
"attribute vec4 color; \n"
"attribute mat4 vMatrix; \n"
@@ -40,7 +40,7 @@ EM_BOOL onScreenSizeChanged(int eventType, const EmscriptenUiEvent *uiEvent, voi
void Renderer2d::load(WebglContext* inContext) {
context = inContext;
printf("Compiling Renderer2d shader...\n");
- shader = loadShader(renderer2dVertexShader, renderer2dFragmentShader);
+ shader = loadShader(Vertex2DShader, renderer2dFragmentShader);
useShader(shader);
attributes.position = getShaderAttribute(shader, "position");
@@ -75,7 +75,7 @@ void Renderer2d::unload() {
}
-void Renderer2dShape::load(Renderer2dVertex* inVertices, u32 inNumVertices, Renderer2d* renderer) {
+void Mesh2D::load(Vertex2D* inVertices, u32 inNumVertices, Renderer2d* renderer) {
numVertices = inNumVertices;
useShader(renderer->shader);
@@ -84,24 +84,24 @@ void Renderer2dShape::load(Renderer2dVertex* inVertices, u32 inNumVertices, Rend
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, inNumVertices * sizeof(Renderer2dVertex), &inVertices[0], GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, inNumVertices * sizeof(Vertex2D), &inVertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(renderer->attributes.position);
- glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)0);
+ glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)0);
glEnableVertexAttribArray(renderer->attributes.color);
- glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, color));
+ glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)offsetof(Vertex2D, color));
for (i32 idx = 0; idx < 4; idx++) {
glEnableVertexAttribArray(renderer->attributes.vMatrix + idx);
- glVertexAttribPointer(renderer->attributes.vMatrix + idx, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)(offsetof(Renderer2dVertex, vMatrix) + (idx * 16)));
+ glVertexAttribPointer(renderer->attributes.vMatrix + idx, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)(offsetof(Vertex2D, vMatrix) + (idx * 16)));
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
-void Renderer2dShape::render(Renderer2d* renderer, GLenum drawType) {
+void Mesh2D::render(Renderer2d* renderer, GLenum drawType) {
setShaderMat4(renderer->uniforms.model, model);
glBindVertexArray(vao);
@@ -109,7 +109,7 @@ void Renderer2dShape::render(Renderer2d* renderer, GLenum drawType) {
glBindVertexArray(0);
}
-void Renderer2dShape::unload() {
+void Mesh2D::unload() {
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
}
diff --git a/themes/Renderer2d.h b/themes/Renderer2d.h
index 30769db..82af673 100644
--- a/themes/Renderer2d.h
+++ b/themes/Renderer2d.h
@@ -29,19 +29,19 @@ struct Renderer2d {
void unload();
};
-struct Renderer2dVertex {
+struct Vertex2D {
Vector2 position;
Vector4 color;
Mat4x4 vMatrix;
};
-struct Renderer2dShape {
+struct Mesh2D {
u32 vao;
u32 vbo;
u32 numVertices = 0;
Mat4x4 model;
- void load(Renderer2dVertex* vertices, u32 numVertices, Renderer2d* renderer);
+ void load(Vertex2D* vertices, u32 numVertices, Renderer2d* renderer);
void render(Renderer2d* renderer, GLenum drawType = GL_TRIANGLES);
void unload();
};
diff --git a/themes/Renderer2d_Frag.glsl b/themes/Renderer2d_Frag.glsl
deleted file mode 100644
index c50e626..0000000
--- a/themes/Renderer2d_Frag.glsl
+++ /dev/null
@@ -1,4 +0,0 @@
-varying lowp vec4 VertexColor;
-void main() {
- gl_FragColor = VertexColor;
-}; \ No newline at end of file
diff --git a/themes/Renderer2d_Vertex.glsl b/themes/Renderer2d_Vertex.glsl
deleted file mode 100644
index f3ab653..0000000
--- a/themes/Renderer2d_Vertex.glsl
+++ /dev/null
@@ -1,10 +0,0 @@
-attribute vec2 position;
-attribute vec4 color;
-uniform mat4 projection;
-uniform mat4 model;
-varying lowp vec4 VertexColor;
-void main() {
- vec4 fragmentPosition = projection * model * vec4(position, 1, 1);
- gl_Position = fragmentPosition;
- VertexColor = color;
-}; \ No newline at end of file
diff --git a/themes/Renderer3d.cpp b/themes/Renderer3d.cpp
new file mode 100644
index 0000000..0106f10
--- /dev/null
+++ b/themes/Renderer3d.cpp
@@ -0,0 +1,73 @@
+#include "Renderer3d.h"
+#include "Shader.h"
+#include "mathlib.h"
+#include "WebglContext.h"
+#include "Logger.h"
+
+// Note: In the 'transform' attribute, the transform.x is the scale,
+// transform.y is the rotation, and transform.zw is the translatiob.
+const char* vertexShader =
+"attribute vec4 position; \n"
+"attribute vec4 color; \n"
+"uniform mat4 projection; \n"
+"uniform mat4 model; \n"
+"varying lowp vec4 VertexColor; \n"
+"void main() { \n"
+" vec4 fragmentPosition = projection * model * position; \n"
+" gl_Position = fragmentPosition; \n"
+" VertexColor = color; \n"
+"}";
+
+const char* fragmentShader =
+"varying lowp vec4 VertexColor; \n"
+"void main() { \n"
+" gl_FragColor = VertexColor; \n"
+"}";
+
+EM_BOOL onScreenSizeChanged_3D(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) {
+ Renderer3D* renderer = (Renderer3D*)userData;
+
+ EMSCRIPTEN_RESULT result = emscripten_set_canvas_element_size( renderer->context->query, uiEvent->documentBodyClientWidth, uiEvent->documentBodyClientHeight);
+ if (result != EMSCRIPTEN_RESULT_SUCCESS) {
+ logger_error("Failed to resize element at query: %s\n", renderer->context->query);
+ }
+ //renderer->projection = Mat4x4().getOrthographicMatrix(0, renderer->context->width, 0, renderer->context->height);
+
+ return true;
+}
+
+void Renderer3D::load(WebglContext* inContext) {
+ context = inContext;
+ printf("Compiling Renderer2d shader...\n");
+ shader = loadShader(vertexShader, fragmentShader);
+
+ useShader(shader);
+ attributes.position = getShaderAttribute(shader, "position");
+ attributes.color = getShaderAttribute(shader, "color");
+ uniforms.projection = getShaderUniform(shader, "projection");
+ 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));
+
+ logger_info("Renderer2d shader compiled.\n");
+
+ emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, onScreenSizeChanged_3D);
+}
+
+void Renderer3D::render() {
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glDepthMask(GL_TRUE);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
+ glClearDepth(1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ useShader(shader);
+ setShaderMat4(uniforms.projection, projection);
+}
+
+void Renderer3D::unload() {
+ glClearColor(0.f, 0.f, 0.f, 0.f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDeleteProgram(shader);
+}
diff --git a/themes/Renderer3d.h b/themes/Renderer3d.h
new file mode 100644
index 0000000..add41d7
--- /dev/null
+++ b/themes/Renderer3d.h
@@ -0,0 +1,46 @@
+#ifndef RENDERER3D_H
+#define RENDERER3D_H
+#include "mathlib.h"
+#include "list.h"
+#include "types.h"
+#include <string>
+
+struct Vertex3d {
+ Vector4 position;
+ Vector4 color;
+};
+
+struct Mesh3d {
+ u32 vao;
+ u32 vbo;
+ u32 ebo;
+ matte::List<Vertex3d> vertices;
+ matte::List<u32> indices;
+ Mat4x4 model;
+};
+
+struct WebglContext;
+struct Renderer3D {
+ WebglContext* context = NULL;
+ Mat4x4 projection;
+ u32 shader;
+ Vector4 clearColor;
+
+ struct {
+ i32 position;
+ i32 color;
+ } attributes;
+
+ struct {
+ i32 projection;
+ i32 model;
+ } uniforms;
+
+ void load(WebglContext* context);
+ void render();
+ void unload();
+};
+
+Mesh3d Mesh3d_fromObj(std::string content);
+
+#endif \ No newline at end of file
diff --git a/themes/Snowflake.cpp b/themes/Snowflake.cpp
index 7379ba3..1e1e648 100644
--- a/themes/Snowflake.cpp
+++ b/themes/Snowflake.cpp
@@ -1,11 +1,11 @@
#include "Snowflake.h"
#include "Renderer2d.h"
#include "mathlib.h"
-#include "List.h"
+#include "list.h"
const Vector4 snowColor = Vector4(1.0, 0.98, 0.98, 1);
-inline void generateSnowflakeShape(List<Renderer2dVertex>* vertices, i32 numArms, f32 radius, f32 innerRadius) {
+inline void generateSnowflakeShape(matte::List<Vertex2D>* vertices, i32 numArms, f32 radius, f32 innerRadius) {
f32 dx = ((2 * PI) / numArms) / 3.0;
for (i32 centerIdx = 0; centerIdx < (3 * numArms); centerIdx+=3) {
f32 degreeStart = dx * centerIdx;
@@ -83,13 +83,13 @@ void SnowflakeParticleRenderer::load(SnowflakeLoadParameters params, Renderer2d*
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, vertices.numElements * sizeof(Renderer2dVertex), &vertices.data[0], GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, vertices.numElements * sizeof(Vertex2D), &vertices.data[0], GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(renderer->attributes.position);
- glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)0);
+ glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)0);
glEnableVertexAttribArray(renderer->attributes.color);
- glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, color));
+ glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)offsetof(Vertex2D, color));
for (i32 idx = 0; idx < 4; idx++) {
i32 offset = (4 * sizeof(f32)) * idx;
@@ -98,8 +98,8 @@ void SnowflakeParticleRenderer::load(SnowflakeLoadParameters params, Renderer2d*
4,
GL_FLOAT,
GL_FALSE,
- sizeof(Renderer2dVertex),
- (GLvoid *)(offsetof(Renderer2dVertex, vMatrix) + offset));
+ sizeof(Vertex2D),
+ (GLvoid *)(offsetof(Vertex2D, vMatrix) + offset));
//glVertexAttribDivisor(renderer->attributes.vMatrix + idx, 1);
}
@@ -169,7 +169,7 @@ void SnowflakeParticleRenderer::render(Renderer2d* renderer) {
setShaderMat4(renderer->uniforms.model, model);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Renderer2dVertex), &vertices.data[startVertex->vtxIdx]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Vertex2D), &vertices.data[startVertex->vtxIdx]);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
diff --git a/themes/Snowflake.h b/themes/Snowflake.h
index 6e0934e..248034c 100644
--- a/themes/Snowflake.h
+++ b/themes/Snowflake.h
@@ -1,9 +1,9 @@
#include "types.h"
#include "mathlib.h"
-#include "List.h"
+#include "list.h"
struct Renderer2d;
-struct Renderer2dVertex;
+struct Vertex2D;
struct SnowflakeLoadParameters {
i32 maxSnowflakes = 1000;
@@ -45,7 +45,7 @@ struct SnowflakeParticleRenderer {
u32 vao;
u32 vbo;
Mat4x4 model;
- List<Renderer2dVertex> vertices;
+ matte::List<Vertex2D> vertices;
void load(SnowflakeLoadParameters params, Renderer2d* renderer);
void update(f32 dtSeconds);
diff --git a/themes/TreeShape.cpp b/themes/TreeShape.cpp
index dfbf875..a3ae8f7 100644
--- a/themes/TreeShape.cpp
+++ b/themes/TreeShape.cpp
@@ -5,7 +5,7 @@
#include <cfloat>
#include <ctime>
-void TreeBranchLoadData::fillVertices(Renderer2dVertex* vertices, int branchTier) {
+void TreeBranchLoadData::fillVertices(Vertex2D* vertices, int branchTier) {
bottomLeft = Vector2 { position.x - width / 2.f, position.y }.rotateAround(rotation, position);
bottomRight = Vector2 { position.x + width / 2.f, position.y }.rotateAround(rotation, position);
topLeft = (Vector2 { position.x - width / 2.f, position.y + height }).rotateAround(rotation, position);
@@ -33,7 +33,7 @@ TreeShapeLoadResult TreeShape::load(Renderer2d* renderer) {
TreeBranchLoadData* generationData = new TreeBranchLoadData[numBranches];
updateData = new TreeBranchUpdateData[numBranches];
- vertices = new Renderer2dVertex[numVertices];
+ vertices = new Vertex2D[numVertices];
// The load result will contain information that we can pass on to our leaf renderer.
TreeShapeLoadResult lr;
@@ -51,17 +51,17 @@ TreeShapeLoadResult TreeShape::load(Renderer2d* renderer) {
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Renderer2dVertex), &vertices[0], GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(Vertex2D), &vertices[0], GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(renderer->attributes.position);
- glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)0);
+ glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)0);
glEnableVertexAttribArray(renderer->attributes.color);
- glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, color));
+ glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)offsetof(Vertex2D, color));
for (i32 idx = 0; idx < 4; idx++) {
glEnableVertexAttribArray(renderer->attributes.vMatrix + idx);
- glVertexAttribPointer(renderer->attributes.vMatrix + idx, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)(offsetof(Renderer2dVertex, vMatrix) + (idx * 16)));
+ glVertexAttribPointer(renderer->attributes.vMatrix + idx, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (GLvoid *)(offsetof(Vertex2D, vMatrix) + (idx * 16)));
glVertexAttribDivisor(renderer->attributes.vMatrix + idx, 1);
}
@@ -77,7 +77,7 @@ const f32 ninetyDegreeRotation = PI / 2.f;
void TreeShape::createBranch(TreeLoadData* ld, TreeBranchLoadData* generationData, i32 numBranches, i32* branchIndex,
i32 branchLevel, f32 width, f32 height, Vector2 position, f32 rotation,
- TreeBranchUpdateData* parent, Renderer2dVertex* vertices, TreeShapeLoadResult* lr) {
+ TreeBranchUpdateData* parent, Vertex2D* vertices, TreeShapeLoadResult* lr) {
TreeBranchLoadData* branchLoadData = &generationData[*branchIndex];
branchLoadData->width = width;
branchLoadData->height = height;
@@ -196,7 +196,7 @@ void TreeShape::render(Renderer2d* renderer) {
setShaderMat4(renderer->uniforms.model, model);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Renderer2dVertex), &vertices[0]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Vertex2D), &vertices[0]);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
diff --git a/themes/TreeShape.h b/themes/TreeShape.h
index 49ea083..32b00d3 100644
--- a/themes/TreeShape.h
+++ b/themes/TreeShape.h
@@ -27,7 +27,7 @@ struct TreeBranchLoadData {
Vector2 topRight;
Vector2 topMidpoint;
- void fillVertices(Renderer2dVertex* vertices, int branchTier);
+ void fillVertices(Vertex2D* vertices, int branchTier);
};
struct TreeBranchUpdateData {
@@ -36,7 +36,7 @@ struct TreeBranchUpdateData {
f32 period = 0;
f32 amplitude = 0;
Vector2 currentOffset;
- Renderer2dVertex* vertices = NULL;
+ Vertex2D* vertices = NULL;
TreeBranchUpdateData* branchToFollow = NULL;
};
@@ -51,7 +51,7 @@ struct TreeShapeLoadResult {
struct TreeShape {
// Update data
TreeBranchUpdateData* updateData = NULL;
- Renderer2dVertex* vertices = NULL;
+ Vertex2D* vertices = NULL;
f32 timeElapsedSeconds = 0.f;
f32 animateTimePerTier = 1.f;
f32 animateStaggerPerTier = 0.2f;
@@ -66,7 +66,7 @@ struct TreeShape {
TreeShapeLoadResult load(Renderer2d* renderer);
void createBranch(TreeLoadData* ld, TreeBranchLoadData* branchList, i32 numBranches,
i32* branchIndex, i32 branchLevel, f32 width, f32 height,
- Vector2 position, f32 rotation, TreeBranchUpdateData* parent, Renderer2dVertex* vertices, TreeShapeLoadResult* lr);
+ Vector2 position, f32 rotation, TreeBranchUpdateData* parent, Vertex2D* vertices, TreeShapeLoadResult* lr);
void update(f32 dtSeconds);
void render(Renderer2d* renderer);
void unload();
diff --git a/themes/a.out.wasm b/themes/a.out.wasm
deleted file mode 100755
index 83398bf..0000000
--- a/themes/a.out.wasm
+++ /dev/null
Binary files differ
diff --git a/themes/dist/output.wasm b/themes/dist/output.wasm
index bf3e6ba..1c12a60 100755
--- a/themes/dist/output.wasm
+++ b/themes/dist/output.wasm
Binary files differ
diff --git a/themes/list.h b/themes/list.h
new file mode 100644
index 0000000..0c5b0a1
--- /dev/null
+++ b/themes/list.h
@@ -0,0 +1,243 @@
+#pragma once
+#include <cstdlib>
+#include <cstring>
+#include "Logger.h"
+
+#define FOREACH(list) \
+ for (i32 idx = 0; idx < list.numElements; idx++) \
+ if (auto value = &list[idx]) \
+
+namespace matte {
+ template <typename T>
+ struct List {
+ T* data = nullptr;
+ size_t capacity = 0;
+ size_t numElements = 0;
+ bool growDynamically = true;
+
+ void allocate(size_t size);
+ void add(T& element);
+ void add(T&& element);
+ void add(T* element);
+ bool grow(size_t newSize);
+ void set(T& value, size_t index);
+ void set(T&& value, size_t index);
+ void set(T* value, size_t index);
+ void remove(size_t index);
+ void clear();
+ void deallocate();
+ bool isEmpty() {
+ return data == nullptr || numElements == 0;
+ }
+ T& getValue(int index) const;
+ T& operator[](int idx) const;
+ void binarySort(int (*f)(const T& first, const T& second));
+ void setFromArray(T* arry, int size) {
+ allocate(size);
+ memcpy(data, arry, size * sizeof(T));
+ numElements = size;
+ }
+ void remove(int index) {
+ if (index >= numElements) {
+ logger_error("Cannot remove element at index: %d", index);
+ return;
+ }
+
+
+ if (index == numElements - 1) {
+ numElements--;
+ return;
+ }
+
+ memmove(&data[index], &data[index + 1], sizeof(T) * (numElements - index));
+ numElements--;
+ }
+ };
+
+ template <typename T>
+ void List<T>::allocate(size_t size) {
+ if (size == 0 || size == capacity) {
+ numElements = 0;
+ return;
+ }
+
+ if (data != nullptr) {
+ deallocate();
+ }
+
+ data = static_cast<T*>(malloc(sizeof(T) * size));
+ capacity = size;
+ numElements = 0;
+ }
+
+ template <typename T>
+ bool List<T>::grow(size_t newSize) {
+ if (!growDynamically) {
+ return false;
+ }
+
+ if (newSize == 0) {
+ return false;
+ }
+
+ T* newData = static_cast<T*>(malloc(sizeof(T) * newSize));
+
+ if (data != nullptr) {
+ memcpy(newData, data, numElements * sizeof(T));
+ delete data;
+ }
+
+ data = newData;
+ capacity = newSize;
+ return true;
+ }
+
+ template <typename T>
+ void List<T>::set(T& value, size_t index) {
+ if (index >= capacity && !grow(index * 2)) {
+ return;
+ }
+
+ memcpy(&data[index], value, sizeof(T));
+ }
+
+ template <typename T>
+ void List<T>::set(T&& value, size_t index) {
+ if (index >= capacity && !grow(index * 2)) {
+ return;
+ }
+
+ data[index] = value;
+ }
+
+ template <typename T>
+ void List<T>::set(T* value, size_t index) {
+ if (index >= capacity && !grow(index * 2)) {
+ return;
+ }
+
+ memcpy(&data[index], value, sizeof(T));
+ }
+
+ template <typename T>
+ void List<T>::add(T* element) {
+ if (data == nullptr) {
+ allocate(2);
+ }
+
+ if (element == nullptr) {
+ logger_error("Element not defined");
+ return;
+ }
+
+ size_t newNumElements = numElements + 1;
+ if (newNumElements > capacity) {
+ if (!grow(2 * capacity)) {
+ logger_error("Trying to add to list but unable to grow the array");
+ return;
+ }
+ }
+
+ memcpy(&data[numElements], element, sizeof(T));
+ numElements = newNumElements;
+ }
+
+ template <typename T>
+ void List<T>::add(T& element) {
+ if (data == nullptr) {
+ allocate(2);
+ }
+
+ size_t newNumElements = numElements + 1;
+ if (newNumElements > capacity) {
+ if (!grow(2 * capacity)) {
+ logger_error("Trying to add to list but unable to grow the array");
+ return;
+ }
+ }
+
+ memcpy(&data[numElements], &element, sizeof(T));
+ numElements = newNumElements;
+ }
+
+ template <typename T>
+ void List<T>::add(T&& element) {
+ if (data == nullptr) {
+ allocate(2);
+ }
+
+ size_t newNumElements = numElements + 1;
+ if (newNumElements > capacity) {
+ if (!grow(2 * capacity)) {
+ logger_error("Trying to add to list but unable to grow the array");
+ return;
+ }
+ }
+
+ memcpy(&data[numElements], &element, sizeof(T));
+ numElements = newNumElements;
+ }
+
+ template <typename T>
+ void List<T>::remove(size_t idx) {
+ if (idx >= numElements) {
+ logger_error("Index is outside of the list: %d >= %d", idx, numElements);
+ return;
+ }
+
+ for (; idx < numElements - 1; idx++) {
+ data[idx] = data[idx + 1];
+ }
+
+ numElements--;
+ }
+
+ template <typename T>
+ void List<T>::deallocate() {
+ if (data != nullptr) {
+ free(data);
+ data = nullptr;
+ }
+
+ capacity = 0;
+ numElements = 0;
+ }
+
+ template <typename T>
+ void List<T>::clear() {
+ numElements = 0;
+ }
+
+ template <typename T>
+ T& List<T>::getValue(int idx) const {
+ return data[idx];
+ }
+
+ template <typename T>
+ T& List<T>::operator[](int idx) const {
+ return data[idx];
+ }
+
+ template <typename T>
+ void List<T>::binarySort(int (*f)(const T& first, const T& second)) {
+ if (data == nullptr) {
+ return;
+ }
+
+ for (size_t idx = 0; idx < numElements - 1; idx++) {
+ int minIdx = idx;
+ T firstValue = data[idx];
+
+ for (int innerIdx = idx + 1; innerIdx < numElements; innerIdx++) {\
+ T secondValue = data[innerIdx];
+ if (f(data[idx], data[innerIdx]) > 0) {
+ minIdx= innerIdx;
+ }
+ }
+
+ T temp = data[minIdx];
+ memmove(&data[minIdx], &data[idx], sizeof(T));
+ memmove(&data[idx], &temp, sizeof(T));
+ }
+ }
+} \ No newline at end of file
diff --git a/themes/main.cpp b/themes/main.cpp
index ad78f31..d3966af 100644
--- a/themes/main.cpp
+++ b/themes/main.cpp
@@ -1,7 +1,7 @@
-#include "Renderer2d.h"
#include "WebglContext.h"
#include "MainLoop.h"
#include "Renderer2d.h"
+#include "Renderer3d.h"
#include "types.h"
#include "TreeShape.h"
#include "LeafParticleRender.h"
@@ -37,9 +37,9 @@ struct WinterTheme {
};
struct SpringTheme {
- void load(Renderer2d* renderer);
+ void load(Renderer3D* renderer);
void update(f32 dtSeconds);
- void render(Renderer2d* renderer);
+ void render(Renderer3D* renderer);
void unload();
};
@@ -52,7 +52,8 @@ EM_BOOL selectWinter(int eventType, const EmscriptenMouseEvent* mouseEvent, void
EM_BOOL selectSpring(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
WebglContext context;
-Renderer2d renderer;
+Renderer2d renderer2d;
+Renderer3D renderer3d;
MainLoop mainLoop;
Theme activeTheme = Theme::Default;
AutumnTheme autumnTheme;
@@ -79,18 +80,20 @@ void load(Theme theme) {
unload(); // Try and unload before we load, so that we start fresh
activeTheme = theme;
- renderer.load(&context);
mainLoop.run(update);
switch (activeTheme) {
case Theme::Autumn:
- autumnTheme.load(&renderer);
+ renderer2d.load(&context);
+ autumnTheme.load(&renderer2d);
break;
case Theme::Winter:
- winterTheme.load(&renderer);
+ renderer2d.load(&context);
+ winterTheme.load(&renderer2d);
break;
case Theme::Spring:
- springTheme.load(&renderer);
+ renderer3d.load(&context);
+ springTheme.load(&renderer3d);
break;
default:
break;
@@ -114,16 +117,18 @@ void update(f32 dtSeconds, void* userData) {
}
// -- Render
- renderer.render();
switch (activeTheme) {
case Theme::Autumn:
- autumnTheme.render(&renderer);
+ renderer2d.render();
+ autumnTheme.render(&renderer2d);
break;
case Theme::Winter:
- winterTheme.render(&renderer);
+ renderer2d.render();
+ winterTheme.render(&renderer2d);
break;
case Theme::Spring:
- springTheme.render(&renderer);
+ renderer3d.render();
+ springTheme.render(&renderer3d);
break;
default:
break;
@@ -148,7 +153,8 @@ void unload() {
activeTheme = Theme::Default;
if (mainLoop.isRunning) {
mainLoop.stop();
- renderer.unload();
+ renderer2d.unload();
+ renderer3d.unload();
}
}
@@ -231,7 +237,7 @@ void onBunnyFail(emscripten_fetch_t *fetch) {
emscripten_fetch_close(fetch); // Also free data on failure.
}
-void SpringTheme::load(Renderer2d* renderer) {
+void SpringTheme::load(Renderer3D* renderer) {
renderer->clearColor = Vector4(160, 231, 160, 255.f).toNormalizedColor();
emscripten_fetch_attr_t attr;
@@ -246,7 +252,7 @@ void SpringTheme::load(Renderer2d* renderer) {
void SpringTheme::update(f32 dtSeconds) {
}
-void SpringTheme::render(Renderer2d* renderer) {
+void SpringTheme::render(Renderer3D* renderer) {
}
void SpringTheme::unload() {