anden3 icon

Min GLFW

anden3 | PRO | 03/21/17 08:51:45 AM UTC | 0 ⭐ | 361 👁️ | Never ⏰ | []
C++ |

8.08 KB

|

None

|

0 👍

/

0 👎

#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