camera fix

This commit is contained in:
Damian 2022-01-15 14:26:23 +01:00
parent ee33aaf2c4
commit c235df208b
3 changed files with 136 additions and 78 deletions

View File

@ -1,40 +1,90 @@
#include "Camera.h"
#include"Camera.h"
glm::mat4 Core::createPerspectiveMatrix(float zNear, float zFar)
Camera::Camera(int width, int height, glm::vec3 position)
{
const float frustumScale = 1.1f;
glm::mat4 perspective;
perspective[0][0] = frustumScale;
perspective[1][1] = frustumScale;
perspective[2][2] = (zFar + zNear) / (zNear - zFar);
perspective[3][2] = (2 * zFar * zNear) / (zNear - zFar);
perspective[2][3] = -1;
perspective[3][3] = 0;
return perspective;
Camera::width = width;
Camera::height = height;
Position = position;
}
glm::mat4 Core::createViewMatrix( glm::vec3 position, glm::vec3 forward, glm::vec3 up )
glm::mat4 Camera::Matrix(float FOVdeg, float nearPlane, float farPlane)
{
glm::vec3 side = glm::cross(forward, up);
// Initializes matrices since otherwise they will be the null matrix
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
// Trzeba pamietac o minusie przy ustawianiu osi Z kamery.
// Wynika to z tego, ze standardowa macierz perspektywiczna zaklada, ze "z przodu" jest ujemna (a nie dodatnia) czesc osi Z.
glm::mat4 cameraRotation;
cameraRotation[0][0] = side.x; cameraRotation[1][0] = side.y; cameraRotation[2][0] = side.z;
cameraRotation[0][1] = up.x; cameraRotation[1][1] = up.y; cameraRotation[2][1] = up.z;
cameraRotation[0][2] = -forward.x; cameraRotation[1][2] = -forward.y; cameraRotation[2][2] = -forward.z;
// Makes camera look in the right direction from the right position
RotationAngle = glm::lookAt(Position, Position + Orientation, Up);
// Adds perspective to the scene
projection = glm::perspective(glm::radians(FOVdeg), (float)width / height, nearPlane, farPlane);
glm::mat4 cameraTranslation;
cameraTranslation[3] = glm::vec4(-position, 1.0f);
return cameraRotation * cameraTranslation;
return projection * RotationAngle;
}
glm::mat4 Core::createViewMatrixQuat(glm::vec3 position, glm::quat rotation)
{
glm::mat4 cameraTranslation;
cameraTranslation[3] = glm::vec4(-position, 1.0f);
return glm::mat4_cast(rotation) * cameraTranslation;
glm::vec3 Camera::getPosition() {
return Position;
}
glm::vec3 Camera::getOrientation() {
return Orientation;
}
glm::vec3 Camera::getUp() {
return Up;
}
glm::mat4 Camera::getRotationAngle() {
return RotationAngle;
}
void Camera::Keyboard(unsigned char key)
{
switch (key) {
// Handles key inputs
case 'w':
Position += speed * Orientation;
break;
case 'a':
Position += speed * -glm::normalize(glm::cross(Orientation, Up));
break;
case 's':
Position += speed * -Orientation;
break;
case 'd':
Position += speed * glm::normalize(glm::cross(Orientation, Up));
break;
}
}
void Camera::Mouse(int x, int y) {
glutSetCursor(GLUT_CURSOR_NONE);
// Stores the coordinates of the cursor
double mouseX = x;
double mouseY = y;
// Fetches the coordinates of the cursor
// Normalizes and shifts the coordinates of the cursor such that they begin in the middle of the screen
// and then "transforms" them into degrees
float rotX = sensitivity * (float)(mouseY - (height / 2)) / height;
float rotY = sensitivity * (float)(mouseX - (width / 2)) / width;
// Calculates upcoming vertical change in the Orientation
glm::vec3 newOrientation = glm::rotate(Orientation, glm::radians(-rotX), glm::normalize(glm::cross(Orientation, Up)));
// Decides whether or not the next vertical Orientation is legal or not
if (abs(glm::angle(newOrientation, Up) - glm::radians(90.0f)) <= glm::radians(85.0f))
{
Orientation = newOrientation;
}
// Rotates the Orientation left and right
Orientation = glm::rotate(Orientation, glm::radians(-rotY), Up);
glutWarpPointer(width / 2, height / 2);
}

View File

@ -1,17 +1,43 @@
#pragma once
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
#include "ext.hpp"
namespace Core
class Camera
{
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 100.0f);
public:
// Stores the main vectors of the camera
glm::vec3 Position;
glm::vec3 Orientation = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 Up = glm::vec3(0.0f, 1.0f, 0.0f);
// position - pozycja kamery
// forward - wektor "do przodu" kamery (jednostkowy)
// up - wektor "w gore" kamery (jednostkowy)
// up i forward musza byc ortogonalne!
glm::mat4 createViewMatrix(glm::vec3 position, glm::vec3 forward, glm::vec3 up);
glm::mat4 RotationAngle;
glm::mat4 createViewMatrixQuat(glm::vec3 position, glm::quat rotation);
}
// Prevents the camera from jumping around when first clicking left click
bool firstClick = true;
// Stores the width and height of the window
int width;
int height;
// Adjust the speed of the camera and it's sensitivity when looking around
float speed = 0.1f;
float sensitivity = 100.0f;
// Camera constructor to set up initial values
Camera();
Camera(int width, int height, glm::vec3 position);
glm::vec3 getPosition();
glm::vec3 getOrientation();
glm::vec3 getUp();
glm::mat4 getRotationAngle();
// Updates and exports the camera matrix to the Vertex Shader
glm::mat4 Matrix(float FOVdeg, float nearPlane, float farPlane);
// Handles camera inputs
void Keyboard(unsigned char key);
void Mouse(int x, int y);
};

View File

@ -21,12 +21,10 @@ Core::Shader_Loader shaderLoader;
Core::RenderContext sharkModel;
Core::RenderContext sphereContext;
glm::vec3 cameraPos = glm::vec3(0, 0, 5);
glm::vec3 cameraDir; // Wektor "do przodu" kamery
glm::vec3 cameraSide; // Wektor "w bok" kamery
float cameraAngle = 0;
glm::mat4 cameraMatrix, perspectiveMatrix;
Camera camera(600, 600, glm::vec3(0.0f, 0.0f, 5.0f));
glm::mat4 cameraMatrix;
glm::vec3 lightDir = glm::vec3(0.0f, 100.0f, 0.0f);
@ -42,51 +40,30 @@ GLuint sharkTexture;
void keyboard(unsigned char key, int x, int y)
{
float angleSpeed = 0.1f;
float moveSpeed = 0.1f;
switch(key)
{
case 'z': cameraAngle -= angleSpeed; break;
case 'x': cameraAngle += angleSpeed; break;
case 'w': cameraPos += cameraDir * moveSpeed; break;
case 's': cameraPos -= cameraDir * moveSpeed; break;
case 'd': cameraPos += cameraSide * moveSpeed; break;
case 'a': cameraPos -= cameraSide * moveSpeed; break;
camera.Keyboard(key);
switch (key) {
case 'q': glutLeaveMainLoop();
}
}
void mouse(int x, int y)
{
mouseX = x - prevX;
prevX = x;
mouseY = y - prevY;
prevY = y;
}
glm::mat4 createCameraMatrix()
{
glm::quat rotationChange = glm::angleAxis((float) glm::radians(mouseY), glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis((float) glm::radians(mouseX), glm::vec3(0.0f, 1.0f, 0.0f)) * glm::angleAxis(cameraAngle, glm::vec3(0.0f, 0.0f, 1.0f));
mouseX = 0;
mouseY = 0;
cameraAngle = 0;
rotation = glm::normalize(rotationChange * rotation);
cameraDir = glm::inverse(rotation) * glm::vec3(0.0f, 0.0f, -1.0f);
cameraSide = glm::inverse(rotation) * glm::vec3(1.0f, 0.0f, 0.0f);
return Core::createViewMatrixQuat(cameraPos,rotation);
camera.Mouse(x, y);
}
void drawObjectColor(Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 color)
{
GLuint program = programColor;
glm::vec3 cameraPos = camera.getPosition();
glUseProgram(program);
glUniform3f(glGetUniformLocation(program, "objectColor"), color.x, color.y, color.z);
glUniform3f(glGetUniformLocation(program, "lightPos"), lightDir.x, lightDir.y, lightDir.z);
glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z);
glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z);
glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix;
glm::mat4 transformation = cameraMatrix;
glUniformMatrix4fv(glGetUniformLocation(program, "modelViewProjectionMatrix"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
@ -101,11 +78,13 @@ void drawObjectTexture(Core::RenderContext context, glm::mat4 modelMatrix, GLuin
glUseProgram(program);
glm::vec3 cameraPos = camera.getPosition();
glUniform3f(glGetUniformLocation(program, "lightPos"), lightDir.x, lightDir.y, lightDir.z);
glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z);
Core::SetActiveTexture(textureId, "textureSampler", program, 0);
glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix;
glm::mat4 transformation = cameraMatrix * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(program, "modelViewProjectionMatrix"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
@ -116,14 +95,16 @@ void drawObjectTexture(Core::RenderContext context, glm::mat4 modelMatrix, GLuin
void renderScene()
{
// Aktualizacja macierzy widoku i rzutowania
cameraMatrix = createCameraMatrix();
perspectiveMatrix = Core::createPerspectiveMatrix();
cameraMatrix = camera.Matrix(45.0f, 0.1f, 100.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.1f, 0.3f, 1.0f);
glm::mat4 shipInitialTransformation = glm::translate(glm::vec3(0,-1.0f,-1.0f)) * glm::rotate(glm::radians(180.0f), glm::vec3(0,1,0)) * glm::scale(glm::vec3(0.25f));
glm::mat4 shipModelMatrix = glm::translate(cameraPos + cameraDir * 0.5f) * glm::mat4_cast(glm::inverse(rotation)) * shipInitialTransformation;
glm::mat4 shipInitialTransformation = glm::translate(glm::vec3(0.0f, -0.5f, 0.0f)) * glm::scale(glm::vec3(0.25f));
//glm::mat4 shipModelMatrix = glm::translate(camera.getPosition() + camera.getOrientation() * 0.5f) * glm::mat4_cast(glm::inverse(rotation)) * shipInitialTransformation;
//glm::mat4 shipModelMatrix = glm::translate(camera.getPosition()) * glm::mat4_cast(glm::inverse(rotation)) * shipInitialTransformation;
glm::mat4 shipModelMatrix = glm::inverse(cameraMatrix) * glm::mat4_cast(glm::inverse(rotation)) * shipInitialTransformation;
drawObjectTexture(sharkModel, shipModelMatrix, sharkTexture);
for (auto& coords : planetsCoords) {
@ -188,6 +169,7 @@ int main(int argc, char ** argv)
glutPassiveMotionFunc(mouse);
glutDisplayFunc(renderScene);
glutIdleFunc(idle);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutMainLoop();