Nun da wir alle Einzelteile zusammen haben, können wir die Fehler in der graphics.cpp beheben und damit die Umstellung auf die neue API vollenden.

Include Statements

Wir benötigen eine reihe von Include Statements, damit unsere neuen Klassen und Strukturen auch genutzt werden:

#include <glad.c>
#include <GLFW/glfw3.h>
#include <iostream>
#include "cgmath.h"
#include "settings.h"
#include "shader.h"
#include "mesh.h"
#include "vertex.h"

Static Variables

static int viewportWidth = 0;
static int viewportHeight = 0;
static int resizeViewport = false;
static Matrix viewMatrix = matrixTranslate(0.0f, 0.0f, -2.0f);
static Matrix viewMatrix;
static Matrix projectionMatrix;
static Shader* shader;
static Mesh* mesh;

Set Viewport

Hier haben wir bisher die Projektionsmatrix direkt an die Grafikkarte gesendet. Das fällt nun weg. Stattdessen speichern wir sie lediglich in die statische Variable, die wir gerade angelegt haben. Hier müssen wir also einiges löschen damit unser Code anschließend so aussieht:

static void setViewport()
{
    if (resizeViewport)
    {
        resizeViewport = false;

        glViewport(0,0, viewportWidth, viewportHeight);
        double zNear = 0.1;
        double zFar = 100.0;
        double fov = 0.785; //45deg
        double aspect = (double)viewportWidth / (double)viewportHeight;
        projectionMatrix = matrixPerspective(fov, aspect, zNear, zFar);
    }
}

Graphics Start

Bei Laden der Graphics Unit wollen wir nun die Vertices in ein Mesh laden und die Shader kompilieren. Die fertige Funktion sieht wie folgt aus:

bool graphicsStart(Settings props)
{
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return false;
    }
    
    glfwSwapInterval(props.vsync ? 1 : 0);
    if (props.msaa) glEnable(GL_MULTISAMPLE);
    if (props.culling) glEnable(GL_CULL_FACE);
    if (props.depth) glEnable(GL_DEPTH_TEST);

    glClearColor(0.29f,0.36f,0.4f,1.0f);

    Vertex vertices[] = {
        { -0.6f,  0.0f, 0.0f },
        {  0.0f, -0.6f, 0.0f },
        {  0.6f,  0.0f, 0.0f },
        { -0.6f,  0.0f, 0.0f },
        {  0.6f,  0.0f, 0.0f },
        {  0.0f,  0.6f, 0.0f },
    };
    mesh = new Mesh(vertices, 6);
    
    shader = new Shader("shaders/vertex_shader.glsl", "shaders/fragment_shader.glsl");

    return true;
}

Graphics Loop

Den Graphics Loop können wir ebenfalls stark vereinfachen. Hier fliegt alles raus was zur alten AP gehört und stattdessen rufen wir nun die passenden Methoden unserer neuen Klassen auf um unser Mesh zu rendern:

void graphicsLoop()
{
    setViewport();
    
    glClear(GL_COLOR_BUFFER_BIT);

    shader->activate();
    shader->setMatrix("ProjectionMatrix", projectionMatrix);
    shader->setMatrix("ViewMatrix", viewMatrix);
    shader->setMatrix("WorldMatrix", matrixTranslate(0,0,0));
    mesh->draw();
}