Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to link an external texture to a shader ?  (Read 3417 times)

0 Members and 1 Guest are viewing this topic.

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
How to link an external texture to a shader ?
« on: October 26, 2020, 03:46:59 pm »
Hi! I'm trying to display a skybox like https://learnopengl.com/Advanced-OpenGL/Cubemaps but with SFML.

The source code is similar to this one https://learnopengl.com/code_viewer_gh.php?code=src/4.advanced_opengl/6.2.cubemaps_environment_mapping/cubemaps_environment_mapping.cpp but I use SFML and not glfw for the window, I use sfml to load images and I use my own view and shader class.

But that doesn't work, it draws a white cube and it doesn't display the skybox.

#include "application.h"
#include <SFML/OpenGL.hpp>
#include "odfaeg/Window/window.hpp"
#include "odfaeg/Window/context.hpp"
#include <SFML/Window/WindowStyle.hpp>
#include "odfaeg/Graphics/sprite.h"
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <stddef.h>
#include <vector>
using namespace odfaeg::core;
using namespace odfaeg::math;
using namespace odfaeg::physic;
using namespace odfaeg::graphic;
using namespace odfaeg::window;
using namespace odfaeg::audio;
using namespace sorrok;
using namespace std;
unsigned int loadTexture(const char *path);
unsigned int loadCubemap(vector<std::string> faces);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
float lastX = (float)SCR_WIDTH / 2.0;
float lastY = (float)SCR_HEIGHT / 2.0;
bool firstMouse = true;

// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;
int main(int argc, char* argv[])
{
    /*EXPORT_CLASS_GUID(BoundingVolumeBoundingBox, BoundingVolume, BoundingBox)
    EXPORT_CLASS_GUID(EntityTile, Entity, Tile)
    EXPORT_CLASS_GUID(EntityTile, Entity, BigTile)
    EXPORT_CLASS_GUID(EntityWall, Entity, g2d::Wall)
    EXPORT_CLASS_GUID(EntityDecor, Entity, g2d::Decor)
    EXPORT_CLASS_GUID(EntityAnimation, Entity, Anim)
    EXPORT_CLASS_GUID(EntityHero, Entity, Hero)
    EXPORT_CLASS_GUID(EntityMesh, Entity, Mesh)
    MyAppli app(sf::VideoMode(800, 600), "Test odfaeg");
    return app.exec();*/

// create the window
    sf::Window window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(32, 0, 4, 3, 3));
    window.setVerticalSyncEnabled(true);

    // activate the window
    window.setActive(true);
    View view(800, 600, 80, 1, 1000);
    view.setCenter(Vec3f(0, 0, 3));
    view.setPerspective(-1, 1, -1, 1, 80, SCR_WIDTH / SCR_HEIGHT, 1, 1000);
    // load resources, initialize the OpenGL states, ...
    glEnable(GL_DEPTH_TEST);
    const std::string cubeMapsVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    layout (location = 1) in vec3 aNormal;

                                    out vec3 Normal;
                                    out vec3 Position;

                                    uniform mat4 model;
                                    uniform mat4 view;
                                    uniform mat4 projection;

                                    void main()
                                    {
                                        Normal = mat3(transpose(inverse(model))) * aNormal;
                                        Position = vec3(model * vec4(aPos, 1.0));
                                        gl_Position = projection * view * model * vec4(aPos, 1.0);
                                    }
                                )"
;
    const std::string cubeMapsFS = R"(#version 330 core
                                        out vec4 FragColor;

                                        in vec3 Normal;
                                        in vec3 Position;

                                        uniform vec3 cameraPos;
                                        uniform samplerCube skybox;

                                        void main()
                                        {
                                            vec3 I = normalize(Position - cameraPos);
                                            vec3 R = reflect(I, normalize(Normal));
                                            FragColor = vec4(texture(skybox, R).rgb, 1.0);
                                        }
                                   )"
;
    const std::string skyboxVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;

                                    out vec3 TexCoords;

                                    uniform mat4 projection;
                                    uniform mat4 view;

                                    void main()
                                    {
                                        TexCoords = aPos;
                                        vec4 pos = projection * view * vec4(aPos, 1.0);
                                        gl_Position = pos.xyww;
                                    }
                                )"
;
    const std::string skyboxFS = R"(#version 330 core
                                    out vec4 FragColor;

                                    in vec3 TexCoords;

                                    uniform samplerCube skybox;

                                    void main()
                                    {
                                        FragColor = texture(skybox, TexCoords);
                                    }
                                    )"
;
    Shader shader;
    shader.loadFromMemory(cubeMapsVS, cubeMapsFS);
    Shader skyboxShader;
    skyboxShader.loadFromMemory(skyboxVS, skyboxFS);
    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    float cubeVertices[] = {
        // positions          // normals
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,

        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
    };
    float skyboxVertices[] = {
        // positions
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f,  1.0f
    };
    // cube VAO
    unsigned int cubeVAO, cubeVBO;
    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &cubeVBO);
    glBindVertexArray(cubeVAO);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    // skybox VAO
    unsigned int skyboxVAO, skyboxVBO;
    glGenVertexArrays(1, &skyboxVAO);
    glGenBuffers(1, &skyboxVBO);
    glBindVertexArray(skyboxVAO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    // load textures
    // -------------
    vector<std::string> faces
    {
        "tilesets/skybox/right.jpg",
        "tilesets/skybox/left.jpg",
        "tilesets/skybox/top.jpg",
        "tilesets/skybox/bottom.jpg",
        "tilesets/skybox/front.jpg",
        "tilesets/skybox/back.jpg"
    };
    unsigned int cubemapTexture = loadCubemap(faces);
    Shader::bind(&shader);
    unsigned int index=0;
    shader.setParameter("texture1", index);
    Shader::bind(&skyboxShader);
    skyboxShader.setParameter("skybox", index);
    sf::Clock time;
    // run the main loop
    bool running = true;
    while (running)
    {
         // per-frame time logic
        // --------------------
        float currentFrame = time.getElapsedTime().asMicroseconds();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
        // handle events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, event.size.width, event.size.height);
            }
        }

        // clear the buffers
        // render
        // ------
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // draw...
        TransformMatrix model;
        Matrix4f modelMatrix = model.getMatrix().transpose();
        Matrix4f viewMatrix = view.getViewMatrix().getMatrix().transpose();
        Matrix4f projectionMatrix = view.getProjMatrix().getMatrix().transpose();
        Shader::bind(&shader);
        shader.setParameter("model", modelMatrix);
        shader.setParameter("view", viewMatrix);
        shader.setParameter("projection", projectionMatrix);
        shader.setParameter("cameraPos", view.getPosition().x, view.getPosition().y, view.getPosition().z);
        // cubes
        glBindVertexArray(cubeVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        // draw skybox as last
        glDepthFunc(GL_LEQUAL);  // change depth function so depth test passes when values are equal to depth buffer's content
        Shader::bind(&skyboxShader);
        skyboxShader.setParameter("view", viewMatrix);
        skyboxShader.setParameter("projection", projectionMatrix);
        // skybox cube
        glBindVertexArray(skyboxVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        glDepthFunc(GL_LESS); // set depth function back to default
        // end the current frame (internally swaps the front and back buffers)
        window.display();
    }

    // release resources...

    return 0;
}
// utility function for loading a 2D texture from file
// ---------------------------------------------------
unsigned int loadTexture(char const * path)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);

    int width, height;
    sf::Image image;
    image.loadFromFile(path);
    width = image.getSize().x;
    height = image.getSize().y;
    if (image.getPixelsPtr())
    {

        glBindTexture(GL_TEXTURE_2D, textureID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image.getPixelsPtr());
        glGenerateMipmap(GL_TEXTURE_2D);

        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);
    }
    else
    {
        std::cout << "Texture failed to load at path: " << path << std::endl;
    }

    return textureID;
}
unsigned int loadCubemap(vector<std::string> faces)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height;
    for (unsigned int i = 0; i < faces.size(); i++)
    {
        sf::Image image;
        image.loadFromFile(faces[i]);
        width = image.getSize().x;
        height = image.getSize().y;
        if (image.getPixelsPtr())
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image.getPixelsPtr());
        }
        else
        {
            std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}
 

Is the code correct to load the texture with the sf::Image ?
And to set the cubeMap parameter to the shader ?
« Last Edit: October 26, 2020, 10:15:18 pm by nagimar »

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Loading textures with sf::Image.
« Reply #1 on: October 26, 2020, 04:33:34 pm »
Ho I forgot to enable GL_TEXTURE_CUBE_MAP but the result is not as I expected.

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Loading textures with sf::Image.
« Reply #2 on: October 26, 2020, 05:25:17 pm »
Here is what I get :

With this code :

