Add working camera
This commit is contained in:
parent
890117d3d0
commit
fbb4cd5101
@ -6,8 +6,9 @@ out vec4 vertex_color;
|
|||||||
|
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * model * vec4(pos, 1.0);
|
gl_Position = projection * view * model * vec4(pos, 1.0);
|
||||||
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
||||||
}
|
}
|
||||||
|
|||||||
64
src/camera.cpp
Normal file
64
src/camera.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
|
||||||
|
Camera::Camera(Vector3 position, Vector3 world_up, f32 yaw, f32 pitch, f32 movement_speed, f32 rotation_speed) : position(position), world_up(world_up), yaw(yaw), pitch(pitch), movement_speed(movement_speed), rotation_speed(rotation_speed) {
|
||||||
|
update_camera(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_camera(Camera *camera) {
|
||||||
|
Vector3 new_front = Vector3(
|
||||||
|
cos(glm::radians(camera->yaw)) * cos(glm::radians(camera->pitch)),
|
||||||
|
sin(glm::radians(camera->pitch)),
|
||||||
|
sin(glm::radians(camera->yaw)) * cos(glm::radians(camera->pitch))
|
||||||
|
);
|
||||||
|
new_front = glm::normalize(new_front);
|
||||||
|
camera->front = new_front;
|
||||||
|
|
||||||
|
camera->right = glm::normalize(glm::cross(camera->front, camera->world_up));
|
||||||
|
camera->up = glm::normalize(glm::cross(camera->right, camera->front));
|
||||||
|
}
|
||||||
|
|
||||||
|
void key_control(Camera *camera, bool *ascii_keys, f32 dt) {
|
||||||
|
f32 velocity = camera->movement_speed * dt;
|
||||||
|
|
||||||
|
if (ascii_keys[GLFW_KEY_W]) {
|
||||||
|
camera->position += camera->front * velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ascii_keys[GLFW_KEY_S]) {
|
||||||
|
camera->position -= camera->front * velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ascii_keys[GLFW_KEY_D]) {
|
||||||
|
camera->position += camera->right * velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ascii_keys[GLFW_KEY_A]) {
|
||||||
|
camera->position -= camera->right * velocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_control(Camera *camera, f32 x_change, f32 y_change) {
|
||||||
|
x_change *= camera->rotation_speed;
|
||||||
|
y_change *= camera->rotation_speed;
|
||||||
|
|
||||||
|
camera->yaw += x_change;
|
||||||
|
camera->pitch += y_change;
|
||||||
|
|
||||||
|
// Clamp camera pitch
|
||||||
|
if (camera->pitch > 89.0f) {
|
||||||
|
camera->pitch = 89.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera->pitch < -89.0f) {
|
||||||
|
camera->pitch = -89.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_camera(camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Matrix4 calculate_view_matrix(Camera *camera) {
|
||||||
|
return glm::lookAt(camera->position, camera->position + camera->front, camera->up);
|
||||||
|
}
|
||||||
|
|
||||||
28
src/camera.h
Normal file
28
src/camera.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
struct Camera {
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 front = Vector3(0.0f, 0.0f, -1.0f);
|
||||||
|
Vector3 up;
|
||||||
|
Vector3 right;
|
||||||
|
Vector3 world_up;
|
||||||
|
|
||||||
|
f32 yaw;
|
||||||
|
f32 pitch;
|
||||||
|
f32 movement_speed;
|
||||||
|
f32 rotation_speed;
|
||||||
|
|
||||||
|
Camera(Vector3 position, Vector3 up, f32 yaw, f32 pitch, f32 movement_speed, f32 rotation_speed);
|
||||||
|
~Camera() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
void update_camera(Camera *camera);
|
||||||
|
void key_control(Camera *camera, bool *ascii_keys, f32 dt);
|
||||||
|
void mouse_control(Camera *camera, f32 x_change, f32 y_change);
|
||||||
|
Matrix4 calculate_view_matrix(Camera *camera);
|
||||||
64
src/main.cpp
64
src/main.cpp
@ -1,6 +1,7 @@
|
|||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *vertex_shader_code = "shaders/shader.vert";
|
static const char *vertex_shader_code = "shaders/shader.vert";
|
||||||
@ -10,9 +11,13 @@ int main() {
|
|||||||
Mesh *meshes[10] = {nullptr};
|
Mesh *meshes[10] = {nullptr};
|
||||||
Shader shaders[10];
|
Shader shaders[10];
|
||||||
|
|
||||||
Window window;
|
Window window(1024, 720);
|
||||||
bool success = setup_window(&window);
|
bool success = setup_window(&window);
|
||||||
|
|
||||||
|
// Delta
|
||||||
|
f32 dt = 0.0f;
|
||||||
|
f32 last_dt = 0.f;
|
||||||
|
|
||||||
{
|
{
|
||||||
// Create a mesh
|
// Create a mesh
|
||||||
f32 vertices[] = {
|
f32 vertices[] = {
|
||||||
@ -29,9 +34,13 @@ int main() {
|
|||||||
0, 1, 2
|
0, 1, 2
|
||||||
};
|
};
|
||||||
|
|
||||||
Mesh *triangle = new Mesh();
|
Mesh *pyramid1 = new Mesh();
|
||||||
create_mesh(triangle, vertices, indices, 12, 12);
|
create_mesh(pyramid1, vertices, indices, 12, 12);
|
||||||
meshes[0] = triangle;
|
meshes[0] = pyramid1;
|
||||||
|
|
||||||
|
Mesh *pyramid2 = new Mesh();
|
||||||
|
create_mesh(pyramid2, vertices, indices, 12, 12);
|
||||||
|
meshes[1] = pyramid2;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -45,33 +54,56 @@ int main() {
|
|||||||
45.0f, (GLfloat)window.buffer_width / (GLfloat)window.buffer_height, 0.1f,
|
45.0f, (GLfloat)window.buffer_width / (GLfloat)window.buffer_height, 0.1f,
|
||||||
100.0f);
|
100.0f);
|
||||||
|
|
||||||
u32 uniform_projection = 0, uniform_model = 0;
|
Camera camera(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f, 5.0f, 1.0f);
|
||||||
f32 current_angle = 0.1f;
|
|
||||||
|
|
||||||
// Loop until window is closed
|
// Loop until window is closed
|
||||||
while (!glfwWindowShouldClose(window.gl_window)) {
|
while (!glfwWindowShouldClose(window.gl_window)) {
|
||||||
|
// Calculate delta
|
||||||
|
f32 now = glfwGetTime();
|
||||||
|
dt = now - last_dt;
|
||||||
|
last_dt = now;
|
||||||
|
|
||||||
// Get and handle user input events
|
// Get and handle user input events
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
|
key_control(&camera, window.ascii_keys, dt);
|
||||||
|
mouse_control(&camera, window.x_change_position, window.y_change_position);
|
||||||
|
|
||||||
|
// This sucks
|
||||||
|
window.x_change_position = 0.0f;
|
||||||
|
window.y_change_position = 0.0f;
|
||||||
|
|
||||||
// Clear window
|
// Clear window
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgram(shaders[0].id);
|
glUseProgram(shaders[0].id);
|
||||||
uniform_model = shaders[0].uniform_model;
|
|
||||||
uniform_projection = shaders[0].uniform_projection;
|
|
||||||
|
|
||||||
Matrix4 model(1.0f);
|
{
|
||||||
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
|
Matrix4 model(1.0f);
|
||||||
model = glm::rotate(model, current_angle * RADIAN_FACTOR, Vector3(0.0f, 1.0f, 0.0f));
|
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
|
||||||
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
// model = glm::rotate(model, current_angle * RADIAN_FACTOR, Vector3(0.0f, 1.0f, 0.0f));
|
||||||
|
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
||||||
|
|
||||||
current_angle += 0.5f;
|
glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
||||||
|
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
||||||
|
render_mesh(meshes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
{
|
||||||
glUniformMatrix4fv(uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
Matrix4 model(1.0f);
|
||||||
|
model = glm::translate(model, Vector3(0.0f, 0.0f, -3.5f));
|
||||||
|
// model = glm::rotate(model, current_angle * RADIAN_FACTOR, Vector3(0.0f, 1.0f, 0.0f));
|
||||||
|
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
||||||
|
|
||||||
|
glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
||||||
|
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
||||||
|
render_mesh(meshes[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4 view = calculate_view_matrix(&camera);
|
||||||
|
glUniformMatrix4fv(shaders[0].uniform_view, 1, GL_FALSE, glm::value_ptr(view));
|
||||||
|
|
||||||
render_mesh(meshes[0]);
|
|
||||||
|
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
|
|||||||
@ -63,6 +63,7 @@ bool create_shader(Shader *shader, const char *vertex_shader_path, const char *f
|
|||||||
|
|
||||||
shader->uniform_projection = glGetUniformLocation(shader->id, "projection");
|
shader->uniform_projection = glGetUniformLocation(shader->id, "projection");
|
||||||
shader->uniform_model = glGetUniformLocation(shader->id, "model");
|
shader->uniform_model = glGetUniformLocation(shader->id, "model");
|
||||||
|
shader->uniform_view = glGetUniformLocation(shader->id, "view");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ struct Shader {
|
|||||||
u32 id;
|
u32 id;
|
||||||
u32 uniform_projection;
|
u32 uniform_projection;
|
||||||
u32 uniform_model;
|
u32 uniform_model;
|
||||||
|
u32 uniform_view;
|
||||||
|
|
||||||
Shader();
|
Shader();
|
||||||
~Shader();
|
~Shader();
|
||||||
|
|||||||
@ -1,5 +1,23 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Window::Window(u32 window_width, u32 window_height) {
|
||||||
|
width = window_width;
|
||||||
|
height = window_height;
|
||||||
|
x_change_position = 0.0f;
|
||||||
|
y_change_position = 0.0f;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 1024; i++) {
|
||||||
|
ascii_keys[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::~Window() {
|
||||||
|
glfwDestroyWindow(gl_window);
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
bool setup_window(Window *window) {
|
bool setup_window(Window *window) {
|
||||||
// Initialize GLFW
|
// Initialize GLFW
|
||||||
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
|
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
|
||||||
@ -20,7 +38,7 @@ bool setup_window(Window *window) {
|
|||||||
|
|
||||||
window->gl_window = glfwCreateWindow(window->width, window->height, "Test Window", NULL, NULL);
|
window->gl_window = glfwCreateWindow(window->width, window->height, "Test Window", NULL, NULL);
|
||||||
|
|
||||||
if (!window) {
|
if (!window->gl_window) {
|
||||||
const char *desc;
|
const char *desc;
|
||||||
int code = glfwGetError(&desc);
|
int code = glfwGetError(&desc);
|
||||||
printf("GLFW window creation failed!");
|
printf("GLFW window creation failed!");
|
||||||
@ -36,7 +54,10 @@ bool setup_window(Window *window) {
|
|||||||
// Set context for GLEW to use
|
// Set context for GLEW to use
|
||||||
glfwMakeContextCurrent(window->gl_window);
|
glfwMakeContextCurrent(window->gl_window);
|
||||||
|
|
||||||
glGetError();
|
glfwSetKeyCallback(window->gl_window, handle_keys);
|
||||||
|
glfwSetCursorPosCallback(window->gl_window, handle_mouse);
|
||||||
|
// Captures the mouse
|
||||||
|
glfwSetInputMode(window->gl_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
|
||||||
// Allow modern extension features
|
// Allow modern extension features
|
||||||
glewExperimental = GL_TRUE;
|
glewExperimental = GL_TRUE;
|
||||||
@ -56,5 +77,43 @@ bool setup_window(Window *window) {
|
|||||||
// Setup viewport size
|
// Setup viewport size
|
||||||
glViewport(0, 0, window->buffer_width, window->buffer_height);
|
glViewport(0, 0, window->buffer_width, window->buffer_height);
|
||||||
|
|
||||||
|
glfwSetWindowUserPointer(window->gl_window, window);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_keys(GLFWwindow *gl_window, int key, int code, int action, int mode) {
|
||||||
|
Window *window = static_cast<Window *>(glfwGetWindowUserPointer(gl_window));
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||||
|
glfwSetWindowShouldClose(gl_window, GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key >= 0 && key < 1024) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
window->ascii_keys[key] = true;
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
window->ascii_keys[key] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_mouse(GLFWwindow *gl_window, f64 x_position, f64 y_position) {
|
||||||
|
Window *window = static_cast<Window *>(glfwGetWindowUserPointer(gl_window));
|
||||||
|
|
||||||
|
if (window->first_mouse_movement) {
|
||||||
|
window->last_x_position = x_position;
|
||||||
|
window->last_y_position = y_position;
|
||||||
|
window->first_mouse_movement = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->x_change_position = x_position - window->last_x_position;
|
||||||
|
// The order here is to avoid up/down inversion
|
||||||
|
window->y_change_position = window->last_y_position - y_position;
|
||||||
|
|
||||||
|
window->last_x_position = x_position;
|
||||||
|
window->last_y_position = y_position;
|
||||||
|
|
||||||
|
// @Todo: reset x/y_change_position back to 0.0f
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/window.h
14
src/window.h
@ -12,7 +12,19 @@ struct Window {
|
|||||||
u32 width = 800, height = 600;
|
u32 width = 800, height = 600;
|
||||||
s32 buffer_width, buffer_height;
|
s32 buffer_width, buffer_height;
|
||||||
GLFWwindow *gl_window = nullptr;
|
GLFWwindow *gl_window = nullptr;
|
||||||
|
bool ascii_keys[1024];
|
||||||
|
|
||||||
|
// Camera coords
|
||||||
|
f32 last_x_position;
|
||||||
|
f32 last_y_position;
|
||||||
|
f32 x_change_position;
|
||||||
|
f32 y_change_position;
|
||||||
|
bool first_mouse_movement;
|
||||||
|
|
||||||
|
Window(u32 window_width, u32 window_height);
|
||||||
|
~Window();
|
||||||
};
|
};
|
||||||
|
|
||||||
bool setup_window(Window *window);
|
bool setup_window(Window *window);
|
||||||
|
void handle_keys(GLFWwindow *gl_window, int key, int code, int action, int mode);
|
||||||
|
void handle_mouse(GLFWwindow *gl_window, f64 x_position, f64 y_position);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user