diff --git a/.gitmodules b/.gitmodules
index 729155b..3167aa9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "ext/glfw"]
path = ext/glfw
url = https://github.com/glfw/glfw.git
+[submodule "ext/glm"]
+ path = ext/glm
+ url = https://github.com/g-truc/glm.git
diff --git a/LivePlotter.vcxproj b/LivePlotter.vcxproj
index f64b801..d42a03b 100644
--- a/LivePlotter.vcxproj
+++ b/LivePlotter.vcxproj
@@ -72,7 +72,7 @@
$(SolutionDir)ext\glfw\build\src\Debug;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)
- $(SolutionDir)ext\glfw\include;$(SolutionDir)inc;$(IncludePath)
+ $(SolutionDir)ext\glm;$(SolutionDir)ext\glfw\include;$(SolutionDir)inc;$(IncludePath)
$(SolutionDir)bin\$(Platform)\$(Configuration)\
$(SolutionDir)obj\$(Platform)\$(Configuration)\
$(SolutionDir)src;$(SourcePath)
@@ -111,7 +111,7 @@
true
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- stdcpp17
+ stdcpp20
Console
@@ -136,6 +136,7 @@
+
diff --git a/LivePlotter.vcxproj.filters b/LivePlotter.vcxproj.filters
index 42191b5..23a472a 100644
--- a/LivePlotter.vcxproj.filters
+++ b/LivePlotter.vcxproj.filters
@@ -27,5 +27,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/compile_commands.json b/compile_commands.json
index d71ff1b..490054d 100644
--- a/compile_commands.json
+++ b/compile_commands.json
@@ -1,25 +1,31 @@
[
{
- "directory": "C:/Users/sethh/Documents/repos/LivePlotter/",
- "command": "\"C:/Users/sethh/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c++ \"C:/Users/sethh/Documents/repos/LivePlotter/src/util.cpp\" -std=c++17 -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/atlmfc/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/cppwinrt\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/inc\"",
- "file": "C:/Users/sethh/Documents/repos/LivePlotter/src/util.cpp"
+ "directory": "C:/Users/seth/Documents/repos/LivePlotter/",
+ "command": "\"C:/Users/seth/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c++ \"C:/Users/seth/Documents/repos/LivePlotter/src/main.cpp\" -std=c++20 -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/atlmfc/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/cppwinrt\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glm\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/inc\"",
+ "file": "C:/Users/seth/Documents/repos/LivePlotter/src/main.cpp"
}
,
{
- "directory": "C:/Users/sethh/Documents/repos/LivePlotter/",
- "command": "\"C:/Users/sethh/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c \"C:/Users/sethh/Documents/repos/LivePlotter/src/glad.c\" -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/atlmfc/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/cppwinrt\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/inc\"",
- "file": "C:/Users/sethh/Documents/repos/LivePlotter/src/glad.c"
+ "directory": "C:/Users/seth/Documents/repos/LivePlotter/",
+ "command": "\"C:/Users/seth/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c++ \"C:/Users/seth/Documents/repos/LivePlotter/src/shaders.cpp\" -std=c++20 -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/atlmfc/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/cppwinrt\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glm\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/inc\"",
+ "file": "C:/Users/seth/Documents/repos/LivePlotter/src/shaders.cpp"
}
,
{
- "directory": "C:/Users/sethh/Documents/repos/LivePlotter/",
- "command": "\"C:/Users/sethh/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c++ \"C:/Users/sethh/Documents/repos/LivePlotter/src/shaders.cpp\" -std=c++17 -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/atlmfc/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/cppwinrt\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/inc\"",
- "file": "C:/Users/sethh/Documents/repos/LivePlotter/src/shaders.cpp"
+ "directory": "C:/Users/seth/Documents/repos/LivePlotter/",
+ "command": "\"C:/Users/seth/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c \"C:/Users/seth/Documents/repos/LivePlotter/src/glad.c\" -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/atlmfc/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/cppwinrt\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glm\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/inc\"",
+ "file": "C:/Users/seth/Documents/repos/LivePlotter/src/glad.c"
}
,
{
- "directory": "C:/Users/sethh/Documents/repos/LivePlotter/",
- "command": "\"C:/Users/sethh/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c++ \"C:/Users/sethh/Documents/repos/LivePlotter/src/main.cpp\" -std=c++17 -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/atlmfc/include\" -isystem\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.22621.0/cppwinrt\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/sethh/Documents/repos/LivePlotter/inc\"",
- "file": "C:/Users/sethh/Documents/repos/LivePlotter/src/main.cpp"
+ "directory": "C:/Users/seth/Documents/repos/LivePlotter/",
+ "command": "\"C:/Users/seth/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c++ \"C:/Users/seth/Documents/repos/LivePlotter/src/util.cpp\" -std=c++20 -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/atlmfc/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/cppwinrt\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glm\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/inc\"",
+ "file": "C:/Users/seth/Documents/repos/LivePlotter/src/util.cpp"
+ }
+ ,
+ {
+ "directory": "C:/Users/seth/Documents/repos/LivePlotter/",
+ "command": "\"C:/Users/seth/AppData/Roaming/ClangPowerTools/LLVM_Lite/Bin/clang++.exe\" -x c++ \"C:/Users/seth/Documents/repos/LivePlotter/src/body.cpp\" -std=c++20 -Wall -fms-compatibility-version=19.10 -Wmicrosoft -Wno-invalid-token-paste -Wno-unknown-pragmas -Wno-unused-value -fsyntax-only \"-DUNICODE\" \"-D_UNICODE\" \"-D_MT\" \"-D_DLL\" \"-D_DEBUG\" \"-D_CONSOLE\" \"-D_DEBUG_FUNCTIONAL_MACHINERY\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/atlmfc/include\" -isystem\"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Auxiliary/VS/include\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/winrt\" -isystem\"C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/cppwinrt\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glm\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/ext/glfw/include\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/inc\"",
+ "file": "C:/Users/seth/Documents/repos/LivePlotter/src/body.cpp"
}
]
diff --git a/ext/glm b/ext/glm
new file mode 160000
index 0000000..2d4c4b4
--- /dev/null
+++ b/ext/glm
@@ -0,0 +1 @@
+Subproject commit 2d4c4b4dd31fde06cfffad7915c2b3006402322f
diff --git a/inc/body.hpp b/inc/body.hpp
new file mode 100644
index 0000000..e27e766
--- /dev/null
+++ b/inc/body.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include
+#include
+#include "util.hpp"
+
+struct body {
+ glm::mat4 pose;
+ uint ebo;
+ uint vao;
+ uint vbo;
+ uint shader;
+ array verts;
+ array faces;
+ glm::vec4 color;
+};
+
+bool load_body(body* out_body, const char* obj_filepath);
+void draw_body(const body& b);
diff --git a/inc/globj.hpp b/inc/globj.hpp
deleted file mode 100644
index 76b8b2b..0000000
--- a/inc/globj.hpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "util.hpp"
-
-
diff --git a/inc/shaders.hpp b/inc/shaders.hpp
index c4a9404..a344fff 100644
--- a/inc/shaders.hpp
+++ b/inc/shaders.hpp
@@ -2,18 +2,16 @@
#include
#include
+#include
#include "util.hpp"
-namespace shader {
-
// Reads shader source files, compiles, and links
-bool load(uint* out_id, const char* vertex_filepath, const char* fragment_filepath);
+bool load_shader(uint* out_id, const char* vertex_filepath, const char* fragment_filepath);
// Sets shader as active on the gpu
-void use(uint id);
+void use_shader(uint id);
// Set uniform value
-typedef std::variant uniform_variant;
+typedef std::variant
+ uniform_variant;
void set_uniform(uint id, const char* name, uniform_variant value);
-
-} // namespace shaders
diff --git a/inc/util.hpp b/inc/util.hpp
index 0a12000..72cfe09 100644
--- a/inc/util.hpp
+++ b/inc/util.hpp
@@ -5,45 +5,9 @@
template struct array {
T* data;
size_t len;
- T& operator[](int i);
+ inline T& operator[](int i) { return data[i]; }
};
typedef unsigned int uint;
bool read_file(array* out, const char* filepath);
-
-struct vec4 {
- float x;
- float y;
- float z;
- float w;
-};
-
-struct vec3 {
- float x;
- float y;
- float z;
-};
-
-struct vec2 {
- float x;
- float y;
-};
-
-struct vec4i {
- int x;
- int y;
- int z;
- int w;
-};
-
-struct vec3i {
- int x;
- int y;
- int z;
-};
-
-struct vec2i {
- int x;
- int y;
-};
diff --git a/src/body.cpp b/src/body.cpp
new file mode 100644
index 0000000..d10f321
--- /dev/null
+++ b/src/body.cpp
@@ -0,0 +1,120 @@
+#include
+#include
+#include "util.hpp"
+#include "body.hpp"
+#include "shaders.hpp"
+
+enum class ParserState {
+ PREFIX,
+ VERTEX,
+ FACE,
+ FACE_SKIP,
+};
+
+bool load_body(body* out_body, const char* obj_filepath) {
+ array source;
+ if (!read_file(&source, obj_filepath)) {
+ return false;
+ }
+
+ size_t num_verts = 0;
+ size_t num_faces = 0;
+ for (int i = 1; i < source.len; i++) {
+ if (source[i] == ' ' && source[i - 1] == 'v') {
+ num_verts++;
+ } else if (source[i] == ' ' && source[i - 1] == 'f') {
+ num_faces++;
+ }
+ }
+
+ array verts = { (float*)malloc(sizeof(float) * num_verts * 3), num_verts * 3 };
+ array faces = { (int*)malloc(sizeof(int) * num_faces * 3), num_faces*3 };
+
+ // Get ready for the parsing loop
+ ParserState state = ParserState::PREFIX;
+ int vert_i = 0;
+ int face_i = 0;
+ int start = 0;
+
+ for (int i = 1; i < source.len; i++) {
+ if (source[i] == '\n') {
+ state = ParserState::PREFIX;
+ continue;
+ }
+ switch (state) {
+ case ParserState::PREFIX:
+ if (source[i - 1] == 'v' && source[i] == ' ') {
+ state = ParserState::VERTEX;
+ start = i + 1;
+ } else if (i > 0 && source[i - 1] == 'f' && source[i] == ' ') {
+ state = ParserState::FACE;
+ start = i + 1;
+ }
+ break;
+ case ParserState::VERTEX:
+ if (source[i] == ' ' || source[i] == '\r' || source[i] == '\n') {
+ verts[vert_i] = atof(&source[start])/1.5;
+ vert_i++;
+ start = i + 1;
+ }
+ break;
+ case ParserState::FACE:
+ if (source[i] == '/') {
+ state = ParserState::FACE_SKIP;
+ faces[face_i] = atoi(&source[start]) - 1;
+ face_i++;
+ }
+ break;
+ case ParserState::FACE_SKIP:
+ if (source[i] == ' ') {
+ state = ParserState::FACE;
+ start = i + 1;
+ }
+ }
+ }
+
+ // Need a good validation check here. This is a stand in.
+ if (verts.len == 0 || faces.len == 0) {
+ printf(
+ "Obj file appears incomplete or corrupted. Num verts %zu. Num Faces %zu.\n", verts.len, faces.len);
+ return false;
+ }
+
+ uint vao, vbo, ebo;
+
+ glGenVertexArrays(1, &vao);
+ glGenBuffers(1, &vbo);
+ glGenBuffers(1, &ebo);
+
+ glBindVertexArray(vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, verts.len * sizeof(float), verts.data, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces.len * sizeof(int), faces.data, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ *out_body = { .pose = glm::mat4(1),
+ .ebo = ebo,
+ .vao = vao,
+ .vbo = vbo,
+ .shader = 0,
+ .verts = verts,
+ .faces = faces,
+ .color = glm::vec4(0.5, 0.5, 0.5, 1)
+ };
+
+ return true;
+}
+
+void draw_body(const body& b) {
+ use_shader(b.shader);
+ set_uniform(b.shader, "global_t", b.pose);
+ set_uniform(b.shader, "color", b.color);
+ glBindVertexArray(b.vao);
+ glDrawElements(GL_TRIANGLES, b.faces.len, GL_UNSIGNED_INT, 0);
+ //glDisableVertexAttribArray(0);
+}
diff --git a/src/main.cpp b/src/main.cpp
index 91cc7e0..ffaca6c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,24 +1,91 @@
-#include
-#include
#include
#include
-#include
+#include
+#include
+#include
#include
-#include
#include "util.hpp"
#include "shaders.hpp"
+#include "body.hpp"
static GLFWwindow* window;
+static float width, height;
-void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); }
-
-void processInput(GLFWwindow* window) {
- if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
- glfwSetWindowShouldClose(window, true);
+void framebuffer_size_callback(GLFWwindow* window, int w, int h) {
+ width = w;
+ height = h;
+ glViewport(0, 0, width, height);
}
-bool glfw_window_setup() {
+void process_input() {
+ if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
+ glfwSetWindowShouldClose(window, true);
+
+}
+
+static bool mouse_pressed = false;
+static bool scroll_pressed = false;
+static double prev_cursor_x, prev_cursor_y;
+
+static double theta = 0.0; // angle of camera trans vect wrt x-z plane
+static double phi = 0.0; // angle of camera trans vect wrt x-axis
+
+static glm::vec3 camera_loc = glm::vec3(0, 0, 2);
+static glm::vec3 focal_point = glm::vec3(0, 0, 0);
+static glm::vec3 up = glm::vec3(0, 1, 0);
+static glm::mat4 camera_t = glm::lookAt(camera_loc, focal_point, up);
+
+static glm::vec4 strafe_x = camera_t[0];
+static glm::vec4 strafe_y = camera_t[1];
+
+static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) {
+ float dx = (xpos - prev_cursor_x);
+ float dy = (ypos - prev_cursor_y);
+ prev_cursor_x = xpos;
+ prev_cursor_y = ypos;
+ if (mouse_pressed) {
+ phi += dx / width * glm::radians(360.0);
+ theta += dy / height * glm::radians(360.0);
+ }
+
+ if (scroll_pressed) {
+ focal_point += strafe_x * (dx/300) + strafe_y * (dy/300);
+ }
+
+ double len = glm::length(camera_loc);
+ camera_loc.x = len * glm::cos(theta) * glm::cos(-phi);
+ camera_loc.y = len * glm::sin(theta);
+ camera_loc.z = -len * glm::cos(theta) * glm::sin(-phi);
+
+ camera_t = glm::lookAt(camera_loc, focal_point, up);
+}
+
+void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
+ if (button == GLFW_MOUSE_BUTTON_RIGHT) {
+ mouse_pressed = action == GLFW_PRESS;
+ }
+
+ if (button == GLFW_MOUSE_BUTTON_MIDDLE) {
+ scroll_pressed = action == GLFW_PRESS;
+ strafe_x = camera_t[0];
+ strafe_y = camera_t[1];
+ }
+
+ glfwGetCursorPos(window, &prev_cursor_x, &prev_cursor_y);
+}
+
+void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
+{
+ glm::vec4 k = camera_t[2];
+ float d = yoffset;
+
+ camera_loc += k * (-d * glm::length(camera_loc) / 10);
+
+ camera_t = glm::lookAt(camera_loc, focal_point, up);
+}
+
+bool glfw_setup() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
@@ -26,147 +93,72 @@ bool glfw_window_setup() {
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
window = glfwCreateWindow(800, 800, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
- std::cout << "Failed to create GLFW windoww" << std::endl;
+ printf("Failed to create GLFW window\n");
glfwTerminate();
return false;
}
glfwMakeContextCurrent(window);
+ glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
+ glfwSetCursorPosCallback(window, cursor_position_callback);
+ glfwSetMouseButtonCallback(window, mouse_button_callback);
+ glfwSetScrollCallback(window, scroll_callback);
+
+ cursor_position_callback(window, 0, 0);
return true;
}
-enum class ParserState {
- PREFIX,
- VERTEX,
- FACE,
- FACE_SKIP,
-};
-std::optional, array>> load_icosphere() {
- std::FILE* f = NULL;
-
- if (fopen_s(&f, "Icosphere.obj", "r")) {
- return {};
- }
-
- // MEMORY LEAK!!! 84 verts currently
- float* vert_data = (float*)malloc(sizeof(float) * 128);
- size_t vert_data_size = 0;
-
- // MEMORY LEAK!!! (I think)
- unsigned int* indices_data = (unsigned int*)malloc(sizeof(int) * 256);
- size_t indices_data_size = 0;
-
- ParserState state = ParserState::PREFIX;
-
- char ln[128];
- int len = 0;
- int start = 0;
- while ((ln[len] = std::fgetc(f)) != EOF) {
- switch (state) {
- case ParserState::PREFIX:
- if (len > 0 && ln[len - 1] == 'v' && ln[len] == ' ') {
- state = ParserState::VERTEX;
- start = len + 1;
- } else if (len > 0 && ln[len - 1] == 'f' && ln[len] == ' ') {
- state = ParserState::FACE;
- start = len + 1;
- }
- break;
- case ParserState::VERTEX:
- if (ln[len] == ' ' || ln[len] == '\n') {
- vert_data[vert_data_size] = atof(&ln[start]);
- vert_data_size++;
- start = len + 1;
- }
- break;
- case ParserState::FACE:
- if (ln[len] == '/') {
- state = ParserState::FACE_SKIP;
- indices_data[indices_data_size] = atoi(&ln[start]) - 1;
- indices_data_size++;
- }
- break;
- case ParserState::FACE_SKIP:
- if (ln[len] == ' ') {
- state = ParserState::FACE;
- start = len + 1;
- }
- }
-
- if (ln[len] == '\n') {
- len = 0;
- state = ParserState::PREFIX;
- }
- len++;
- }
-
- array verts = { vert_data, vert_data_size };
- array indices = { indices_data, indices_data_size };
-
- return std::make_pair(verts, indices);
-}
int main() {
- if (!glfw_window_setup())
+ if (!glfw_setup())
return -1;
- auto data = load_icosphere();
- if (!data) {
- std::cout << "ERROR loading the icosphere obj file failed" << std::endl;
- return -1;
- }
-
- auto verts = data.value().first;
- auto indices = data.value().second;
-
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
- std::cout << "Failed to initialize GLAD" << std::endl;
+ printf("Failed to initialize GLAD\n");
return -1;
}
glViewport(0, 0, 800, 800);
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
+ width = 800;
+ height = 800;
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
+ uint shader;
+ const char* vertex_filepath = "src/shaders/vertex.glsl";
+ const char* fragment_filepath = "src/shaders/fragment.glsl";
+ if (!load_shader(&shader, vertex_filepath, fragment_filepath))
+ return -1;
+
+ //glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
+ glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT); // Write to back buffer
glfwSwapBuffers(window); // front buffer is now back
glClear(GL_COLOR_BUFFER_BIT); // Write to back buffer again (former front buf)
- unsigned int VAO;
- glGenVertexArrays(1, &VAO);
- glBindVertexArray(VAO);
-
- unsigned int VBO;
- glGenBuffers(1, &VBO);
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, verts.len * sizeof(float), verts.data, GL_STATIC_DRAW);
-
- unsigned int EBO;
- glGenBuffers(1, &EBO);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.len * sizeof(unsigned int), indices.data, GL_STATIC_DRAW);
-
- uint program_id;
- const char* vertex_filepath = "src/shaders/vertex.glsl";
- const char* fragment_filepath = "src/shaders/fragment.glsl";
- if (!shader::load(&program_id, vertex_filepath, fragment_filepath))
+ body b;
+ if (!load_body(&b, "Icosphere.obj"))
return -1;
- shader::use(program_id);
-
- // Tell opengl which attribute our data is for (i.e. location)
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
+ b.shader = shader;
+ b.pose = glm::translate(b.pose, glm::vec3(0, 0, 0));
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ //set_uniform(shader, "color", glm::vec4 { sin(time), sin(time + glm::radians(45.0f)), sin(time + glm::radians(90.0f)), 1.0 } / 2.0f);
+ //time = glfwGetTime();
+
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+
+ float time;
+
+ glm::mat4 projection_t
+ = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.1f, 1300.0f);
while (!glfwWindowShouldClose(window)) {
- float time = glfwGetTime();
- shader::set_uniform(program_id, "color", vec4 { 1, sin(time), 1, 1.0 });
- shader::use(program_id);
- glClear(GL_COLOR_BUFFER_BIT);
- glDrawElements(GL_TRIANGLES, indices.len, GL_UNSIGNED_INT, 0);
- glBindVertexArray(VAO);
+ process_input();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ set_uniform(b.shader, "projection_t", projection_t);
+ set_uniform(b.shader, "camera_t", camera_t);
+ draw_body(b);
- processInput(window);
glfwSwapBuffers(window);
glfwPollEvents();
}
diff --git a/src/shaders.cpp b/src/shaders.cpp
index 2c66c7c..127c456 100644
--- a/src/shaders.cpp
+++ b/src/shaders.cpp
@@ -1,5 +1,7 @@
-#include
+#include
#include
+#include
+#include
#include "util.hpp"
#include "shaders.hpp"
@@ -14,11 +16,9 @@ struct overload : Ts ... {
};
template overload(Ts...) -> overload;
-namespace shader {
-
bool _compile_shader(uint *out_id, const char* filepath, int shader_type);
-bool load(uint* out_id, const char* vertex_filepath, const char* fragment_filepath) {
+bool load_shader(uint* out_id, const char* vertex_filepath, const char* fragment_filepath) {
uint vertex_id;
if (!_compile_shader(&vertex_id, vertex_filepath, GL_VERTEX_SHADER))
return false;
@@ -49,25 +49,24 @@ bool load(uint* out_id, const char* vertex_filepath, const char* fragment_filepa
return true;
}
-void use(uint id) { glUseProgram(id); }
+void use_shader(uint id) { glUseProgram(id); }
void set_uniform(uint id, const char* name, uniform_variant value) {
const auto visitor = overload {
[id, name](int i) { glUniform1i(glGetUniformLocation(id, name), i); },
[id, name](float f) { glUniform1f(glGetUniformLocation(id, name), f); },
[id, name](bool b) { glUniform1i(glGetUniformLocation(id, name), b); },
- [id, name](vec4 v) { glUniform4f(glGetUniformLocation(id, name), v.x, v.y, v.z, v.w); },
- [id, name](vec3 v) { glUniform3f(glGetUniformLocation(id, name), v.x, v.y, v.z); },
- [id, name](vec2 v) { glUniform2f(glGetUniformLocation(id, name), v.x, v.y); },
- [id, name](vec4i v) { glUniform4i(glGetUniformLocation(id, name), v.x, v.y, v.z, v.w); },
- [id, name](vec3i v) { glUniform3i(glGetUniformLocation(id, name), v.x, v.y, v.z); },
- [id, name](vec2i v) { glUniform2i(glGetUniformLocation(id, name), v.x, v.y); },
+ [id, name](glm::vec4 v) { glUniform4f(glGetUniformLocation(id, name), v.x, v.y, v.z, v.w); },
+ [id, name](glm::vec3 v) { glUniform3f(glGetUniformLocation(id, name), v.x, v.y, v.z); },
+ [id, name](glm::vec2 v) { glUniform2f(glGetUniformLocation(id, name), v.x, v.y); },
+ [id, name](glm::ivec4 v) { glUniform4i(glGetUniformLocation(id, name), v.x, v.y, v.z, v.w); },
+ [id, name](glm::ivec3 v) { glUniform3i(glGetUniformLocation(id, name), v.x, v.y, v.z); },
+ [id, name](glm::ivec2 v) { glUniform2i(glGetUniformLocation(id, name), v.x, v.y); },
+ [id, name](glm::mat4 v) { glUniformMatrix4fv(glGetUniformLocation(id, name), 1, GL_FALSE, glm::value_ptr(v)); },
};
visit(visitor, value);
}
-// Privates
-
bool _compile_shader(uint *out_id, const char* filepath, int shader_type) {
array source;
if (!read_file(&source, filepath))
@@ -77,6 +76,8 @@ bool _compile_shader(uint *out_id, const char* filepath, int shader_type) {
glShaderSource(id, 1, &source.data, (int*)&source.len);
glCompileShader(id);
+ free(source.data);
+
int status;
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
@@ -89,5 +90,3 @@ bool _compile_shader(uint *out_id, const char* filepath, int shader_type) {
*out_id = id;
return status == GL_TRUE;
}
-
-} // namespace shader
diff --git a/src/shaders/fragment.glsl b/src/shaders/fragment.glsl
index 2b3c651..978727c 100644
--- a/src/shaders/fragment.glsl
+++ b/src/shaders/fragment.glsl
@@ -2,8 +2,15 @@
uniform vec4 color;
+in vec3 frag_pos;
+
out vec4 frag_color;
void main() {
- frag_color = color;
+ vec3 dx = dFdx(frag_pos) * 100;
+ vec3 dy = dFdy(frag_pos) * 100;
+ vec3 N = normalize(cross(dFdx(frag_pos), dFdy(frag_pos)));
+ frag_color = color + vec4(N/2, 1)/3;
+ //frag_color = vec4(length(dx), length(dy), length(dy), 1.0);
+ //frag_color += color;
}
diff --git a/src/shaders/vertex.glsl b/src/shaders/vertex.glsl
index d126556..03ca3e6 100644
--- a/src/shaders/vertex.glsl
+++ b/src/shaders/vertex.glsl
@@ -1,8 +1,13 @@
#version 330 core
-layout (location = 0) in vec3 pos;
-uniform vec4 color;
+layout (location = 0) in vec3 pos;
+out vec3 frag_pos;
+
+uniform mat4 global_t;
+uniform mat4 camera_t;
+uniform mat4 projection_t;
void main() {
- gl_Position = vec4(pos.x, pos.y, pos.z, 1.0);
+ gl_Position = projection_t * camera_t * global_t * vec4(pos.x, pos.y, pos.z, 1.0);
+ frag_pos = pos;
}
diff --git a/src/util.cpp b/src/util.cpp
index 351a15d..c69b6c5 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1,4 +1,5 @@
#include
+#include
#include
#include "util.hpp"