#include "application.h"
#include <SFML/OpenGL.hpp>
#include "odfaeg/Window/window.hpp"
#include "odfaeg/Window/context.hpp"
#include <SFML/Window/WindowStyle.hpp>
#include "odfaeg/Graphics/sprite.h"
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <stddef.h>
#include <vector>
using namespace odfaeg::core;
using namespace odfaeg::math;
using namespace odfaeg::physic;
using namespace odfaeg::graphic;
using namespace odfaeg::window;
using namespace odfaeg::audio;
using namespace sorrok;
using namespace std;
unsigned int loadCubemap(vector<std::string> faces);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
float speed = 10.f;
float sensivity = 0.1f;
int main(int argc, char* argv[])
{
    /*EXPORT_CLASS_GUID(BoundingVolumeBoundingBox, BoundingVolume, BoundingBox)
    EXPORT_CLASS_GUID(EntityTile, Entity, Tile)
    EXPORT_CLASS_GUID(EntityTile, Entity, BigTile)
    EXPORT_CLASS_GUID(EntityWall, Entity, g2d::Wall)
    EXPORT_CLASS_GUID(EntityDecor, Entity, g2d::Decor)
    EXPORT_CLASS_GUID(EntityAnimation, Entity, Anim)
    EXPORT_CLASS_GUID(EntityHero, Entity, Hero)
    EXPORT_CLASS_GUID(EntityMesh, Entity, Mesh)
    MyAppli app(sf::VideoMode(800, 600), "Test odfaeg");
    return app.exec();*/

// create the window
    sf::Window window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(32, 0, 4, 3, 3));
    window.setVerticalSyncEnabled(true);

    // activate the window
    window.setActive(true);
    View view(800, 600, 80, 1, 1000);
    view.setCenter(Vec3f(0, 0, 3));
    view.setPerspective(-1, 1, -1, 1, 80, SCR_WIDTH / SCR_HEIGHT, 1, 1000);
    // load resources, initialize the OpenGL states, ...
    glEnable(GL_DEPTH_TEST);
    const std::string cubeMapsVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    layout (location = 1) in vec3 aNormal;

                                    out vec3 Normal;
                                    out vec3 Position;

                                    uniform mat4 model;
                                    uniform mat4 view;
                                    uniform mat4 projection;

                                    void main()
                                    {
                                        Normal = mat3(transpose(inverse(model))) * aNormal;
                                        Position = vec3(model * vec4(aPos, 1.0));
                                        gl_Position = projection * view * model * vec4(aPos, 1.0);
                                    }
                                )"
;
    const std::string cubeMapsFS = R"(#version 330 core
                                        out vec4 FragColor;

                                        in vec3 Normal;
                                        in vec3 Position;

                                        uniform vec3 cameraPos;
                                        uniform samplerCube skybox;

                                        void main()
                                        {
                                            vec3 I = normalize(Position - cameraPos);
                                            vec3 R = reflect(I, normalize(Normal));
                                            FragColor = vec4(texture(skybox, R).rgb, 1.0);
                                        }
                                   )"
;
    const std::string skyboxVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;

                                    out vec3 TexCoords;

                                    uniform mat4 projection;
                                    uniform mat4 view;

                                    void main()
                                    {
                                        TexCoords = aPos;
                                        vec4 pos = projection * view * vec4(aPos, 1.0);
                                        gl_Position = pos.xyww;
                                    }
                                )"
;
    const std::string skyboxFS = R"(#version 330 core
                                    out vec4 FragColor;

                                    in vec3 TexCoords;

                                    uniform samplerCube skybox;

                                    void main()
                                    {
                                        FragColor = texture(skybox, TexCoords);
                                    }
                                    )"
;
    Shader shader;
    shader.loadFromMemory(cubeMapsVS, cubeMapsFS);
    Shader skyboxShader;
    skyboxShader.loadFromMemory(skyboxVS, skyboxFS);
    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    float cubeVertices[] = {
        // positions          // normals
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,

        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
    };
    float skyboxVertices[] = {
        // positions
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f,  1.0f
    };
    // cube VAO
    unsigned int cubeVAO, cubeVBO;
    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &cubeVBO);
    glBindVertexArray(cubeVAO);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    // skybox VAO
    unsigned int skyboxVAO, skyboxVBO;
    glGenVertexArrays(1, &skyboxVAO);
    glGenBuffers(1, &skyboxVBO);
    glBindVertexArray(skyboxVAO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    // load textures
    // -------------
    vector<std::string> faces
    {
        "tilesets/skybox/right.jpg",
        "tilesets/skybox/left.jpg",
        "tilesets/skybox/top.jpg",
        "tilesets/skybox/bottom.jpg",
        "tilesets/skybox/front.jpg",
        "tilesets/skybox/back.jpg"
    };
    unsigned int cubemapTexture = loadCubemap(faces);
    glEnable(GL_TEXTURE_CUBE_MAP);
    Shader::bind(&shader);
    unsigned int index=0;
    shader.setParameter("texture1", index);
    Shader::bind(&skyboxShader);
    skyboxShader.setParameter("skybox", index);
    int oldX = sf::Mouse::getPosition(window).x;
    int oldY = sf::Mouse::getPosition(window).y;
    sf::Clock time;
    // run the main loop
    bool running = true;
    while (running)
    {
         // per-frame time logic
        // --------------------

        // handle events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, event.size.width, event.size.height);
            }
            else if (event.type == sf::Event::MouseMoved && sf::Mouse::isButtonPressed(sf::Mouse::Right)) {
                int relX = (event.mouseMove.x - oldX) * sensivity;
                int relY = (event.mouseMove.y - oldY) * sensivity;
                int teta = view.getTeta() - relX;
                int phi = view.getPhi() - relY;
                view.rotate(teta, phi);
            }
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
            view.move(view.getForward(), -speed * time.getElapsedTime().asSeconds());
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
            view.move(view.getForward(), speed * time.getElapsedTime().asSeconds());
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
            view.move(view.getLeft(), speed * time.getElapsedTime().asSeconds());
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
            view.move(view.getLeft(), -speed * time.getElapsedTime().asSeconds());
        }
        // clear the buffers
        // render
        // ------
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // draw...
        TransformMatrix model;
        Matrix4f modelMatrix = model.getMatrix().transpose();
        Matrix4f viewMatrix = view.getViewMatrix().getMatrix().transpose();
        Matrix4f projectionMatrix = view.getProjMatrix().getMatrix().transpose();
        Shader::bind(&shader);
        shader.setParameter("model", modelMatrix);
        shader.setParameter("view", viewMatrix);
        shader.setParameter("projection", projectionMatrix);
        shader.setParameter("cameraPos", view.getPosition().x, view.getPosition().y, view.getPosition().z);
        // cubes
        glBindVertexArray(cubeVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        // draw skybox as last
        glDepthFunc(GL_LEQUAL);  // change depth function so depth test passes when values are equal to depth buffer's content
        Shader::bind(&skyboxShader);
        skyboxShader.setParameter("view", viewMatrix);
        skyboxShader.setParameter("projection", projectionMatrix);
        // skybox cube
        glBindVertexArray(skyboxVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        glDepthFunc(GL_LESS); // set depth function back to default
        // end the current frame (internally swaps the front and back buffers)
        window.display();
        oldX = sf::Mouse::getPosition(window).x;
        oldY = sf::Mouse::getPosition(window).y;
        time.restart();
    }

    // release resources...

    return 0;
}
unsigned int loadCubemap(vector<std::string> faces)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height;
    for (unsigned int i = 0; i < faces.size(); i++)
    {
        sf::Image image;
        image.loadFromFile(faces[i]);
        width = image.getSize().x;
        height = image.getSize().y;
        if (image.getPixelsPtr())
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image.getPixelsPtr());
        }
        else
        {
            std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}
 

There is really a problem wen displaying my skybox.

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Loading textures with sf::Image.
« Reply #3 on: October 26, 2020, 07:10:31 pm »
It seems the cubemap pixel colour is wrong because the backgound colour is the same everywhere I tried to replace GL_RBG by GL_RGBA but this time the background is gray everywhere.

Is the cubemap not loaded correctly with sf::Image.

It works for 2D textures but not for the cubemap.

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: Loading textures with sf::Image.
« Reply #4 on: October 26, 2020, 10:03:05 pm »
Hi!
I made some tests and the problem is in the shader class.
Everything draws well with the shader class of the tutorial.

So it doesn't work with this code.

#include "application.h"
#include <SFML/OpenGL.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <stddef.h>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
/*using namespace odfaeg::core;
using namespace odfaeg::math;
using namespace odfaeg::physic;
using namespace odfaeg::graphic;
using namespace odfaeg::window;
using namespace odfaeg::audio;
using namespace sorrok;*/

using namespace std;
class Shader
{
public:
    unsigned int ID;
    // constructor generates the shader on the fly
    // ------------------------------------------------------------------------
    Shader(std::string vertexCode, std::string fragmentCode)
    {
        // 1. retrieve the vertex/fragment source code from filePath
        const char* vShaderCode = vertexCode.c_str();
        const char * fShaderCode = fragmentCode.c_str();
        // 2. compile shaders
        unsigned int vertex, fragment;
        // vertex shader
        vertex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex, 1, &vShaderCode, NULL);
        glCompileShader(vertex);
        checkCompileErrors(vertex, "VERTEX");
        // fragment Shader
        fragment = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment, 1, &fShaderCode, NULL);
        glCompileShader(fragment);
        checkCompileErrors(fragment, "FRAGMENT");
        // shader Program
        ID = glCreateProgram();
        glAttachShader(ID, vertex);
        glAttachShader(ID, fragment);
        glLinkProgram(ID);
        checkCompileErrors(ID, "PROGRAM");
        // delete the shaders as they're linked into our program now and no longer necessery
        glDeleteShader(vertex);
        glDeleteShader(fragment);
    }
    // activate the shader
    // ------------------------------------------------------------------------
    void use()
    {
        glUseProgram(ID);
    }
    // utility uniform functions
    // ------------------------------------------------------------------------
    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)
    {
        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]);
    }

private:
    // utility function for checking shader compilation/linking errors.
    // ------------------------------------------------------------------------
    void checkCompileErrors(GLuint shader, std::string type)
    {
        GLint success;
        GLchar infoLog[1024];
        if(type != "PROGRAM")
        {
            glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
            if(!success)
            {
                glGetShaderInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
        else
        {
            glGetProgramiv(shader, GL_LINK_STATUS, &success);
            if(!success)
            {
                glGetProgramInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
    }
};
// 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));
    }
};
unsigned int loadCubemap(vector<std::string> faces);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = (float)SCR_WIDTH / 2.0;
float lastY = (float)SCR_HEIGHT / 2.0;
bool firstMouse = true;

// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;

int main(int argc, char* argv[])
{
    /*EXPORT_CLASS_GUID(BoundingVolumeBoundingBox, BoundingVolume, BoundingBox)
    EXPORT_CLASS_GUID(EntityTile, Entity, Tile)
    EXPORT_CLASS_GUID(EntityTile, Entity, BigTile)
    EXPORT_CLASS_GUID(EntityWall, Entity, g2d::Wall)
    EXPORT_CLASS_GUID(EntityDecor, Entity, g2d::Decor)
    EXPORT_CLASS_GUID(EntityAnimation, Entity, Anim)
    EXPORT_CLASS_GUID(EntityHero, Entity, Hero)
    EXPORT_CLASS_GUID(EntityMesh, Entity, Mesh)
    MyAppli app(sf::VideoMode(800, 600), "Test odfaeg");
    return app.exec();*/

// create the window
    sf::Window window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(32, 0, 4, 3, 3));
    glewInit();
    window.setVerticalSyncEnabled(true);

    // activate the window
    window.setActive(true);
    // load resources, initialize the OpenGL states, ...
    glEnable(GL_DEPTH_TEST);
    // build and compile shaders
    // -------------------------
    const std::string cubeMapsVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    layout (location = 1) in vec3 aNormal;
                                    out vec3 Normal;
                                    out vec3 Position;
                                    uniform mat4 model;
                                    uniform mat4 view;
                                    uniform mat4 projection;
                                    void main()
                                    {
                                        Normal = mat3(transpose(inverse(model))) * aNormal;
                                        Position = vec3(model * vec4(aPos, 1.0));
                                        gl_Position = projection * view * model * vec4(aPos, 1.0);
                                    }
                                )"
;
    const std::string cubeMapsFS = R"(#version 330 core
                                        out vec4 FragColor;
                                        in vec3 Normal;
                                        in vec3 Position;
                                        uniform vec3 cameraPos;
                                        uniform samplerCube skybox;
                                        void main()
                                        {
                                            vec3 I = normalize(Position - cameraPos);
                                            vec3 R = reflect(I, normalize(Normal));
                                            FragColor = vec4(texture(skybox, R).rgb, 1.0);
                                        }
                                   )"
;
    const std::string skyboxVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    out vec3 TexCoords;
                                    uniform mat4 projection;
                                    uniform mat4 view;
                                    void main()
                                    {
                                        TexCoords = aPos;
                                        vec4 pos = projection * view * vec4(aPos, 1.0);
                                        gl_Position = pos.xyww;
                                    }
                                )"
;
    const std::string skyboxFS = R"(#version 330 core
                                    out vec4 FragColor;
                                    in vec3 TexCoords;
                                    uniform samplerCube skybox;
                                    void main()
                                    {
                                        FragColor = texture(skybox, TexCoords);
                                    }
                                    )"
;
    odfaeg::graphic::Shader shader, skyboxShader;
    shader.loadFromMemory(cubeMapsVS, cubeMapsFS);
    skyboxShader.loadFromMemory(skyboxFS, skyboxVS);
    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    float cubeVertices[] = {
        // positions          // normals
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,

        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
    };
    float skyboxVertices[] = {
        // positions
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f,  1.0f
    };
    // cube VAO
    unsigned int cubeVAO, cubeVBO;
    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &cubeVBO);
    glBindVertexArray(cubeVAO);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    // skybox VAO
    unsigned int skyboxVAO, skyboxVBO;
    glGenVertexArrays(1, &skyboxVAO);
    glGenBuffers(1, &skyboxVBO);
    glBindVertexArray(skyboxVAO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    // load textures
    // -------------
    vector<std::string> faces
    {
        "tilesets/skybox/right.jpg",
        "tilesets/skybox/left.jpg",
        "tilesets/skybox/top.jpg",
        "tilesets/skybox/bottom.jpg",
        "tilesets/skybox/front.jpg",
        "tilesets/skybox/back.jpg"
    };
    unsigned int cubemapTexture = loadCubemap(faces);
    glEnable(GL_TEXTURE_CUBE_MAP);
   // shader configuration
    // --------------------
    odfaeg::graphic::Shader::bind(&shader);
    unsigned int index = 0;
    shader.setParameter("skybox", index);

    odfaeg::graphic::Shader::bind(&skyboxShader);
    skyboxShader.setParameter("skybox", index);
    int oldX = sf::Mouse::getPosition(window).x;
    int oldY = sf::Mouse::getPosition(window).y;
    sf::Clock time;
    // run the main loop
    bool running = true;
    while (running)
    {
         // per-frame time logic
        // --------------------
        // per-frame time logic
        // --------------------
        float currentFrame = time.getElapsedTime().asSeconds();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
        // handle events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, event.size.width, event.size.height);
            }
            else if (event.type == sf::Event::MouseMoved) {
                if (firstMouse)
                {
                    lastX = event.mouseMove.x;
                    lastY = event.mouseMove.y;
                    firstMouse = false;
                }

                float xoffset = event.mouseMove.x - lastX;
                float yoffset = lastY - event.mouseMove.y; // reversed since y-coordinates go from bottom to top

                lastX = event.mouseMove.x;
                lastY = event.mouseMove.y;

                camera.ProcessMouseMovement(xoffset, yoffset);
            } else if (event.type == sf::Event::MouseWheelScrolled) {
                camera.ProcessMouseScroll(event.mouseWheelScroll.delta);
            }
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
            camera.ProcessKeyboard(FORWARD, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
            camera.ProcessKeyboard(BACKWARD, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
            camera.ProcessKeyboard(RIGHT, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
            camera.ProcessKeyboard(LEFT, deltaTime);
        }
        // clear the buffers
        // render
        // ------
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // draw...
        odfaeg::graphic::Shader::bind(&shader);
        glm::mat4 model = glm::mat4(1.0f);
        glm::mat4 view = camera.GetViewMatrix();
        glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        odfaeg::math::Matrix4f modelMatrix(model[0][0],model[0][1],model[0][2],model[0][3],
                                  model[1][0],model[1][1],model[1][2],model[1][3],
                                  model[2][0],model[2][1],model[2][2],model[2][3],
                                  model[3][0],model[3][1],model[3][2],model[3][3]);
        odfaeg::math::Matrix4f viewMatrix(view[0][0],view[0][1],view[0][2],view[0][3],
                                  view[1][0],view[1][1],view[1][2],view[1][3],
                                  view[2][0],view[2][1],view[2][2],view[2][3],
                                  view[3][0],view[3][1],view[3][2],view[3][3]);
        odfaeg::math::Matrix4f projectionMatrix(projection[0][0],projection[0][1],projection[0][2],projection[0][3],
                                  projection[1][0],projection[1][1],projection[1][2],projection[1][3],
                                  projection[2][0],projection[2][1],projection[2][2],projection[2][3],
                                  projection[3][0],projection[3][1],projection[3][2],projection[3][3]);
        shader.setParameter("model", modelMatrix);
        shader.setParameter("view", viewMatrix);
        shader.setParameter("projection", projectionMatrix);
        shader.setParameter("cameraPos", camera.Position.x,camera.Position.y,camera.Position.z);
        // cubes
        glBindVertexArray(cubeVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        // draw skybox as last
        glDepthFunc(GL_LEQUAL);  // change depth function so depth test passes when values are equal to depth buffer's content
        odfaeg::graphic::Shader::bind(&skyboxShader);
        view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix
        viewMatrix = odfaeg::math::Matrix4f(view[0][0],view[0][1],view[0][2],view[0][3],
                                  view[1][0],view[1][1],view[1][2],view[1][3],
                                  view[2][0],view[2][1],view[2][2],view[2][3],
                                  view[3][0],view[3][1],view[3][2],view[3][3]);
        skyboxShader.setParameter("view", viewMatrix);
        skyboxShader.setParameter("projection", projectionMatrix);
        // skybox cube
        glBindVertexArray(skyboxVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        glDepthFunc(GL_LESS); // set depth function back to default
        // end the current frame (internally swaps the front and back buffers)
        window.display();
        oldX = sf::Mouse::getPosition(window).x;
        oldY = sf::Mouse::getPosition(window).y;
    }
    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    glDeleteVertexArrays(1, &cubeVAO);
    glDeleteVertexArrays(1, &skyboxVAO);
    glDeleteBuffers(1, &cubeVBO);
    glDeleteBuffers(1, &skyboxVAO);
    // release resources...

    return 0;
}
unsigned int loadCubemap(vector<std::string> faces)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height;
    for (unsigned int i = 0; i < faces.size(); i++)
    {
        sf::Image image;
        image.loadFromFile(faces[i]);
        width = image.getSize().x;
        height = image.getSize().y;
        if (image.getPixelsPtr())
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
        }
        else
        {
            std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}
 


I guess I've to change the shader class with doesn't work, it's a copy of the shader class of the SFML.

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "../../../include/odfaeg/Graphics/shader.h"
#include "../../../include/odfaeg/Graphics/texture.h"
#include "glCheck.h"
#include <SFML/System/InputStream.hpp>
#include <SFML/System/Err.hpp>
#include <fstream>
#include <vector>
#include <GL/glew.h>
#include <SFML/OpenGL.hpp>
using namespace sf;

namespace
{
    // Retrieve the maximum number of texture units available
    GLint getMaxTextureUnits()
    {
        GLint maxUnits;
        glCheck(glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxUnits));
        return maxUnits;
    }

    // Read the contents of a file into an array of char
    bool getFileContents(const std::string& filename, std::vector<char>& buffer)
    {
        std::ifstream file(filename.c_str(), std::ios_base::binary);
        if (file)
        {
            file.seekg(0, std::ios_base::end);
            std::streamsize size = file.tellg();
            if (size > 0)
            {
                file.seekg(0, std::ios_base::beg);
                buffer.resize(static_cast<std::size_t>(size));
                file.read(&buffer[0], size);
            }
            buffer.push_back('\0');
            return true;
        }
        else
        {
            return false;
        }
    }

    // Read the contents of a stream into an array of char
    bool getStreamContents(sf::InputStream& stream, std::vector<char>& buffer)
    {
        bool success = true;
        sf::Int64 size = stream.getSize();
        if (size > 0)
        {
            buffer.resize(static_cast<std::size_t>(size));
            stream.seek(0);
            sf::Int64 read = stream.read(&buffer[0], size);
            success = (read == size);
        }
        buffer.push_back('\0');
        return success;
    }
}


namespace odfaeg {
    namespace graphic {
        ////////////////////////////////////////////////////////////
        Shader::CurrentTextureType Shader::CurrentTexture;
        unsigned int Shader::shading_language_version_major = 0;
        unsigned int Shader::shading_language_version_minor = 0;
        ////////////////////////////////////////////////////////////
        Shader::Shader() :
        m_shaderProgram (0),
        m_currentTexture(-1),
        m_textures      (),
        m_params        (),
        m_vertexAttribs ()
        {
            shading_language_version_major = getVersionMajor();
            shading_language_version_minor = getVersionMinor();
        }


        ////////////////////////////////////////////////////////////
        Shader::~Shader()
        {
            //ensureGlContext();

            // Destroy effect program
            if (m_shaderProgram) {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
                    glCheck(glDeleteProgram(m_shaderProgram));
                else
                    glCheck(glDeleteObjectARB(m_shaderProgram));
            }
        }


        ////////////////////////////////////////////////////////////
        bool Shader::loadFromFile(const std::string& filename, Type type)
        {
            // Read the file
            std::vector<char> shader;
            if (!getFileContents(filename, shader))
            {
                err() << "Failed to open shader file \"" << filename << "\"" << std::endl;
                return false;
            }

            // Compile the shader program
            if (type == Vertex)
                return compile(&shader[0], NULL);
            else
                return compile(NULL, &shader[0]);
        }


        ////////////////////////////////////////////////////////////
        bool Shader::loadFromFile(const std::string& vertexShaderFilename, const std::string& fragmentShaderFilename)
        {
            // Read the vertex shader file
            std::vector<char> vertexShader;
            if (!getFileContents(vertexShaderFilename, vertexShader))
            {
                err() << "Failed to open vertex shader file \"" << vertexShaderFilename << "\"" << std::endl;
                return false;
            }

            // Read the fragment shader file
            std::vector<char> fragmentShader;
            if (!getFileContents(fragmentShaderFilename, fragmentShader))
            {
                err() << "Failed to open fragment shader file \"" << fragmentShaderFilename << "\"" << std::endl;
                return false;
            }

            // Compile the shader program
            return compile(&vertexShader[0], &fragmentShader[0]);
        }


        ////////////////////////////////////////////////////////////
        bool Shader::loadFromMemory(const std::string& shader, Type type)
        {
            // Compile the shader program
            if (type == Vertex)
                return compile(shader.c_str(), NULL);
            else
                return compile(NULL, shader.c_str());
        }


        ////////////////////////////////////////////////////////////
        bool Shader::loadFromMemory(const std::string& vertexShader, const std::string& fragmentShader)
        {
            // Compile the shader program
            return compile(vertexShader.c_str(), fragmentShader.c_str());
        }


        ////////////////////////////////////////////////////////////
        bool Shader::loadFromStream(InputStream& stream, Type type)
        {
            // Read the shader code from the stream
            std::vector<char> shader;
            if (!getStreamContents(stream, shader))
            {
                err() << "Failed to read shader from stream" << std::endl;
                return false;
            }

            // Compile the shader program
            if (type == Vertex)
                return compile(&shader[0], NULL);
            else
                return compile(NULL, &shader[0]);
        }


        ////////////////////////////////////////////////////////////
        bool Shader::loadFromStream(InputStream& vertexShaderStream, InputStream& fragmentShaderStream)
        {
            // Read the vertex shader code from the stream
            std::vector<char> vertexShader;
            if (!getStreamContents(vertexShaderStream, vertexShader))
            {
                err() << "Failed to read vertex shader from stream" << std::endl;
                return false;
            }

            // Read the fragment shader code from the stream
            std::vector<char> fragmentShader;
            if (!getStreamContents(fragmentShaderStream, fragmentShader))
            {
                err() << "Failed to read fragment shader from stream" << std::endl;
                return false;
            }

            // Compile the shader program
            return compile(&vertexShader[0], &fragmentShader[0]);
        }
        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, unsigned int x)
        {
            if (m_shaderProgram)
            {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(m_shaderProgram));
                    GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
                    if (location != -1) {
                        glCheck(glUniform1ui(location, x));
                    }
                } else {
                    // Enable program
                    GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
                    glCheck(glUseProgramObjectARB(m_shaderProgram));

                    // Get parameter location and assign it new values
                    GLint location = getParamLocation(name);
                    if (location != -1)
                        glCheck(glUniform1ui(location, x));

                    // Disable program
                    glCheck(glUseProgramObjectARB(program));
                }
            }
        }
        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, float x)
        {
            if (m_shaderProgram)
            {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(m_shaderProgram));
                    GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
                    if (location != -1) {
                        glCheck(glUniform1f(location, x));
                    }
                } else {
                    // Enable program
                    GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
                    glCheck(glUseProgramObjectARB(m_shaderProgram));

                    // Get parameter location and assign it new values
                    GLint location = getParamLocation(name);
                    if (location != -1)
                        glCheck(glUniform1fARB(location, x));

                    // Disable program
                    glCheck(glUseProgramObjectARB(program));
                }
            }
        }


        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, float x, float y)
        {
            if (m_shaderProgram)
            {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(m_shaderProgram));
                    GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
                    if (location != -1) {
                        glCheck(glUniform2f(location, x, y));
                    }
                } else {
                    // Enable program
                    GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
                    glCheck(glUseProgramObjectARB(m_shaderProgram));

                    // Get parameter location and assign it new values
                    GLint location = getParamLocation(name);
                    if (location != -1)
                        glCheck(glUniform2fARB(location, x, y));

                    // Disable program
                    glCheck(glUseProgramObjectARB(program));
                }
            }
        }


        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, float x, float y, float z)
        {
            if (m_shaderProgram)
            {
                 if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(m_shaderProgram));
                    GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
                    if (location != -1) {
                        glCheck(glUniform3f(location, x, y, z));
                    }
                } else {
                    // Enable program
                    GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
                    glCheck(glUseProgramObjectARB(m_shaderProgram));

                    // Get parameter location and assign it new values
                    GLint location = getParamLocation(name);
                    if (location != -1)
                        glCheck(glUniform3fARB(location, x, y, z));

                    // Disable program
                    glCheck(glUseProgramObjectARB(program));
                }
            }
        }


        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, float x, float y, float z, float w)
        {
            if (m_shaderProgram)
            {


                 if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(m_shaderProgram));
                    GLint location = glGetUniformLocation(m_shaderProgram, name.c_str());
                    if (location != -1) {
                        glCheck(glUniform4f(location, x, y, z, w));
                    }
                } else {
                    // Enable program
                    GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
                    glCheck(glUseProgramObjectARB(m_shaderProgram));

                    // Get parameter location and assign it new values
                    GLint location = getParamLocation(name);
                    if (location != -1)
                        glCheck(glUniform4fARB(location, x, y, z, w));

                    // Disable program
                    glCheck(glUseProgramObjectARB(program));
                }
            }
        }


        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, const Vector2f& v)
        {
            setParameter(name, v.x, v.y);
        }


        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, const Vector3f& v)
        {
            setParameter(name, v.x, v.y, v.z);
        }

        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, const Color& color)
        {
            setParameter(name, color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f);
        }


        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, math::Matrix4f matrix)
        {
            if (m_shaderProgram)
            {

                 if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(m_shaderProgram));
                    GLint location = getParamLocation(name);
                    if (location != -1) {
                        glCheck(glUniformMatrix4fv(location, 1, GL_FALSE,matrix.toGlMatrix().data()));
                    }
                    glCheck(glUseProgram(0));
                } else {
                    // Enable program
                    GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
                    glCheck(glUseProgramObjectARB(m_shaderProgram));

                    // Get parameter location and assign it new values
                    GLint location = getParamLocation(name);
                    if (location != -1) {
                        std::array<float, 16> glmatrix = matrix.toGlMatrix();
                        glCheck(glUniformMatrix4fvARB(location, 1, GL_FALSE, glmatrix.data()));
                    }
                    // Disable program
                    glCheck(glUseProgramObjectARB(program));
                }
            }
        }
        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, std::vector<TransformMatrix*> transforms)
        {
            if (m_shaderProgram)
            {

                 /*if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(m_shaderProgram));
                    GLint location = getParamLocation(name);
                    if (location != -1) {
                        glCheck(glUniformMatrix4fv(location, 1, GL_FALSE,matrix.toGlMatrix().data()));
                    }
                    glCheck(glUseProgram(0));
                } else {*/

                    // Enable program
                    GLhandleARB program = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
                    glCheck(glUseProgramObjectARB(m_shaderProgram));

                    // Get parameter location and assign it new values
                    GLint location = getParamLocation(name);
                    if (location != -1) {
                        std::vector<float> matrices;
                        for (unsigned int i = 0; i < transforms.size(); i++) {
                            std::array<float, 16> glmatrix = transforms[i]->getMatrix().transpose().toGlMatrix();
                            for (unsigned int j = 0; j < glmatrix.size(); j++) {
                                matrices.push_back(glmatrix[j]);
                            }
                        }
                        glCheck(glUniformMatrix4fvARB(location, static_cast<GLsizei>(transforms.size()), GL_FALSE, &matrices[0]));
                    }
                    // Disable program
                    glCheck(glUseProgramObjectARB(program));
                //}
            }
        }

        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, const Texture& texture)
        {
            if (m_shaderProgram)
            {


                // Find the location of the variable in the shader
                int location = getParamLocation(name);
                if (location != -1)
                {
                    // Store the location -> texture mapping
                    TextureTable::iterator it = m_textures.find(location);
                    if (it == m_textures.end())
                    {
                        // New entry, make sure there are enough texture units
                        static const GLint maxUnits = getMaxTextureUnits();
                        if (m_textures.size() + 1 >= static_cast<std::size_t>(maxUnits))
                        {
                            err() << "Impossible to use texture \"" << name << "\" for shader: all available texture units are used" << std::endl;
                            return;
                        }

                        m_textures[location] = &texture;
                    }
                    else
                    {
                        // Location already used, just replace the texture
                        it->second = &texture;
                    }
                }
            }
        }
        void Shader::setParameter(const std::string& name) {
            GLuint imageLoc = glGetUniformLocation(m_shaderProgram, name.c_str());
        }
        ////////////////////////////////////////////////////////////
        void Shader::bindAttribute(int location, const std::string& name) {
            if (m_shaderProgram) {

                GLint n;
                glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &n);
                if (location < n) {
                    if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                        glCheck(glBindAttribLocation(m_shaderProgram,location,name.c_str()));
                    } else {
                        glCheck(glBindAttribLocationARB(m_shaderProgram,location,name.c_str()));
                    }
                    m_currentAttrib = getVertexAttribLocation(name);
                } else {
                    err() << "Invalid attribute location " << location << " in vertex." << std::endl;
                }
            }
        }

        ////////////////////////////////////////////////////////////
        void Shader::setParameter(const std::string& name, CurrentTextureType)
        {
            if (m_shaderProgram)
            {


                // Find the location of the variable in the shader
                m_currentTexture = getParamLocation(name);
            }
        }


        ////////////////////////////////////////////////////////////
        void Shader::bind(const Shader* shader)
        {


            if (shader && shader->m_shaderProgram)
            {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(shader->m_shaderProgram));
                    shader->bindTextures();
                    // Bind the current texture
                    if (shader->m_currentTexture != -1)
                        glCheck(glUniform1i(shader->m_currentTexture, 0));

                } else {
                    // Enable the program
                    glCheck(glUseProgramObjectARB(shader->m_shaderProgram));

                    // Bind the textures
                    shader->bindTextures();

                    // Bind the current texture
                    if (shader->m_currentTexture != -1)
                        glCheck(glUniform1iARB(shader->m_currentTexture, 0));
                }
            }
            else
            {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUseProgram(0));
                } else {
                    // Bind no shader
                    glCheck(glUseProgramObjectARB(0));
                }
            }
        }


        ////////////////////////////////////////////////////////////
        bool Shader::isAvailable()
        {


            // Make sure that GLEW is initialized
            priv::ensureGlewInit();
            /*if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
                return true;*/

            return true;
        }


        ////////////////////////////////////////////////////////////
        bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCode)
        {


            // First make sure that we can use shaders
            if (!isAvailable())
            {
                err() << "Failed to create a shader: your system doesn't support shaders "
                      << "(you should test Shader::isAvailable() before trying to use the Shader class)" << std::endl;
                return false;
            }

            // Destroy the shader if it was already created
            if (m_shaderProgram) {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
                    glCheck(glDeleteProgram(m_shaderProgram));
                else
                    glCheck(glDeleteObjectARB(m_shaderProgram));
            }

            // Reset the internal state
            m_currentTexture = -1;
            m_textures.clear();
            m_params.clear();

            // Create the program
            if (shading_language_version_major >= 3 && shading_language_version_minor >= 3)
                m_shaderProgram = glCreateProgram();
            else
                m_shaderProgram = glCreateProgramObjectARB();
            // Create the vertex shader if needed
            if (vertexShaderCode)
            {
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
                    glCheck(glShaderSource(vertexShaderID, 1, &vertexShaderCode, nullptr));
                    glCheck(glCompileShader(vertexShaderID));
                    GLint success;
                    glCheck(glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS,&success));
                    if (success == GL_FALSE) {
                        int infoLogLength;
                        glCheck(glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength));
                        char log[infoLogLength];
                        glCheck(glGetShaderInfoLog(vertexShaderID, infoLogLength, 0, &log[0]));
                        std::cerr << "Failed to compile vertex shader:" << std::endl
                        << log << std::endl;
                        glCheck(glDeleteShader(vertexShaderID));
                        glCheck(glDeleteProgram(m_shaderProgram));
                        m_shaderProgram = 0;
                        return false;
                    }
                    glCheck(glAttachShader(m_shaderProgram, vertexShaderID));
                    glCheck(glDeleteShader(vertexShaderID));

                } else {
                    // Create and compile the shader
                    GLhandleARB vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
                    glCheck(glShaderSourceARB(vertexShader, 1, &vertexShaderCode, NULL));
                    glCheck(glCompileShaderARB(vertexShader));

                    // Check the compile log
                    GLint success;
                    glCheck(glGetObjectParameterivARB(vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &success));
                    if (success == GL_FALSE)
                    {
                        char log[1024];
                        glCheck(glGetInfoLogARB(vertexShader, sizeof(log), 0, log));
                        std::cerr << "Failed to compile vertex shader:" << std::endl
                              << log << std::endl;
                        glCheck(glDeleteObjectARB(vertexShader));
                        glCheck(glDeleteObjectARB(m_shaderProgram));
                        m_shaderProgram = 0;
                        return false;
                    }
                    glCheck(glAttachObjectARB(m_shaderProgram, vertexShader));
                    glCheck(glDeleteObjectARB(vertexShader));
                }
            }

            // Create the fragment shader if needed
            if (fragmentShaderCode)
            {
                // Create and compile the shader
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
                    glCheck(glShaderSource(fragmentShaderID, 1, &fragmentShaderCode, nullptr));
                    glCheck(glCompileShader(fragmentShaderID));
                    GLint success;
                    glCheck(glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS,&success));
                    if (success == GL_FALSE) {
                        int infoLogLength;
                        glCheck(glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength));
                        char log[infoLogLength];
                        glCheck(glGetShaderInfoLog(fragmentShaderID, infoLogLength, 0, &log[0]));
                        std::cerr << "Failed to compile fragment shader:" << std::endl
                        << log << std::endl;
                        glCheck(glDeleteShader(fragmentShaderID));
                        glCheck(glDeleteProgram(m_shaderProgram));
                        m_shaderProgram = 0;
                        return false;
                    }
                    glCheck(glAttachShader(m_shaderProgram, fragmentShaderID));
                    glCheck(glDeleteShader(fragmentShaderID));
                } else {
                    GLhandleARB fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
                    glCheck(glShaderSourceARB(fragmentShader, 1, &fragmentShaderCode, NULL));
                    glCheck(glCompileShaderARB(fragmentShader));

                    // Check the compile log
                    GLint success;
                    glCheck(glGetObjectParameterivARB(fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &success));
                    if (success == GL_FALSE)
                    {
                        char log[1024];
                        glCheck(glGetInfoLogARB(fragmentShader, sizeof(log), 0, log));
                        std::cerr << "Failed to compile fragment shader:" << std::endl
                              << log << std::endl;
                        glCheck(glDeleteObjectARB(fragmentShader));
                        glCheck(glDeleteObjectARB(m_shaderProgram));
                        m_shaderProgram = 0;
                        return false;
                    }
                    glCheck(glAttachObjectARB(m_shaderProgram, fragmentShader));
                    glCheck(glDeleteObjectARB(fragmentShader));
                }
            }
            if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                glCheck(glLinkProgram(m_shaderProgram));
                GLint success;
                glCheck(glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &success));
                if (success == GL_FALSE) {
                    int infoLogLength;
                    glCheck(glGetProgramiv(m_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength));
                    std::vector<char> programErrorMessage(std::max(infoLogLength, int(1)) );
                    glCheck(glGetProgramInfoLog(m_shaderProgram, infoLogLength, nullptr, &programErrorMessage[0]));
                    std::cerr << "Failed to link shader:" << std::endl
                         /* << log << std::endl*/;
                    glCheck(glDeleteProgram(m_shaderProgram));
                    m_shaderProgram = 0;
                    return false;
                }

            } else {
                // Link the program
                glCheck(glLinkProgramARB(m_shaderProgram));

                // Check the link log
                GLint success;
                glCheck(glGetObjectParameterivARB(m_shaderProgram, GL_OBJECT_LINK_STATUS_ARB, &success));
                if (success == GL_FALSE)
                {
                    char log[1024];
                    glCheck(glGetInfoLogARB(m_shaderProgram, sizeof(log), 0, log));
                    err() << "Failed to link shader:" << std::endl
                          << log << std::endl;
                    glCheck(glDeleteObjectARB(m_shaderProgram));
                    m_shaderProgram = 0;
                    return false;
                }
            }
            // Force an OpenGL flush, so that the shader will appear updated
            // in all contexts immediately (solves problems in multi-threaded apps)
            glCheck(glFlush());

            return true;
        }


        ////////////////////////////////////////////////////////////
        void Shader::bindTextures() const
        {
            TextureTable::const_iterator it = m_textures.begin();
            for (std::size_t i = 0; i < m_textures.size(); ++i)
            {
                GLint index = static_cast<GLsizei>(i + 1);
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    glCheck(glUniform1i(it->first, index));
                    glCheck(glActiveTexture(GL_TEXTURE0 + index));
                } else {
                    glCheck(glUniform1iARB(it->first, index));
                    glCheck(glActiveTextureARB(GL_TEXTURE0_ARB + index));
                }
                Texture::bind(it->second);
                ++it;
            }
            if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                glCheck(glActiveTexture(GL_TEXTURE0));
            } else {
                // Make sure that the texture unit which is left active is the number 0
                glCheck(glActiveTextureARB(GL_TEXTURE0_ARB));
            }
        }
        int Shader::getVertexAttribLocation(const std::string& name) {
            VertexAttribTable::const_iterator it = m_vertexAttribs.find(name);
            if (it != m_vertexAttribs.end()) {
                return it->second;
            } else {
                int location;
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    location = glGetAttribLocation(m_shaderProgram,name.c_str());
                } else {
                    location = glGetAttribLocationARB(m_shaderProgram,name.c_str());
                }
                if (location != -1)
                {
                    // Location found: add it to the cache
                    m_vertexAttribs.insert(std::make_pair(name, location));
                }
                else
                {
                    // Error: location not found
                    err() << "Vertex attrib " << name << "  not found in shader" << std::endl;
                }

                return location;
            }
        }

        ////////////////////////////////////////////////////////////
        int Shader::getParamLocation(const std::string& name)
        {
            // Check the cache
            ParamTable::const_iterator it = m_params.find(name);
            if (it != m_params.end())
            {
                // Already in cache, return it
                return it->second;
            }
            else
            {
                // Not in cache, request the location from OpenGL
                int location;
                if (shading_language_version_major >= 3 && shading_language_version_minor >= 3) {
                    location = glGetUniformLocation(m_shaderProgram, name.c_str());
                } else {
                    location = glGetUniformLocationARB(m_shaderProgram, name.c_str());
                }
                if (location != -1)
                {
                    // Location found: add it to the cache
                    m_params.insert(std::make_pair(name, location));
                }
                else
                {
                    // Error: location not found
                    err() << "Parameter " << name << " not found in shader" << std::endl;
                }

                return location;
            }
        }
        unsigned int Shader::getHandle() {
            return m_shaderProgram;
        }
        unsigned int Shader::getVersionMajor() {
            //ensureGlContext();
            const GLubyte* glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
            if (glslversion)
                return glslversion[0] - '0';
            return 2;
        }
        unsigned int Shader::getVersionMinor() {
            //ensureGlContext();
            const GLubyte* glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
            if (glslversion)
                return glslversion[1] - '0';
            return 0;
        }
    }
} // namespace sf

 

How to link an external texture to an SFML shader ?
« Last Edit: October 26, 2020, 10:14:28 pm by nagimar »

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: How to link an external texture to a shader ?
« Reply #5 on: October 26, 2020, 10:32:53 pm »
I tried this :
#include "application.h"
#include <SFML/OpenGL.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <stddef.h>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
/*using namespace odfaeg::core;
using namespace odfaeg::math;
using namespace odfaeg::physic;
using namespace odfaeg::graphic;
using namespace odfaeg::window;
using namespace odfaeg::audio;
using namespace sorrok;*/

using namespace std;
class Shader
{
public:
    unsigned int ID;
    // constructor generates the shader on the fly
    // ------------------------------------------------------------------------
    Shader(std::string vertexCode, std::string fragmentCode)
    {
        // 1. retrieve the vertex/fragment source code from filePath
        const char* vShaderCode = vertexCode.c_str();
        const char * fShaderCode = fragmentCode.c_str();
        // 2. compile shaders
        unsigned int vertex, fragment;
        // vertex shader
        vertex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex, 1, &vShaderCode, NULL);
        glCompileShader(vertex);
        checkCompileErrors(vertex, "VERTEX");
        // fragment Shader
        fragment = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment, 1, &fShaderCode, NULL);
        glCompileShader(fragment);
        checkCompileErrors(fragment, "FRAGMENT");
        // shader Program
        ID = glCreateProgram();
        glAttachShader(ID, vertex);
        glAttachShader(ID, fragment);
        glLinkProgram(ID);
        checkCompileErrors(ID, "PROGRAM");
        // delete the shaders as they're linked into our program now and no longer necessery
        glDeleteShader(vertex);
        glDeleteShader(fragment);
    }
    // activate the shader
    // ------------------------------------------------------------------------
    void use()
    {
        glUseProgram(ID);
    }
    // utility uniform functions
    // ------------------------------------------------------------------------
    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)
    {
        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]);
    }

