From 4079e69fe4107d2a50b122dbd58710bbeb10ace2 Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Thu, 17 Jun 2021 20:02:20 -0400 Subject: (WIP) Getting started in 3d land --- shared_cpp/Camera3d.h | 8 ++++ shared_cpp/Renderer3d.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++++ shared_cpp/Renderer3d.h | 47 +++++++++++++++++++++ shared_cpp/Shader.h | 3 +- shared_cpp/mathlib.h | 21 ++++++++++ 5 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 shared_cpp/Camera3d.h create mode 100644 shared_cpp/Renderer3d.cpp create mode 100644 shared_cpp/Renderer3d.h (limited to 'shared_cpp') diff --git a/shared_cpp/Camera3d.h b/shared_cpp/Camera3d.h new file mode 100644 index 0000000..7186975 --- /dev/null +++ b/shared_cpp/Camera3d.h @@ -0,0 +1,8 @@ +#pragma once + +#include "mathlib.h" + +struct Camera3d { + Mat4x4 projection; + Mat4x4 view; +}; diff --git a/shared_cpp/Renderer3d.cpp b/shared_cpp/Renderer3d.cpp new file mode 100644 index 0000000..7afaea0 --- /dev/null +++ b/shared_cpp/Renderer3d.cpp @@ -0,0 +1,104 @@ +#include "Renderer3d.h" +#include "Camera3d.h" +#include "WebglContext.h" + +const char* vertexSrc = + "attribute vec3 position;\n" + "attribute vec3 normal;\n" + "attribute vec4 color;\n" + "uniform mat4 projection;\n" + "uniform mat4 view;\n" + "uniform mat4 model;\n" + "varying lowp vec4 VertexColor;\n" + "varying lowp vec3 VertexNormal;\n" + "void main() { \n" + " vec4 fragmentPosition = projection * view * model * vec4(position, 1);" + " gl_Position = fragmentPosition;\n" + " VertexColor = color;\n" + " VertexNormal = normal;\n" + "}\n"; + +const char* fragmentSrc = + "varying lowp vec4 VertexColor; \n" + "varying lowp vec3 VertexNormal; \n" + "void main() { \n" + " gl_FragColor = VertexColor; \n" + "}"; + + +void Renderer3d::load(WebglContext* context) { + printf("Compiling 3d shader...\n"); + + shader = loadShader(vertexSrc, fragmentSrc); + + useShader(shader); + attributes.position = getShaderAttribute(shader, "position"); + attributes.color = getShaderAttribute(shader, "color"); + attributes.normal = getShaderAttribute(shader, "normal"); + + uniforms.projection = getShaderUniform(shader, "projection"); + uniforms.view = getShaderUniform(shader, "view"); + uniforms.model = getShaderUniform(shader, "model"); + + printf("3d shader compiled.\n"); +} + +void Renderer3d::render(Camera3d* camera) { + 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(uniforms.projection, camera->projection); + setShaderMat4(uniforms.view, camera->view); +} + +void Renderer3d::unload() { + glClearColor(0.2f, 0.3f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glDeleteProgram(shader); +} + +void Mesh3d::load(Vertex3d* inVertices, uint32 inNumVertices, uint32* inIndices, uint32 inNumIndices, Renderer3d* renderer) { + numIndices = inNumIndices; + useShader(renderer->shader); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + glGenBuffers(1, &vbo); + glGenBuffers(1, &ebo); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, inNumVertices * sizeof(Vertex3d), &inVertices[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, inNumIndices * sizeof(uint32), &inIndices[0], GL_STATIC_DRAW); + + glEnableVertexAttribArray(renderer->attributes.position); + glVertexAttribPointer(renderer->attributes.position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)0); + + glEnableVertexAttribArray(renderer->attributes.normal); + glVertexAttribPointer(renderer->attributes.normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)offsetof(Vertex3d, normal)); + + glEnableVertexAttribArray(renderer->attributes.color); + glVertexAttribPointer(renderer->attributes.color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3d), (GLvoid *)offsetof(Vertex3d, color)); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void Mesh3d::render(Renderer3d* renderer, GLenum drawType) { + setShaderMat4(renderer->uniforms.model, model); + + glBindVertexArray(vao); + glDrawElements(drawType, numIndices, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); +} + +void Mesh3d::unload() { + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} diff --git a/shared_cpp/Renderer3d.h b/shared_cpp/Renderer3d.h new file mode 100644 index 0000000..64288ad --- /dev/null +++ b/shared_cpp/Renderer3d.h @@ -0,0 +1,47 @@ +#pragma once + +#include "types.h" +#include "Shader.h" +#include "mathlib.h" + +struct Camera3d; +struct WebglContext; + +struct Renderer3d { + uint32 shader; + + struct { + int32 position; + int32 color; + int32 normal; + } attributes; + + struct { + int32 projection; + int32 view; + int32 model; + } uniforms; + + void load(WebglContext* context); + void render(Camera3d* camera); + void unload(); +}; + +struct Vertex3d { + Vector3 position; + Vector3 normal; + Vector4 color; +}; + +struct Mesh3d { + uint32 vao; + uint32 vbo; + uint32 ebo; + uint32 numIndices = 0; + + Mat4x4 model; + + void load(Vertex3d* vertices, uint32 numVertices, uint32* indices, uint32 numIndices, Renderer3d* renderer); + void render(Renderer3d* renderer, GLenum drawType = GL_TRIANGLES); + void unload(); +}; diff --git a/shared_cpp/Shader.h b/shared_cpp/Shader.h index 6ee9981..bc81764 100644 --- a/shared_cpp/Shader.h +++ b/shared_cpp/Shader.h @@ -21,6 +21,7 @@ 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) { + printf("Unable to get attribute %s for shader %d\n", name, shader); return -1; } return uid; @@ -60,4 +61,4 @@ inline void setShaderBVec4(GLint location, bool first, bool second, bool third, inline void setShaderBool(GLint location, bool value) { glUniform1i(location, value); -} \ No newline at end of file +} diff --git a/shared_cpp/mathlib.h b/shared_cpp/mathlib.h index 3ed61cd..ec0ae87 100644 --- a/shared_cpp/mathlib.h +++ b/shared_cpp/mathlib.h @@ -87,6 +87,10 @@ struct Vector3 { float x = 0.f; float y = 0.f; float z = 0.f; + + float length() { + return sqrtf(x * x + y * y + z * z); + } }; struct Vector4 { @@ -217,6 +221,21 @@ struct Mat4x4 { return inv; } + Mat4x4 getPerspectiveProjection(float near, float far, float fieldOfViewRadians, float aspectRatio) { + float halfFieldOfView = fieldOfViewRadians * 0.5f; + float top = tan(halfFieldOfView) * near; + float bottom = -top; + float right = top * aspectRatio; + float left = -right; + + return { + { (2 * near) / (right - left), 0, 0, 0, + 0, (2 * near) / (top - bottom), 0, 0, + (right + left) / (right - left), (top + bottom) / (top - bottom), -(far + near) / (far - near), -1, + 0, 0, (-2 * far * near) / (far - near), 0 } + }; + } + void print() { printf("[ "); for (int idx = 0; idx < 16; idx++) { @@ -225,3 +244,5 @@ struct Mat4x4 { printf(" ]\n"); } }; + + -- cgit v1.2.1