Camera Panning oh my godddd

master
Nicole Collings 2020-05-31 17:27:20 -07:00
parent 043014a805
commit 7318ba44b7
25 changed files with 437 additions and 142 deletions

View File

@ -3,13 +3,12 @@
in vec2 texCoords;
in vec3 normal;
//uniform sampler2D tex;
uniform sampler2D tex;
out vec3 color;
void main() {
vec4 spec = vec4(1, 0, 0, 1);
// vec4 spec = texture(tex, texCoords);
vec4 spec = texture(tex, texCoords);
if (spec.a < 0.1) discard;
color = spec.xyz;

View File

@ -1,19 +1,19 @@
#version 330 core
layout (location = 0) in vec3 aPosition;
//layout (location = 1) in vec2 aTexCoords;
layout (location = 1) in vec2 aTexCoords;
layout (location = 2) in vec3 aNormal;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
//out vec2 texCoords;
out vec2 texCoords;
out vec3 normal;
void main() {
vec4 worldPos = model * vec4(aPosition, 1);
gl_Position = projection * view * worldPos;
normal = aNormal;
// texCoords = aTexCoords;
texCoords = aTexCoords;
}

BIN
assets/textures/dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -7,7 +7,23 @@
App::App() :
window(),
camera(window.getSize()),
renderer(&window, &camera) {
renderer(&window, &camera),
input(window.getInput()),
controller(input, camera),
test({
{{-30, -20, -20}, {0, 0}, {0, 0, 0}},
{{-30, 20, -20}, {0, 1}, {0, 0, 0}},
{{-30, 20, 20}, {1, 1}, {0, 0, 0}},
{{-30, -20, 20}, {1, 0}, {0, 0, 0}},
}, {0, 3, 2, 2, 1, 0}),
test2({
{{30, -20, -20}, {0, 0}, {0, 0, 0}},
{{30, 20, -20}, {0, 1}, {0, 0, 0}},
{{30, 20, 20}, {1, 1}, {0, 0, 0}},
{{30, -20, 20}, {1, 0}, {0, 0, 0}},
}, {0, 3, 2, 2, 1, 0}),
tex("../assets/textures/dirt.png") {
while (!window.shouldEnd()) {
update();
@ -16,13 +32,18 @@ App::App() :
}
void App::update() {
window.update();
controller.update();
}
void App::render() {
renderer.reset();
glm::mat4 model = glm::mat4(1.0);
tex.use(0);
renderer.setModelMatrix(model);
test.draw();
test2.draw();
renderer.swap();
}

View File

@ -4,9 +4,14 @@
#pragma once
#include "Window.h"
#include "Camera.h"
#include "Renderer.h"
#include "graph/Window.h"
#include "graph/Camera.h"
#include "graph/Renderer.h"
#include "input/ViewportControl.h"
#include "graph/Mesh.h"
#include "graph/Texture.h"
class App {
public:
@ -19,4 +24,10 @@ private:
Window window;
Camera camera;
Renderer renderer;
Input& input;
ViewportControl controller;
BlockMesh test,test2;
Texture tex;
};

View File

@ -1,3 +1,3 @@
set(MODELLER_SRC
Renderer.cpp Renderer.h App.cpp App.h Window.cpp Window.h Shader.cpp Shader.h Camera.h Camera.cpp Mesh.inl Mesh.h Vertex.cpp Vertex.h)
graph/Renderer.cpp graph/Renderer.h App.cpp App.h graph/Window.cpp graph/Window.h graph/Shader.cpp graph/Shader.h graph/Camera.h graph/Camera.cpp graph/Mesh.inl graph/Mesh.h graph/Vertex.h graph/Texture.h graph/Texture.cpp input/ViewportControl.cpp input/ViewportControl.h input/Input.cpp input/Input.h)
add_library(${MAIN_LIB_NAME} ${MODELLER_SRC})

View File

@ -1,33 +0,0 @@
//
// Created by aurailus on 2020-05-29.
//
#pragma once
#include <vector>
#include "Vertex.h"
template <const VertexParamList* P, class V>
class Mesh {
public:
Mesh() = default;
Mesh(const std::vector<V>& vertices, const std::vector<unsigned int>& indices);
void create(const std::vector<V>& vertices, const std::vector<unsigned int>& indices);
virtual void draw() const;
void cleanup();
~Mesh();
private:
void genArrays(unsigned int vboLength, unsigned int iboLength, const void* verticesPtr, const void* indicesPtr);
void createVertexAttrib(unsigned int offset, unsigned int size, int type, unsigned int stride, const void* pointer);
unsigned int VAO, VBO, IBO;
unsigned long indCount;
};
typedef Mesh<&blockVertexParams, BlockVertex> BlockMesh;
#include "Mesh.inl"

View File

@ -1,5 +0,0 @@
//
// Created by aurailus on 2020-05-29.
//
#include "Vertex.h"

View File

@ -1,26 +0,0 @@
//
// Created by aurailus on 2020-05-29.
//
#pragma once
#include <array>
#include <GL/glew.h>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
struct VertexParam { unsigned int offset, size, type, stride, pointer; };
struct VertexParamList { unsigned char count; std::array<VertexParam, 16> params; };
struct BlockVertex {
glm::vec3 position;
glm::vec2 texCoords;
glm::vec3 normal;
};
#define STRIDE_OFFSET_BLOCK(m) sizeof(struct BlockVertex), offsetof(struct BlockVertex, m)
constexpr static VertexParamList blockVertexParams {3, {
VertexParam {0, 3, GL_FLOAT, STRIDE_OFFSET_BLOCK(position)},
VertexParam {1, 2, GL_FLOAT, STRIDE_OFFSET_BLOCK(texCoords)},
VertexParam {2, 3, GL_FLOAT, STRIDE_OFFSET_BLOCK(normal)} }};

View File

@ -37,7 +37,7 @@ private:
glm::mat4 projectionMatrix;
glm::mat4 orthographicMatrix;
float fov = 80.0f;
float fov = 90.0f;
float ratio = 0;
static constexpr float projNearClip = 0.1f;

57
src/graph/Mesh.h Normal file
View File

@ -0,0 +1,57 @@
//
// Created by aurailus on 2020-05-29.
//
#include "Vertex.h"
#pragma once
#include <memory>
#include <vector>
#include <GL/glew.h>
template <class V>
class Mesh {
public:
Mesh() = default;
Mesh(const std::vector<V>& vertices, const std::vector<unsigned int>& indices);
void create(const std::vector<V>& vertices, const std::vector<unsigned int>& indices);
virtual void draw() const;
void cleanup();
~Mesh();
protected:
void createArrays(unsigned int vboLength, unsigned int iboLength, const void* verticesPtr, const void* indicesPtr);
void createVertexAttrib(unsigned int offset, unsigned int size, int type, unsigned int stride, const void* pointer);
void finish();
unsigned int VAO, VBO, IBO;
unsigned long indCount;
std::shared_ptr<int> refs = std::make_shared<int>();
};
#include "Mesh.inl"
class BlockMesh : public Mesh<BlockVertex> {
public:
BlockMesh(const std::vector<BlockVertex>& vertices, const std::vector<unsigned int>& indices) : Mesh(vertices, indices) {
auto& p = BlockVertexParams;
for (unsigned int idx = 0; idx < p.count; idx++)
createVertexAttrib(idx, p.params[idx].size, p.params[idx].type,
p.params[idx].stride, reinterpret_cast<const void*>(p.params[idx].pointer));
finish();
};
};
class GuiMesh : public Mesh<GuiVertex> {
public:
GuiMesh(const std::vector<GuiVertex>& vertices, const std::vector<unsigned int>& indices) : Mesh(vertices, indices) {
auto& p = BlockVertexParams;
for (unsigned int idx = 0; idx < p.count; idx++)
createVertexAttrib(idx, p.params[idx].size, p.params[idx].type,
p.params[idx].stride, reinterpret_cast<const void*>(p.params[idx].pointer));
finish();
};
};

View File

@ -2,35 +2,31 @@
// Created by aurailus on 2020-05-29.
//
#include <GL/glew.h>
#include "Mesh.h"
template <const VertexParamList* P, class V>
Mesh<P, V>::Mesh(const std::vector<V>& vertices, const std::vector<unsigned int>& indices) {
template <class V>
Mesh<V>::Mesh(const std::vector<V>& vertices, const std::vector<unsigned int>& indices) {
create(vertices, indices);
}
template <const VertexParamList* P, class V>
void Mesh<P, V>::create(const std::vector<V> &vertices, const std::vector<unsigned int> &indices) {
template <class V>
void Mesh<V>::create(const std::vector<V> &vertices, const std::vector<unsigned int> &indices) {
indCount = static_cast<size_t>(indices.size());
genArrays(static_cast<unsigned int>(vertices.size() * sizeof(V)),
static_cast<unsigned int>(indices.size() * sizeof(unsigned int)),
&vertices.front(), &indices.front());
for (unsigned int idx = 0; idx < P->count; idx++) {
const auto& param = P->params[idx];
createVertexAttrib(idx, param.size, param.type, param.stride, param.pointer);
}
createArrays(static_cast<unsigned int>(vertices.size() * sizeof(V)),
static_cast<unsigned int>(indices.size() * sizeof(unsigned int)),
&vertices.front(), &indices.front());
}
template<class V>
void Mesh<V>::finish() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
template <const VertexParamList* P, class V>
void Mesh<P, V>::genArrays(unsigned int vboLength, unsigned int iboLength, const void *verticesPtr, const void *indicesPtr) {
template <class V>
void Mesh<V>::createArrays(unsigned int vboLength, unsigned int iboLength, const void *verticesPtr, const void *indicesPtr) {
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
@ -43,23 +39,23 @@ void Mesh<P, V>::genArrays(unsigned int vboLength, unsigned int iboLength, const
glBufferData(GL_ARRAY_BUFFER, vboLength, verticesPtr, GL_STATIC_DRAW);
}
template <const VertexParamList* P, class V>
void Mesh<P, V>::createVertexAttrib(unsigned int offset, unsigned int size, int type, unsigned int stride, const void* pointer) {
template <class V>
void Mesh<V>::createVertexAttrib(unsigned int offset, unsigned int size, int type, unsigned int stride, const void* pointer) {
glEnableVertexAttribArray(offset);
if (type == GL_INT) glVertexAttribIPointer(offset, size, type, stride, pointer);
else glVertexAttribPointer(offset, size, type, GL_FALSE, stride, pointer);
}
template <const VertexParamList* P, class V>
void Mesh<P, V>::draw() const {
template <class V>
void Mesh<V>::draw() const {
if (VAO == 0) return;
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_TRIANGLES, indCount, GL_UNSIGNED_INT, nullptr);
}
template <const VertexParamList* P, class V>
void Mesh<P, V>::cleanup() {
template <class V>
void Mesh<V>::cleanup() {
if (VAO) glDeleteVertexArrays(1, &VAO);
if (VBO) glDeleteBuffers(1, &VBO);
if (IBO) glDeleteBuffers(1, &IBO);
@ -71,7 +67,7 @@ void Mesh<P, V>::cleanup() {
indCount = 0;
}
template <const VertexParamList* P, class V>
Mesh<P, V>::~Mesh() {
cleanup();
}
template <class V>
Mesh<V>::~Mesh() {
if (refs.use_count() == 1) cleanup();
}

View File

@ -2,10 +2,9 @@
// Created by aurailus on 2020-05-28.
//
#include <iostream>
#include <stdexcept>
#include <GL/glew.h>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include "Renderer.h"
@ -29,20 +28,14 @@ void Renderer::setModelMatrix(const glm::mat4& modelMatrix) {
glUniformMatrix4fv(uModel, 1, GL_FALSE, glm::value_ptr(modelMatrix));
}
void Renderer::reset() {
if (dir) {
color++;
if (color == 255) dir = !dir;
}
else {
color--;
if (color == 0) dir = !dir;
}
void Renderer::setClearColor(glm::vec4 color) {
glClearColor(color.r, color.g, color.b, color.a);
}
glClearColor(color / 255.f, color / 255.f, color / 255.f, 1);
void Renderer::reset() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
// glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDisable(GL_BLEND);
@ -55,4 +48,4 @@ void Renderer::reset() {
void Renderer::swap() {
window->swapBuffers();
}
}

View File

@ -14,6 +14,7 @@ public:
explicit Renderer(Window* window, Camera* camera);
void setModelMatrix(const glm::mat4& modelMatrix);
static void setClearColor(glm::vec4 color);
void reset();
void swap();

72
src/graph/Texture.cpp Normal file
View File

@ -0,0 +1,72 @@
//
// Created by aurailus on 31/05/20.
//
#include <GL/glew.h>
#include <iostream>
#pragma clang diagnostic push
#pragma ide diagnostic ignored "OCUnusedMacroInspection"
#define STB_IMAGE_IMPLEMENTATION
#pragma clang diagnostic pop
#include <stb_image/stb_image.h>
#include "Texture.h"
Texture::Texture(const std::string& file) {
loadFromFile(file);
}
void Texture::loadFromFile(std::string file) {
int bitDepth;
unsigned char *texData = stbi_load(file.c_str(), &size.x, &size.y, &bitDepth, 0);
if (!texData) {
std::cout << "Failed to load texture \"" << file << "\"" << std::endl;
exit(0);
}
loadFromBytes(texData, size);
stbi_image_free(texData);
}
void Texture::loadFromBytes(unsigned char* bytes, glm::ivec2 size) {
if (textureID != 0) clear();
this->size = size;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture::updateTexture(glm::ivec2 pos, glm::ivec2 size, unsigned char *bytes) {
glBindTexture(GL_TEXTURE_2D, textureID);
glTexSubImage2D(GL_TEXTURE_2D, 0, pos.x, pos.y, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
}
void Texture::use(unsigned short position) {
glActiveTexture(GL_TEXTURE0 + position);
glBindTexture(GL_TEXTURE_2D, textureID);
}
void Texture::clear() {
glDeleteTextures(1, &textureID);
textureID = 0;
size = {};
}
Texture::~Texture() {
if (refs.use_count() == 1) clear();
}

30
src/graph/Texture.h Normal file
View File

@ -0,0 +1,30 @@
//
// Created by aurailus on 31/05/20.
//
#pragma once
#include <memory>
#include <string>
#include <glm/vec2.hpp>
class Texture {
public:
Texture() = default;
explicit Texture(const std::string& file);
void loadFromFile(std::string file);
void loadFromBytes(unsigned char* bytes, glm::ivec2 size);
void updateTexture(glm::ivec2 pos, glm::ivec2 size, unsigned char* bytes);
void use(unsigned short position = 0);
void clear();
~Texture();
protected:
glm::ivec2 size {};
unsigned int textureID = 0;
std::shared_ptr<int> refs = std::make_shared<int>();
};

43
src/graph/Vertex.h Normal file
View File

@ -0,0 +1,43 @@
//
// Created by aurailus on 2020-05-29.
//
#pragma once
#include <array>
#include <GL/glew.h>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
struct VertexParam { unsigned int offset, size, type, stride, pointer; };
struct VertexParamList { unsigned char count; std::array<VertexParam, 16> params; };
#define STRIDE_OFFSET(c, m) sizeof(struct c), offsetof(struct c, m)
// Block Vertex
// For blocks, rendered in 3d space.
struct BlockVertex {
glm::vec3 position;
glm::vec2 texCoords;
glm::vec3 normal;
};
constexpr static VertexParamList BlockVertexParams {3, {
VertexParam {0, 3, GL_FLOAT, STRIDE_OFFSET(BlockVertex, position)},
VertexParam {1, 2, GL_FLOAT, STRIDE_OFFSET(BlockVertex, texCoords)},
VertexParam {2, 3, GL_FLOAT, STRIDE_OFFSET(BlockVertex, normal)}
}};
// Gui Vertex
// For Gui Elements, rendered in 2d space.
struct GuiVertex {
glm::vec2 position;
glm::vec2 texCoords;
};
constexpr static VertexParamList GuiVertexParams {2, {
VertexParam {0, 2, GL_FLOAT, STRIDE_OFFSET(GuiVertex, position)},
VertexParam {1, 2, GL_FLOAT, STRIDE_OFFSET(GuiVertex, texCoords)}
}};

View File

@ -36,7 +36,6 @@ Window::Window(glm::ivec2 size) :
// Setup callbacks
glfwSetWindowUserPointer(window, this);
glfwSetScrollCallback(window, scrollCallback);
glfwSetWindowSizeCallback(window, resizeCallback);
// Set basic properties (v-sync, cursor mode, maximize)
@ -56,6 +55,12 @@ Window::Window(glm::ivec2 size) :
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, size.x, size.y);
input.init(window);
}
void Window::update() {
input.update();
}
glm::ivec2 Window::getSize() {
@ -64,8 +69,13 @@ glm::ivec2 Window::getSize() {
void Window::swapBuffers() {
glfwSwapBuffers(window);
glfwPollEvents();
}
bool Window::shouldEnd() {
return static_cast<bool>(glfwWindowShouldClose(window)) || glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS;
}
Input &Window::getInput() {
return input;
}

View File

@ -6,6 +6,8 @@
#include <glm/vec2.hpp>
#include "../input/Input.h"
class GLFWwindow;
class Window {
@ -13,13 +15,17 @@ public:
Window() : Window({800, 600}) {};
explicit Window(glm::ivec2 size);
void update();
glm::ivec2 getSize();
Input& getInput();
void swapBuffers();
bool shouldEnd();
private:
glm::ivec2 size;
GLFWwindow* window;
Input input;
static void scrollCallback(GLFWwindow* window, double xOffset, double yOffset) {};
static void resizeCallback(GLFWwindow* window, int width, int height) {};

89
src/input/Input.cpp Normal file
View File

@ -0,0 +1,89 @@
//
// Created by aurailus on 09/04/19.
//
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "Input.h"
#include "../graph/Window.h"
Input::Input() {
for (bool& key : keysDown) key = false;
for (bool& key : keysPressed) key = false;
for (bool& key : keysReleased) key = false;
for (bool& key : keysNew) key = false;
}
void Input::init(GLFWwindow *window) {
this->window = window;
glfwSetKeyCallback(window, keyCallback);
glfwSetScrollCallback(window, scrollCallback);
}
void Input::update() {
for (bool &key : keysPressed) key = false;
for (bool &key : keysReleased) key = false;
for (int i = 32; i < 1024; i++) {
if (keysNew[i]) {
if (!keysDown[i]) keysPressed[i] = true;
keysDown[i] = true;
}
else {
if (keysDown[i]) keysReleased[i] = true;
keysDown[i] = false;
}
}
for (unsigned int i = GLFW_MOUSE_BUTTON_1; i < GLFW_MOUSE_BUTTON_LAST; i++) {
if (glfwGetMouseButton(window, i) == GLFW_PRESS) {
if (!keysDown[i]) keysPressed[i] = true;
keysDown[i] = true;
}
else {
if (keysDown[i]) keysReleased[i] = true;
keysDown[i] = false;
}
}
lastMouse = mouse;
double x, y;
glfwGetCursorPos(window, &x, &y);
mouse = { static_cast<int>(x), static_cast<int>(y) };
}
bool Input::keyDown(int key) const {
return keysDown[key];
}
bool Input::keyPressed(int key) const {
return keysPressed[key];
}
bool Input::keyReleased(int key) const {
return keysReleased[key];
}
void Input::keyCallback(GLFWwindow* window, int key, int, int action, int) {
auto w = static_cast<Window*>(glfwGetWindowUserPointer(window));
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE);
if (key >= 32 && key < 1024) {
if (action == GLFW_PRESS) w->getInput().keysNew[key] = true;
else if (action == GLFW_RELEASE) w->getInput().keysNew[key] = false;
}
}
void Input::scrollCallback(GLFWwindow *window, double xO, double yO) {
// auto w = static_cast<Window*>(glfwGetWindowUserPointer(window));
}
glm::ivec2 Input::mousePos() const {
return mouse;
}
glm::ivec2 Input::mouseDelta() const {
return mouse - lastMouse;
}

34
src/input/Input.h Normal file
View File

@ -0,0 +1,34 @@
//
// Created by aurailus on 09/04/19.
//
#pragma once
#include <glm/vec2.hpp>
class GLFWwindow;
class Input {
public:
Input();
void init(GLFWwindow* window);
void update();
bool keyDown(int key) const;
bool keyPressed(int key) const;
bool keyReleased(int key) const;
glm::ivec2 mousePos() const;
glm::ivec2 mouseDelta() const;
private:
static void keyCallback(GLFWwindow* window, int key, int code, int action, int mode);
static void scrollCallback(GLFWwindow* window, double, double yO);
bool keysNew[1024] {false};
bool keysDown[1024] {false};
bool keysPressed[1024] {false};
bool keysReleased[1024] {false};
GLFWwindow* window = nullptr;
glm::ivec2 mouse, lastMouse;
};

View File

@ -21,30 +21,27 @@ void ViewportControl::update() {
if (input.keyDown(GLFW_MOUSE_BUTTON_LEFT)) {
yaw += -input.mouseDelta().x * panFactor;
pitch += -input.mouseDelta().y * panFactor;
pitch = fmin(fmax(pitch, -1.5), 1.5);
}
float camAngleX = yaw;
float camAngleY = pitch;
glm::vec3 camPos = {
distance * -sinf(yaw) * cosf(pitch),
distance * -sinf(pitch),
-distance * cosf(yaw) * cosf(pitch)
};
camera.setPos({
distance * -sinf(camAngleX) * cosf(camAngleY),
distance * -sinf(camAngleY),
-distance * cosf(camAngleX) * cosf(camAngleY)
});
glm::vec3 look = -camPos;
float length = glm::length(look) + 0.00001;
std::cout << camera.getPos().x << ", " << camera.getPos().y << ", " << camera.getPos().z << std::endl;
float lookPitch = asin(look.y / length);
float lookYaw = asin(look.z / (cos(asin(look.y / length)) * length));
glm::vec3 cp = -camera.getPos();
if (look.x <= 0) {
lookYaw *= -1;
lookYaw += 3.14159;
}
// camera.setPitch(asin(-cp.y));
// camera.setYaw(atan2(cp.x, cp.z));
camera.setPitch(asin(cp.y / glm::length(cp)));
camera.setYaw(asin(cp.z / (cos(asin(cp.y / glm::length(cp))) * glm::length(cp))));
// camera.setPos({sin(yaw) * distance * sin(pitch), sin(pitch) * distance, cos(yaw) * distance * sin(pitch)});
// camera.setYaw(-yaw);
// camera.setPitch(-pitch);
camera.setPos(camPos);
camera.setPitch(lookPitch);
camera.setYaw(lookYaw);
}

View File

@ -18,7 +18,7 @@ private:
Camera& camera;
double panFactor = 0.01;
double distance = 60;
double distance = 120;
double pitch, yaw;
};