private:
    // utility function for checking shader compilation/linking errors.
    // ------------------------------------------------------------------------
    void checkCompileErrors(GLuint shader, std::string type)
    {
        GLint success;
        GLchar infoLog[1024];
        if(type != "PROGRAM")
        {
            glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
            if(!success)
            {
                glGetShaderInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
        else
        {
            glGetProgramiv(shader, GL_LINK_STATUS, &success);
            if(!success)
            {
                glGetProgramInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
    }
};
// 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));
    }
};
unsigned int loadCubemap(vector<std::string> faces);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = (float)SCR_WIDTH / 2.0;
float lastY = (float)SCR_HEIGHT / 2.0;
bool firstMouse = true;

// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;

int main(int argc, char* argv[])
{
    /*EXPORT_CLASS_GUID(BoundingVolumeBoundingBox, BoundingVolume, BoundingBox)
    EXPORT_CLASS_GUID(EntityTile, Entity, Tile)
    EXPORT_CLASS_GUID(EntityTile, Entity, BigTile)
    EXPORT_CLASS_GUID(EntityWall, Entity, g2d::Wall)
    EXPORT_CLASS_GUID(EntityDecor, Entity, g2d::Decor)
    EXPORT_CLASS_GUID(EntityAnimation, Entity, Anim)
    EXPORT_CLASS_GUID(EntityHero, Entity, Hero)
    EXPORT_CLASS_GUID(EntityMesh, Entity, Mesh)
    MyAppli app(sf::VideoMode(800, 600), "Test odfaeg");
    return app.exec();*/

// create the window
    sf::Window window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(32, 0, 4, 3, 3));
    glewInit();
    window.setVerticalSyncEnabled(true);

    // activate the window
    window.setActive(true);
    // load resources, initialize the OpenGL states, ...
    glEnable(GL_DEPTH_TEST);
    // build and compile shaders
    // -------------------------
    const std::string cubeMapsVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    layout (location = 1) in vec3 aNormal;
                                    out vec3 Normal;
                                    out vec3 Position;
                                    uniform mat4 model;
                                    uniform mat4 view;
                                    uniform mat4 projection;
                                    void main()
                                    {
                                        Normal = mat3(transpose(inverse(model))) * aNormal;
                                        Position = vec3(model * vec4(aPos, 1.0));
                                        gl_Position = projection * view * model * vec4(aPos, 1.0);
                                    }
                                )"
;
    const std::string cubeMapsFS = R"(#version 330 core
                                        out vec4 FragColor;
                                        in vec3 Normal;
                                        in vec3 Position;
                                        uniform vec3 cameraPos;
                                        uniform samplerCube skybox;
                                        void main()
                                        {
                                            vec3 I = normalize(Position - cameraPos);
                                            vec3 R = reflect(I, normalize(Normal));
                                            FragColor = vec4(texture(skybox, R).rgb, 1.0);
                                        }
                                   )"
;
    const std::string skyboxVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    out vec3 TexCoords;
                                    uniform mat4 projection;
                                    uniform mat4 view;
                                    void main()
                                    {
                                        TexCoords = aPos;
                                        vec4 pos = projection * view * vec4(aPos, 1.0);
                                        gl_Position = pos.xyww;
                                    }
                                )"
;
    const std::string skyboxFS = R"(#version 330 core
                                    out vec4 FragColor;
                                    in vec3 TexCoords;
                                    uniform samplerCube skybox;
                                    void main()
                                    {
                                        FragColor = texture(skybox, TexCoords);
                                    }
                                    )"
