aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--LICENSE2
-rw-r--r--README.md3
-rw-r--r--include/RenderBackend/OpenGL/DeviceMemory.hpp3
-rw-r--r--include/RenderBackend/OpenGL/ShaderProgram.hpp7
-rw-r--r--include/RenderBackend/OpenGL/Uniform.hpp29
-rw-r--r--include/Result.hpp12
-rw-r--r--include/Triangle.hpp23
-rw-r--r--include/Triangle2D.hpp16
-rw-r--r--include/Vertex.hpp28
-rw-r--r--include/Vertex2D.hpp18
-rw-r--r--shaders/fragment.frag3
-rw-r--r--shaders/vertex.vert8
-rw-r--r--src/RenderBackend/OpenGL/DeviceMemory.cpp9
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp19
-rw-r--r--src/RenderBackend/OpenGL/Uniform.cpp24
-rw-r--r--src/main.cpp101
17 files changed, 226 insertions, 80 deletions
diff --git a/.gitignore b/.gitignore
index a9b6c2d..d758aec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
sibs-build
.kdev4
amalgine.kdev4
+compile_commands.json
diff --git a/LICENSE b/LICENSE
index b3402c4..1bb2d01 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2017 dec05eba
+Copyright (c) 2017 DEC05EBA
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/README.md b/README.md
index ed3496f..2168a8a 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,6 @@ glfw3
glew
glm
sibs (https://github.com/DEC05EBA/sibs)
+
+# TODO
+Make use shader a no-op if already in use \ No newline at end of file
diff --git a/include/RenderBackend/OpenGL/DeviceMemory.hpp b/include/RenderBackend/OpenGL/DeviceMemory.hpp
index c9c8b23..3ccd0c9 100644
--- a/include/RenderBackend/OpenGL/DeviceMemory.hpp
+++ b/include/RenderBackend/OpenGL/DeviceMemory.hpp
@@ -2,7 +2,7 @@
#include "../../DataView.hpp"
#include "../../utils.hpp"
-#include "../../Triangle2D.hpp"
+#include "../../Triangle.hpp"
namespace amalgine {
enum class DeviceMemoryType {
@@ -37,6 +37,7 @@ namespace amalgine {
~DeviceMemory();
//void copy(const DataView<f32> &data, StorageType storageType, PrimitiveType primitiveType = PrimitiveType::TRIANGLE);
void copy(const DataView<Triangle2D> &triangles, StorageType storageType);
+ void copy(const DataView<Triangle3D> &triangles, StorageType storageType);
void draw();
DeviceMemoryType get_type() const { return type; }
diff --git a/include/RenderBackend/OpenGL/ShaderProgram.hpp b/include/RenderBackend/OpenGL/ShaderProgram.hpp
index ca96d0c..f1fea00 100644
--- a/include/RenderBackend/OpenGL/ShaderProgram.hpp
+++ b/include/RenderBackend/OpenGL/ShaderProgram.hpp
@@ -4,9 +4,13 @@
#include "../../types.hpp"
#include "../../utils.hpp"
#include "../../Vec.hpp"
+#include "Uniform.hpp"
#include "DeviceMemory.hpp"
+
#include <vector>
#include <memory>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
namespace amalgine {
class Shader;
@@ -17,7 +21,8 @@ namespace amalgine {
public:
~ShaderProgram();
static Result<std::unique_ptr<ShaderProgram>> build(const std::vector<Shader*> &shaders);
- int set_uniform(const char *name, const vec3f &value);
+
+ Result<Uniform> get_uniform_by_name(const char *name);
int set_vertex_input(const char *name, const DeviceMemory &data);
void use();
diff --git a/include/RenderBackend/OpenGL/Uniform.hpp b/include/RenderBackend/OpenGL/Uniform.hpp
new file mode 100644
index 0000000..288c9b8
--- /dev/null
+++ b/include/RenderBackend/OpenGL/Uniform.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "../../Result.hpp"
+#include "../../types.hpp"
+#include "../../utils.hpp"
+#include "../../Vec.hpp"
+
+#include <glm/gtc/type_ptr.hpp>
+
+namespace amalgine {
+ class Uniform {
+ DISABLE_COPY(Uniform)
+ friend class ShaderProgram;
+ friend class Result<Uniform>;
+ public:
+ Uniform(Uniform&&) = default;
+ ~Uniform();
+
+ void set(const vec3f &value);
+ void set(const glm::mat4 &value);
+ private:
+ Uniform(){}
+ Uniform(i32 uniform_id, u32 shader_program_id);
+ void use();
+ private:
+ i32 uniform_id;
+ u32 program_id;
+ };
+}
diff --git a/include/Result.hpp b/include/Result.hpp
index 50a0d0c..86ae176 100644
--- a/include/Result.hpp
+++ b/include/Result.hpp
@@ -11,9 +11,7 @@ namespace amalgine
public:
static Result<T> Ok(T data)
{
- Result<T> result;
- result.data = std::move(data);
- result.errorCode = 0;
+ Result<T> result(std::move(data));
return result;
}
@@ -42,11 +40,17 @@ namespace amalgine
assert(isOk());
return data;
}
+
+ T* operator -> () {
+ assert(isOk());
+ return &data;
+ }
const std::string& getErrorMsg() const { return errorMsg; }
int getErrorCode() const { return errorCode; }
private:
- Result(){}
+ Result() {}
+ Result(T data) : data(std::move(data)), errorCode(0) {}
private:
T data;
int errorCode;
diff --git a/include/Triangle.hpp b/include/Triangle.hpp
new file mode 100644
index 0000000..5caff05
--- /dev/null
+++ b/include/Triangle.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "Vertex.hpp"
+
+namespace amalgine {
+ class Triangle2D {
+ public:
+ Triangle2D(const Vertex2D &_p1, const Vertex2D &_p2, const Vertex2D &_p3) : p1(_p1), p2(_p2), p3(_p3) {}
+
+ Vertex2D p1;
+ Vertex2D p2;
+ Vertex2D p3;
+ };
+
+ class Triangle3D {
+ public:
+ Triangle3D(const Vertex3D &_p1, const Vertex3D &_p2, const Vertex3D &_p3) : p1(_p1), p2(_p2), p3(_p3) {}
+
+ Vertex3D p1;
+ Vertex3D p2;
+ Vertex3D p3;
+ };
+}
diff --git a/include/Triangle2D.hpp b/include/Triangle2D.hpp
deleted file mode 100644
index d5d76bd..0000000
--- a/include/Triangle2D.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include "Vertex2D.hpp"
-
-namespace amalgine
-{
- class Triangle2D
- {
- public:
- Triangle2D(const Vertex2D &_p1, const Vertex2D &_p2, const Vertex2D &_p3) : p1(_p1), p2(_p2), p3(_p3) {}
-
- Vertex2D p1;
- Vertex2D p2;
- Vertex2D p3;
- };
-}
diff --git a/include/Vertex.hpp b/include/Vertex.hpp
new file mode 100644
index 0000000..ab98d3b
--- /dev/null
+++ b/include/Vertex.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "types.hpp"
+
+namespace amalgine {
+ class Vertex2D {
+ public:
+ Vertex2D(f32 _x = 0.0f, f32 _y = 0.0f) : x(_x), y(_y)
+ {
+
+ }
+
+ f32 x;
+ f32 y;
+ };
+
+ class Vertex3D {
+ public:
+ Vertex3D(f32 _x = 0.0f, f32 _y = 0.0f, f32 _z = 0.0f) : x(_x), y(_y), z(_z)
+ {
+
+ }
+
+ f32 x;
+ f32 y;
+ f32 z;
+ };
+} \ No newline at end of file
diff --git a/include/Vertex2D.hpp b/include/Vertex2D.hpp
deleted file mode 100644
index de22cd9..0000000
--- a/include/Vertex2D.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include "types.hpp"
-
-namespace amalgine
-{
- class Vertex2D
- {
- public:
- Vertex2D(f32 _x = 0.0f, f32 _y = 0.0f) : x(_x), y(_y)
- {
-
- }
-
- f32 x;
- f32 y;
- };
-}
diff --git a/shaders/fragment.frag b/shaders/fragment.frag
index ea1ca7d..60791c2 100644
--- a/shaders/fragment.frag
+++ b/shaders/fragment.frag
@@ -1,8 +1,9 @@
#version 330 core
-uniform vec3 triangle_color;
out vec4 out_color;
+uniform vec3 triangle_color;
+
void main() {
out_color = vec4(triangle_color, 1.0);
} \ No newline at end of file
diff --git a/shaders/vertex.vert b/shaders/vertex.vert
index d1cc433..a44217b 100644
--- a/shaders/vertex.vert
+++ b/shaders/vertex.vert
@@ -1,7 +1,11 @@
#version 330 core
-in vec2 position;
+in vec3 position;
+
+uniform mat4 proj;
+uniform mat4 view;
+uniform mat4 model;
void main() {
- gl_Position = vec4(position, 0.0, 1.0);
+ gl_Position = proj * view * model * vec4(position, 1.0);
} \ No newline at end of file
diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp
index 2d40569..f071cd8 100644
--- a/src/RenderBackend/OpenGL/DeviceMemory.cpp
+++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp
@@ -65,6 +65,15 @@ namespace amalgine
numVertices = triangles.size * 3;
type = DeviceMemoryType::VEC2;
}
+
+ void DeviceMemory::copy(const DataView<Triangle3D> &triangles, StorageType storageType)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
+ glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType));
+ primitiveType = GL_TRIANGLES;
+ numVertices = triangles.size * 3;
+ type = DeviceMemoryType::VEC3;
+ }
void DeviceMemory::draw()
{
diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp
index e613668..389a929 100644
--- a/src/RenderBackend/OpenGL/ShaderProgram.cpp
+++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp
@@ -64,13 +64,13 @@ namespace amalgine {
return Result<std::unique_ptr<ShaderProgram>>::Ok(std::move(shader_program));
}
- int ShaderProgram::set_uniform(const char *name, const vec3f &value) {
- GLint uniformId = glGetUniformLocation(program_id, name);
- if(uniformId == -1)
- return -1;
- use();
- glUniform3f(uniformId, value.x, value.y, value.z);
- return 0;
+ Result<Uniform> ShaderProgram::get_uniform_by_name(const char *name) {
+ GLint uniform_id = glGetUniformLocation(program_id, name);
+ if(uniform_id == -1)
+ return Result<Uniform>::Err(std::string("Uniform with name ") + name + " was not found");
+
+ Uniform uniform(uniform_id, program_id);
+ return Result<Uniform>::Ok(std::move(uniform));
}
int ShaderProgram::set_vertex_input(const char *name, const DeviceMemory &data) {
@@ -88,7 +88,10 @@ namespace amalgine {
glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
break;
}
- case DeviceMemoryType::VEC3: assert(false); return -1;
+ case DeviceMemoryType::VEC3: {
+ glVertexAttribPointer(attrib_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ break;
+ }
}
glEnableVertexAttribArray(attrib_location);
return 0;
diff --git a/src/RenderBackend/OpenGL/Uniform.cpp b/src/RenderBackend/OpenGL/Uniform.cpp
new file mode 100644
index 0000000..67cf3c6
--- /dev/null
+++ b/src/RenderBackend/OpenGL/Uniform.cpp
@@ -0,0 +1,24 @@
+#include "../../../include/RenderBackend/OpenGL/Uniform.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+
+namespace amalgine {
+ Uniform::~Uniform() {}
+
+ void Uniform::set(const vec3f &value) {
+ use();
+ glUniform3f(uniform_id, value.x, value.y, value.z);
+ }
+
+ void Uniform::set(const glm::mat4 &value) {
+ use();
+ glUniformMatrix4fv(uniform_id, 1, GL_FALSE, glm::value_ptr(value));
+ }
+
+ Uniform::Uniform(i32 uniform_id, u32 shader_program_id) : uniform_id(uniform_id), program_id(shader_program_id) {
+
+ }
+
+ void Uniform::use() {
+ glUseProgram(program_id);
+ }
+} \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index f6f827f..c073a43 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,13 +1,12 @@
-#include <cstdio>
#include "../include/RenderBackend/OpenGL/opengl.hpp"
#include "../include/RenderBackend/OpenGL/Shader.hpp"
#include "../include/RenderBackend/OpenGL/ShaderProgram.hpp"
#include "../include/RenderBackend/OpenGL/DeviceMemory.hpp"
#include "../include/RenderBackend/OpenGL/DeviceFrame.hpp"
-#include "../include/Triangle2D.hpp"
+#include "../include/Triangle.hpp"
-// TODO: Disallow shader variables that begin with "gl_" as reserved variables
-// start with that. What about hlsl?
+#include <cstdio>
+#include <chrono>
// TODO: Creating buffers etc should be somehow created/drawn using the window object, since they are associated with the window
// opengl context
@@ -20,43 +19,83 @@ static void initGlfw();
static void initGlew();
static GLFWwindow *createWindow();
static std::unique_ptr<Shader> load_shader_from_file(const char *filepath, Shader::Type shader_type);
+static std::unique_ptr<ShaderProgram> build_shader_program_from_shaders(const std::vector<Shader*> &shaders);
int main()
{
initGlfw();
glfwSetErrorCallback(glfwErrorHandler);
GLFWwindow *window = createWindow();
+ int window_width = 1;
+ int window_height = 1;
+ glfwGetWindowSize(window, &window_width, &window_height);
DeviceFrame frame;
- Triangle2D cpuTriangle(
- Vertex2D(0.0f, 0.5f),
- Vertex2D(0.5f, -0.5f),
- Vertex2D(-0.5f, -0.5f)
- );
- DataView<Triangle2D> cpuTriangles(&cpuTriangle, 1);
+ std::array<Triangle3D, 2> cpuTriangle = {
+ Triangle3D(
+ Vertex3D(0.0f, 0.0f, 0.0f),
+ Vertex3D(1.0f, 0.0f, 0.0f),
+ Vertex3D(0.0f, 1.0f, 0.0f)
+ ),
+ Triangle3D(
+ Vertex3D(1.0f, 0.0f, 0.0f),
+ Vertex3D(1.0f, 1.0f, 0.0f),
+ Vertex3D(0.0f, 1.0f, 0.0f)
+ ),
+ };
+ DataView<Triangle3D> cpuTriangles(cpuTriangle.data(), cpuTriangle.size());
DeviceMemory *gpuTriangle = frame.alloc();
gpuTriangle->copy(cpuTriangles, DeviceMemory::StorageType::STATIC);
std::unique_ptr<Shader> vertex_shader = load_shader_from_file("shaders/vertex.vert", Shader::Type::VERTEX);
std::unique_ptr<Shader> pixel_shader = load_shader_from_file("shaders/fragment.frag", Shader::Type::PIXEL);
-
- Result<std::unique_ptr<ShaderProgram>> shader_program_result = ShaderProgram::build({ vertex_shader.get(), pixel_shader.get() });
- if(!shader_program_result) {
- fprintf(stderr, "Failed to link shaders, error: %s\n", shader_program_result.getErrorMsg().c_str());
- exit(13);
- }
- std::unique_ptr<ShaderProgram> shader_program = std::move(shader_program_result.unwrap());
-
+ std::unique_ptr<ShaderProgram> shader_program = build_shader_program_from_shaders({ vertex_shader.get(), pixel_shader.get() });
+
shader_program->set_vertex_input("position", *gpuTriangle);
- shader_program->set_uniform("triangle_color", vec3f{ 1.0f, 0.0f, 0.0f });
+
+ Result<Uniform> proj_uniform = shader_program->get_uniform_by_name("proj");
+ glm::mat4 proj = glm::perspective(glm::radians(75.0f), (float)window_width / (float)window_height, 0.2f, 1000.0f);
+ proj_uniform->set(proj);
+
+ Result<Uniform> triangle_color_uniform = shader_program->get_uniform_by_name("triangle_color");
+ triangle_color_uniform->set(vec3f{ 1.0f, 0.0f, 0.0f });
+
+ Result<Uniform> view_uniform = shader_program->get_uniform_by_name("view");
+ Result<Uniform> model_uniform = shader_program->get_uniform_by_name("model");
+
+ glm::vec3 character_pos(0.0f, 3.0f, 3.0f);
+ auto t_start = std::chrono::high_resolution_clock::now();
- while(!glfwWindowShouldClose(window))
- {
+ while(!glfwWindowShouldClose(window)) {
glfwPollEvents();
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
+ auto t_now = std::chrono::high_resolution_clock::now();
+ float time_delta = std::chrono::duration_cast<std::chrono::duration<float>>(t_now - t_start).count();
+ t_start = t_now;
+
+ if(glfwGetKey(window, GLFW_KEY_W))
+ character_pos.y -= time_delta;
+ if(glfwGetKey(window, GLFW_KEY_S))
+ character_pos.y += time_delta;
+
+ glm::mat4 view = glm::lookAt(
+ character_pos,
+ character_pos - glm::vec3(0.0f, 3.0f, 3.0f),
+ glm::vec3(0.0f, 0.0f, 1.0f)
+ );
+ view_uniform->set(view);
+
+ glm::mat4 model = glm::mat4(1.0f);
+ model = glm::rotate(
+ model,
+ 0.0f,
+ glm::vec3(0.0f, 0.0f, 1.0f)
+ );
+ model_uniform->set(model);
+
// Set color for clearing
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Do the actual screen clearing, using the color set using glClearColor
@@ -90,19 +129,16 @@ void initGlfw()
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
}
-void initGlew()
-{
+void initGlew() {
glewExperimental = true;
- if(glewInit() != GLEW_OK)
- {
+ if(glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
glfwTerminate();
exit(-1);
}
}
-GLFWwindow* createWindow()
-{
+GLFWwindow* createWindow() {
GLFWwindow *window = glfwCreateWindow(1280, 720, "Amalgine", nullptr, nullptr);
if(!window)
{
@@ -111,7 +147,7 @@ GLFWwindow* createWindow()
exit(10);
}
- glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
+ glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_FALSE);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
initGlew();
@@ -145,4 +181,13 @@ std::unique_ptr<Shader> load_shader_from_file(const char *filepath, Shader::Type
exit(12);
}
return std::move(vertex_shader_result.unwrap());
+}
+
+std::unique_ptr<ShaderProgram> build_shader_program_from_shaders(const std::vector<Shader*> &shaders) {
+ Result<std::unique_ptr<ShaderProgram>> shader_program_result = ShaderProgram::build(shaders);
+ if(!shader_program_result) {
+ fprintf(stderr, "Failed to link shaders, error: %s\n", shader_program_result.getErrorMsg().c_str());
+ exit(13);
+ }
+ return std::move(shader_program_result.unwrap());
} \ No newline at end of file