diff options
author | Matthew Kosarek <matthew.kosarek@vention.cc> | 2021-03-13 15:43:56 -0500 |
---|---|---|
committer | Matthew Kosarek <matthew.kosarek@vention.cc> | 2021-03-13 15:43:56 -0500 |
commit | 98d7d6cb702af2708f20e7cf16ee10a9f71b578a (patch) | |
tree | 92cec56a5a31a9658c44d49ed896ba8b7859450f /frontend/_wasm/wasm.cpp | |
parent | 3b0514ed3a21c39b7ea1a68d2fb381c808dcfeeb (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.cpp | 145 |
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 |