diff --git a/shaders/basic.frag b/shaders/basic.frag new file mode 100644 index 0000000..c9c2054 --- /dev/null +++ b/shaders/basic.frag @@ -0,0 +1,15 @@ +#version 460 core + +layout (location = 0) in vec3 normal; +layout (location = 1) in vec2 texture_coord; + +out vec4 frag_color; + +uniform sampler2D tex; +vec3 light_pos = vec3(4.0, 5.0, -3.0); +vec3 light_color = vec3(0.5, 0.5, 0.5); + +void main() { + float light_angle = max(dot(normalize(normal), normalize(light_pos)), 0.0); + frag_color = texture(tex, tex_coord) * vec4((0.3 + 0.7 * light_angle) * light_color, 1.0); +} diff --git a/shaders/basic.vert b/shaders/basic.vert new file mode 100644 index 0000000..2fa73e7 --- /dev/null +++ b/shaders/basic.vert @@ -0,0 +1,20 @@ +#version 460 core + +layout (location = 0) in vec3 in_position; +layout (location = 1) in vec3 in_normal; +layout (location = 2) in vec2 in_texture_coord; + +layout (location = 0) out vec3 normal; +layout (location = 1) out vec2 texture_coord; + +layout (std140, binding = 0) uniform Matrices { + mat4 view; + mat4 projection; +}; + +void main() { + gl_Position = projection * view * vec4(a_pos, 1.0); + normal = in_normal; + texture_coord = in_texture_coord; +} + diff --git a/src/file.cpp b/src/file.cpp new file mode 100644 index 0000000..d6b4676 --- /dev/null +++ b/src/file.cpp @@ -0,0 +1,28 @@ +#include "file.h" + +string load_file_to_string(string filepath) { + std::ifstream in_file(filepath); + string str; + + if (in_file.is_open()) { + in_file.seekg(0, std::ios::end); + str.reserve(in_file.tellg()); + in_file.seekg(0, std::ios::beg); + + str.assign((std::istreambuf_iterator(in_file)), + std::istreambuf_iterator()); + in_file.close(); + } else { + return ""; + } + + if (in_file.bad() || in_file.fail()) { + in_file.close(); + return ""; + } + + in_file.close(); + + return str; +} + diff --git a/src/file.h b/src/file.h new file mode 100644 index 0000000..8b901f0 --- /dev/null +++ b/src/file.h @@ -0,0 +1,5 @@ +#pragma once +#include "basic.h" +#include + +string load_file_to_string(string filepath); diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..8e7e29a --- /dev/null +++ b/src/logger.h @@ -0,0 +1,12 @@ +#pragma once + +#include "basic.h" +#include + +template +void log(u32 log_level, Args ... args) { + if (log_level <= 9) { + std::printf(args ...); + std::fflush(stdout); + } +} diff --git a/src/main.cpp b/src/main.cpp index 33b0bba..e3b97ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,3 +15,4 @@ int main () { return 0; } + diff --git a/src/renderer.cpp b/src/renderer.cpp index bea86fe..1c029c8 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1,5 +1,6 @@ #include "renderer.h" + bool init_renderer(Renderer* renderer) { // Creating the window and setting it as the current context glfwInit(); @@ -49,6 +50,17 @@ void update_renderer(Renderer* renderer) { glfwPollEvents(); } +void draw_frame(Renderer* renderer) { + // Faux mesh + f32 vertices[] = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f + }; + + u32 vbo; +} + void framebuffer_size_callback(GLFWwindow* window, s32 width, s32 height) { glViewport(0, 0, width, height); } diff --git a/src/renderer.h b/src/renderer.h index b541ffd..7839de4 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -2,6 +2,7 @@ #include #include + struct Renderer { GLFWwindow* window = nullptr; u32 window_width = 800; @@ -10,5 +11,6 @@ struct Renderer { bool init_renderer(Renderer* renderer); void cleanup_renderer(Renderer* renderer); +void draw_frame(Renderer* renderer); void update_renderer(Renderer* renderer); void framebuffer_size_callback(GLFWwindow* window, s32 width, s32 height); diff --git a/src/shaders.cpp b/src/shaders.cpp new file mode 100644 index 0000000..d2ffa00 --- /dev/null +++ b/src/shaders.cpp @@ -0,0 +1,64 @@ +#include "shaders.h" +#include "file.h" +#include "logger.h" + + +bool load_shaders(Shader *shader, string vertex_shader_filepath, string fragment_shader_filepath) { + u32 vertex_shader = load_shader(vertex_shader_filepath, VERTEX_SHADER); + if (!vertex_shader) { + log(1, "%s: could not load vertex shader\n", __FUNCTION__); + return false; + } + + u32 fragment_shader = load_shader(fragment_shader_filepath, FRAGMENT_SHADER); + if (!fragment_shader) { + log(1, "%s: could not load fragment shader\n", __FUNCTION__); + return false; + } + + shader->program = glCreateProgram(); + glAttachShader(shader->program, vertex_shader); + glAttachShader(shader->program, fragment_shader); + glLinkProgram(shader->program); + + s32 is_program_linked; + glGetProgramiv(shader->program, GL_LINK_STATUS, &is_program_linked); + if (!is_program_linked) { + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + return false; + } + + s32 ubo_index = glGetUniformBlockIndex(shader->program, "Matrices"); + glUniformBlockBinding(shader->program, ubo_index, 0); + + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + return true; +} + +void cleanup_shader(Shader *shader) { + glDeleteProgram(shader->program); +} + +u32 load_shader(string filepath, Shader_Type shader_type) { + string shader_as_text = load_file_to_string(filepath); + + const char* shader_source = shader_as_text.c_str(); + u32 shader = glCreateShader(shader_type); + glShaderSource(shader, 1, (const char**) &shader_source, 0); + glCompileShader(shader); + + s32 is_shader_compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &is_shader_compiled); + if (!is_shader_compiled) { + return 0; + } + + return shader; +} + +void use_shader(Shader *shader) { + glUseProgram(shader->program); +} diff --git a/src/shaders.h b/src/shaders.h new file mode 100644 index 0000000..97875c6 --- /dev/null +++ b/src/shaders.h @@ -0,0 +1,21 @@ +#pragma once + +#include "basic.h" +#include +#include + + +enum Shader_Type : u32 { + VERTEX_SHADER = GL_VERTEX_SHADER, + FRAGMENT_SHADER = GL_FRAGMENT_SHADER +}; + +struct Shader { + u32 program = 0; +}; + +bool load_shaders(Shader *shader, string vertex_shader_filepath, string fragment_shader_filepath); +u32 load_shader(string filepath, Shader_Type shader_type); +void use_shader(Shader *shader); +void cleanup_shader(Shader *shader); +