;
    odfaeg::graphic::Shader shader, skyboxShader;
    shader.loadFromMemory(cubeMapsVS, cubeMapsFS);
    skyboxShader.loadFromMemory(skyboxVS, skyboxFS);
    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    float cubeVertices[] = {
        // positions          // normals
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,

        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
    };
    float skyboxVertices[] = {
        // positions
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f,  1.0f
    };
    // cube VAO
    unsigned int cubeVAO, cubeVBO;
    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &cubeVBO);
    glBindVertexArray(cubeVAO);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    // skybox VAO
    unsigned int skyboxVAO, skyboxVBO;
    glGenVertexArrays(1, &skyboxVAO);
    glGenBuffers(1, &skyboxVBO);
    glBindVertexArray(skyboxVAO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    // load textures
    // -------------
    vector<std::string> faces
    {
        "tilesets/skybox/right.jpg",
        "tilesets/skybox/left.jpg",
        "tilesets/skybox/top.jpg",
        "tilesets/skybox/bottom.jpg",
        "tilesets/skybox/front.jpg",
        "tilesets/skybox/back.jpg"
    };
    unsigned int cubemapTexture = loadCubemap(faces);

   // shader configuration
    // --------------------
    odfaeg::graphic::Shader::bind(&shader);
    glUniform1f(glGetUniformLocation(shader.getHandle(), "skybox"), 0);

    odfaeg::graphic::Shader::bind(&skyboxShader);
    glUniform1f(glGetUniformLocation(skyboxShader.getHandle(), "skybox"), 0);
    int oldX = sf::Mouse::getPosition(window).x;
    int oldY = sf::Mouse::getPosition(window).y;
    sf::Clock time;
    // run the main loop
    bool running = true;
    glEnable(GL_TEXTURE_CUBE_MAP);
    while (running)
    {
         // per-frame time logic
        // --------------------
        // per-frame time logic
        // --------------------
        float currentFrame = time.getElapsedTime().asSeconds();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
        // handle events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, event.size.width, event.size.height);
            }
            else if (event.type == sf::Event::MouseMoved) {
                if (firstMouse)
                {
                    lastX = event.mouseMove.x;
                    lastY = event.mouseMove.y;
                    firstMouse = false;
                }

                float xoffset = event.mouseMove.x - lastX;
                float yoffset = lastY - event.mouseMove.y; // reversed since y-coordinates go from bottom to top

                lastX = event.mouseMove.x;
                lastY = event.mouseMove.y;

                camera.ProcessMouseMovement(xoffset, yoffset);
            } else if (event.type == sf::Event::MouseWheelScrolled) {
                camera.ProcessMouseScroll(event.mouseWheelScroll.delta);
            }
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
            camera.ProcessKeyboard(FORWARD, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
            camera.ProcessKeyboard(BACKWARD, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
            camera.ProcessKeyboard(RIGHT, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
            camera.ProcessKeyboard(LEFT, deltaTime);
        }
        // clear the buffers
        // render
        // ------
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // draw...
        odfaeg::graphic::Shader::bind(&shader);
        glm::mat4 model = glm::mat4(1.0f);
        glm::mat4 view = camera.GetViewMatrix();
        glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        odfaeg::math::Matrix4f modelMatrix(model[0][0],model[0][1],model[0][2],model[0][3],
                                  model[1][0],model[1][1],model[1][2],model[1][3],
                                  model[2][0],model[2][1],model[2][2],model[2][3],
                                  model[3][0],model[3][1],model[3][2],model[3][3]);
        odfaeg::math::Matrix4f viewMatrix(view[0][0],view[0][1],view[0][2],view[0][3],
                                  view[1][0],view[1][1],view[1][2],view[1][3],
                                  view[2][0],view[2][1],view[2][2],view[2][3],
                                  view[3][0],view[3][1],view[3][2],view[3][3]);
        odfaeg::math::Matrix4f projectionMatrix(projection[0][0],projection[0][1],projection[0][2],projection[0][3],
                                  projection[1][0],projection[1][1],projection[1][2],projection[1][3],
                                  projection[2][0],projection[2][1],projection[2][2],projection[2][3],
                                  projection[3][0],projection[3][1],projection[3][2],projection[3][3]);
        shader.setParameter("model", modelMatrix);
        shader.setParameter("view", viewMatrix);
        shader.setParameter("projection", projectionMatrix);
        shader.setParameter("cameraPos", camera.Position.x,camera.Position.y,camera.Position.z);
        // cubes
        glBindVertexArray(cubeVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        // draw skybox as last
        glDepthFunc(GL_LEQUAL);  // change depth function so depth test passes when values are equal to depth buffer's content
        odfaeg::graphic::Shader::bind(&skyboxShader);
        view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix
        viewMatrix = odfaeg::math::Matrix4f(view[0][0],view[0][1],view[0][2],view[0][3],
                                  view[1][0],view[1][1],view[1][2],view[1][3],
                                  view[2][0],view[2][1],view[2][2],view[2][3],
                                  view[3][0],view[3][1],view[3][2],view[3][3]);
        skyboxShader.setParameter("view", viewMatrix);
        skyboxShader.setParameter("projection", projectionMatrix);
        // skybox cube
        glBindVertexArray(skyboxVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        glDepthFunc(GL_LESS); // set depth function back to default
        // end the current frame (internally swaps the front and back buffers)
        window.display();
        oldX = sf::Mouse::getPosition(window).x;
        oldY = sf::Mouse::getPosition(window).y;
    }
    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    glDeleteVertexArrays(1, &cubeVAO);
    glDeleteVertexArrays(1, &skyboxVAO);
    glDeleteBuffers(1, &cubeVBO);
    glDeleteBuffers(1, &skyboxVAO);
    // release resources...

    return 0;
}
unsigned int loadCubemap(vector<std::string> faces)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height;
    for (unsigned int i = 0; i < faces.size(); i++)
    {
        sf::Image image;
        image.loadFromFile(faces[i]);
        width = image.getSize().x;
        height = image.getSize().y;
        if (image.getPixelsPtr())
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
        }
        else
        {
            std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}

 

But that doesn't work it seems the problem is in the sf::Shader class which doesn't bind my cubemap texture correctly.

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: How to link an external texture to a shader ?
« Reply #6 on: October 26, 2020, 10:56:13 pm »
Ok the problem is  my Shader SFML like class which doesn't bind the cubemap texture properly I tried to use an SFML like texture class but that doesn't work.

#include "application.h"
#include <SFML/OpenGL.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <stddef.h>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
/*using namespace odfaeg::core;
using namespace odfaeg::math;
using namespace odfaeg::physic;
using namespace odfaeg::graphic;
using namespace odfaeg::window;
using namespace odfaeg::audio;
using namespace sorrok;*/

using namespace std;
class Shader
{
public:
    unsigned int ID;
    // constructor generates the shader on the fly
    // ------------------------------------------------------------------------
    Shader(std::string vertexCode, std::string fragmentCode)
    {
        // 1. retrieve the vertex/fragment source code from filePath
        const char* vShaderCode = vertexCode.c_str();
        const char * fShaderCode = fragmentCode.c_str();
        // 2. compile shaders
        unsigned int vertex, fragment;
        // vertex shader
        vertex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex, 1, &vShaderCode, NULL);
        glCompileShader(vertex);
        checkCompileErrors(vertex, "VERTEX");
        // fragment Shader
        fragment = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment, 1, &fShaderCode, NULL);
        glCompileShader(fragment);
        checkCompileErrors(fragment, "FRAGMENT");
        // shader Program
        ID = glCreateProgram();
        glAttachShader(ID, vertex);
        glAttachShader(ID, fragment);
        glLinkProgram(ID);
        checkCompileErrors(ID, "PROGRAM");
        // delete the shaders as they're linked into our program now and no longer necessery
        glDeleteShader(vertex);
        glDeleteShader(fragment);
    }
    // activate the shader
    // ------------------------------------------------------------------------
    void use()
    {
        glUseProgram(ID);
    }
    // utility uniform functions
    // ------------------------------------------------------------------------
    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)
    {
        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]);
    }

private:
    // utility function for checking shader compilation/linking errors.
    // ------------------------------------------------------------------------
    void checkCompileErrors(GLuint shader, std::string type)
    {
        GLint success;
        GLchar infoLog[1024];
        if(type != "PROGRAM")
        {
            glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
            if(!success)
            {
                glGetShaderInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
        else
        {
            glGetProgramiv(shader, GL_LINK_STATUS, &success);
            if(!success)
            {
                glGetProgramInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
    }
};
// 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));
    }
};
unsigned int loadCubemap(vector<std::string> faces);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = (float)SCR_WIDTH / 2.0;
float lastY = (float)SCR_HEIGHT / 2.0;
bool firstMouse = true;

// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;

int main(int argc, char* argv[])
{
    /*EXPORT_CLASS_GUID(BoundingVolumeBoundingBox, BoundingVolume, BoundingBox)
    EXPORT_CLASS_GUID(EntityTile, Entity, Tile)
    EXPORT_CLASS_GUID(EntityTile, Entity, BigTile)
    EXPORT_CLASS_GUID(EntityWall, Entity, g2d::Wall)
    EXPORT_CLASS_GUID(EntityDecor, Entity, g2d::Decor)
    EXPORT_CLASS_GUID(EntityAnimation, Entity, Anim)
    EXPORT_CLASS_GUID(EntityHero, Entity, Hero)
    EXPORT_CLASS_GUID(EntityMesh, Entity, Mesh)
    MyAppli app(sf::VideoMode(800, 600), "Test odfaeg");
    return app.exec();*/

// create the window
    sf::Window window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(32, 0, 4, 3, 3));
    glewInit();
    window.setVerticalSyncEnabled(true);

    // activate the window
    window.setActive(true);
    // load resources, initialize the OpenGL states, ...
    glEnable(GL_DEPTH_TEST);
    // build and compile shaders
    // -------------------------
    const std::string cubeMapsVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    layout (location = 1) in vec3 aNormal;
                                    out vec3 Normal;
                                    out vec3 Position;
                                    uniform mat4 model;
                                    uniform mat4 view;
                                    uniform mat4 projection;
                                    void main()
                                    {
                                        Normal = mat3(transpose(inverse(model))) * aNormal;
                                        Position = vec3(model * vec4(aPos, 1.0));
                                        gl_Position = projection * view * model * vec4(aPos, 1.0);
                                    }
                                )"
