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 = 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() {
|
||||
gl_Position = vec4(a_pos, 1.0);
|
||||
gl_Position = projection * view * vec4(a_pos, 1.0);
|
||||
tex_color = vec4(a_color, 1.0);
|
||||
tex_coord = a_tex_coord;
|
||||
}
|
||||
|
||||
@ -3,6 +3,10 @@
|
||||
|
||||
|
||||
bool init_renderer(Renderer *renderer, u32 width, u32 height) {
|
||||
renderer->m_width = width;
|
||||
renderer->m_height = height;
|
||||
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||
log(1, "%s error: failed to initialize GLAD\n", __FUNCTION__);
|
||||
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) {
|
||||
log(1, "%s: shader loading failed\n", __FUNCTION__);
|
||||
log(1, "%s: uniform buffer successfully created\n", __FUNCTION__);
|
||||
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;
|
||||
@ -66,13 +87,30 @@ void draw_renderer(Renderer *renderer) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
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_vertex_buffer(&renderer->vertex_buffer);
|
||||
|
||||
|
||||
draw_vertex_buffer(GL_TRIANGLES, 0, renderer->triangle_count * 3);
|
||||
|
||||
unbind_vertex_buffer();
|
||||
@ -89,6 +127,7 @@ void upload_renderer_data(Renderer *renderer, Mesh *vertex_data) {
|
||||
|
||||
void cleanup_renderer(Renderer *renderer) {
|
||||
cleanup_shader(&renderer->shader);
|
||||
cleanup_shader(&renderer->alt_shader);
|
||||
cleanup_texture(&renderer->texture);
|
||||
cleanup_vertex_buffer(&renderer->vertex_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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -304,6 +367,9 @@ bool load_shaders(Shader *shader, string vertex_shader_filepath, string fragment
|
||||
return false;
|
||||
}
|
||||
|
||||
s32 ubo_index = glGetUniformBlockIndex(shader->program, "Matrices");
|
||||
glUniformBlockBinding(shader->program, ubo_index, 0);
|
||||
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <stb_image.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
|
||||
struct Vertex {
|
||||
@ -32,6 +33,10 @@ struct Vertex_Buffer {
|
||||
u32 vbo = 0;
|
||||
};
|
||||
|
||||
struct Uniform_Buffer {
|
||||
u32 ubo_buffer = 0;
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
u32 texture = 0;
|
||||
s32 width = 0;
|
||||
@ -44,14 +49,20 @@ struct Shader {
|
||||
u32 program = 0;
|
||||
};
|
||||
|
||||
|
||||
struct Renderer {
|
||||
Shader shader;
|
||||
Shader alt_shader;
|
||||
Frame_Buffer frame_buffer;
|
||||
Vertex_Buffer vertex_buffer;
|
||||
Uniform_Buffer uniform_buffer;
|
||||
Texture texture;
|
||||
Mesh mesh;
|
||||
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 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);
|
||||
void bind_texture(Texture *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) {
|
||||
Window *window = static_cast<Window *>(glfwGetWindowUserPointer(gl_window));
|
||||
|
||||
string action_name;
|
||||
|
||||
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;
|
||||
if (glfwGetKey(window->glfw_window, GLFW_KEY_SPACE) == GLFW_PRESS) {
|
||||
window->renderer->use_alt_shader = !window->renderer->use_alt_shader;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user