Add perspective camera and shader-hot-swapping
This commit is contained in:
parent
32a4097a21
commit
67e7d73614
12
shaders/alt.frag
Normal file
12
shaders/alt.frag
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 460 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec4 tex_color;
|
||||||
|
layout (location = 1) in vec2 tex_coord;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = texture(tex, tex_coord) * (vec4(1.0) - tex_color);
|
||||||
|
}
|
||||||
21
shaders/alt.vert
Normal file
21
shaders/alt.vert
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#version 460 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 a_pos;
|
||||||
|
layout (location = 1) in vec3 a_color;
|
||||||
|
layout (location = 2) in vec2 a_tex_coord;
|
||||||
|
|
||||||
|
layout (std140, binding = 0) uniform Matrices {
|
||||||
|
mat4 view;
|
||||||
|
mat4 projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 tex_color;
|
||||||
|
layout (location = 1) out vec2 tex_coord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 offset = vec3(0.0, 0.0, -1.0);
|
||||||
|
gl_Position = projection * view * vec4(a_pos + offset, 1.0);
|
||||||
|
tex_color = vec4(a_color, 1.0);
|
||||||
|
tex_coord = a_tex_coord;
|
||||||
|
}
|
||||||
|
|
||||||
@ -4,11 +4,16 @@ layout (location = 0) in vec3 a_pos;
|
|||||||
layout (location = 1) in vec3 a_color;
|
layout (location = 1) in vec3 a_color;
|
||||||
layout (location = 2) in vec2 a_tex_coord;
|
layout (location = 2) in vec2 a_tex_coord;
|
||||||
|
|
||||||
|
layout (std140, binding = 0) uniform Matrices {
|
||||||
|
mat4 view;
|
||||||
|
mat4 projection;
|
||||||
|
};
|
||||||
|
|
||||||
layout (location = 0) out vec4 tex_color;
|
layout (location = 0) out vec4 tex_color;
|
||||||
layout (location = 1) out vec2 tex_coord;
|
layout (location = 1) out vec2 tex_coord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(a_pos, 1.0);
|
gl_Position = projection * view * vec4(a_pos, 1.0);
|
||||||
tex_color = vec4(a_color, 1.0);
|
tex_color = vec4(a_color, 1.0);
|
||||||
tex_coord = a_tex_coord;
|
tex_coord = a_tex_coord;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
|
|
||||||
bool init_renderer(Renderer *renderer, u32 width, u32 height) {
|
bool init_renderer(Renderer *renderer, u32 width, u32 height) {
|
||||||
|
renderer->m_width = width;
|
||||||
|
renderer->m_height = height;
|
||||||
|
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||||
log(1, "%s error: failed to initialize GLAD\n", __FUNCTION__);
|
log(1, "%s error: failed to initialize GLAD\n", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
@ -40,12 +44,29 @@ bool init_renderer(Renderer *renderer, u32 width, u32 height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
bool success = load_shaders(&renderer->shader, "shaders/basic.vert", "shaders/basic.frag");
|
bool success = init_uniform_buffer(&renderer->uniform_buffer);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
log(1, "%s: shader loading failed\n", __FUNCTION__);
|
log(1, "%s: uniform buffer successfully created\n", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
log(1, "%s: shaders succesfully loaded\n", __FUNCTION__);
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bool success = load_shaders(&renderer->shader, "shaders/basic.vert", "shaders/basic.frag");
|
||||||
|
if (!success) {
|
||||||
|
log(1, "%s: basic shader loading failed\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log(1, "%s: basic shaders succesfully loaded\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bool success = load_shaders(&renderer->alt_shader, "shaders/alt.vert", "shaders/alt.frag");
|
||||||
|
if (!success) {
|
||||||
|
log(1, "%s: alt shader loading failed\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log(1, "%s: alt shaders succesfully loaded\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -66,13 +87,30 @@ void draw_renderer(Renderer *renderer) {
|
|||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
use_shader(&renderer->shader);
|
Vector3 camera_position = Vector3(0.4f, 0.3f, 1.0f);
|
||||||
|
Vector3 camera_look_at_position = Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
Vector3 camera_up_vector = Vector3(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
renderer->projection_matrix = glm::perspective(glm::radians(90.0f), static_cast<f32>(renderer->m_width) / static_cast<f32>(renderer->m_height), 0.1f, 100.0f);
|
||||||
|
|
||||||
|
f32 dt = glfwGetTime();
|
||||||
|
Matrix4 model = Matrix4(1.0);
|
||||||
|
|
||||||
|
if (!renderer->use_alt_shader) {
|
||||||
|
use_shader(&renderer->shader);
|
||||||
|
model = glm::rotate(Matrix4(1.0f), dt, Vector3(0.0f, 0.0f, 1.0f));
|
||||||
|
} else {
|
||||||
|
use_shader(&renderer->alt_shader);
|
||||||
|
model = glm::rotate(Matrix4(1.0f), -dt, Vector3(0.0f, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->view_matrix = glm::lookAt(camera_position, camera_look_at_position, camera_up_vector) * model;
|
||||||
|
|
||||||
|
upload_uniform_buffer_data(&renderer->uniform_buffer, renderer->view_matrix, renderer->projection_matrix);
|
||||||
|
|
||||||
bind_texture(&renderer->texture);
|
bind_texture(&renderer->texture);
|
||||||
|
|
||||||
bind_vertex_buffer(&renderer->vertex_buffer);
|
bind_vertex_buffer(&renderer->vertex_buffer);
|
||||||
|
|
||||||
|
|
||||||
draw_vertex_buffer(GL_TRIANGLES, 0, renderer->triangle_count * 3);
|
draw_vertex_buffer(GL_TRIANGLES, 0, renderer->triangle_count * 3);
|
||||||
|
|
||||||
unbind_vertex_buffer();
|
unbind_vertex_buffer();
|
||||||
@ -89,6 +127,7 @@ void upload_renderer_data(Renderer *renderer, Mesh *vertex_data) {
|
|||||||
|
|
||||||
void cleanup_renderer(Renderer *renderer) {
|
void cleanup_renderer(Renderer *renderer) {
|
||||||
cleanup_shader(&renderer->shader);
|
cleanup_shader(&renderer->shader);
|
||||||
|
cleanup_shader(&renderer->alt_shader);
|
||||||
cleanup_texture(&renderer->texture);
|
cleanup_texture(&renderer->texture);
|
||||||
cleanup_vertex_buffer(&renderer->vertex_buffer);
|
cleanup_vertex_buffer(&renderer->vertex_buffer);
|
||||||
cleanup_frame_buffer(&renderer->frame_buffer);
|
cleanup_frame_buffer(&renderer->frame_buffer);
|
||||||
@ -231,6 +270,30 @@ void draw_vertex_buffer(u32 mode, u32 start, u32 num) {
|
|||||||
glDrawArrays(mode, start, num);
|
glDrawArrays(mode, start, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uniform buffer
|
||||||
|
*/
|
||||||
|
bool init_uniform_buffer(Uniform_Buffer *uniform_buffer) {
|
||||||
|
glGenBuffers(1, &uniform_buffer->ubo_buffer);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, uniform_buffer->ubo_buffer);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(Matrix4), nullptr, GL_STATIC_DRAW);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void upload_uniform_buffer_data(Uniform_Buffer *uniform_buffer, Matrix4 view_matrix, Matrix4 projection_matrix) {
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, uniform_buffer->ubo_buffer);
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(Matrix4), glm::value_ptr(view_matrix));
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(Matrix4), sizeof(Matrix4), glm::value_ptr(projection_matrix));
|
||||||
|
glBindBufferRange(GL_UNIFORM_BUFFER, 0, uniform_buffer->ubo_buffer, 0, 2 * sizeof(Matrix4));
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanup(Uniform_Buffer *uniform_buffer) {
|
||||||
|
glDeleteBuffers(1, &uniform_buffer->ubo_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Texture
|
* Texture
|
||||||
@ -304,6 +367,9 @@ bool load_shaders(Shader *shader, string vertex_shader_filepath, string fragment
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 ubo_index = glGetUniformBlockIndex(shader->program, "Matrices");
|
||||||
|
glUniformBlockBinding(shader->program, ubo_index, 0);
|
||||||
|
|
||||||
glDeleteShader(vertex_shader);
|
glDeleteShader(vertex_shader);
|
||||||
glDeleteShader(fragment_shader);
|
glDeleteShader(fragment_shader);
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
@ -32,6 +33,10 @@ struct Vertex_Buffer {
|
|||||||
u32 vbo = 0;
|
u32 vbo = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Uniform_Buffer {
|
||||||
|
u32 ubo_buffer = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
u32 texture = 0;
|
u32 texture = 0;
|
||||||
s32 width = 0;
|
s32 width = 0;
|
||||||
@ -44,14 +49,20 @@ struct Shader {
|
|||||||
u32 program = 0;
|
u32 program = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Renderer {
|
struct Renderer {
|
||||||
Shader shader;
|
Shader shader;
|
||||||
|
Shader alt_shader;
|
||||||
Frame_Buffer frame_buffer;
|
Frame_Buffer frame_buffer;
|
||||||
Vertex_Buffer vertex_buffer;
|
Vertex_Buffer vertex_buffer;
|
||||||
|
Uniform_Buffer uniform_buffer;
|
||||||
Texture texture;
|
Texture texture;
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
s32 triangle_count = 0;
|
s32 triangle_count = 0;
|
||||||
|
bool use_alt_shader = false;
|
||||||
|
Matrix4 view_matrix = Matrix4(1.0f);
|
||||||
|
Matrix4 projection_matrix = Matrix4(1.0f);
|
||||||
|
u32 m_width = 0;
|
||||||
|
u32 m_height = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -76,6 +87,10 @@ void bind_vertex_buffer(Vertex_Buffer *vertex_buffer);
|
|||||||
void unbind_vertex_buffer();
|
void unbind_vertex_buffer();
|
||||||
void draw_vertex_buffer(u32 mode, u32 start, u32 num);
|
void draw_vertex_buffer(u32 mode, u32 start, u32 num);
|
||||||
|
|
||||||
|
bool init_uniform_buffer(Uniform_Buffer *uniform_buffer);
|
||||||
|
void upload_uniform_buffer_data(Uniform_Buffer *uniform_buffer, Matrix4 view_matrix, Matrix4 projection_matrix);
|
||||||
|
void cleanup(Uniform_Buffer *uniform_buffer);
|
||||||
|
|
||||||
bool load_texture(Texture *texture, string filepath);
|
bool load_texture(Texture *texture, string filepath);
|
||||||
void bind_texture(Texture *texture);
|
void bind_texture(Texture *texture);
|
||||||
void unbind_texture();
|
void unbind_texture();
|
||||||
|
|||||||
@ -82,25 +82,9 @@ void handle_close(GLFWwindow *gl_window) {
|
|||||||
void handle_key_events(GLFWwindow *gl_window, s32 key, s32 scancode, s32 action, s32 mods) {
|
void handle_key_events(GLFWwindow *gl_window, s32 key, s32 scancode, s32 action, s32 mods) {
|
||||||
Window *window = static_cast<Window *>(glfwGetWindowUserPointer(gl_window));
|
Window *window = static_cast<Window *>(glfwGetWindowUserPointer(gl_window));
|
||||||
|
|
||||||
string action_name;
|
if (glfwGetKey(window->glfw_window, GLFW_KEY_SPACE) == GLFW_PRESS) {
|
||||||
|
window->renderer->use_alt_shader = !window->renderer->use_alt_shader;
|
||||||
switch(action) {
|
|
||||||
case GLFW_PRESS:
|
|
||||||
action_name = "pressed";
|
|
||||||
break;
|
|
||||||
case GLFW_RELEASE:
|
|
||||||
action_name = "released";
|
|
||||||
break;
|
|
||||||
case GLFW_REPEAT:
|
|
||||||
action_name = "repeated";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
action_name = "invalid";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *key_name = glfwGetKeyName(key, 0);
|
|
||||||
log(1, "%s: key %s (key %i, scancode %i) %s\n", __FUNCTION__, key_name, key, scancode, action_name.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_mouse_position_events(GLFWwindow *gl_window, f64 x_pos, f64 y_pos) {
|
void handle_mouse_position_events(GLFWwindow *gl_window, f64 x_pos, f64 y_pos) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user