Add view matrix and start implementing camera movement
This commit is contained in:
parent
8e00014ad0
commit
229b039617
@ -4,11 +4,12 @@ layout(location=0) in vec3 position;
|
|||||||
layout(location=1) in vec3 vert_colour;
|
layout(location=1) in vec3 vert_colour;
|
||||||
|
|
||||||
uniform mat4 u_model;
|
uniform mat4 u_model;
|
||||||
|
uniform mat4 u_view;
|
||||||
uniform mat4 u_projection;
|
uniform mat4 u_projection;
|
||||||
|
|
||||||
out vec3 vert_colours;
|
out vec3 vert_colours;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vert_colours = vert_colour;
|
vert_colours = vert_colour;
|
||||||
gl_Position = u_projection * u_model * vec4(position, 1.0f);
|
gl_Position = u_projection * u_view * u_model * vec4(position, 1.0f);
|
||||||
};
|
};
|
||||||
|
166
src/main.cc
166
src/main.cc
@ -1,15 +1,25 @@
|
|||||||
|
// GLAD
|
||||||
#include "glad/glad.h"
|
#include "glad/glad.h"
|
||||||
|
|
||||||
|
// GLM
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include "glm/ext/matrix_transform.hpp"
|
#include "glm/ext/matrix_transform.hpp"
|
||||||
|
#include "glm/ext/vector_float3.hpp"
|
||||||
#include "glm/gtc/type_ptr.hpp"
|
#include "glm/gtc/type_ptr.hpp"
|
||||||
#include "glm/trigonometric.hpp"
|
#include "glm/trigonometric.hpp"
|
||||||
|
#include "glm/gtx/rotate_vector.hpp"
|
||||||
|
#include "glm/gtx/string_cast.hpp"
|
||||||
|
|
||||||
|
// SDL
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_stdinc.h>
|
||||||
#include <SDL2/SDL_error.h>
|
#include <SDL2/SDL_error.h>
|
||||||
#include <SDL2/SDL_video.h>
|
#include <SDL2/SDL_video.h>
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
|
#include <SDL2/SDL_mouse.h>
|
||||||
#include <SDL2/SDL_keycode.h>
|
#include <SDL2/SDL_keycode.h>
|
||||||
#include <glm/vec3.hpp>
|
|
||||||
#include <glm/mat4x4.hpp>
|
// STDLIB
|
||||||
#include <glm/ext.hpp>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -26,6 +36,12 @@ enum exit_codes : int {
|
|||||||
EXIT_CODE_GLAD_LOADER_FAILED,
|
EXIT_CODE_GLAD_LOADER_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Camera {
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 view_direction;
|
||||||
|
glm::vec3 up_vector;
|
||||||
|
};
|
||||||
|
|
||||||
struct App {
|
struct App {
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_GLContext context;
|
SDL_GLContext context;
|
||||||
@ -49,6 +65,8 @@ struct App {
|
|||||||
|
|
||||||
GLuint shader_program;
|
GLuint shader_program;
|
||||||
|
|
||||||
|
Camera camera;
|
||||||
|
|
||||||
float speed;
|
float speed;
|
||||||
glm::mat4 translation;
|
glm::mat4 translation;
|
||||||
glm::mat4 rotation;
|
glm::mat4 rotation;
|
||||||
@ -57,7 +75,10 @@ struct App {
|
|||||||
// Model matrix to be sent as uniform to the vertex shader
|
// Model matrix to be sent as uniform to the vertex shader
|
||||||
glm::mat4 model_mat;
|
glm::mat4 model_mat;
|
||||||
GLint u_model_idx;
|
GLint u_model_idx;
|
||||||
bool recalc_model_mat;
|
|
||||||
|
// View matrix to be sent as uniform to the vertex shader
|
||||||
|
glm::mat4 view_mat;
|
||||||
|
GLint u_view_idx;
|
||||||
|
|
||||||
// Projection matrix to be sent as uniform to the vertex shader
|
// Projection matrix to be sent as uniform to the vertex shader
|
||||||
glm::mat4 projection_mat;
|
glm::mat4 projection_mat;
|
||||||
@ -74,6 +95,8 @@ void cleanup (App &app);
|
|||||||
GLuint create_shader_program (const std::string &vertex_shader_source, const std::string &fragment_shader_source);
|
GLuint create_shader_program (const std::string &vertex_shader_source, const std::string &fragment_shader_source);
|
||||||
GLuint compile_shader (GLuint type, const std::string &source);
|
GLuint compile_shader (GLuint type, const std::string &source);
|
||||||
std::string load_shader (const std::string &filepath);
|
std::string load_shader (const std::string &filepath);
|
||||||
|
void handle_object_movement (App &app);
|
||||||
|
void handle_camera_movement (App &app);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
App app = {};
|
App app = {};
|
||||||
@ -109,6 +132,8 @@ int init(App &app) {
|
|||||||
return EXIT_CODE_WINDOW_CREATION_FAILED;
|
return EXIT_CODE_WINDOW_CREATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
@ -134,16 +159,20 @@ int init(App &app) {
|
|||||||
glGetString(GL_SHADING_LANGUAGE_VERSION)
|
glGetString(GL_SHADING_LANGUAGE_VERSION)
|
||||||
);
|
);
|
||||||
|
|
||||||
app.speed = 0.02f;
|
app.speed = 0.02f;
|
||||||
app.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -1.5f));
|
app.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -1.5f));
|
||||||
app.rotation = glm::mat4(1.0f);
|
app.rotation = glm::mat4(1.0f);
|
||||||
app.scale = glm::mat4(1.0f);
|
app.scale = glm::mat4(1.0f);
|
||||||
app.model_mat = app.translation * app.rotation * app.scale;
|
app.camera.position = glm::vec3(0.0f);
|
||||||
app.projection_mat = glm::perspective(glm::radians(60.0f),
|
app.camera.view_direction = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||||
(float)WINDOW_WIDTH / (float)WINDOW_HEIGHT,
|
app.camera.up_vector = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||||
0.1f,
|
app.model_mat = app.translation * app.rotation * app.scale;
|
||||||
20.0f
|
app.view_mat = glm::lookAt(app.camera.position, app.camera.view_direction, app.camera.up_vector);
|
||||||
);
|
app.projection_mat = glm::perspective(glm::radians(60.0f),
|
||||||
|
(float)WINDOW_WIDTH / (float)WINDOW_HEIGHT,
|
||||||
|
0.1f,
|
||||||
|
20.0f
|
||||||
|
);
|
||||||
|
|
||||||
return EXIT_CODE_SUCCESS;
|
return EXIT_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -230,6 +259,12 @@ void create_graphics_pipeline(App &app) {
|
|||||||
printf("Failed to find uniform %s\n", u_model);
|
printf("Failed to find uniform %s\n", u_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *u_view = "u_view";
|
||||||
|
app.u_view_idx = glGetUniformLocation(app.shader_program, u_view);
|
||||||
|
if (app.u_view_idx < 0) {
|
||||||
|
printf("Failed to find uniform %s\n", u_view);
|
||||||
|
}
|
||||||
|
|
||||||
const char *u_projection = "u_projection";
|
const char *u_projection = "u_projection";
|
||||||
app.u_projection_idx = glGetUniformLocation(app.shader_program, u_projection);
|
app.u_projection_idx = glGetUniformLocation(app.shader_program, u_projection);
|
||||||
if (app.u_projection_idx < 0) {
|
if (app.u_projection_idx < 0) {
|
||||||
@ -247,37 +282,11 @@ void run_main_loop(App &app) {
|
|||||||
app.running = false;
|
app.running = false;
|
||||||
break;
|
break;
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
if (app.event.key.keysym.sym == SDLK_w) {
|
// handle_object_movement(app);
|
||||||
app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, app.speed));
|
handle_camera_movement(app);
|
||||||
app.recalc_model_mat = true;
|
break;
|
||||||
} else if (app.event.key.keysym.sym == SDLK_s) {
|
case SDL_MOUSEMOTION:
|
||||||
app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, -app.speed));
|
handle_camera_movement(app);
|
||||||
app.recalc_model_mat = true;
|
|
||||||
} else if (app.event.key.keysym.sym == SDLK_d) {
|
|
||||||
app.translation = glm::translate(app.translation, glm::vec3(app.speed, 0.0f, 0.0f));
|
|
||||||
app.recalc_model_mat = true;
|
|
||||||
} else if (app.event.key.keysym.sym == SDLK_a) {
|
|
||||||
app.translation = glm::translate(app.translation, glm::vec3(-app.speed, 0.0f, 0.0f));
|
|
||||||
app.recalc_model_mat = true;
|
|
||||||
} else if (app.event.key.keysym.sym == SDLK_RIGHT) {
|
|
||||||
app.rotation = glm::rotate(app.rotation, glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
app.recalc_model_mat = true;
|
|
||||||
} else if (app.event.key.keysym.sym == SDLK_LEFT) {
|
|
||||||
app.rotation = glm::rotate(app.rotation, glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
app.recalc_model_mat = true;
|
|
||||||
} else if (app.event.key.keysym.sym == SDLK_r) {
|
|
||||||
app.scale = glm::scale(app.scale, glm::vec3(1.2f));
|
|
||||||
app.recalc_model_mat = true;
|
|
||||||
} else if (app.event.key.keysym.sym == SDLK_e) {
|
|
||||||
app.scale = glm::scale(app.scale, glm::vec3(0.8f));
|
|
||||||
app.recalc_model_mat = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (app.recalc_model_mat) {
|
|
||||||
app.recalc_model_mat = false;
|
|
||||||
app.model_mat = app.translation * app.rotation * app.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,12 +297,15 @@ void run_main_loop(App &app) {
|
|||||||
|
|
||||||
glViewport (0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
glViewport (0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
glClearColor(0.36f, 0.34f, 0.42f, 1.0f);
|
glClearColor(0.36f, 0.34f, 0.42f, 1.0f);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgram(app.shader_program);
|
glUseProgram(app.shader_program);
|
||||||
if (app.u_model_idx >= 0) {
|
if (app.u_model_idx >= 0) {
|
||||||
glUniformMatrix4fv(app.u_model_idx, 1, GL_FALSE, glm::value_ptr(app.model_mat));
|
glUniformMatrix4fv(app.u_model_idx, 1, GL_FALSE, glm::value_ptr(app.model_mat));
|
||||||
}
|
}
|
||||||
|
if (app.u_view_idx >= 0) {
|
||||||
|
glUniformMatrix4fv(app.u_view_idx, 1, GL_FALSE, glm::value_ptr(app.view_mat));
|
||||||
|
}
|
||||||
if (app.u_projection_idx >= 0) {
|
if (app.u_projection_idx >= 0) {
|
||||||
glUniformMatrix4fv(app.u_projection_idx, 1, GL_FALSE, glm::value_ptr(app.projection_mat));
|
glUniformMatrix4fv(app.u_projection_idx, 1, GL_FALSE, glm::value_ptr(app.projection_mat));
|
||||||
}
|
}
|
||||||
@ -301,7 +313,7 @@ void run_main_loop(App &app) {
|
|||||||
|
|
||||||
// Draw call
|
// Draw call
|
||||||
glBindVertexArray(app.vao);
|
glBindVertexArray(app.vao);
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void *)0);
|
glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void *)0);
|
||||||
// End draw call
|
// End draw call
|
||||||
|
|
||||||
// Not necessary if we only have one shader program
|
// Not necessary if we only have one shader program
|
||||||
@ -383,3 +395,63 @@ std::string load_shader(const std::string &filepath) {
|
|||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_object_movement(App &app) {
|
||||||
|
switch (app.event.key.keysym.sym) {
|
||||||
|
case SDLK_w:
|
||||||
|
app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, app.speed));
|
||||||
|
break;
|
||||||
|
case SDLK_s:
|
||||||
|
app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, -app.speed));
|
||||||
|
break;
|
||||||
|
case SDLK_d:
|
||||||
|
app.translation = glm::translate(app.translation, glm::vec3(app.speed, 0.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case SDLK_a:
|
||||||
|
app.translation = glm::translate(app.translation, glm::vec3(-app.speed, 0.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
app.rotation = glm::rotate(app.rotation, glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case SDLK_LEFT:
|
||||||
|
app.rotation = glm::rotate(app.rotation, glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case SDLK_r:
|
||||||
|
app.scale = glm::scale(app.scale, glm::vec3(1.2f));
|
||||||
|
break;
|
||||||
|
case SDLK_e:
|
||||||
|
app.scale = glm::scale(app.scale, glm::vec3(0.8f));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.model_mat = app.translation * app.rotation * app.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_camera_movement(App &app) {
|
||||||
|
if (app.event.type == SDL_MOUSEMOTION) {
|
||||||
|
app.camera.view_direction = glm::rotate(app.camera.view_direction,
|
||||||
|
glm::radians((float)app.event.motion.xrel * -0.5f),
|
||||||
|
app.camera.up_vector);
|
||||||
|
} else {
|
||||||
|
switch (app.event.key.keysym.sym) {
|
||||||
|
case SDLK_w:
|
||||||
|
app.camera.position += app.camera.view_direction * app.speed;
|
||||||
|
break;
|
||||||
|
case SDLK_s:
|
||||||
|
app.camera.position -= app.camera.view_direction * app.speed;
|
||||||
|
break;
|
||||||
|
case SDLK_d:
|
||||||
|
app.camera.position.x += app.speed;
|
||||||
|
break;
|
||||||
|
case SDLK_a:
|
||||||
|
app.camera.position.x -= app.speed;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.view_mat = glm::lookAt(app.camera.position, app.camera.view_direction, app.camera.up_vector);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user