Camera Class with freecam mouse and WASD movement
parent
5f4751a27e
commit
a5f05974c5
|
@ -13,7 +13,7 @@ find_package(glfw3 REQUIRED)
|
|||
link_directories(GlProject/Libraries/glew/lib)
|
||||
|
||||
add_executable(GlProject
|
||||
GlProject/Main.cpp GlProject/Mesh.cpp GlProject/Mesh.h GlProject/Entity.cpp GlProject/Entity.h GlProject/Shader.cpp GlProject/Shader.h GlProject/Window.cpp GlProject/Window.h)
|
||||
GlProject/Main.cpp GlProject/Mesh.cpp GlProject/Mesh.h GlProject/Entity.cpp GlProject/Entity.h GlProject/Shader.cpp GlProject/Shader.h GlProject/Window.cpp GlProject/Window.h GlProject/Camera.cpp GlProject/Camera.h)
|
||||
|
||||
target_link_libraries(GlProject
|
||||
${OPENGL_gl_LIBRARY}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// Created by aurailus on 27/11/18.
|
||||
//
|
||||
|
||||
#include "Camera.h"
|
||||
#include <stdio.h>
|
||||
|
||||
//Camera::Camera() {}
|
||||
|
||||
Camera::Camera(glm::vec3 position, glm::vec3 up, GLfloat yaw, GLfloat pitch, GLfloat moveSpeed, GLfloat turnSpeed) {
|
||||
this->position = position;
|
||||
this->worldUp = up;
|
||||
this->yaw = yaw;
|
||||
this->pitch = pitch;
|
||||
this->front = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||
this->moveSpeed = moveSpeed;
|
||||
this->turnSpeed = turnSpeed;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void Camera::keyControl(bool *keys, GLfloat delta) {
|
||||
GLfloat moveMult = moveSpeed * delta;
|
||||
|
||||
if (keys[GLFW_KEY_W]) {
|
||||
position += front * moveMult;
|
||||
}
|
||||
|
||||
if (keys[GLFW_KEY_S]) {
|
||||
position -= front * moveMult;
|
||||
}
|
||||
|
||||
if (keys[GLFW_KEY_D]) {
|
||||
position += right * moveMult;
|
||||
}
|
||||
|
||||
if (keys[GLFW_KEY_A]) {
|
||||
position -= right * moveMult;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::mouseControl(double deltaX, double deltaY) {
|
||||
|
||||
deltaX *= turnSpeed;
|
||||
deltaY *= turnSpeed;
|
||||
//
|
||||
// if (deltaX != 0 || deltaY != 0) {
|
||||
// printf("%f, %f\n", deltaX, deltaY);
|
||||
// }
|
||||
//
|
||||
yaw += deltaX;
|
||||
pitch += deltaY;
|
||||
|
||||
if (pitch > 89.0f) {
|
||||
pitch = 89.0f;
|
||||
}
|
||||
if (pitch < -89.0f) {
|
||||
pitch = -89.0f;
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
glm::mat4 Camera::calculateViewMatrix() {
|
||||
return glm::lookAt(position, position + front, up);
|
||||
}
|
||||
|
||||
void Camera::update() {
|
||||
front.x = (float)(cos(glm::radians(yaw)) * cos(glm::radians(pitch)));
|
||||
front.y = (float)(sin(glm::radians(pitch)));
|
||||
front.z = (float)(sin(glm::radians(yaw)) * cos(glm::radians(pitch)));
|
||||
front = glm::normalize(front);
|
||||
|
||||
right = glm::normalize(glm::cross(front, worldUp));
|
||||
up = glm::normalize(glm::cross(right, front));
|
||||
}
|
||||
|
||||
Camera::~Camera() {
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// Created by aurailus on 27/11/18.
|
||||
//
|
||||
|
||||
#ifndef GLPROJECT_CAMERA_H
|
||||
#define GLPROJECT_CAMERA_H
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <glm.hpp>
|
||||
#include <gtc/matrix_transform.hpp>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
// Camera();
|
||||
Camera(glm::vec3 position, glm::vec3 up, GLfloat yaw, GLfloat pitch, GLfloat moveSpeed, GLfloat turnSpeed);
|
||||
|
||||
void keyControl(bool* keys, GLfloat delta);
|
||||
void mouseControl(double deltaX, double deltaY);
|
||||
|
||||
glm::mat4 calculateViewMatrix();
|
||||
|
||||
~Camera();
|
||||
|
||||
private:
|
||||
glm::vec3 position;
|
||||
|
||||
glm::vec3 front;
|
||||
glm::vec3 up;
|
||||
glm::vec3 right;
|
||||
glm::vec3 worldUp;
|
||||
|
||||
double yaw;
|
||||
double pitch;
|
||||
|
||||
GLfloat moveSpeed;
|
||||
GLfloat turnSpeed;
|
||||
|
||||
void update();
|
||||
};
|
||||
|
||||
|
||||
#endif //GLPROJECT_CAMERA_H
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
Entity::Entity() {
|
||||
position = glm::vec3(0, 0, 0);
|
||||
rotation = glm::vec3(0, 0, 0);
|
||||
scale = glm::vec3(1, 1, 1);
|
||||
scale = glm::vec3(1, 1, 1);
|
||||
angle = 0;
|
||||
}
|
||||
|
||||
void Entity::create(Mesh* myMesh) {
|
||||
|
@ -31,6 +31,14 @@ glm::vec3* Entity::getPosition() {
|
|||
return &position;
|
||||
}
|
||||
|
||||
void Entity::setAngle(GLfloat angle) {
|
||||
this->angle = angle;
|
||||
}
|
||||
|
||||
GLfloat* Entity::getAngle() {
|
||||
return ∠
|
||||
}
|
||||
|
||||
void Entity::setScale(float scale) {
|
||||
setScale(glm::vec3(scale, scale, scale));
|
||||
}
|
||||
|
@ -47,7 +55,7 @@ glm::mat4 Entity::getModelMatrix() {
|
|||
glm::mat4 model = glm::mat4(1.0);
|
||||
|
||||
model = glm::translate(model, position);
|
||||
// model = glm::rotate(model, triAngle * toRadians, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
model = glm::rotate(model, angle * (GLfloat)(3.14159265 / 180), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
model = glm::scale(model, scale);
|
||||
|
||||
return model;
|
||||
|
|
|
@ -21,8 +21,8 @@ public:
|
|||
void setPosition(glm::vec3 position);
|
||||
glm::vec3* getPosition();
|
||||
|
||||
//void setRotation(glm::vec3 rotation);
|
||||
//glm::vec3* getRotation();
|
||||
void setAngle(GLfloat angle);
|
||||
GLfloat* getAngle();
|
||||
|
||||
void setScale(float scale);
|
||||
void setScale(glm::vec3 scale);
|
||||
|
@ -35,8 +35,8 @@ private:
|
|||
Mesh* mesh;
|
||||
|
||||
glm::vec3 position;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
GLfloat angle;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -13,30 +13,63 @@
|
|||
#include "Mesh.h"
|
||||
#include "Entity.h"
|
||||
#include "Shader.h"
|
||||
#include "Camera.h"
|
||||
|
||||
Window mainWindow;
|
||||
std::vector<Entity*> entities;
|
||||
Window* window;
|
||||
Shader* shader;
|
||||
std::vector<Entity*> entities;
|
||||
Camera* camera;
|
||||
|
||||
bool triDirection = true; //Right
|
||||
float triOffset = 0;
|
||||
float triMaxOffset = 0.7;
|
||||
float triMoveStep = 0.01;
|
||||
GLfloat deltaTime = 0.0f;
|
||||
GLfloat lastTime = 0.0f;
|
||||
|
||||
void makeEntities() {
|
||||
unsigned int indices[] {
|
||||
0, 3, 1,
|
||||
1, 3, 2,
|
||||
2, 3, 0,
|
||||
0, 1, 2
|
||||
};
|
||||
// unsigned int indices[] {
|
||||
// 0, 3, 1,
|
||||
// 1, 3, 2,
|
||||
// 2, 3, 0,
|
||||
// 0, 1, 2
|
||||
// };
|
||||
//
|
||||
// GLfloat vertices[] = {
|
||||
// -1.0f, -1.0f, -0.5f,
|
||||
// 0.0f, -1.0f, 1.0f,
|
||||
// 1.0f, -1.0f, -0.5f,
|
||||
// 0.0f, 1.0f, 0.0f
|
||||
// };
|
||||
|
||||
GLfloat vertices[] = {
|
||||
-1.0f, -1.0f, -0.5f,
|
||||
0.0f, -1.0f, 1.0f,
|
||||
1.0f, -1.0f, -0.5f,
|
||||
0.0f, 1.0f, 0.0f
|
||||
};
|
||||
unsigned int indices[] {
|
||||
//Bottom
|
||||
0, 2, 3,
|
||||
3, 1, 0,
|
||||
//Top
|
||||
4, 6, 7,
|
||||
7, 5, 4,
|
||||
//Left
|
||||
0, 1, 5,
|
||||
5, 4, 0,
|
||||
//Right
|
||||
7, 3, 2,
|
||||
2, 6, 7,
|
||||
//Back
|
||||
0, 2, 6,
|
||||
6, 4, 0,
|
||||
//Front
|
||||
1, 3, 7,
|
||||
7, 5, 1
|
||||
};
|
||||
|
||||
GLfloat vertices[] = {
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
};
|
||||
|
||||
Mesh* mesh = new Mesh();
|
||||
mesh->create(vertices, indices, (sizeof(vertices)/sizeof(*vertices)), (sizeof(indices)/sizeof(*indices)));
|
||||
|
@ -47,8 +80,8 @@ void makeEntities() {
|
|||
|
||||
auto *tri = new Entity();
|
||||
tri->create(mesh);
|
||||
tri->setPosition(glm::vec3(i, y + 0.25, j));
|
||||
tri->setScale(0.3);
|
||||
tri->setPosition(glm::vec3(i * 1.45, (y + 0.5) * 1.6, j));
|
||||
tri->setScale(0.7);
|
||||
|
||||
entities.push_back(tri);
|
||||
}
|
||||
|
@ -58,8 +91,11 @@ void makeEntities() {
|
|||
|
||||
int main() {
|
||||
//Window
|
||||
mainWindow = Window(800, 600);
|
||||
mainWindow.initialize();
|
||||
window = new Window(1366, 768);
|
||||
window->initialize();
|
||||
|
||||
//Create camera
|
||||
camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0, 1, 0), -90.0f, 0.0f, 10.0f, 0.1f);
|
||||
|
||||
//Create entities
|
||||
makeEntities();
|
||||
|
@ -68,24 +104,21 @@ int main() {
|
|||
shader = new Shader();
|
||||
shader->createFromFile("../GlProject/Shaders/world.vs", "../GlProject/Shaders/world.fs");
|
||||
|
||||
glm::mat4 projectionMatrix = glm::perspective(45.0f, mainWindow.getBufferWidth() / mainWindow.getBufferHeight(), 0.1f, 100.0f);
|
||||
|
||||
glm::mat4 projectionMatrix = glm::perspective(45.0f, window->getBufferWidth() / window->getBufferHeight(), 0.1f, 100.0f);
|
||||
|
||||
//Game Loop
|
||||
while (!mainWindow.getShouldClose()) {
|
||||
while (!window->getShouldClose()) {
|
||||
auto now = (GLfloat)glfwGetTime();
|
||||
deltaTime = now - lastTime;
|
||||
lastTime = now;
|
||||
|
||||
//Get & Handle Input
|
||||
glfwPollEvents();
|
||||
window->update();
|
||||
|
||||
if (triDirection /*Right*/) {
|
||||
triOffset += triMoveStep;
|
||||
}
|
||||
else /*Left*/ {
|
||||
triOffset -= triMoveStep;
|
||||
}
|
||||
|
||||
if (std::abs(triOffset) >= triMaxOffset) triDirection = !triDirection;
|
||||
|
||||
// triangle->setPosition(glm::vec3(triOffset, 0, -2.5f));
|
||||
// triangle->setScale(glm::vec3(0.4, 0.4, 1));
|
||||
camera->keyControl(window->getKeysArray(), deltaTime);
|
||||
camera->mouseControl(window->getDeltaX(), window->getDeltaY());
|
||||
|
||||
//Clear Window
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
|
@ -94,18 +127,18 @@ int main() {
|
|||
shader->useShader();
|
||||
|
||||
glUniformMatrix4fv(shader->getProjectionLocation(), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
|
||||
glUniformMatrix4fv(shader->getViewLocation(), 1, GL_FALSE, glm::value_ptr(camera->calculateViewMatrix()));
|
||||
|
||||
for (auto &entity : entities) {
|
||||
glUniformMatrix4fv(shader->getModelLocation(), 1, GL_FALSE, glm::value_ptr(entity->getModelMatrix()));
|
||||
|
||||
entity->getPosition()->x += triMoveStep * (triDirection ? 1 : -1);
|
||||
entity->setAngle(*entity->getAngle() + 0.5f);
|
||||
entity->draw();
|
||||
}
|
||||
|
||||
Shader::clearShader();
|
||||
|
||||
//Finish Drawing - Swap buffers
|
||||
mainWindow.swapBuffers();
|
||||
//Finish Drawing
|
||||
window->swapBuffers();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -9,6 +9,7 @@ Shader::Shader() {
|
|||
shaderID = 0;
|
||||
uModel = 0;
|
||||
uProj = 0;
|
||||
uView = 0;
|
||||
}
|
||||
|
||||
void Shader::createFromString(const char *vertexSource, const char *fragmentSource) {
|
||||
|
@ -76,6 +77,7 @@ void Shader::compileShader(const char *vertexSource, const char *fragmentSource)
|
|||
|
||||
uModel = glGetUniformLocation(shaderID, "model");
|
||||
uProj = glGetUniformLocation(shaderID, "projection");
|
||||
uView = glGetUniformLocation(shaderID, "view");
|
||||
}
|
||||
|
||||
void Shader::useShader() {
|
||||
|
@ -90,6 +92,10 @@ GLint Shader::getProjectionLocation() {
|
|||
return uProj;
|
||||
}
|
||||
|
||||
GLint Shader::getViewLocation() {
|
||||
return uView;
|
||||
}
|
||||
|
||||
void Shader::cleanup() {
|
||||
if (shaderID != 0) {
|
||||
glDeleteProgram(shaderID);
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
|
||||
GLint getProjectionLocation();
|
||||
GLint getModelLocation();
|
||||
GLint getViewLocation();
|
||||
|
||||
void useShader();
|
||||
static void clearShader() {
|
||||
|
@ -35,7 +36,7 @@ public:
|
|||
|
||||
private:
|
||||
GLuint shaderID;
|
||||
GLint uProj, uModel;
|
||||
GLint uProj, uModel, uView;
|
||||
|
||||
void compileShader(const char* vertexSource, const char* fragmentSource);
|
||||
void addShader(GLuint program, const char* shaderCode, GLenum shaderType);
|
||||
|
|
|
@ -4,10 +4,11 @@ layout (location = 0) in vec3 pos;
|
|||
|
||||
uniform mat4 model;
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * model * vec4(pos, 1.0);
|
||||
gl_Position = projection * view * model * vec4(pos, 1.0);
|
||||
color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
||||
}
|
|
@ -4,14 +4,18 @@
|
|||
|
||||
#include "Window.h"
|
||||
|
||||
Window::Window() {
|
||||
width = 800;
|
||||
height = 600;
|
||||
}
|
||||
Window::Window() : Window(800, 600) {};
|
||||
|
||||
Window::Window(GLint windowWidth, GLint windowHeight) {
|
||||
width = windowWidth;
|
||||
height = windowHeight;
|
||||
|
||||
centerX = width / 2;
|
||||
centerY = height / 2;
|
||||
|
||||
for (bool &key : keys) {
|
||||
key = false;
|
||||
}
|
||||
}
|
||||
|
||||
int Window::initialize() {
|
||||
|
@ -61,14 +65,58 @@ int Window::initialize() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
//Setup viewport (draw) size
|
||||
glViewport(0, 0, bufferWidth, bufferHeight);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glfwSetWindowUserPointer(mainWindow, this);
|
||||
glfwSetKeyCallback(mainWindow, handleKeys);
|
||||
glfwSetInputMode(mainWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Window::update() {
|
||||
double mouseX, mouseY;
|
||||
glfwGetCursorPos(mainWindow, &mouseX, &mouseY);
|
||||
|
||||
if (glfwGetWindowAttrib(mainWindow, GLFW_FOCUSED)) {
|
||||
deltaX = mouseX - centerX;
|
||||
deltaY = centerY - mouseY;
|
||||
glfwSetCursorPos(mainWindow, centerX, centerY);
|
||||
}
|
||||
else {
|
||||
deltaX = 0;
|
||||
deltaY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
double Window::getDeltaX() {
|
||||
return deltaX;
|
||||
}
|
||||
|
||||
double Window::getDeltaY() {
|
||||
return deltaY;
|
||||
}
|
||||
|
||||
void Window::handleKeys(GLFWwindow* glfwWindow, int key, int code, int action, int mode) {
|
||||
auto window = static_cast<Window*>(glfwGetWindowUserPointer(glfwWindow));
|
||||
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(glfwWindow, GL_TRUE);
|
||||
}
|
||||
|
||||
if (key > 0 && key < 1024) {
|
||||
if (action == GLFW_PRESS) {
|
||||
window->keys[key] = true;
|
||||
}
|
||||
else if (action == GLFW_RELEASE) {
|
||||
window->keys[key] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
glfwDestroyWindow(mainWindow);
|
||||
glfwTerminate();
|
||||
|
|
|
@ -16,11 +16,18 @@ public:
|
|||
|
||||
int initialize();
|
||||
|
||||
void update();
|
||||
|
||||
GLfloat getBufferWidth() { return bufferWidth; }
|
||||
GLfloat getBufferHeight() { return bufferHeight; }
|
||||
|
||||
bool getShouldClose() { return (bool)glfwWindowShouldClose(mainWindow); }
|
||||
|
||||
bool* getKeysArray() { return keys; }
|
||||
|
||||
double getDeltaX();
|
||||
double getDeltaY();
|
||||
|
||||
void swapBuffers() { glfwSwapBuffers(mainWindow); }
|
||||
|
||||
~Window();
|
||||
|
@ -29,7 +36,16 @@ private:
|
|||
GLFWwindow *mainWindow;
|
||||
|
||||
GLint width, height;
|
||||
GLint centerX, centerY;
|
||||
GLint bufferWidth, bufferHeight;
|
||||
|
||||
bool keys[1024];
|
||||
|
||||
//Static so that GLFW can run callback
|
||||
static void handleKeys(GLFWwindow* glfwWindow, int key, int code, int action, int mode);
|
||||
|
||||
double deltaX;
|
||||
double deltaY;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue