added a camera class
This commit is contained in:
parent
39cf068e91
commit
0bdca85075
10 changed files with 492 additions and 261 deletions
128
include/myEngine/camera.hpp
Normal file
128
include/myEngine/camera.hpp
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
|
||||||
|
enum Camera_Movement {
|
||||||
|
FORWARD,
|
||||||
|
BACKWARD,
|
||||||
|
LEFT,
|
||||||
|
RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
// Default camera values
|
||||||
|
const float YAW = -90.0f;
|
||||||
|
const float PITCH = 0.0f;
|
||||||
|
const float SPEED = 2.5f;
|
||||||
|
const float SENSITIVITY = 0.1f;
|
||||||
|
const float ZOOM = 45.0f;
|
||||||
|
|
||||||
|
|
||||||
|
// An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// camera Attributes
|
||||||
|
glm::vec3 Position;
|
||||||
|
glm::vec3 Front;
|
||||||
|
glm::vec3 Up;
|
||||||
|
glm::vec3 Right;
|
||||||
|
glm::vec3 WorldUp;
|
||||||
|
// euler Angles
|
||||||
|
float Yaw;
|
||||||
|
float Pitch;
|
||||||
|
// camera options
|
||||||
|
float MovementSpeed;
|
||||||
|
float MouseSensitivity;
|
||||||
|
float Zoom;
|
||||||
|
|
||||||
|
// constructor with vectors
|
||||||
|
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
|
||||||
|
{
|
||||||
|
Position = position;
|
||||||
|
WorldUp = up;
|
||||||
|
Yaw = yaw;
|
||||||
|
Pitch = pitch;
|
||||||
|
updateCameraVectors();
|
||||||
|
}
|
||||||
|
// constructor with scalar values
|
||||||
|
Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
|
||||||
|
{
|
||||||
|
Position = glm::vec3(posX, posY, posZ);
|
||||||
|
WorldUp = glm::vec3(upX, upY, upZ);
|
||||||
|
Yaw = yaw;
|
||||||
|
Pitch = pitch;
|
||||||
|
updateCameraVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the view matrix calculated using Euler Angles and the LookAt Matrix
|
||||||
|
glm::mat4 GetViewMatrix()
|
||||||
|
{
|
||||||
|
return glm::lookAt(Position, Position + Front, Up);
|
||||||
|
}
|
||||||
|
|
||||||
|
// processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
|
||||||
|
void ProcessKeyboard(Camera_Movement direction, float deltaTime)
|
||||||
|
{
|
||||||
|
float velocity = MovementSpeed * deltaTime;
|
||||||
|
if (direction == FORWARD)
|
||||||
|
Position += Front * velocity;
|
||||||
|
if (direction == BACKWARD)
|
||||||
|
Position -= Front * velocity;
|
||||||
|
if (direction == LEFT)
|
||||||
|
Position -= Right * velocity;
|
||||||
|
if (direction == RIGHT)
|
||||||
|
Position += Right * velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// processes input received from a mouse input system. Expects the offset value in both the x and y direction.
|
||||||
|
void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)
|
||||||
|
{
|
||||||
|
xoffset *= MouseSensitivity;
|
||||||
|
yoffset *= MouseSensitivity;
|
||||||
|
|
||||||
|
Yaw += xoffset;
|
||||||
|
Pitch += yoffset;
|
||||||
|
|
||||||
|
// make sure that when pitch is out of bounds, screen doesn't get flipped
|
||||||
|
if (constrainPitch)
|
||||||
|
{
|
||||||
|
if (Pitch > 89.0f)
|
||||||
|
Pitch = 89.0f;
|
||||||
|
if (Pitch < -89.0f)
|
||||||
|
Pitch = -89.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update Front, Right and Up Vectors using the updated Euler angles
|
||||||
|
updateCameraVectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
|
||||||
|
void ProcessMouseScroll(float yoffset)
|
||||||
|
{
|
||||||
|
Zoom -= (float)yoffset;
|
||||||
|
if (Zoom < 1.0f)
|
||||||
|
Zoom = 1.0f;
|
||||||
|
if (Zoom > 45.0f)
|
||||||
|
Zoom = 45.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// calculates the front vector from the Camera's (updated) Euler Angles
|
||||||
|
void updateCameraVectors()
|
||||||
|
{
|
||||||
|
// calculate the new Front vector
|
||||||
|
glm::vec3 front;
|
||||||
|
front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||||
|
front.y = sin(glm::radians(Pitch));
|
||||||
|
front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||||
|
Front = glm::normalize(front);
|
||||||
|
// also re-calculate the Right and Up vector
|
||||||
|
Right = glm::normalize(glm::cross(Front, WorldUp)); // normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
|
||||||
|
Up = glm::normalize(glm::cross(Right, Front));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
158
include/myEngine/shader.hpp
Normal file
158
include/myEngine/shader.hpp
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
#ifndef SHADER_H
|
||||||
|
#define SHADER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// the program ID
|
||||||
|
unsigned int ID;
|
||||||
|
|
||||||
|
Shader(const char* vertexPath, const char* fragmentPath)
|
||||||
|
{
|
||||||
|
std::string vertexCode;
|
||||||
|
std::string fragmentCode;
|
||||||
|
std::ifstream vShaderFile;
|
||||||
|
std::ifstream fShaderFile;
|
||||||
|
|
||||||
|
vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vShaderFile.open(vertexPath);
|
||||||
|
fShaderFile.open(fragmentPath);
|
||||||
|
std::stringstream vShaderStream, fShaderStream;
|
||||||
|
|
||||||
|
vShaderStream << vShaderFile.rdbuf();
|
||||||
|
fShaderStream << fShaderFile.rdbuf();
|
||||||
|
|
||||||
|
vShaderFile.close();
|
||||||
|
fShaderFile.close();
|
||||||
|
|
||||||
|
vertexCode = vShaderStream.str();
|
||||||
|
fragmentCode = fShaderStream.str();
|
||||||
|
}
|
||||||
|
catch(std::ifstream::failure e)
|
||||||
|
{
|
||||||
|
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* vShaderCode = vertexCode.c_str();
|
||||||
|
const char* fShaderCode = fragmentCode.c_str();
|
||||||
|
|
||||||
|
unsigned int vertex, fragment;
|
||||||
|
int success;
|
||||||
|
char infoLog[512];
|
||||||
|
|
||||||
|
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||||
|
|
||||||
|
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||||
|
|
||||||
|
glCompileShader(vertex);
|
||||||
|
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
glCompileShader(fragment);
|
||||||
|
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
ID = glCreateProgram();
|
||||||
|
glAttachShader(ID, vertex);
|
||||||
|
glAttachShader(ID, fragment);
|
||||||
|
glLinkProgram(ID);
|
||||||
|
|
||||||
|
glGetProgramiv(ID, GL_LINK_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetProgramInfoLog(ID, 512, NULL, infoLog);
|
||||||
|
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vertex);
|
||||||
|
glDeleteShader(fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void use()
|
||||||
|
{
|
||||||
|
glUseProgram(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBool(const std::string &name, bool value) const
|
||||||
|
{
|
||||||
|
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setInt(const std::string &name, int value) const
|
||||||
|
{
|
||||||
|
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFloat(const std::string &name, float value) const
|
||||||
|
{
|
||||||
|
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVec2(const std::string &name, const glm::vec2 &value) const
|
||||||
|
{
|
||||||
|
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVec2(const std::string &name, float x, float y) const
|
||||||
|
{
|
||||||
|
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVec3(const std::string &name, const glm::vec3 &value) const
|
||||||
|
{
|
||||||
|
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVec3(const std::string &name, float x, float y, float z) const
|
||||||
|
{
|
||||||
|
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVec4(const std::string &name, const glm::vec4 &value) const
|
||||||
|
{
|
||||||
|
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVec4(const std::string &name, float x, float y, float z, float w) const
|
||||||
|
{
|
||||||
|
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMat2(const std::string &name, const glm::mat2 &mat) const
|
||||||
|
{
|
||||||
|
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMat3(const std::string &name, const glm::mat3 &mat) const
|
||||||
|
{
|
||||||
|
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMat4(const std::string &name, const glm::mat4 &mat) const
|
||||||
|
{
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
15
include/myEngine/shapes/cube.hpp
Normal file
15
include/myEngine/shapes/cube.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef CUBE_H
|
||||||
|
#define CUBE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Cube
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned int VBO, EBO;
|
||||||
|
|
||||||
|
Cube()
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
51
include/myEngine/texture.hpp
Normal file
51
include/myEngine/texture.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef TEXTURE_H
|
||||||
|
#define TEXTURE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned int ID;
|
||||||
|
|
||||||
|
Texture(const char* texturePath)
|
||||||
|
{
|
||||||
|
glGenTextures(1, &ID);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, ID);
|
||||||
|
// set the texture wrapping/filtering options (on the currently bound texture object)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// load and generate the texture
|
||||||
|
int width, height, nrChannels;
|
||||||
|
stbi_set_flip_vertically_on_load(true);
|
||||||
|
unsigned char *data = stbi_load(texturePath, &width, &height, &nrChannels, 0);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
GLenum format = GL_RGB;
|
||||||
|
if (nrChannels == 1) format = GL_RED;
|
||||||
|
else if (nrChannels == 3) format = GL_RGB;
|
||||||
|
else if (nrChannels == 4) format = GL_RGBA;
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Failed to load texture" << std::endl;
|
||||||
|
}
|
||||||
|
stbi_image_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void use()
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, ID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,32 +0,0 @@
|
||||||
#ifndef SHADER_H
|
|
||||||
#define SHADER_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
class Shader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// the program ID
|
|
||||||
unsigned int ID;
|
|
||||||
|
|
||||||
// constructor reads and builds the shader
|
|
||||||
Shader(const char* vertexPath, const char* fragmentPath);
|
|
||||||
// use/activate the shader
|
|
||||||
void use();
|
|
||||||
// utility uniform functions
|
|
||||||
void setBool(const std::string &name, bool value) const;
|
|
||||||
void setInt(const std::string &name, int value) const;
|
|
||||||
void setFloat(const std::string &name, float value) const;
|
|
||||||
void setVec2(const std::string &name, const glm::vec2 &value) const;
|
|
||||||
void setVec2(const std::string &name, float x, float y) const;
|
|
||||||
void setVec3(const std::string &name, const glm::vec3 &value) const;
|
|
||||||
void setVec3(const std::string &name, float x, float y, float z) const;
|
|
||||||
void setVec4(const std::string &name, const glm::vec4 &value) const;
|
|
||||||
void setVec4(const std::string &name, float x, float y, float z, float w) const;
|
|
||||||
void setMat2(const std::string &name, const glm::mat2 &mat) const;
|
|
||||||
void setMat3(const std::string &name, const glm::mat3 &mat) const;
|
|
||||||
void setMat4(const std::string &name, const glm::mat4 &mat) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef TEXTURE_H
|
|
||||||
#define TEXTURE_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class Texture
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
unsigned int ID;
|
|
||||||
|
|
||||||
Texture(const char* texturePath);
|
|
||||||
void use();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -3,11 +3,13 @@ layout (location = 0) in vec3 aPos;
|
||||||
layout (location = 1) in vec2 aTexCoord;
|
layout (location = 1) in vec2 aTexCoord;
|
||||||
|
|
||||||
out vec2 TexCoord;
|
out vec2 TexCoord;
|
||||||
|
|
||||||
uniform mat4 transform;
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = transform * vec4(aPos, 1.0f);
|
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||||
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
|
TexCoord = aTexCoord;
|
||||||
}
|
}
|
157
src/main.cpp
157
src/main.cpp
|
@ -1,14 +1,27 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <shaders/shader.hpp>
|
#include <myEngine/shader.hpp>
|
||||||
#include <textures/texture.hpp>
|
#include <myEngine/texture.hpp>
|
||||||
|
#include <myEngine/camera.hpp>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
||||||
void processInput(GLFWwindow *window);
|
void processInput(GLFWwindow *window);
|
||||||
|
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
|
||||||
|
|
||||||
|
const unsigned int SCR_WIDTH = 800;
|
||||||
|
const unsigned int SCR_HEIGHT = 600;
|
||||||
|
|
||||||
|
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
|
||||||
|
float lastX = SCR_WIDTH / 2.0f;
|
||||||
|
float lastY = SCR_HEIGHT / 2.0f;
|
||||||
|
bool firstMouse = true;
|
||||||
|
|
||||||
|
float deltaTime = 0.0f;
|
||||||
|
float lastFrame = 0.0f;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -26,6 +39,8 @@ int main()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
glfwSetCursorPosCallback(window, mouse_callback);
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||||
{
|
{
|
||||||
|
@ -38,15 +53,47 @@ int main()
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
|
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
|
||||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
|
||||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
};
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
|
||||||
|
|
||||||
unsigned int indices[] = {
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
0, 1, 2,
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
2, 3, 0
|
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
|
||||||
|
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int VAO;
|
unsigned int VAO;
|
||||||
|
@ -58,10 +105,10 @@ int main()
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
unsigned int EBO;
|
/*unsigned int EBO;
|
||||||
glGenBuffers(1, &EBO);
|
glGenBuffers(1, &EBO);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);*/
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
@ -73,24 +120,60 @@ int main()
|
||||||
Texture sataaAndagii("textures/saataa_andagii.png");
|
Texture sataaAndagii("textures/saataa_andagii.png");
|
||||||
Texture ohMyGah("textures/oh_my_gah.png");
|
Texture ohMyGah("textures/oh_my_gah.png");
|
||||||
|
|
||||||
glm::mat4 trans = glm::mat4(1.0f);
|
glm::mat4 model = glm::mat4(1.0f);
|
||||||
trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
|
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
|
|
||||||
|
glm::mat4 view = glm::mat4(1.0f);
|
||||||
|
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
|
||||||
|
|
||||||
|
glm::mat4 projection;
|
||||||
|
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glm::vec3 cubePositions[] = {
|
||||||
|
glm::vec3( 0.0f, 0.0f, 0.0f),
|
||||||
|
glm::vec3( 2.0f, 5.0f, -15.0f),
|
||||||
|
glm::vec3(-1.5f, -2.2f, -2.5f),
|
||||||
|
glm::vec3(-3.8f, -2.0f, -12.3f),
|
||||||
|
glm::vec3( 2.4f, -0.4f, -3.5f),
|
||||||
|
glm::vec3(-1.7f, 3.0f, -7.5f),
|
||||||
|
glm::vec3( 1.3f, -2.0f, -2.5f),
|
||||||
|
glm::vec3( 1.5f, 2.0f, -2.5f),
|
||||||
|
glm::vec3( 1.5f, 0.2f, -1.5f),
|
||||||
|
glm::vec3(-1.3f, 1.0f, -1.5f)
|
||||||
|
};
|
||||||
|
|
||||||
while(!glfwWindowShouldClose(window))
|
while(!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
|
float currentFrame = glfwGetTime();
|
||||||
|
deltaTime = currentFrame - lastFrame;
|
||||||
|
lastFrame = currentFrame;
|
||||||
|
|
||||||
processInput(window);
|
processInput(window);
|
||||||
|
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glm::mat4 view = camera.GetViewMatrix();
|
||||||
|
|
||||||
ourShader.use();
|
ourShader.use();
|
||||||
trans = glm::rotate(trans, (float)glfwGetTime() / 100, glm::vec3(0.0f, 0.0f, 1.0f));
|
ourShader.setMat4("model", model);
|
||||||
ourShader.setMat4("transform", trans);
|
ourShader.setMat4("view", view);
|
||||||
|
ourShader.setMat4("projection", projection);
|
||||||
|
|
||||||
ohMyGah.use();
|
ohMyGah.use();
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
for(unsigned int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
glm::mat4 model = glm::mat4(1.0f);
|
||||||
|
model = glm::translate(model, cubePositions[i]);
|
||||||
|
float angle = 20.0f * i;
|
||||||
|
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
|
||||||
|
ourShader.setMat4("model", model);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
|
}
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
@ -109,8 +192,36 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
|
|
||||||
void processInput(GLFWwindow *window)
|
void processInput(GLFWwindow *window)
|
||||||
{
|
{
|
||||||
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||||
{
|
|
||||||
glfwSetWindowShouldClose(window, true);
|
glfwSetWindowShouldClose(window, true);
|
||||||
}
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(FORWARD, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(BACKWARD, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(LEFT, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(RIGHT, deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
|
||||||
|
{
|
||||||
|
float xpos = static_cast<float>(xposIn);
|
||||||
|
float ypos = static_cast<float>(yposIn);
|
||||||
|
|
||||||
|
if (firstMouse)
|
||||||
|
{
|
||||||
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
|
firstMouse = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float xoffset = xpos - lastX;
|
||||||
|
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
|
||||||
|
|
||||||
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
|
|
||||||
|
camera.ProcessMouseMovement(xoffset, yoffset);
|
||||||
|
}
|
147
src/shader.cpp
147
src/shader.cpp
|
@ -1,147 +0,0 @@
|
||||||
#include <glad/glad.h> // include glad to get all the required OpenGL headers
|
|
||||||
#include <shaders/shader.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
|
||||||
{
|
|
||||||
std::string vertexCode;
|
|
||||||
std::string fragmentCode;
|
|
||||||
std::ifstream vShaderFile;
|
|
||||||
std::ifstream fShaderFile;
|
|
||||||
|
|
||||||
vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
|
||||||
fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
vShaderFile.open(vertexPath);
|
|
||||||
fShaderFile.open(fragmentPath);
|
|
||||||
std::stringstream vShaderStream, fShaderStream;
|
|
||||||
|
|
||||||
vShaderStream << vShaderFile.rdbuf();
|
|
||||||
fShaderStream << fShaderFile.rdbuf();
|
|
||||||
|
|
||||||
vShaderFile.close();
|
|
||||||
fShaderFile.close();
|
|
||||||
|
|
||||||
vertexCode = vShaderStream.str();
|
|
||||||
fragmentCode = fShaderStream.str();
|
|
||||||
}
|
|
||||||
catch(std::ifstream::failure e)
|
|
||||||
{
|
|
||||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* vShaderCode = vertexCode.c_str();
|
|
||||||
const char* fShaderCode = fragmentCode.c_str();
|
|
||||||
|
|
||||||
unsigned int vertex, fragment;
|
|
||||||
int success;
|
|
||||||
char infoLog[512];
|
|
||||||
|
|
||||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
|
||||||
|
|
||||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
|
||||||
|
|
||||||
glCompileShader(vertex);
|
|
||||||
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
|
||||||
if(!success)
|
|
||||||
{
|
|
||||||
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
|
|
||||||
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
|
||||||
};
|
|
||||||
|
|
||||||
glCompileShader(fragment);
|
|
||||||
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
|
||||||
if(!success)
|
|
||||||
{
|
|
||||||
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
|
|
||||||
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
|
|
||||||
};
|
|
||||||
|
|
||||||
ID = glCreateProgram();
|
|
||||||
glAttachShader(ID, vertex);
|
|
||||||
glAttachShader(ID, fragment);
|
|
||||||
glLinkProgram(ID);
|
|
||||||
|
|
||||||
glGetProgramiv(ID, GL_LINK_STATUS, &success);
|
|
||||||
if(!success)
|
|
||||||
{
|
|
||||||
glGetProgramInfoLog(ID, 512, NULL, infoLog);
|
|
||||||
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
glDeleteShader(vertex);
|
|
||||||
glDeleteShader(fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::use()
|
|
||||||
{
|
|
||||||
glUseProgram(ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setBool(const std::string &name, bool value) const
|
|
||||||
{
|
|
||||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setInt(const std::string &name, int value) const
|
|
||||||
{
|
|
||||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setFloat(const std::string &name, float value) const
|
|
||||||
{
|
|
||||||
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setVec2(const std::string &name, const glm::vec2 &value) const
|
|
||||||
{
|
|
||||||
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setVec2(const std::string &name, float x, float y) const
|
|
||||||
{
|
|
||||||
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setVec3(const std::string &name, const glm::vec3 &value) const
|
|
||||||
{
|
|
||||||
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setVec3(const std::string &name, float x, float y, float z) const
|
|
||||||
{
|
|
||||||
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setVec4(const std::string &name, const glm::vec4 &value) const
|
|
||||||
{
|
|
||||||
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setVec4(const std::string &name, float x, float y, float z, float w) const
|
|
||||||
{
|
|
||||||
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setMat2(const std::string &name, const glm::mat2 &mat) const
|
|
||||||
{
|
|
||||||
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setMat3(const std::string &name, const glm::mat3 &mat) const
|
|
||||||
{
|
|
||||||
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::setMat4(const std::string &name, const glm::mat4 &mat) const
|
|
||||||
{
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
#include <glad/glad.h> // include glad to get all the required OpenGL headers
|
|
||||||
#include <textures/texture.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
|
||||||
#include "stb_image.h"
|
|
||||||
|
|
||||||
Texture::Texture(const char* texturePath)
|
|
||||||
{
|
|
||||||
glGenTextures(1, &ID);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, ID);
|
|
||||||
// set the texture wrapping/filtering options (on the currently bound texture object)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
// load and generate the texture
|
|
||||||
int width, height, nrChannels;
|
|
||||||
stbi_set_flip_vertically_on_load(true);
|
|
||||||
unsigned char *data = stbi_load(texturePath, &width, &height, &nrChannels, 0);
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
GLenum format = GL_RGB;
|
|
||||||
if (nrChannels == 1) format = GL_RED;
|
|
||||||
else if (nrChannels == 3) format = GL_RGB;
|
|
||||||
else if (nrChannels == 4) format = GL_RGBA;
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Failed to load texture" << std::endl;
|
|
||||||
}
|
|
||||||
stbi_image_free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::use()
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, ID);
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue