From cc05fdc7396532b329f30decde5583853da92a44 Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Sat, 27 Mar 2021 20:54:27 -0400 Subject: Drawing an ellipse --- frontend/2d/_collisions/pill_line/dist/output.wasm | Bin 27360 -> 37565 bytes frontend/2d/_collisions/pill_line/main.cpp | 85 +++++++++++++++++---- frontend/shared_cpp/OrthographicRenderer.cpp | 47 +++++++++++- frontend/shared_cpp/OrthographicRenderer.h | 49 ++---------- frontend/shared_cpp/WebglContext.h | 6 +- frontend/shared_cpp/mathlib.h | 22 +++++- frontend/shared_cpp/types.h | 2 + 7 files changed, 153 insertions(+), 58 deletions(-) diff --git a/frontend/2d/_collisions/pill_line/dist/output.wasm b/frontend/2d/_collisions/pill_line/dist/output.wasm index be1afc5..92ee1f2 100755 Binary files a/frontend/2d/_collisions/pill_line/dist/output.wasm and b/frontend/2d/_collisions/pill_line/dist/output.wasm differ diff --git a/frontend/2d/_collisions/pill_line/main.cpp b/frontend/2d/_collisions/pill_line/main.cpp index 321a4ba..df20fa0 100644 --- a/frontend/2d/_collisions/pill_line/main.cpp +++ b/frontend/2d/_collisions/pill_line/main.cpp @@ -7,16 +7,70 @@ #include #include #include +#include -typedef OrthographicShape<3> TriangleShape; +// +// Pill object +// +struct Pill { + OrthographicShape shape; + float32 width = 1.f; + float32 height = 1.f; + + void load(OrthographicRenderer* renderer, float32 numSegments) { + // Note that a so-called "pill" is simply an ellipse. + // Equation of an ellipse is: + // + // x^2 / a^2 + y^2 / b^2 = 1 + // + // or, in parametric form: + // + // x = a * cos(t), y = b * sin(t) + // + float32 angleIncrements = (2.f * PI) / numSegments; + uint32 numVertices = static_cast(numSegments * 3.f); + OrthographicVertex* vertices = new OrthographicVertex[numVertices]; + + float32 a = width / 2.f; + float32 b = height / 2.f; + + Vector4 color = Vector4().fromColor(243,166,207, 255); + + for (uint32 vertexIndex = 0; vertexIndex < numVertices; vertexIndex += 3) { + // Create a single "slice" of the ellipse (like a pizza) + float32 currAngle = (vertexIndex / 3.f) * angleIncrements; + float32 nextAngle = (vertexIndex / 3.f + 1.f) * angleIncrements; + + vertices[vertexIndex].position = Vector2 { 0.f, 0.f }; + vertices[vertexIndex].color = color; + + vertices[vertexIndex + 1].position = Vector2 { a * cosf(currAngle), b * sinf(currAngle) }; + vertices[vertexIndex + 1].color = color; + + vertices[vertexIndex + 2].position = Vector2 { a * cosf(nextAngle), b * sinf(nextAngle) }; + vertices[vertexIndex + 2].color = color; + } + + shape.load(vertices, numVertices, renderer); + } + + void unload() { + shape.unload(); + } + + float32 getArea() { + return 0.f; + } +}; EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); EM_BOOL update(float time, void* userData); +// Global Variables WebglContext context; OrthographicRenderer renderer; -TriangleShape shape; +Pill pill; MainLoop mainLoop; int main() { @@ -26,14 +80,23 @@ int main() { return 0; } +EM_BOOL update(float deltaTimeSeconds, void* userData) { + renderer.render(); + pill.shape.render(&renderer); + return true; +} + +// +// Interactions with DOM handled below +// EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { printf("Play clicked\n"); - renderer.load(); - shape.vertices[0] = { Vector2 { -1, -1 }, Vector4 { 1, 0, 0, 1 } }; - shape.vertices[1] = { Vector2 { 0, 1 }, Vector4{ 0, 1, 0, 1 } }; - shape.vertices[2] = { Vector2 { 1, -1 }, Vector4 { 0, 0, 1, 1 } }; - shape.load(&renderer); + renderer.load(&context); + pill.width = 100.f; + pill.height = 50.f; + pill.shape.model = pill.shape.model.translateByVec2(Vector2 { context.width / 2.f, context.height / 2.f }); + pill.load(&renderer, 64); mainLoop.run(update); return true; } @@ -41,13 +104,7 @@ EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, voi EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { printf("Stop clicked\n"); mainLoop.stop(); - shape.unload(); + pill.unload(); renderer.unload(); return true; -} - -EM_BOOL update(float deltaTimeSeconds, void* userData) { - renderer.render(); - shape.render(&renderer); - return true; } \ No newline at end of file diff --git a/frontend/shared_cpp/OrthographicRenderer.cpp b/frontend/shared_cpp/OrthographicRenderer.cpp index b6bd5b6..1d62c04 100644 --- a/frontend/shared_cpp/OrthographicRenderer.cpp +++ b/frontend/shared_cpp/OrthographicRenderer.cpp @@ -1,4 +1,6 @@ #include "OrthographicRenderer.h" +#include "WebglContext.h" +#include "mathlib.h" const char* orthographicVertex = "attribute vec2 position; \n" @@ -18,7 +20,7 @@ const char* orthographicFragment = " gl_FragColor = VertexColor; \n" "}"; -void OrthographicRenderer::load() { +void OrthographicRenderer::load(WebglContext* context) { printf("Compiling orthographic shader...\n"); shader = loadShader(orthographicVertex, orthographicFragment); @@ -27,6 +29,7 @@ void OrthographicRenderer::load() { attributes.color = getShaderAttribute(shader, "color"); uniforms.projection = getShaderUniform(shader, "projection"); uniforms.model = getShaderUniform(shader, "model"); + projection = Mat4x4().getOrthographicMatrix(0, context->width, 0, context->height); printf("Orthographic shader compiled.\n"); } @@ -47,3 +50,45 @@ void OrthographicRenderer::unload() { glClear(GL_COLOR_BUFFER_BIT); glDeleteProgram(shader); } + + +void OrthographicShape::load(OrthographicVertex* inVertices, uint32 inNumVertices, OrthographicRenderer* renderer) { + vertices = inVertices; + numVertices = inNumVertices; + useShader(renderer->shader); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, inNumVertices * sizeof(OrthographicVertex), &vertices[0], GL_STATIC_DRAW); + + glEnableVertexAttribArray(renderer->attributes.position); + glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)0); + + glEnableVertexAttribArray(renderer->attributes.color); + glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)offsetof(OrthographicVertex, color)); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void OrthographicShape::render(OrthographicRenderer* renderer) { + setShaderMat4(renderer->uniforms.model, model); + + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, numVertices); + glBindVertexArray(0); +} + +void OrthographicShape::unload() { + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); + + if (vertices != NULL) { + delete vertices; + } + + vertices = NULL; +} \ No newline at end of file diff --git a/frontend/shared_cpp/OrthographicRenderer.h b/frontend/shared_cpp/OrthographicRenderer.h index c72639e..0cdfc78 100644 --- a/frontend/shared_cpp/OrthographicRenderer.h +++ b/frontend/shared_cpp/OrthographicRenderer.h @@ -1,9 +1,12 @@ #pragma once +#include "WebglContext.h" #include "types.h" #include "Shader.h" #include "mathlib.h" +struct WebglContext; + struct OrthographicRenderer { Mat4x4 projection; uint32 shader; @@ -18,7 +21,7 @@ struct OrthographicRenderer { int32 model; } uniforms; - void load(); + void load(WebglContext* context); void render(); void unload(); }; @@ -28,50 +31,14 @@ struct OrthographicVertex { Vector4 color; }; -template struct OrthographicShape { uint32 vao; uint32 vbo; - OrthographicVertex vertices[N]; + uint32 numVertices = 0; + OrthographicVertex* vertices = NULL; Mat4x4 model; - void load(OrthographicRenderer* renderer); + void load(OrthographicVertex* vertices, uint32 numVertices, OrthographicRenderer* renderer); void render(OrthographicRenderer* renderer); void unload(); -}; - -template -void OrthographicShape::load(OrthographicRenderer* renderer) { - useShader(renderer->shader); - - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, N * sizeof(OrthographicVertex), &vertices[0], GL_STATIC_DRAW); - - glEnableVertexAttribArray(renderer->attributes.position); - glVertexAttribPointer(renderer->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)0); - - glEnableVertexAttribArray(renderer->attributes.color); - glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)offsetof(OrthographicVertex, color)); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); -} - -template -void OrthographicShape::render(OrthographicRenderer* renderer) { - setShaderMat4(renderer->uniforms.model, model); - - glBindVertexArray(vao); - glDrawArrays(GL_TRIANGLES, 0, 3); - glBindVertexArray(0); -} - -template -void OrthographicShape::unload() { - glDeleteVertexArrays(1, &vao); - glDeleteBuffers(1, &vbo); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/frontend/shared_cpp/WebglContext.h b/frontend/shared_cpp/WebglContext.h index 1ea1c91..017498f 100644 --- a/frontend/shared_cpp/WebglContext.h +++ b/frontend/shared_cpp/WebglContext.h @@ -7,8 +7,12 @@ struct WebglContext { EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context; + int width = 640; + int height = 480; - void init(const char* query, int width = 640, int height = 480) { + void init(const char* query, int inWidth = 640, int inHeight = 480) { + width = inWidth; + height = inHeight; emscripten_set_canvas_element_size( query, width, height); EmscriptenWebGLContextAttributes attrs; diff --git a/frontend/shared_cpp/mathlib.h b/frontend/shared_cpp/mathlib.h index 93ddbbd..7595045 100644 --- a/frontend/shared_cpp/mathlib.h +++ b/frontend/shared_cpp/mathlib.h @@ -41,6 +41,10 @@ struct Vector2 { Vector2 getPerp() { return { -y, x }; } + + void printDebug(const char* name) { + printf("%s=Vector2(%f, %f)\n", name, x, y); + } }; struct Vector3 { @@ -54,6 +58,22 @@ struct Vector4 { float y = 0.f; float z = 0.f; float w = 0.f; + + float length() { + return sqrtf(x * x + y * y + z * z + w * w); + } + + Vector4 normalize() { + float len = length(); + float inverseLength = len == 0 ? 1.0 : 1.0 / len; + + return { x * inverseLength, y * inverseLength, z * inverseLength, w * inverseLength }; + } + + Vector4 fromColor(float r, float g, float b, float a) { + float scale = 1.f / 255.f; + return { r * scale, g * scale, b * scale, a * scale }; + } }; struct Mat4x4 { @@ -123,7 +143,7 @@ struct Mat4x4 { void print() { printf("[ "); for (int idx = 0; idx < 16; idx++) { - printf("%d, ", idx); + printf("%f, ", m[idx]); } printf(" ]\n"); } diff --git a/frontend/shared_cpp/types.h b/frontend/shared_cpp/types.h index 7bac7f3..3739699 100644 --- a/frontend/shared_cpp/types.h +++ b/frontend/shared_cpp/types.h @@ -14,3 +14,5 @@ typedef unsigned long uint64; typedef float float32; typedef double float64; + +#define PI 3.14159265358979323846 \ No newline at end of file -- cgit v1.2.1