#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Shader.h"
const float DEFAULT_FOV = 90.0f;
class Camera {
public:
glm::vec3 Position = glm::vec3(0.0f);
glm::vec3 Front;
glm::vec3 Up;
glm::vec3 Right;
glm::vec3 FrontDirection;
glm::vec3 RightDirection;
float Yaw = 270.0f;
float Pitch = 0.0f;
float Zoom = DEFAULT_FOV;
Camera() {
UpdateCameraVectors();
}
inline glm::mat4 GetViewMatrix() {
return glm::lookAt(Position, Position + Front, Up);
}
void UpdateCameraVectors();
};
void Camera::UpdateCameraVectors() {
glm::vec3 front;
front.x = glm::cos(glm::radians(Yaw)) * glm::cos(glm::radians(Pitch));
front.y = glm::sin(glm::radians(Pitch));
front.z = glm::sin(glm::radians(Yaw)) * glm::cos(glm::radians(Pitch));
FrontDirection = glm::normalize(glm::vec3(front.x, 0, front.z));
RightDirection = glm::vec3(-FrontDirection.z, 0, FrontDirection.x);
Front = glm::normalize(front);
Right = glm::normalize(glm::cross(Front, glm::vec3(0, 1, 0)));
Up = glm::normalize(glm::cross(Right, Front));
}
static bool WindowFocused = true;
static bool WindowMinimized = false;
double DeltaTime = 0.0;
double LastFrame = 0.0;
// Defining shaders.
Shader* shader = nullptr;
// Initializing objects.
Camera Cam = Camera();
UniformBuffer UBO = UniformBuffer();
// The main window which everything is rendered in.
GLFWwindow* Window = nullptr;
bool FULLSCREEN = true;
bool VSYNC = true;
int FOV = 90;
int MIPMAP_LEVEL = 4;
int SCREEN_HEIGHT = 1080;
int SCREEN_WIDTH = 1920;
int ANISOTROPIC_FILTERING = 16;
void Key_Proxy(GLFWwindow* window, int key, int scancode, int action, int mods) {
}
void Mouse_Proxy(GLFWwindow* window, double posX, double posY) {
}
// Proxy for receiving Unicode codepoints, very useful for getting text input.
void Text_Proxy(GLFWwindow* window, unsigned int codepoint) {
}
void Scroll_Proxy(GLFWwindow* window, double offsetX, double offsetY) {
}
void Click_Proxy(GLFWwindow* window, int button, int action, int mods) {
}
void Window_Focused(GLFWwindow* window, int focused) {
WindowFocused = focused > 0;
}
void Window_Minimized(GLFWwindow* window, int iconified) {
WindowMinimized = iconified > 0;
}
void Exit(void* caller) {
glfwSetWindowShouldClose(Window, true);
}
void Init_GL() {
// Set the OpenGL version.
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, false);
glfwWindowHint(GLFW_AUTO_ICONIFY, false);
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
// Get the video mode of the monitor.
const GLFWvidmode* videoMode = glfwGetVideoMode(monitor);
int sWidth, sHeight;
glfwGetMonitorPhysicalSize(monitor, &sWidth, &sHeight);
SCREEN_DPI = videoMode->width / (sWidth / 25.4);
if (FULLSCREEN) {
// Stops the window from having any decoration, such as a title bar.
glfwWindowHint(GLFW_DECORATED, false);
// Set SCREEN_WIDTH and SCREEN_HEIGHT to the resolution of the primary monitor.
SCREEN_WIDTH = videoMode->width;
SCREEN_HEIGHT = videoMode->height;
glfwWindowHint(GLFW_REFRESH_RATE, videoMode->refreshRate);
// Create a fullscreen window.
Window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Craftmine", monitor, nullptr);
}
else {
// Set the window to be decorated, allowing users to close it.
glfwWindowHint(GLFW_DECORATED, true);
// Create a windowed window.
Window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Craftmine", nullptr, nullptr);
}
// Set the window's position to the upper left corner.
glfwSetWindowPos(Window, 0, 0);
// Set the window to be used for future OpenGL calls.
glfwMakeContextCurrent(Window);
// Set whether to use VSync based on the value in the config file.
glfwSwapInterval(VSYNC);
// Set GLEW to experimental mode (doesn't work otherwise D:)
glewExperimental = GL_TRUE;
// Initializes GLEW, which enables vendor-specific OpenGL extensions.
glewInit();
// Set all the callback functions for events to the appropiate proxy functions.
glfwSetKeyCallback(Window, Key_Proxy);
glfwSetCharCallback(Window, Text_Proxy);
glfwSetScrollCallback(Window, Scroll_Proxy);
glfwSetCursorPosCallback(Window, Mouse_Proxy);
glfwSetMouseButtonCallback(Window, Click_Proxy);
glfwSetWindowIconifyCallback(Window, Window_Minimized);
// Enable Blending, which makes transparency work.
glEnable(GL_BLEND);
// Enable Fade Culling, which disables rendering of hidden faces.
glEnable(GL_CULL_FACE);
// Enable Depth Testing,
// which chooses which elements to draw based on their depth, thus allowing 3D to work.
glEnable(GL_DEPTH_TEST);
// Set the proper function for evaluating blending.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Specify the size of the OpenGL view port.
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Set the color that the window gets filled with when the color buffer gets cleared.
glClearColor(CLEAR_COLOR.r, CLEAR_COLOR.g, CLEAR_COLOR.b, 1.0f);
}
void Init_Textures() {
glActiveTexture(GL_TEXTURE0);
// Load the texture atlas into a texture array, with mipmapping enabled,
// and store it in the active Texture Unit.
glBindTexture(
GL_TEXTURE_2D_ARRAY,
Load_Array_Texture(
"atlas.png", {16, 32},
MIPMAP_LEVEL, static_cast<float>(ANISOTROPIC_FILTERING)
)
);
}
void Init_Shaders() {
// Load the shaders.
shader = new Shader("shader");
// Create the frustrum projection matrix for the camera.
glm::mat4 projection = glm::perspective(
glm::radians(static_cast<float>(FOV)),
static_cast<float>(SCREEN_WIDTH) / SCREEN_HEIGHT,
Z_NEAR_LIMIT, Z_FAR_LIMIT
);
// Create a matrix storage block in the shaders referenced in the last argument.
UBO.Create("Matrices", 0, 2 * sizeof(glm::mat4),
{shader}
);
UBO.Upload(1, projection);
}
void Init_Rendering() {
// Default identity matrix, does nothing.
glm::mat4 model;
// Upload the empty matrix.
shader->Upload("model", model);
// Upload the light level of an unlit block.
shader->Upload("ambient", AMBIENT_LIGHT);
// Upload the max light level of a block.
shader->Upload("diffuse", DIFFUSE_LIGHT);
// Upload the texture unit index of the main textures.
shader->Upload("diffTex", 0);
}
void Render_Scene() {
UBO.Upload(0, Cam.GetViewMatrix());
/*
* RENDER SHIT
*/
}
int main() {
// Initialize GLFW, the library responsible for windowing, events, etc...
glfwInit();
Init_GL();
Init_Textures();
Init_Shaders();
Init_Rendering();
// The main loop.
// Runs until window is closed.
while (!glfwWindowShouldClose(Window)) {
if (WindowMinimized || !WindowFocused) {
glfwWaitEvents();
continue;
}
// Clear the screen buffer from the last frame.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Get the time difference between this frame and the last one.
double currentFrame = glfwGetTime();
DeltaTime = currentFrame - LastFrame;
LastFrame = currentFrame;
// Polls and processes received events.
glfwPollEvents();
Render_Scene();
// Swap the newly rendered frame with the old one.
glfwSwapBuffers(Window);
}
// Shut down the graphics library, and return.
glfwTerminate();
return 0;
}
Comments