shader.h

#pragma once
#include "cgmath.h"
#include "texture.h"

class Shader
{
    public:
    Shader(const char* vertexShaderFile, const char* fragmentShaderFile);
    ~Shader();
    void activate();
    void setMatrix(const char*, Matrix);
    void setVector3(const char*, Vector3);
    void setTexture(const char*, Texture*);

    private:
    unsigned int shaderProgram;
    bool shaderCompile(const char* filename, unsigned int* shader, unsigned int type);
    char* readFile(const char* filename);
};

shader.cpp

void Shader::setTexture(const char* key, Texture* texture)
{
    static const char* textureSlots[16] = { nullptr };
    GLint location = glGetUniformLocation(shaderProgram, key);
    if (location >= 0)
    {
        for (int i = 0; i < 16; i++)
        {
            if (textureSlots[i] == nullptr)
            {
                textureSlots[i] = key;
                glUniform1i(location, i);
            }
            if (strcmp(textureSlots[i], key) == 0)
            {
                glActiveTexture(GL_TEXTURE0 + i);
                glBindTexture(GL_TEXTURE_2D, texture->Id);
                break;
            }
        }
    }
}

vertex_shader.glsl

#version 330 core
layout (location = 0) in vec3 Pos;
layout (location = 1) in vec2 TexCoordIn;

out vec2 TexCoord;

uniform mat4 WorldMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

void main()
{
    mat4 WvpMatrix = ProjectionMatrix * ViewMatrix * WorldMatrix;
    gl_Position = WvpMatrix * vec4(Pos.x, Pos.y, Pos.z, 1.0);
    TexCoord = TexCoordIn;
}

fragment_shader.glsl

#version 330 core
out vec4 FragColor;

in vec2 TexCoord;

uniform sampler2D Diffuse;

void main()
{
    FragColor = texture(Diffuse, TexCoord);
}