;
    const std::string cubeMapsFS = R"(#version 330 core
                                        out vec4 FragColor;
                                        in vec3 Normal;
                                        in vec3 Position;
                                        uniform vec3 cameraPos;
                                        uniform samplerCube skybox;
                                        void main()
                                        {
                                            vec3 I = normalize(Position - cameraPos);
                                            vec3 R = reflect(I, normalize(Normal));
                                            FragColor = vec4(texture(skybox, R).rgb, 1.0);
                                        }
                                   )"
;
    const std::string skyboxVS = R"(#version 330 core
                                    layout (location = 0) in vec3 aPos;
                                    out vec3 TexCoords;
                                    uniform mat4 projection;
                                    uniform mat4 view;
                                    void main()
                                    {
                                        TexCoords = aPos;
                                        vec4 pos = projection * view * vec4(aPos, 1.0);
                                        gl_Position = pos.xyww;
                                    }
                                )"
;
    const std::string skyboxFS = R"(#version 330 core
                                    out vec4 FragColor;
                                    in vec3 TexCoords;
                                    uniform samplerCube skybox;
                                    void main()
                                    {
                                        FragColor = texture(skybox, TexCoords);
                                    }
                                    )"
;
    odfaeg::graphic::Shader shader, skyboxShader;
    shader.loadFromMemory(cubeMapsVS, cubeMapsFS);
    skyboxShader.loadFromMemory(skyboxVS, skyboxFS);
    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    float cubeVertices[] = {
        // positions          // normals
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,

        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
         0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
         0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
    };
    float skyboxVertices[] = {
        // positions
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
         1.0f,  1.0f, -1.0f,
         1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
         1.0f, -1.0f,  1.0f
    };
    // cube VAO
    unsigned int cubeVAO, cubeVBO;
    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &cubeVBO);
    glBindVertexArray(cubeVAO);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    // skybox VAO
    unsigned int skyboxVAO, skyboxVBO;
    glGenVertexArrays(1, &skyboxVAO);
    glGenBuffers(1, &skyboxVBO);
    glBindVertexArray(skyboxVAO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    // load textures
    // -------------
    vector<std::string> faces
    {
        "tilesets/skybox/right.jpg",
        "tilesets/skybox/left.jpg",
        "tilesets/skybox/top.jpg",
        "tilesets/skybox/bottom.jpg",
        "tilesets/skybox/front.jpg",
        "tilesets/skybox/back.jpg"
    };
    std::vector<sf::Image> images;
    for (unsigned int i = 0; i < 6; i++) {
        sf::Image image;
        image.loadFromFile(faces[i]);
        images.push_back(image);
    }
    int width = images[0].getSize().x;
    int height = images[0].getSize().y;
    odfaeg::graphic::Texture cubeMapTex;
    cubeMapTex.createCubeMap(width, height, images);
   // shader configuration
    // --------------------
    shader.setParameter("skybox", cubeMapTex);
    skyboxShader.setParameter("skybox", cubeMapTex);
    int oldX = sf::Mouse::getPosition(window).x;
    int oldY = sf::Mouse::getPosition(window).y;
    sf::Clock time;
    // run the main loop
    bool running = true;
    glEnable(GL_TEXTURE_CUBE_MAP);
    while (running)
    {
         // per-frame time logic
        // --------------------
        // per-frame time logic
        // --------------------
        float currentFrame = time.getElapsedTime().asSeconds();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
        // handle events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, event.size.width, event.size.height);
            }
            else if (event.type == sf::Event::MouseMoved) {
                if (firstMouse)
                {
                    lastX = event.mouseMove.x;
                    lastY = event.mouseMove.y;
                    firstMouse = false;
                }

                float xoffset = event.mouseMove.x - lastX;
                float yoffset = lastY - event.mouseMove.y; // reversed since y-coordinates go from bottom to top

                lastX = event.mouseMove.x;
                lastY = event.mouseMove.y;

                camera.ProcessMouseMovement(xoffset, yoffset);
            } else if (event.type == sf::Event::MouseWheelScrolled) {
                camera.ProcessMouseScroll(event.mouseWheelScroll.delta);
            }
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
            camera.ProcessKeyboard(FORWARD, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
            camera.ProcessKeyboard(BACKWARD, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
            camera.ProcessKeyboard(RIGHT, deltaTime);
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
            camera.ProcessKeyboard(LEFT, deltaTime);
        }
        // clear the buffers
        // render
        // ------
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // draw...
        odfaeg::graphic::Shader::bind(&shader);
        glm::mat4 model = glm::mat4(1.0f);
        glm::mat4 view = camera.GetViewMatrix();
        glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        odfaeg::math::Matrix4f modelMatrix(model[0][0],model[0][1],model[0][2],model[0][3],
                                  model[1][0],model[1][1],model[1][2],model[1][3],
                                  model[2][0],model[2][1],model[2][2],model[2][3],
                                  model[3][0],model[3][1],model[3][2],model[3][3]);
        odfaeg::math::Matrix4f viewMatrix(view[0][0],view[0][1],view[0][2],view[0][3],
                                  view[1][0],view[1][1],view[1][2],view[1][3],
                                  view[2][0],view[2][1],view[2][2],view[2][3],
                                  view[3][0],view[3][1],view[3][2],view[3][3]);
        odfaeg::math::Matrix4f projectionMatrix(projection[0][0],projection[0][1],projection[0][2],projection[0][3],
                                  projection[1][0],projection[1][1],projection[1][2],projection[1][3],
                                  projection[2][0],projection[2][1],projection[2][2],projection[2][3],
                                  projection[3][0],projection[3][1],projection[3][2],projection[3][3]);
        shader.setParameter("model", modelMatrix);
        shader.setParameter("view", viewMatrix);
        shader.setParameter("projection", projectionMatrix);
        shader.setParameter("cameraPos", camera.Position.x,camera.Position.y,camera.Position.z);
        // cubes
        glBindVertexArray(cubeVAO);
        glActiveTexture(GL_TEXTURE0);
        odfaeg::graphic::Texture::bind(&cubeMapTex, odfaeg::graphic::Texture::Normalized);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        // draw skybox as last
        glDepthFunc(GL_LEQUAL);  // change depth function so depth test passes when values are equal to depth buffer's content
        odfaeg::graphic::Shader::bind(&skyboxShader);
        view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix
        viewMatrix = odfaeg::math::Matrix4f(view[0][0],view[0][1],view[0][2],view[0][3],
                                  view[1][0],view[1][1],view[1][2],view[1][3],
                                  view[2][0],view[2][1],view[2][2],view[2][3],
                                  view[3][0],view[3][1],view[3][2],view[3][3]);
        skyboxShader.setParameter("view", viewMatrix);
        skyboxShader.setParameter("projection", projectionMatrix);
        // skybox cube
        glBindVertexArray(skyboxVAO);
        glActiveTexture(GL_TEXTURE0);
        odfaeg::graphic::Texture::bind(&cubeMapTex, odfaeg::graphic::Texture::Normalized);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        glDepthFunc(GL_LESS); // set depth function back to default
        // end the current frame (internally swaps the front and back buffers)
        window.display();
        oldX = sf::Mouse::getPosition(window).x;
        oldY = sf::Mouse::getPosition(window).y;
    }
    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    glDeleteVertexArrays(1, &cubeVAO);
    glDeleteVertexArrays(1, &skyboxVAO);
    glDeleteBuffers(1, &cubeVBO);
    glDeleteBuffers(1, &skyboxVAO);
    // release resources...

    return 0;
}
unsigned int loadCubemap(vector<std::string> faces)
{
    unsigned int textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height;
    for (unsigned int i = 0; i < faces.size(); i++)
    {
        sf::Image image;
        image.loadFromFile(faces[i]);
        width = image.getSize().x;
        height = image.getSize().y;
        if (image.getPixelsPtr())
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
        }
        else
        {
            std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}
 

Can you tell me how to modify my shader class to draw my cubemap texture properly ?

nagimar

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: How to link an external texture to a shader ?
« Reply #7 on: October 26, 2020, 11:39:50 pm »
Ok I've found the problem, I put in comment this lines :
 Shader::Shader() :
        m_shaderProgram (0),
        m_currentTexture(-1),
        m_textures      (),
        m_params        (),
        m_vertexAttribs ()
        {
            /*shading_language_version_major = getVersionMajor();
            shading_language_version_minor = getVersionMinor();*/

        }
 

And now, it's working.
I don't understand how the glGet function can affect the drawing.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: How to link an external texture to a shader ?
« Reply #8 on: October 27, 2020, 08:23:34 am »
You should really investigate and debug your code before posting here ;)

Now your topic is full of lengthy code blocks and comments, it's hardly readable for us. You should wait until you're really stuck in your investigations, then post a summary of what you've found so far, with a complete and minimal code that reproduces the problem.
Laurent Gomila - SFML developer