From f6fe40e125a99bd3ea47c476f6a95b6e820a51aa Mon Sep 17 00:00:00 2001
From: Matthew Kosarek
Date: Wed, 13 Oct 2021 07:29:09 -0400
Subject: Adding square leaves to the tree
---
index.css | 1 +
index.html | 5 +--
resume.css | 2 ++
resume.html | 2 +-
themes/LeafParticleRender.cpp | 48 ++++++++++++++++++++-----
themes/LeafParticleRender.h | 8 +++--
themes/Renderer2d.cpp | 7 +---
themes/Renderer2d.h | 2 --
themes/TreeShape.cpp | 79 ++++++++++++++++++++++++++++--------------
themes/TreeShape.h | 15 ++++++--
themes/dist/output.wasm | Bin 49375 -> 54718 bytes
themes/main.cpp | 8 ++++-
themes/mathlib.cpp | 1 -
themes/mathlib.h | 10 ++++++
14 files changed, 137 insertions(+), 51 deletions(-)
diff --git a/index.css b/index.css
index 1d95d04..76b7187 100644
--- a/index.css
+++ b/index.css
@@ -73,6 +73,7 @@ header > nav > ul a:hover {
#carousel {
width: 100%;
position: relative;
+ overflow: hidden;
}
#carousel > button {
diff --git a/index.html b/index.html
index a85ca65..f76e3ab 100644
--- a/index.html
+++ b/index.html
@@ -18,7 +18,7 @@
@@ -52,7 +52,8 @@
- My name is Matthew Kosarek. I am a computer programmer currently living in New Jersey. I keep my CV up to date on this website. I also write some posts about computers when I find something particularly interesting. You can find a link to my Github here. I am also building a website about physics simulation in video games which you can find here.
+ My name is Matthew Kosarek. I am a computer programmer currently living in Montreal. I keep my CV up to date on this website.
+ You can find a link to my Github here. I am also building a website about physics simulation in video games which you can find here.
diff --git a/resume.css b/resume.css
index 3275691..d580d80 100755
--- a/resume.css
+++ b/resume.css
@@ -1,5 +1,6 @@
body {
font-size: 14px !important;
+ width: 100%;
}
header {
@@ -15,6 +16,7 @@ header {
}
#resume {
+ width: 80%;
position: relative;
text-align: left;
background-color: white;
diff --git a/resume.html b/resume.html
index 90a33b4..6b88570 100755
--- a/resume.html
+++ b/resume.html
@@ -14,7 +14,7 @@
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
#include
-
+#include
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(rand()) / static_cast(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
Binary files a/themes/dist/output.wasm and b/themes/dist/output.wasm 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(rand()) / static_cast(RAND_MAX);
+ return (max - min) * random + min;
+}
+
+inline int randomIntBetween(int min, int max) {
+ return static_cast(randomFloatBetween(min, max));
+}
+
struct Vector2 {
float x = 0;
float y = 0;
--
cgit v1.2.1