From 40a924db3664318615a9a3f11ee25c206cb77fe1 Mon Sep 17 00:00:00 2001 From: mattkae Date: Sun, 1 May 2022 21:44:04 -0400 Subject: Renderer3d basics --- .../LeafParticleRender.cpp.C2E152FEB0B3916C.idx | Bin 3404 -> 3400 bytes .../LeafParticleRender.h.A0C89D6CC01BA1D6.idx | Bin 2398 -> 2388 bytes .../index/Renderer2d.cpp.DF430723818BC87C.idx | Bin 2676 -> 2676 bytes .../clangd/index/Renderer2d.h.F1518A7EF7C2E747.idx | Bin 1856 -> 1858 bytes .../index/Snowflake.cpp.3E4BE700DA4CDAC9.idx | Bin 3612 -> 3608 bytes .../clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idx | Bin 2620 -> 2606 bytes .../index/TreeShape.cpp.3271E9D39A039C82.idx | Bin 4654 -> 4650 bytes .../clangd/index/TreeShape.h.68863A800A0A4201.idx | Bin 3380 -> 3368 bytes .../clangd/index/list.h.94D5DE92B51D5CD7.idx | Bin 0 -> 2590 bytes themes/LeafParticleRender.cpp | 14 +- themes/LeafParticleRender.h | 6 +- themes/List.h | 222 ------------------- themes/Renderer2d.cpp | 18 +- themes/Renderer2d.h | 6 +- themes/Renderer2d_Frag.glsl | 4 - themes/Renderer2d_Vertex.glsl | 10 - themes/Renderer3d.cpp | 73 +++++++ themes/Renderer3d.h | 46 ++++ themes/Snowflake.cpp | 16 +- themes/Snowflake.h | 6 +- themes/TreeShape.cpp | 16 +- themes/TreeShape.h | 8 +- themes/a.out.wasm | Bin 26539 -> 0 bytes themes/dist/output.wasm | Bin 85845 -> 89344 bytes themes/list.h | 243 +++++++++++++++++++++ themes/main.cpp | 36 +-- 26 files changed, 428 insertions(+), 296 deletions(-) create mode 100644 themes/.cache/clangd/index/list.h.94D5DE92B51D5CD7.idx delete mode 100644 themes/List.h delete mode 100644 themes/Renderer2d_Frag.glsl delete mode 100644 themes/Renderer2d_Vertex.glsl create mode 100644 themes/Renderer3d.cpp create mode 100644 themes/Renderer3d.h delete mode 100755 themes/a.out.wasm create mode 100644 themes/list.h (limited to 'themes') diff --git a/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx b/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx index 6f82b75..1023991 100644 Binary files a/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx and b/themes/.cache/clangd/index/LeafParticleRender.cpp.C2E152FEB0B3916C.idx 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 Binary files a/themes/.cache/clangd/index/LeafParticleRender.h.A0C89D6CC01BA1D6.idx and b/themes/.cache/clangd/index/LeafParticleRender.h.A0C89D6CC01BA1D6.idx 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 Binary files a/themes/.cache/clangd/index/Renderer2d.cpp.DF430723818BC87C.idx and b/themes/.cache/clangd/index/Renderer2d.cpp.DF430723818BC87C.idx 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 Binary files a/themes/.cache/clangd/index/Renderer2d.h.F1518A7EF7C2E747.idx and b/themes/.cache/clangd/index/Renderer2d.h.F1518A7EF7C2E747.idx 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 Binary files a/themes/.cache/clangd/index/Snowflake.cpp.3E4BE700DA4CDAC9.idx and b/themes/.cache/clangd/index/Snowflake.cpp.3E4BE700DA4CDAC9.idx 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 Binary files a/themes/.cache/clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idx and b/themes/.cache/clangd/index/Snowflake.h.CAD2EF1A1EEC6A99.idx 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 Binary files a/themes/.cache/clangd/index/TreeShape.cpp.3271E9D39A039C82.idx and b/themes/.cache/clangd/index/TreeShape.cpp.3271E9D39A039C82.idx 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 Binary files a/themes/.cache/clangd/index/TreeShape.h.68863A800A0A4201.idx and b/themes/.cache/clangd/index/TreeShape.h.68863A800A0A4201.idx 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 Binary files /dev/null and b/themes/.cache/clangd/index/list.h.94D5DE92B51D5CD7.idx 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 -#include -#include "Logger.h" - -#define FOREACH(list) \ - for (size_t idx = 0; idx < list.numElements; idx++) \ - if (auto value = list.getValue(idx)) \ - - -template -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 -void List::allocate(size_t size) { - if (size == 0 || size == capacity) { - numElements = 0; - return; - } - - if (data != nullptr) { - deallocate(); - } - - data = static_cast(malloc(sizeof(T) * size)); - capacity = size; - numElements = 0; -} - -template -bool List::grow(size_t newSize) { - if (!growDynamically) { - return false; - } - - if (newSize == 0) { - return false; - } - - T* newData = static_cast(malloc(sizeof(T) * newSize)); - - if (data != nullptr) { - memcpy(newData, data, numElements * sizeof(T)); - delete data; - } - - data = newData; - capacity = newSize; - return true; -} - -template -void List::set(T* value, size_t index) { - if (index >= capacity && !grow(index * 2)) { - return; - } - - memcpy(&data[index], value, sizeof(T)); -} - -template -void List::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 -void List::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 -void List::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 -void List::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 -void List::deallocate() { - if (data != nullptr) { - free(data); - data = nullptr; - } - - capacity = 0; - numElements = 0; -} - -template -void List::clear() { - numElements = 0; -} - -template -T* List::getValue(int idx) const { - return &data[idx]; -} - -template -T& List::operator[](int idx) const { - return data[idx]; -} - -template -void List::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(context->width) / static_cast(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 + +struct Vertex3d { + Vector4 position; + Vector4 color; +}; + +struct Mesh3d { + u32 vao; + u32 vbo; + u32 ebo; + matte::List vertices; + matte::List 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* vertices, i32 numArms, f32 radius, f32 innerRadius) { +inline void generateSnowflakeShape(matte::List* 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 vertices; + matte::List 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 #include -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 Binary files a/themes/a.out.wasm and /dev/null differ diff --git a/themes/dist/output.wasm b/themes/dist/output.wasm index bf3e6ba..1c12a60 100755 Binary files a/themes/dist/output.wasm and b/themes/dist/output.wasm 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 +#include +#include "Logger.h" + +#define FOREACH(list) \ + for (i32 idx = 0; idx < list.numElements; idx++) \ + if (auto value = &list[idx]) \ + +namespace matte { + template + 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 + void List::allocate(size_t size) { + if (size == 0 || size == capacity) { + numElements = 0; + return; + } + + if (data != nullptr) { + deallocate(); + } + + data = static_cast(malloc(sizeof(T) * size)); + capacity = size; + numElements = 0; + } + + template + bool List::grow(size_t newSize) { + if (!growDynamically) { + return false; + } + + if (newSize == 0) { + return false; + } + + T* newData = static_cast(malloc(sizeof(T) * newSize)); + + if (data != nullptr) { + memcpy(newData, data, numElements * sizeof(T)); + delete data; + } + + data = newData; + capacity = newSize; + return true; + } + + template + void List::set(T& value, size_t index) { + if (index >= capacity && !grow(index * 2)) { + return; + } + + memcpy(&data[index], value, sizeof(T)); + } + + template + void List::set(T&& value, size_t index) { + if (index >= capacity && !grow(index * 2)) { + return; + } + + data[index] = value; + } + + template + void List::set(T* value, size_t index) { + if (index >= capacity && !grow(index * 2)) { + return; + } + + memcpy(&data[index], value, sizeof(T)); + } + + template + void List::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 + void List::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 + void List::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 + void List::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 + void List::deallocate() { + if (data != nullptr) { + free(data); + data = nullptr; + } + + capacity = 0; + numElements = 0; + } + + template + void List::clear() { + numElements = 0; + } + + template + T& List::getValue(int idx) const { + return data[idx]; + } + + template + T& List::operator[](int idx) const { + return data[idx]; + } + + template + void List::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() { -- cgit v1.2.1