diff --git a/cw 6/src/Camera.cpp b/cw 6/src/Camera.cpp index 7155315..4e323cd 100644 --- a/cw 6/src/Camera.cpp +++ b/cw 6/src/Camera.cpp @@ -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); + +} \ No newline at end of file diff --git a/cw 6/src/Camera.h b/cw 6/src/Camera.h index e7df83e..fb20892 100644 --- a/cw 6/src/Camera.h +++ b/cw 6/src/Camera.h @@ -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); -} \ No newline at end of file + // 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); +}; \ No newline at end of file diff --git a/cw 6/src/main_6_1.cpp b/cw 6/src/main_6_1.cpp index 44cab65..0f29aa2 100644 --- a/cw 6/src/main_6_1.cpp +++ b/cw 6/src/main_6_1.cpp @@ -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();