summaryrefslogtreecommitdiff
path: root/themes
diff options
context:
space:
mode:
authorMatthew Kosarek <mattkae@protonmail.com>2021-10-13 07:29:09 -0400
committerMatthew Kosarek <mattkae@protonmail.com>2021-10-13 07:29:09 -0400
commitf6fe40e125a99bd3ea47c476f6a95b6e820a51aa (patch)
tree0c4675c30d9b2aa556594c3a0e697388269006de /themes
parent2074f6be3096386fb543f040dec314290f6eb920 (diff)
Adding square leaves to the tree
Diffstat (limited to 'themes')
-rw-r--r--themes/LeafParticleRender.cpp48
-rw-r--r--themes/LeafParticleRender.h8
-rw-r--r--themes/Renderer2d.cpp7
-rw-r--r--themes/Renderer2d.h2
-rw-r--r--themes/TreeShape.cpp79
-rw-r--r--themes/TreeShape.h15
-rwxr-xr-xthemes/dist/output.wasmbin49375 -> 54718 bytes
-rw-r--r--themes/main.cpp8
-rw-r--r--themes/mathlib.cpp1
-rw-r--r--themes/mathlib.h10
10 files changed, 130 insertions, 48 deletions
diff --git a/themes/LeafParticleRender.cpp b/themes/LeafParticleRender.cpp
index 1abdd49..df2a453 100644
--- a/themes/LeafParticleRender.cpp
+++ b/themes/LeafParticleRender.cpp
@@ -1,12 +1,43 @@
#include "LeafParticleRender.h"
#include "Renderer2d.h"
+#include "mathlib.h"
+#include "TreeShape.h"
+#include "types.h"
-void LeafParticleRender::load(Renderer2d *renderer, TreeShape *tree) {
- numVertices = 0;
- numLeaves = 0;
+const int32 verticesPerLeaf = 6;
+const float32 leafRadius = 3.f;
+inline void createLeaf(Renderer2dVertex* vertices, Vector2 position, Vector4 color) {
+ Vector2 bottomLeft = Vector2(-leafRadius, -leafRadius) + position;
+ Vector2 bottomRight = Vector2(leafRadius, -leafRadius) + position;
+ Vector2 topLeft = Vector2(-leafRadius, leafRadius) + position;
+ Vector2 topRight = Vector2(leafRadius, leafRadius) + position;
+
+ vertices[0] = { bottomLeft, color };
+ vertices[1] = { bottomRight, color };
+ vertices[2] = { topLeft, color };
+ vertices[3] = { topLeft, color };
+ vertices[4] = { topRight, color };
+ vertices[5] = { bottomRight, color };
+}
+
+void LeafParticleRender::load(Renderer2d *renderer, TreeShapeLoadResult* lr) {
+ LeafParticleLoadData ld;
+ ld.numLeaves = 640;
+ numLeaves = ld.numLeaves;
+ numVertices = ld.numLeaves * verticesPerLeaf;
+
+ updateData = new LeafParticleUpdateData[numLeaves];
vertices = new Renderer2dVertex[numVertices];
+ for (int32 leafIdx = 0; leafIdx < numLeaves; leafIdx++) {
+ int32 randomBranch = randomIntBetween(0, lr->numBranches);
+ int32 randomVertex = randomIntBetween(0, 6); // TODO: Manually entering num vertices per branch.
+ updateData[leafIdx].vertexToFollow = &lr->updateData[randomBranch].vertices[randomVertex];
+ updateData[leafIdx].color = Vector4(randomFloatBetween(0.3, 0.9), randomFloatBetween(0.1, 0.6), 0, 1);
+ updateData[leafIdx].vertexPtr = &vertices[leafIdx * verticesPerLeaf];
+ }
+
useShader(renderer->shader);
glGenVertexArrays(1, &vao);
@@ -22,15 +53,16 @@ void LeafParticleRender::load(Renderer2d *renderer, TreeShape *tree) {
glEnableVertexAttribArray(renderer->attributes.color);
glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, color));
- glEnableVertexAttribArray(renderer->attributes.transform);
- glVertexAttribPointer(renderer->attributes.transform, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, transform));
-
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void LeafParticleRender::update(float32 dtSeconds) {
-
+ for (int32 leafIdx = 0; leafIdx < numLeaves; leafIdx++) {
+ auto updateDataItem = &updateData[leafIdx];
+
+ createLeaf(updateDataItem->vertexPtr, updateDataItem->vertexToFollow->position, updateDataItem->color);
+ }
}
void LeafParticleRender::render(Renderer2d *renderer) {
@@ -40,7 +72,7 @@ void LeafParticleRender::render(Renderer2d *renderer) {
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Renderer2dVertex), &vertices[0]);
glBindVertexArray(vao);
- glDrawArraysInstanced(GL_TRIANGLES, 0, 6 * numVertices, numLeaves);
+ glDrawArrays(GL_TRIANGLES, 0, numVertices);
glBindVertexArray(0);
}
diff --git a/themes/LeafParticleRender.h b/themes/LeafParticleRender.h
index 5953000..c305363 100644
--- a/themes/LeafParticleRender.h
+++ b/themes/LeafParticleRender.h
@@ -2,7 +2,7 @@
#include "mathlib.h"
#include "types.h"
-struct TreeShape;
+struct TreeShapeLoadResult;
struct LeafParticleLoadData {
Vector2 initPosition;
@@ -12,14 +12,18 @@ struct LeafParticleLoadData {
struct LeafParticleUpdateData {
bool canFall = false;
+ Renderer2dVertex* vertexToFollow = NULL;
Vector4 color = Vector4(1.f, 0.f, 0.f, 0.f);
float32 scale = 1.f;
Vector2 fallDirection;
+ Renderer2dVertex* vertexPtr = NULL;
};
struct LeafParticleRender {
// Update data
int32 numLeaves = 0;
+
+ LeafParticleUpdateData* updateData = NULL;
Renderer2dVertex* vertices = NULL;
// Render data
@@ -28,7 +32,7 @@ struct LeafParticleRender {
uint32 numVertices = 0;
Mat4x4 model;
- void load(Renderer2d* renderer, TreeShape* tree);
+ void load(Renderer2d* renderer, TreeShapeLoadResult* lr);
void update(float32 dtSeconds);
void render(Renderer2d* renderer);
void unload();
diff --git a/themes/Renderer2d.cpp b/themes/Renderer2d.cpp
index 3e29656..2750557 100644
--- a/themes/Renderer2d.cpp
+++ b/themes/Renderer2d.cpp
@@ -9,12 +9,11 @@
const char* renderer2dVertexShader =
"attribute vec2 position; \n"
"attribute vec4 color; \n"
-"attribute vec4 transform; \n"
"uniform mat4 projection; \n"
"uniform mat4 model; \n"
"varying lowp vec4 VertexColor; \n"
"void main() { \n"
-" vec4 fragmentPosition = projection * model * vec4(position.x + transform.x, position.y + transform.x, 1, 1); \n"
+" vec4 fragmentPosition = projection * model * vec4(position.x, position.y, 0, 1); \n"
" gl_Position = fragmentPosition; \n"
" VertexColor = color; \n"
"}";
@@ -46,7 +45,6 @@ void Renderer2d::load(WebglContext* inContext) {
useShader(shader);
attributes.position = getShaderAttribute(shader, "position");
attributes.color = getShaderAttribute(shader, "color");
- attributes.transform = getShaderAttribute(shader, "transform");
uniforms.projection = getShaderUniform(shader, "projection");
uniforms.model = getShaderUniform(shader, "model");
projection = Mat4x4().getOrthographicMatrix(0, context->width, 0, context->height);
@@ -93,9 +91,6 @@ void Renderer2dShape::load(Renderer2dVertex* inVertices, uint32 inNumVertices, R
glEnableVertexAttribArray(renderer->attributes.color);
glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, color));
- glEnableVertexAttribArray(renderer->attributes.transform);
- glVertexAttribPointer(renderer->attributes.transform, 2, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, transform));
-
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
diff --git a/themes/Renderer2d.h b/themes/Renderer2d.h
index 33e0dac..cbdf4d4 100644
--- a/themes/Renderer2d.h
+++ b/themes/Renderer2d.h
@@ -16,7 +16,6 @@ struct Renderer2d {
struct {
int32 position;
int32 color;
- int32 transform;
} attributes;
struct {
@@ -32,7 +31,6 @@ struct Renderer2d {
struct Renderer2dVertex {
Vector2 position;
Vector4 color;
- Vector4 transform;
};
struct Renderer2dShape {
diff --git a/themes/TreeShape.cpp b/themes/TreeShape.cpp
index ec9e052..8532fdc 100644
--- a/themes/TreeShape.cpp
+++ b/themes/TreeShape.cpp
@@ -2,7 +2,7 @@
#include "mathlib.h"
#include <cstdio>
#include <cstdlib>
-
+#include <cfloat>
void TreeBranchLoadData::fillVertices(Renderer2dVertex* vertices, int branchTier) {
bottomLeft = Vector2 { position.x - width / 2.f, position.y }.rotateAbout(rotation, position);
@@ -12,20 +12,17 @@ void TreeBranchLoadData::fillVertices(Renderer2dVertex* vertices, int branchTier
topMidpoint = topLeft + (topRight - topLeft) / 2.f;
- vertices[0] = { bottomLeft, color, Vector4(0, 0, 0, 0) };
- vertices[1] = { bottomRight, color, Vector4(0, 0, 0, 0) };
- vertices[2] = { topLeft, color, Vector4(0, 0, 0, 0) };
- vertices[3] = { topLeft, color, Vector4(0, 0, 0, 0) };
- vertices[4] = { topRight, color, Vector4(0, 0, 0, 0) };
- vertices[5] = { bottomRight, color, Vector4(0, 0, 0, 0) };
+ vertices[0] = { bottomLeft, color};
+ vertices[1] = { bottomRight, color};
+ vertices[2] = { topLeft, color};
+ vertices[3] = { topLeft, color};
+ vertices[4] = { topRight, color};
+ vertices[5] = { bottomRight, color};
};
-inline float32 randomFloatBetween(float32 min, float32 max) {
- float32 random = static_cast<float32>(rand()) / static_cast<float32>(RAND_MAX);
- return (max - min) * random + min;
-}
+TreeShapeLoadResult TreeShape::load(Renderer2d* renderer) {
+ timeElapsedSeconds = 0;
-void TreeShape::load(Renderer2d* renderer) {
TreeLoadData ld;
numBranches = pow(ld.divisionsPerBranch, ld.numBranchLevels + 1);
@@ -35,8 +32,14 @@ void TreeShape::load(Renderer2d* renderer) {
updateData = new TreeBranchUpdateData[numBranches];
vertices = new Renderer2dVertex[numVertices];
+ // The load result will contain information that we can pass on to our leaf renderer.
+ TreeShapeLoadResult lr;
+ lr.lowerBounds = Vector2(FLT_MAX, FLT_MAX);
+ lr.upperBounds = Vector2(FLT_MIN, FLT_MIN);
+ lr.updateData = updateData;
+ lr.numBranches = numBranches;
int32 branchIndex = 0;
- createBranch(&ld, generationData, numBranches, &branchIndex, 0, ld.trunkWidth, ld.trunkHeight, Vector2 { 400.f, 50.f }, 0, vertices);
+ createBranch(&ld, generationData, numBranches, &branchIndex, 0, ld.trunkWidth, ld.trunkHeight, Vector2 { 300.f, 50.f }, 0, vertices, &lr);
useShader(renderer->shader);
@@ -53,18 +56,17 @@ void TreeShape::load(Renderer2d* renderer) {
glEnableVertexAttribArray(renderer->attributes.color);
glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, color));
- glEnableVertexAttribArray(renderer->attributes.transform);
- glVertexAttribPointer(renderer->attributes.transform, 4, GL_FLOAT, GL_FALSE, sizeof(Renderer2dVertex), (GLvoid *)offsetof(Renderer2dVertex, transform));
-
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
delete [] generationData;
+
+ return lr;
}
const float32 ninetyDegreeRotation = PI / 2.f;
-void TreeShape::createBranch(TreeLoadData* ld, TreeBranchLoadData* generationData, int32 numBranches, int32* branchIndex, int32 branchLevel, float32 width, float32 height, Vector2 position, float32 rotation, Renderer2dVertex* vertices) {
+void TreeShape::createBranch(TreeLoadData* ld, TreeBranchLoadData* generationData, int32 numBranches, int32* branchIndex, int32 branchLevel, float32 width, float32 height, Vector2 position, float32 rotation, Renderer2dVertex* vertices, TreeShapeLoadResult* lr) {
TreeBranchLoadData* branchLoadData = &generationData[*branchIndex];
branchLoadData->width = width;
branchLoadData->height = height;
@@ -72,9 +74,24 @@ void TreeShape::createBranch(TreeLoadData* ld, TreeBranchLoadData* generationDat
branchLoadData->rotation = rotation;
branchLoadData->fillVertices(&vertices[(*branchIndex) * 6], branchLevel);
+ // Fil in the bounds for the LeafRenderer later.
+ if (branchLoadData->topMidpoint.x > lr->upperBounds.x) {
+ lr->upperBounds.x = branchLoadData->topMidpoint.x;
+ }
+ if (branchLoadData->topMidpoint.y > lr->upperBounds.y) {
+ lr->upperBounds.y = branchLoadData->topMidpoint.y;
+ }
+ if (branchLoadData->topMidpoint.x < lr->lowerBounds.x) {
+ lr->lowerBounds.x = branchLoadData->topMidpoint.x;
+ }
+ if (branchLoadData->topMidpoint.y < lr->lowerBounds.y) {
+ lr->lowerBounds.y = branchLoadData->topMidpoint.y;
+ }
+
TreeBranchUpdateData* branchUpdateData = &updateData[*branchIndex];
branchUpdateData->tier = branchLevel;
branchUpdateData->randomOffset = randomFloatBetween(-1.f, 1.f);
+ branchUpdateData->vertices = &vertices[(*branchIndex) * 6];
if (branchLevel == ld->numBranchLevels) {
return;
@@ -104,7 +121,7 @@ void TreeShape::createBranch(TreeLoadData* ld, TreeBranchLoadData* generationDat
Vector2 branchPosition = branchLoadData->topLeft + ((branchLoadData->topRight - branchLoadData->topLeft) * weight) - branchOffsetVertical; // Position of branch along the top of the parent branch
(*branchIndex)++;
- createBranch(ld, generationData, numBranches, branchIndex, branchLevel + 1, branchWidth, branchHeight, branchPosition, branchRotation, vertices);
+ createBranch(ld, generationData, numBranches, branchIndex, branchLevel + 1, branchWidth, branchHeight, branchPosition, branchRotation, vertices, lr);
}
}
@@ -129,14 +146,21 @@ void TreeShape::update(float32 dtSeconds) {
alpha = (1.f - (animationEnd - timeElapsedSeconds)) / animateTimePerTier;
}
- int startParentIndex = bIdx * 6;
- for (int32 sIdx = 0; sIdx < 6; sIdx++) {
- int32 vidx = startParentIndex + sIdx;
- vertices[vidx].color.w = alpha;
-
- // Wind simualtion
- vertices[vidx].position.x += ((branchUpdataData->randomOffset + branchUpdataData->tier) * 0.01f) * sinf(timeElapsedSeconds);
- }
+ int32 startParentIndex = bIdx * 6;
+ float32 xOffset = ((branchUpdataData->randomOffset + branchUpdataData->tier) * 0.01f) * sinf(timeElapsedSeconds);
+
+ branchUpdataData->vertices[0].color.w = alpha;
+ branchUpdataData->vertices[0].position.x += xOffset;
+ branchUpdataData->vertices[1].color.w = alpha;
+ branchUpdataData->vertices[1].position.x += xOffset;
+ branchUpdataData->vertices[2].color.w = alpha;
+ branchUpdataData->vertices[2].position.x += xOffset;
+ branchUpdataData->vertices[3].color.w = alpha;
+ branchUpdataData->vertices[3].position.x += xOffset;
+ branchUpdataData->vertices[4].color.w = alpha;
+ branchUpdataData->vertices[4].position.x += xOffset;
+ branchUpdataData->vertices[5].color.w = alpha;
+ branchUpdataData->vertices[5].position.x += xOffset;
}
}
@@ -156,4 +180,7 @@ void TreeShape::unload() {
glDeleteBuffers(1, &vbo);
delete[] vertices;
delete [] updateData;
+ timeElapsedSeconds = 0;
+ vertices = NULL;
+ updateData = NULL;
}
diff --git a/themes/TreeShape.h b/themes/TreeShape.h
index d7570da..06a8f81 100644
--- a/themes/TreeShape.h
+++ b/themes/TreeShape.h
@@ -33,6 +33,15 @@ struct TreeBranchLoadData {
struct TreeBranchUpdateData {
int32 tier = 0;
float32 randomOffset = 0;
+ Renderer2dVertex* vertices = NULL;
+};
+
+struct TreeShapeLoadResult {
+ Vector2 lowerBounds;
+ Vector2 upperBounds;
+ Vector2 center;
+ TreeBranchUpdateData* updateData;
+ uint32 numBranches = 0;
};
struct TreeShape {
@@ -50,8 +59,10 @@ struct TreeShape {
uint32 numVertices = 0;
Mat4x4 model;
- void load(Renderer2d* renderer);
- void createBranch(TreeLoadData* ld, TreeBranchLoadData* branchList, int32 numBranches, int32* branchIndex, int32 branchLevel, float32 width, float32 height, Vector2 position, float32 rotation, Renderer2dVertex* vertices);
+ TreeShapeLoadResult load(Renderer2d* renderer);
+ void createBranch(TreeLoadData* ld, TreeBranchLoadData* branchList, int32 numBranches,
+ int32* branchIndex, int32 branchLevel, float32 width, float32 height,
+ Vector2 position, float32 rotation, Renderer2dVertex* vertices, TreeShapeLoadResult* lr);
void update(float32 dtSeconds);
void render(Renderer2d* renderer);
void unload();
diff --git a/themes/dist/output.wasm b/themes/dist/output.wasm
index 17a1d97..32331e3 100755
--- a/themes/dist/output.wasm
+++ b/themes/dist/output.wasm
Binary files differ
diff --git a/themes/main.cpp b/themes/main.cpp
index c3ecad0..e037dcf 100644
--- a/themes/main.cpp
+++ b/themes/main.cpp
@@ -4,6 +4,7 @@
#include "Renderer2d.h"
#include "types.h"
#include "TreeShape.h"
+#include "LeafParticleRender.h"
enum Theme {
Default = 0,
@@ -12,6 +13,7 @@ enum Theme {
struct AutumnTheme {
TreeShape tree;
+ LeafParticleRender leafParticles;
void load(Renderer2d* renderer);
void update(float32 dtSeconds);
@@ -114,18 +116,22 @@ EM_BOOL selectAutumn(int eventType, const EmscriptenMouseEvent* mouseEvent, void
// -- Autumn theme3
void AutumnTheme::load(Renderer2d* renderer) {
renderer->clearColor = Vector4(252,76,2, 0.5).toNormalizedColor();
- tree.load(renderer);
+ auto lr = tree.load(renderer);
+ leafParticles.load(renderer, &lr);
}
void AutumnTheme::update(float32 dtSeconds) {
tree.update(dtSeconds);
+ leafParticles.update(dtSeconds);
}
void AutumnTheme::render(Renderer2d* renderer) {
tree.render(renderer);
+ leafParticles.render(renderer);
}
void AutumnTheme::unload() {
tree.unload();
+ leafParticles.unload();
}
diff --git a/themes/mathlib.cpp b/themes/mathlib.cpp
index 7efbb24..ee9bb1d 100644
--- a/themes/mathlib.cpp
+++ b/themes/mathlib.cpp
@@ -348,7 +348,6 @@ void Vector4::printDebug(const char* name) {
printf("%s=Vector4(%f, %f, %f, %f)\n", name, x, y, z, w);
}
-
// ***************************************
// Mat4x4
Mat4x4 Mat4x4::copy() {
diff --git a/themes/mathlib.h b/themes/mathlib.h
index 99dfb62..82f85a2 100644
--- a/themes/mathlib.h
+++ b/themes/mathlib.h
@@ -21,6 +21,16 @@
#define DEG_TO_RAD(x) (x * (PI / 180.f))
#define RAD_TO_DEG(x) (x * (180.f / PI))
+// -- Random
+inline float randomFloatBetween(float min, float max) {
+ float random = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
+ return (max - min) * random + min;
+}
+
+inline int randomIntBetween(int min, int max) {
+ return static_cast<int>(randomFloatBetween(min, max));
+}
+
struct Vector2 {
float x = 0;
float y = 0;