diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..bcb2903
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,8 @@
+# Format Style Options - Created with Clang Power Tools
+---
+BasedOnStyle: WebKit
+BreakBeforeBraces: Attach
+ColumnLimit: 110
+SortIncludes: false
+SpaceAfterTemplateKeyword: false
+...
diff --git a/.gitignore b/.gitignore
index 2d84e6d..82c309d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ x64**
**.idb
**.pdb
**.exe
+.cache**
diff --git a/LivePlotter.vcxproj b/LivePlotter.vcxproj
index ca2b0d7..4c85fdf 100644
--- a/LivePlotter.vcxproj
+++ b/LivePlotter.vcxproj
@@ -73,6 +73,9 @@
$(SolutionDir)ext\glfw\build\src\Debug;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)
$(SolutionDir)ext\glfw\include;$(SolutionDir)inc;$(IncludePath)
+ $(SolutionDir)bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)obj\$(Platform)\$(Configuration)\
+ $(SolutionDir)src;$(SourcePath)
@@ -135,6 +138,8 @@
+
+
diff --git a/LivePlotter.vcxproj.filters b/LivePlotter.vcxproj.filters
index bead6d0..7d52e7e 100644
--- a/LivePlotter.vcxproj.filters
+++ b/LivePlotter.vcxproj.filters
@@ -21,5 +21,11 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
\ No newline at end of file
diff --git a/compile_commands.json b/compile_commands.json
new file mode 100644
index 0000000..ead1093
--- /dev/null
+++ b/compile_commands.json
@@ -0,0 +1,13 @@
+[
+ {
+ "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/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/glfw/include\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/inc\"",
+ "file": "C:/Users/seth/Documents/repos/LivePlotter/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/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 (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/glfw/include\" -isystem\"C:/Users/seth/Documents/repos/LivePlotter/inc\"",
+ "file": "C:/Users/seth/Documents/repos/LivePlotter/src/main.cpp"
+ }
+]
diff --git a/inc/shaders.hpp b/inc/shaders.hpp
new file mode 100644
index 0000000..470f530
--- /dev/null
+++ b/inc/shaders.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#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);
+
+// Sets shader as active on the gpu
+void use(uint id);
+
+// Set uniform value
+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
new file mode 100644
index 0000000..9c46f73
--- /dev/null
+++ b/inc/util.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include
+
+template struct Array {
+ T* _data;
+ size_t len;
+
+ T& operator[](int i);
+};
+
+typedef unsigned int uint;
+
+bool read_file(Array* out, const char* filepath);
diff --git a/src/main.cpp b/src/main.cpp
index 5754432..64c48e1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,26 +1,13 @@
#include
#include
#include
-#include
#include
#include
+#include "shaders.hpp"
+
using namespace std;
-const char* vertexShaderSource = "#version 330 core\n"
- "layout (location = 0) in vec3 aPos;\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
- "}\0";
-
-const char* fragmentShaderSource = "#version 330 core\n"
- "out vec4 FragColor;\n"
- "void main()\n"
- "{\n"
- " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);"
- "} ";
-
static GLFWwindow* window;
template
@@ -62,9 +49,9 @@ enum class ParserState {
FACE,
FACE_SKIP,
};
-optional, SimpleArray>> load_iconsphere() {
+optional, SimpleArray>> load_icosphere() {
std::FILE* f = NULL;
-
+
if (fopen_s(&f, "Icosphere.obj", "r")) {
return {};
}
@@ -133,7 +120,7 @@ int main()
{
if (!glfw_window_setup()) return -1;
- auto data = load_iconsphere();
+ auto data = load_icosphere();
if (!data) {
std::cout << "ERROR loading the icosphere obj file failed" << std::endl;
return -1;
@@ -156,12 +143,6 @@ int main()
glfwSwapBuffers(window); // front buffer is now back
glClear(GL_COLOR_BUFFER_BIT); // Write to back buffer again (former front buf)
- /*float vertices[] = {
- -0.5f, -0.5f, 0.0f,
- 0.5f, -0.5f, 0.0f,
- 0.0f, 0.5f, 0.0f
- };*/
-
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
@@ -175,54 +156,10 @@ int main()
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size * sizeof(unsigned int), indices.data, GL_STATIC_DRAW);
-
- // Vertex shader
- unsigned int vertexShader;
- vertexShader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
- glCompileShader(vertexShader);
-
- // Verify vertex shader compilation
- int success;
- char infoLog[512];
- glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
- std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
- }
- // Fragment shader
- unsigned int fragmentShader;
- fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
- glCompileShader(fragmentShader);
-
- // Verify fragment shader compilation
- glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
- std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
- }
-
- // Link shader programs together
- unsigned int shaderProgram;
- shaderProgram = glCreateProgram();
- glAttachShader(shaderProgram, vertexShader);
- glAttachShader(shaderProgram, fragmentShader);
- glLinkProgram(shaderProgram);
- glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
- if (!success) {
- glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
- std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
- }
- glUseProgram(shaderProgram); // Set shaderProgram as active shader
-
- // Delete shader program parts (like deleting obj files).
- // We want this memory back
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
+ uint program_id;
+ if (!shader::load(&program_id, "src/shaders/vertex.vs", "src/shaders/fragment.fs")) 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);
@@ -242,4 +179,4 @@ int main()
}
glfwTerminate();
return 0;
-}
\ No newline at end of file
+}
diff --git a/src/shaders.cpp b/src/shaders.cpp
new file mode 100644
index 0000000..e5ece76
--- /dev/null
+++ b/src/shaders.cpp
@@ -0,0 +1,88 @@
+#include
+#include
+
+#include "util.hpp"
+#include "shaders.hpp"
+
+#define MAX_ERR_MSG_LEN 256
+
+
+// Visit/Variant overload pattern
+// https://www.modernescpp.com/index.php/visiting-a-std-variant-with-the-overload-pattern/
+template
+struct overload : Ts ... {
+ using Ts::operator() ...;
+};
+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) {
+ uint vertex_id;
+ if (!_compile_shader(&vertex_id, vertex_filepath, GL_VERTEX_SHADER))
+ return false;
+
+ uint fragment_id;
+ if (!_compile_shader(&fragment_id, fragment_filepath, GL_FRAGMENT_SHADER))
+ return false;
+
+ uint program_id = glCreateProgram();
+ glAttachShader(program_id, vertex_id);
+ glAttachShader(program_id, fragment_id);
+ glLinkProgram(program_id);
+
+ int status;
+ glGetProgramiv(program_id, GL_LINK_STATUS, &status);
+ if (status == GL_FALSE) {
+ char err_msg[MAX_ERR_MSG_LEN];
+ glGetProgramInfoLog(program_id, MAX_ERR_MSG_LEN, NULL, err_msg);
+ printf("Error linking shaders %s and %s\n", vertex_filepath, fragment_filepath);
+ printf("Error msg: %s\n", err_msg);
+ return false;
+ }
+
+ glDeleteShader(vertex_id);
+ glDeleteShader(fragment_id);
+
+ *out_id = program_id;
+ return true;
+}
+
+void use(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); },
+ };
+ visit(visitor, value);
+}
+
+// Privates
+
+bool _compile_shader(uint *out_id, const char* filepath, int shader_type) {
+ Array source;
+ if (!read_file(&source, filepath))
+ return false;
+
+ uint id = glCreateShader(shader_type);
+ glShaderSource(id, 1, &source._data, (int*)&source.len);
+ glCompileShader(id);
+
+ int status;
+ glGetShaderiv(id, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE) {
+ char err_msg[MAX_ERR_MSG_LEN];
+ glGetShaderInfoLog(id, MAX_ERR_MSG_LEN, NULL, err_msg);
+ printf("Error compiling shader %s\n", filepath);
+ printf("%.*s\n", (int)source.len, source._data);
+ printf("Error msg: %s\n", err_msg);
+ }
+ *out_id = id;
+ return status == GL_TRUE;
+}
+
+} // namespace shader
diff --git a/src/shaders/fragment.fs b/src/shaders/fragment.fs
new file mode 100644
index 0000000..d7b1433
--- /dev/null
+++ b/src/shaders/fragment.fs
@@ -0,0 +1,7 @@
+#version 330 core
+
+out vec4 frag_color;
+
+void main() {
+ frag_color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
+}
diff --git a/src/shaders/vertex.vs b/src/shaders/vertex.vs
new file mode 100644
index 0000000..e390af0
--- /dev/null
+++ b/src/shaders/vertex.vs
@@ -0,0 +1,6 @@
+#version 330 core
+layout (location = 0) in vec3 aPos;
+
+void main() {
+ gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
+}
diff --git a/src/util.cpp b/src/util.cpp
new file mode 100644
index 0000000..af994b3
--- /dev/null
+++ b/src/util.cpp
@@ -0,0 +1,23 @@
+#include
+#include
+
+#include "util.hpp"
+
+bool read_file(Array* out, const char* filepath) {
+ FILE* fp = NULL;
+ if (fopen_s(&fp, filepath, "r") != 0) {
+ printf("ERROR Failed to open file %s\n", filepath);
+ return false;
+ }
+
+ fseek(fp, 0L, SEEK_END);
+ size_t sz = ftell(fp);
+ fseek(fp, 0L, 0L);
+
+ char *data = (char*)malloc(sizeof(char)*sz);
+ fread(data, sizeof(char), sz, fp);
+ fclose(fp);
+ out->_data = data;
+ out->len = sz;
+ return true;
+}