diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/RenderBackend/OpenGL/DeviceMemory.cpp | 9 | ||||
-rw-r--r-- | src/RenderBackend/OpenGL/ShaderProgram.cpp | 19 | ||||
-rw-r--r-- | src/RenderBackend/OpenGL/Uniform.cpp | 24 | ||||
-rw-r--r-- | src/main.cpp | 101 |
4 files changed, 117 insertions, 36 deletions
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 |