summaryrefslogtreecommitdiff
path: root/frontend/shared_cpp
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/shared_cpp')
-rw-r--r--frontend/shared_cpp/OrthographicRenderer.cpp76
-rw-r--r--frontend/shared_cpp/OrthographicRenderer.h41
-rw-r--r--frontend/shared_cpp/Shader.cpp61
-rw-r--r--frontend/shared_cpp/Shader.h63
-rw-r--r--frontend/shared_cpp/WebglContext.h31
-rw-r--r--frontend/shared_cpp/mathlib.h130
-rw-r--r--frontend/shared_cpp/types.h16
7 files changed, 418 insertions, 0 deletions
diff --git a/frontend/shared_cpp/OrthographicRenderer.cpp b/frontend/shared_cpp/OrthographicRenderer.cpp
new file mode 100644
index 0000000..9dc9892
--- /dev/null
+++ b/frontend/shared_cpp/OrthographicRenderer.cpp
@@ -0,0 +1,76 @@
+#include "OrthographicRenderer.h"
+
+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"
+"}";
+
+void OrthographicRenderer::load() {
+ printf("Compiling orthographic...\n");
+ shader = loadShader(orthographicVertex, orthographicFragment);
+
+ useShader(shader);
+ attributes.position = getShaderAttribute(shader, "position");
+ attributes.color = getShaderAttribute(shader, "color");
+ uniforms.projection = getShaderUniform(shader, "projection");
+ uniforms.model = getShaderUniform(shader, "model");
+
+ printf("Orthographic compiled.\n");
+}
+
+void OrthographicRenderer::render() {
+ useShader(shader);
+ setShaderMat4(uniforms.projection, projection);
+}
+
+void OrthographicRenderer::unload() {
+ glDeleteProgram(shader);
+}
+
+template <uint32 N>
+void OrthographicShape::load(OrthographicRenderer* renderer) {
+ useShader(renderer->shader);
+
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+
+ glGenBuffeloadrs(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, N * sizeof(OrthographicVertex), &vertices[0], GL_STATIC_DRAW);
+
+ glEnableVerloadtexAttribArray(renderer->attributes.position);
+ glVertexAttribPointer(attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)0);
+
+ glEnableVertexAttribArray(renderer->attributes.color);
+ glVertexAttribPointer(attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(OrthographicVertex), (GLvoid *)offsetof(OrthographicVertex, color));
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+}
+
+template <uint32 N>
+void OrthographicShape::render(OrthographicRenderer* renderer) {
+ setShaderMat4(renderer->uniforms.model, model);
+
+ glBindVertexArray(vao);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glBindVertexArray(0);
+}
+
+void OrthographicShape::unload() {
+ glDeleteVertexArrays(1, &vao);
+ gDeleteBuffers(1, &vbo);
+}
diff --git a/frontend/shared_cpp/OrthographicRenderer.h b/frontend/shared_cpp/OrthographicRenderer.h
new file mode 100644
index 0000000..e04b5ec
--- /dev/null
+++ b/frontend/shared_cpp/OrthographicRenderer.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "types.h"
+#include "Shader.h"
+#include "mathlib.h"
+
+struct OrthographicRenderer {
+ Mat4x4 projection;
+ uint32 shader;
+
+ struct {
+ int32 position;
+ int32 color;
+ } attributes;
+
+ struct {
+ int32 projection;
+ int32 model;
+ } uniforms;
+
+ void load();
+ void render();
+ void unload();
+};
+
+struct OrthographicVertex {
+ Vector2 position;
+ Vector2 color;
+};
+
+template <uint32 N>
+struct OrthographicShape {
+ uint32 vao;
+ uint32 vbo;
+ OrthographicVertex vertices[N];
+ Mat4x4 model;
+
+ void load(OrthographicRenderer* renderer);
+ void render(OrthographicRenderer* renderer);
+ void unload();
+};
diff --git a/frontend/shared_cpp/Shader.cpp b/frontend/shared_cpp/Shader.cpp
new file mode 100644
index 0000000..5f2b00e
--- /dev/null
+++ b/frontend/shared_cpp/Shader.cpp
@@ -0,0 +1,61 @@
+#include "Shader.h"
+#include <string>
+
+GLuint loadIndividualShader(GLenum shaderType, const GLchar* cCode) {
+ GLuint shader = glCreateShader(shaderType);
+ glShaderSource(shader, 1, &cCode, 0);
+ glCompileShader(shader);
+ GLint success;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+ if (!success) {
+ GLchar infoLog[512];
+ glGetShaderInfoLog(shader, 512, 0, infoLog);
+ printf("Failed to load shader: %s, Shader =%s\n", infoLog, cCode);
+ return 0;
+ }
+
+ return shader;
+}
+
+void attachShaders(Shader& retVal, const GLchar* vertexShader, const GLchar* fragmentShader) {
+ GLuint vertex = 0, fragment = 0, geometry = 0;
+ if (vertexShader) {
+ vertex = loadIndividualShader(GL_VERTEX_SHADER, vertexShader);
+ glAttachShader(retVal, vertex);
+ }
+
+ if (fragmentShader) {
+ fragment = loadIndividualShader(GL_FRAGMENT_SHADER, fragmentShader);
+ glAttachShader(retVal, fragment);
+ }
+
+ glLinkProgram(retVal);
+ GLint isLinked = 0;
+ glGetProgramiv(retVal, GL_LINK_STATUS, (int*)&isLinked);
+ if (isLinked == GL_FALSE) {
+ GLint maxLength = 0;
+ glGetProgramiv(retVal, GL_INFO_LOG_LENGTH, &maxLength);
+
+ // The maxLength includes the NULL character
+ GLchar* infoLog = new GLchar[maxLength];
+ glGetProgramInfoLog(retVal, maxLength, &maxLength, infoLog);
+ glDeleteProgram(retVal);
+ printf("Error. Could not initialize shader with vertex=%s, error=%s\n", vertexShader, infoLog);
+ delete []infoLog;
+ }
+
+ if (vertexShader)
+ glDeleteShader(vertex);
+ if (fragmentShader)
+ glDeleteShader(fragment);
+}
+
+Shader loadShader(const GLchar* vertexShader, const GLchar* fragmentShader) {
+ Shader retVal;
+ retVal = glCreateProgram();
+
+ attachShaders(retVal, vertexShader, fragmentShader);
+ useShader(retVal);
+
+ return retVal;
+}
diff --git a/frontend/shared_cpp/Shader.h b/frontend/shared_cpp/Shader.h
new file mode 100644
index 0000000..6ee9981
--- /dev/null
+++ b/frontend/shared_cpp/Shader.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <string>
+#include <vector>
+#include "mathlib.h"
+
+typedef GLuint Shader;
+
+Shader loadShader(const GLchar* vertexShader, const GLchar* fragmentShader);
+
+inline GLint getShaderUniform(const Shader& shader, const GLchar *name) {
+ GLint uid = glGetUniformLocation(shader, name);
+ if (uid < 0) {
+ return -1;
+ }
+ return uid;
+}
+
+inline GLint getShaderAttribute(const Shader& shader, const GLchar *name) {
+ printf("Getting attribute for shader, name: %d, %s\n", shader, name);
+ GLint uid = glGetAttribLocation(shader, name);
+ if (uid < 0) {
+ return -1;
+ }
+ return uid;
+}
+
+inline void useShader(const Shader& shader) {
+ glUseProgram(shader);
+}
+
+inline void setShaderFloat(GLint location, GLfloat value) {
+ glUniform1f(location, value);
+}
+
+inline void setShaderInt(GLint location, GLint value) {
+ glUniform1i(location, value);
+}
+
+inline void setShaderUint(GLint location, GLuint value) {
+ glUniform1ui(location, value);
+}
+
+inline void setShaderVec2(GLint location, const Vector2& value) {
+ glUniform2f(location, value.x, value.y);
+}
+
+inline void setShaderMat4(GLint location, const Mat4x4& matrix) {
+ glUniformMatrix4fv(location, 1, GL_FALSE, matrix.m);
+}
+
+inline void setShaderBVec3(GLint location, bool first, bool second, bool third) {
+ glUniform3i(location, first, second, third);
+}
+
+inline void setShaderBVec4(GLint location, bool first, bool second, bool third, bool fourth) {
+ glUniform4i(location, first, second, third, fourth);
+}
+
+inline void setShaderBool(GLint location, bool value) {
+ glUniform1i(location, value);
+} \ No newline at end of file
diff --git a/frontend/shared_cpp/WebglContext.h b/frontend/shared_cpp/WebglContext.h
new file mode 100644
index 0000000..cf9cce2
--- /dev/null
+++ b/frontend/shared_cpp/WebglContext.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <emscripten.h>
+#include <emscripten/html5.h>
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+
+struct WebglContext {
+ void init(const char* query, int width = 640, int height = 480) {
+ emscripten_set_canvas_element_size( query, width, height);
+
+ EmscriptenWebGLContextAttributes attrs;
+ emscripten_webgl_init_context_attributes(&attrs);
+
+ attrs.enableExtensionsByDefault = 1;
+ attrs.majorVersion = 3;
+ attrs.minorVersion = 0;
+
+ context = emscripten_webgl_create_context( "#wasm_canvas", &attrs );
+ makeCurrentContext();
+ };
+
+ void makeCurrentContext() {
+ emscripten_webgl_make_context_current(context);
+ };
+
+ void destroy() {
+ emscripten_webgl_destroy_context(context);
+ }
+
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context;
+};
diff --git a/frontend/shared_cpp/mathlib.h b/frontend/shared_cpp/mathlib.h
new file mode 100644
index 0000000..93ddbbd
--- /dev/null
+++ b/frontend/shared_cpp/mathlib.h
@@ -0,0 +1,130 @@
+#pragma once
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+struct Vector2 {
+ float x = 0;
+ float y = 0;
+
+ Vector2 operator+(Vector2 other) {
+ return { x + other.x, y + other.y };
+ }
+
+ Vector2 operator-(Vector2 other) {
+ return { x - other.x, y - other.y };
+ }
+
+ Vector2 operator*(float s) {
+ return { x * s, y * s };
+ }
+
+ float dot(Vector2 other) {
+ return x * other.x + y * other.y;
+ }
+
+ float length() {
+ return sqrtf(x * x + y * y);
+ }
+
+ Vector2 normalize() {
+ float len = length();
+ float inverseLength = len == 0 ? 1.0 : 1.0 / len;
+
+ return { x * inverseLength, y * inverseLength };
+ }
+
+ Vector2 negate() {
+ return { -x, -y };
+ }
+
+ Vector2 getPerp() {
+ return { -y, x };
+ }
+};
+
+struct Vector3 {
+ float x = 0.f;
+ float y = 0.f;
+ float z = 0.f;
+};
+
+struct Vector4 {
+ float x = 0.f;
+ float y = 0.f;
+ float z = 0.f;
+ float w = 0.f;
+};
+
+struct Mat4x4 {
+ float m[16] = {
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1
+ };
+
+ Mat4x4 copy() {
+ Mat4x4 result;
+ memcpy(result.m, m, sizeof(float) * 16);
+ return result;
+ }
+
+ Mat4x4 scale(Vector3 v) {
+ Mat4x4 result = copy();
+ result.m[0] = result.m[0] * v.x;
+ result.m[5] = result.m[5] *v.y;
+ result.m[10] = result.m[10] * v.z;
+ return result;
+ }
+
+ Mat4x4 translate(Vector3 v) {
+ Mat4x4 result = copy();
+ result.m[12] += v.x;
+ result.m[13] += v.y;
+ result.m[14] += v.z;
+ return result;
+ }
+
+ Mat4x4 translateByVec2(Vector2 v) {
+ Mat4x4 result = copy();
+ result.m[12] += v.x;
+ result.m[13] += v.y;
+ return result;
+ }
+
+ Mat4x4 rotate2D(float angle) {
+ Mat4x4 result = copy();
+ result.m[0] = cos(angle);
+ result.m[1] = -sin(angle);
+ result.m[4] = sin(angle);
+ result.m[5] = cos(angle);
+ return result;
+ }
+
+ Vector2 multByVec2(Vector2 v) {
+ Vector4 vec4 = { v.x, v.y, 0.0, 1.0 };
+ return {
+ vec4.x * m[0] + vec4.y * m[4] + vec4.z * m[8] + vec4.w * m[12],
+ vec4.x * m[1] + vec4.y * m[5] + vec4.z * m[9] + vec4.w * m[13]
+ };
+ }
+
+ Mat4x4 getOrthographicMatrix(float left, float right, float bottom, float top) {
+ Mat4x4 result;
+ result.m[0] = 2.0 / (right - left);
+ result.m[5] = 2.0 / (top - bottom);
+ result.m[10] = 1.0;
+ result.m[12] = -(right + left) / (right - left);
+ result.m[13] = -(top + bottom) / (top - bottom);
+ return result;
+ }
+
+ void print() {
+ printf("[ ");
+ for (int idx = 0; idx < 16; idx++) {
+ printf("%d, ", idx);
+ }
+ printf(" ]\n");
+ }
+};
diff --git a/frontend/shared_cpp/types.h b/frontend/shared_cpp/types.h
new file mode 100644
index 0000000..39d6c17
--- /dev/null
+++ b/frontend/shared_cpp/types.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <cstdint>
+
+typedef int8 int8_t;
+typedef int16 int16_t;
+typedef int32 int32_t;
+typedef int64 int64_t;
+
+typedef uint8 uint8_t;
+typedef uint16 uint16_t;
+typedef uint32 uint32_t;
+typedef uint64 uint;
+
+typedef float32 float;
+typedef float64 double;