summaryrefslogtreecommitdiff
path: root/frontend/_wasm/wasm.cpp
diff options
context:
space:
mode:
authorMatthew Kosarek <matthew.kosarek@vention.cc>2021-03-13 15:43:56 -0500
committerMatthew Kosarek <matthew.kosarek@vention.cc>2021-03-13 15:43:56 -0500
commit98d7d6cb702af2708f20e7cf16ee10a9f71b578a (patch)
tree92cec56a5a31a9658c44d49ed896ba8b7859450f /frontend/_wasm/wasm.cpp
parent3b0514ed3a21c39b7ea1a68d2fb381c808dcfeeb (diff)
My First WASM application is rendering a triangle on the frontend
Diffstat (limited to 'frontend/_wasm/wasm.cpp')
-rw-r--r--frontend/_wasm/wasm.cpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/frontend/_wasm/wasm.cpp b/frontend/_wasm/wasm.cpp
new file mode 100644
index 0000000..91d440f
--- /dev/null
+++ b/frontend/_wasm/wasm.cpp
@@ -0,0 +1,145 @@
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <emscripten.h>
+#include <emscripten/html5.h>
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+
+#include "mathlib.h"
+#include "Shader.h"
+
+// Shader code inlined
+const char* orthographicVertex =
+"attribute vec2 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 * vec4(position, 1, 1); \n"
+" gl_Position = fragmentPosition; \n"
+" VertexColor = color; \n"
+"}";
+
+const char* orthographicFragment =
+"varying lowp vec4 VertexColor; \n"
+"void main() { \n"
+" gl_FragColor = VertexColor; \n"
+"}";
+
+struct OrthographicProgramData {
+ GLuint shader;
+
+ struct {
+ int position;
+ int color;
+ } attributes;
+
+ struct {
+ int projection;
+ int model;
+ } uniformVariables;
+};
+
+struct OrthographicVertex {
+ Vector2 position;
+ Vector4 color;
+};
+
+// Create a triangle
+struct TriangleObject {
+ OrthographicVertex vertices[3];
+ GLuint mVao;
+ GLuint mVbo;
+ Mat4x4 model;
+
+ void initialize(OrthographicProgramData* programData) {
+ useShader(programData->shader);
+
+ glGenVertexArrays(1, &mVao);
+ glBindVertexArray(mVao);
+
+ glGenBuffers(1, &mVbo);
+ glBindBuffer(GL_ARRAY_BUFFER, mVbo);
+ glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(OrthographicVertex), &vertices[0], GL_STATIC_DRAW);
+
+ for (int idx = 0; idx < 3; idx++) {
+ printf("%f, %f\n", vertices[idx].position.x, vertices[idx].position.y);
+ }
+
+ glEnableVertexAttribArray(programData->attributes.position);
+ glVertexAttribPointer(programData->attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)0);
+
+ glEnableVertexAttribArray(programData->attributes.color);
+ glVertexAttribPointer(programData->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)offsetof(OrthographicVertex, color));
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+ }
+
+ void render(OrthographicProgramData* programData) {
+ setShaderMat4(programData->uniformVariables.model, model);
+
+ glBindVertexArray(mVao);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glBindVertexArray(0);
+ }
+
+};
+
+int main() {
+ printf("Initializing the canvas...\n");
+ emscripten_set_canvas_element_size( "#wasm_canvas", 640, 480 );
+
+ EmscriptenWebGLContextAttributes attrs;
+ emscripten_webgl_init_context_attributes(&attrs);
+
+ attrs.enableExtensionsByDefault = 1;
+ attrs.majorVersion = 3;
+ attrs.minorVersion = 0;
+
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context( "#wasm_canvas", &attrs );
+
+ if (!context)
+ {
+ attrs.majorVersion = 1;
+ context = emscripten_webgl_create_context( "#wasm_canvas", &attrs );
+ if (context) printf("Skipping test: WebGL 2.0 is not available.\n");
+ else printf("Test failed: WebGL is not available!\n");
+ return 0;
+ }
+ emscripten_webgl_make_context_current(context);
+ printf("Canvas ready.\n");
+
+ printf("Compiling shaders...\n");
+ GLuint shader = loadShader(orthographicVertex, orthographicFragment);
+ useShader(shader);
+ OrthographicProgramData programData;
+ programData.shader = shader;
+ programData.attributes.position = getShaderAttribute(shader, "position");
+ programData.attributes.color = getShaderAttribute(shader, "color");
+ programData.uniformVariables.projection = getShaderUniform(shader, "projection");
+ programData.uniformVariables.model = getShaderUniform(shader, "model");
+ printf("Compiling ready.\n");
+
+ TriangleObject triangle;
+ triangle.vertices[0] = { Vector2 { 50, 50 }, Vector4 { 1.f, 0.f, 0.f, 1.f }};
+ triangle.vertices[1] = { Vector2 { 150, 300 }, Vector4 { 0.f, 1.f, 0.f, 1.f }};
+ triangle.vertices[2] = { Vector2 { 250, 50 }, Vector4 { 0.f, 0.f, 1.f, 1.f }};
+ triangle.initialize(&programData);
+
+ Mat4x4 projection = Mat4x4().getOrthographicMatrix(0, 480, 0, 640);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glDepthMask(GL_TRUE);
+ glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
+ glClearDepth(1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ useShader(shader);
+ setShaderMat4(programData.uniformVariables.projection, projection);
+ triangle.render(&programData);
+
+ return EXIT_SUCCESS;
+} \ No newline at end of file