Strange result when displaying the refraction texture

Hi! For refraction effect I draw the scene 6 times into a cubemap attached to an FBO. (X positive, X negative, Y positive, Y negative, Z positive and Z negative), and then I draw the cubemap onto a 2D texture attached to another FBO.

The problem is that at some execution, the refraction texture is flickering, and the pixels are not good so it looks strange; in this video we can see at the first execution the refraction texture is displaying well but not at the next executions.

https://www.youtube.com/watch?v=x2Fw6Q7so7k&feature=youtu.be

The source code can be found here you just need to install cwc to build and run it.

I think I’ve found the problem but I don’t know how to solve it, it seems my refraction shader executes before my cubemap is drawn :

void ReflectRefractRenderComponent::drawNextFrame() {
            if (reflectRefractTex.getSettings().versionMajor >= 4 && reflectRefractTex.getSettings().versionMinor >= 3) {
                RenderStates currentStates;
                math::Matrix4f viewMatrix = view.getViewMatrix().getMatrix().transpose();
                math::Matrix4f projMatrix = view.getProjMatrix().getMatrix().transpose();
                sBuildDepthBuffer.setParameter("viewMatrix", viewMatrix);
                sBuildDepthBuffer.setParameter("projectionMatrix", projMatrix);
                sBuildDepthBufferNormal.setParameter("viewMatrix", viewMatrix);
                sBuildDepthBufferNormal.setParameter("projectionMatrix", projMatrix);
                for (unsigned int i = 0; i < m_instances.size(); i++) {
                    if (m_instances[i].getAllVertices().getVertexCount() > 0) {
                        if (m_instances[i].getMaterial().getTexture() != nullptr) {
                            math::Matrix4f texMatrix = m_instances[i].getMaterial().getTexture()->getTextureMatrix();
                            sBuildDepthBuffer.setParameter("textureMatrix", texMatrix);
                            sBuildDepthBuffer.setParameter("haveTexture", 1.f);
                        } else {
                            sBuildDepthBuffer.setParameter("haveTexture", 0.f);
                        }
                        vb.clear();
                        vb.setPrimitiveType(m_instances[i].getVertexArrays()[0]->getPrimitiveType());
                        matrices.clear();
                        std::vector<TransformMatrix*> tm = m_instances[i].getTransforms();
                        for (unsigned int j = 0; j < tm.size(); j++) {
                            tm[j]->update();
                            std::array<float, 16> matrix = tm[j]->getMatrix().transpose().toGlMatrix();
                            for (unsigned int n = 0; n < 16; n++) {
                                matrices.push_back(matrix[n]);
                            }
                        }
                        glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboWorldMatrices));
                        glCheck(glBufferData(GL_ARRAY_BUFFER, matrices.size() * sizeof(float), &matrices[0], GL_DYNAMIC_DRAW));
                        glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
                        if (m_instances[i].getVertexArrays().size() > 0) {
                            for (unsigned int j = 0; j < m_instances[i].getVertexArrays()[0]->getVertexCount(); j++) {
                                vb.append((*m_instances[i].getVertexArrays()[0])[j]);
                            }
                            vb.update();
                        }
                        currentStates.blendMode = sf::BlendNone;
                        currentStates.shader = &sBuildDepthBuffer;
                        currentStates.texture = m_instances[i].getMaterial().getTexture();
                        depthBuffer.drawInstanced(vb, m_instances[i].getVertexArrays()[0]->getPrimitiveType(), 0, m_instances[i].getVertexArrays()[0]->getVertexCount(), tm.size(), currentStates, vboWorldMatrices);
                    }
                }
                for (unsigned int i = 0; i < m_normals.size(); i++) {
                    if (m_normals[i].getAllVertices().getVertexCount() > 0) {
                        if (m_normals[i].getMaterial().getTexture() != nullptr) {
                            math::Matrix4f texMatrix = m_normals[i].getMaterial().getTexture()->getTextureMatrix();
                            sBuildDepthBufferNormal.setParameter("textureMatrix", texMatrix);
                            sBuildDepthBufferNormal.setParameter("haveTexture", 1.f);
                        } else {
                            sBuildDepthBufferNormal.setParameter("haveTexture", 0.f);
                        }
                        vb.clear();
                        vb.setPrimitiveType(m_normals[i].getAllVertices().getPrimitiveType());
                        for (unsigned int j = 0; j < m_normals[i].getAllVertices().getVertexCount(); j++) {
                            vb.append(m_normals[i].getAllVertices()[j]);
                        }
                        vb.update();
                        currentStates.blendMode = sf::BlendNone;
                        currentStates.shader = &sBuildDepthBufferNormal;
                        currentStates.texture = m_instances[i].getMaterial().getTexture();
                        depthBuffer.drawVertexBuffer(vb, currentStates);
                    }
                }
                depthBuffer.display();
                View reflectView;
                if (view.isOrtho()) {
                    reflectView = View (squareSize, squareSize,0, 1000);
                } else {
                    reflectView = View (squareSize, squareSize, 90, 0, 1000);
                }
                reflectView.setCenter(view.getPosition());
                for (unsigned int m = 0; m < 6; m++) {
                    math::Vec3f target = reflectView.getPosition() + dirs[m];
                    reflectView.lookAt(target.x, target.y, target.z);
                    std::vector<Entity*> visibleReflEntities = World::getEntitiesInRect(reflectView.getViewVolume(), expression);
                    std::vector<Entity*> copy;
                    for (unsigned int j = 0; j < visibleReflEntities.size(); j++)  {
                        if (!visibleReflEntities[j]->isReflectable()) {
                            copy.push_back(visibleReflEntities[j]);
                        }
                    }
                    environmentMap.setActive();
                    environmentMap.setView(reflectView);
                    GLuint zero = 0;
                    glCheck(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer));
                    glCheck(glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &zero));
                    glCheck(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0));
                    glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, clearBuf));
                    glCheck(glBindTexture(GL_TEXTURE_2D, headPtrTex));
                    glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, squareSize, squareSize, GL_RED_INTEGER,
                    GL_UNSIGNED_INT, NULL));
                    glCheck(glBindTexture(GL_TEXTURE_2D, 0));
                    environmentMap.resetGLStates();
                    glCheck(glEnable(GL_TEXTURE_CUBE_MAP));
                    environmentMap.selectCubemapFace(m);
                    viewMatrix = reflectView.getViewMatrix().getMatrix().transpose();
                    projMatrix = reflectView.getProjMatrix().getMatrix().transpose();
                    sLinkedList.setParameter("viewMatrix", viewMatrix);
                    sLinkedList.setParameter("projectionMatrix", projMatrix);
                    rvBatcher.clear();
                    normalRvBatcher.clear();
                    for (unsigned int j = 0; j < copy.size(); j++) {
                        for (unsigned int n = 0; n < copy[j]->getNbFaces(); n++) {
                            if (copy[j]->getDrawMode() == Entity::INSTANCED) {
                                rvBatcher.addFace(copy[j]->getFace(n));
                            } else {
                                normalRvBatcher.addFace(copy[j]->getFace(n));
                            }
                        }
                    }
                    std::vector<Instance> rvInstances = rvBatcher.getInstances();
                    std::vector<Instance> rvNormals = normalRvBatcher.getInstances();
                    for (unsigned int i = 0; i < rvInstances.size(); i++) {
                        if (rvInstances[i].getAllVertices().getVertexCount() > 0) {
                            vb.clear();
                            vb.setPrimitiveType(rvInstances[i].getVertexArrays()[0]->getPrimitiveType());
                            matrices.clear();
                            std::vector<TransformMatrix*> tm = rvInstances[i].getTransforms();
                            for (unsigned int j = 0; j < tm.size(); j++) {
                                tm[j]->update();
                                std::array<float, 16> matrix = tm[j]->getMatrix().transpose().toGlMatrix();
                                for (unsigned int n = 0; n < 16; n++) {
                                    matrices.push_back(matrix[n]);
                                }
                            }
                            glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboWorldMatrices));
                            glCheck(glBufferData(GL_ARRAY_BUFFER, matrices.size() * sizeof(float), &matrices[0], GL_DYNAMIC_DRAW));
                            glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
                            if (rvInstances[i].getVertexArrays().size() > 0) {
                                for (unsigned int j = 0; j < rvInstances[i].getVertexArrays()[0]->getVertexCount(); j++) {
                                    vb.append((*rvInstances[i].getVertexArrays()[0])[j]);
                                }
                                vb.update();
                            }
                            currentStates.blendMode = sf::BlendNone;
                            currentStates.shader = &sLinkedList;
                            currentStates.texture =rvInstances[i].getMaterial().getTexture();
                            if (rvInstances[i].getMaterial().getTexture() != nullptr) {
                                math::Matrix4f texMatrix = rvInstances[i].getMaterial().getTexture()->getTextureMatrix();
                                sLinkedList.setParameter("textureMatrix", texMatrix);
                                sLinkedList.setParameter("haveTexture", 1.f);
                            } else {
                                sLinkedList.setParameter("haveTexture", 0.f);
                            }
                            environmentMap.drawInstanced(vb, rvInstances[i].getVertexArrays()[0]->getPrimitiveType(), 0, rvInstances[i].getVertexArrays()[0]->getVertexCount(), tm.size(), currentStates, vboWorldMatrices);
                        }
                    }
                    viewMatrix = reflectView.getViewMatrix().getMatrix().transpose();
                    projMatrix = reflectView.getProjMatrix().getMatrix().transpose();
                    sLinkedListNormal.setParameter("viewMatrix", viewMatrix);
                    sLinkedListNormal.setParameter("projectionMatrix", projMatrix);
                    for (unsigned int i = 0; i < rvNormals.size(); i++) {
                       if (rvNormals[i].getAllVertices().getVertexCount() > 0) {
                            if (rvNormals[i].getMaterial().getTexture() == nullptr) {
                                sLinkedListNormal.setParameter("haveTexture", 0.f);
                            } else {
                                math::Matrix4f texMatrix = rvNormals[i].getMaterial().getTexture()->getTextureMatrix();
                                sLinkedListNormal.setParameter("textureMatrix", texMatrix);
                                sLinkedListNormal.setParameter("haveTexture", 1.f);
                            }
                            currentStates.blendMode = sf::BlendNone;
                            currentStates.shader = &sLinkedListNormal;
                            currentStates.texture = rvNormals[i].getMaterial().getTexture();
                            vb.clear();
                            vb.setPrimitiveType(rvNormals[i].getAllVertices().getPrimitiveType());
                            for (unsigned int j = 0; j < rvNormals[i].getAllVertices().getVertexCount(); j++) {
                                vb.append(rvNormals[i].getAllVertices()[j]);
                            }
                            vb.update();
                            environmentMap.drawVertexBuffer(vb, currentStates);
                        }
                    }
                    glCheck(glFinish());
                    glCheck(glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT));
                    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
                    vb2.clear();
                    vb2.setPrimitiveType(sf::Quads);
                    Vertex v1 (sf::Vector3f(0, 0, 0));
                    Vertex v2 (sf::Vector3f(quad.getSize().x,0, 0));
                    Vertex v3 (sf::Vector3f(quad.getSize().x, quad.getSize().y, quad.getSize().z));
                    Vertex v4 (sf::Vector3f(0, quad.getSize().y, quad.getSize().z));
                    vb2.append(v1);
                    vb2.append(v2);
                    vb2.append(v3);
                    vb2.append(v4);
                    vb2.update();
                    math::Matrix4f matrix = quad.getTransform().getMatrix().transpose();
                    sLinkedList2.setParameter("worldMat", matrix);
                    currentStates.shader = &sLinkedList2;
                    environmentMap.drawVertexBuffer(vb2, currentStates);
                    glCheck(glFinish());
                }
                environmentMap.display();
                for (unsigned int i = 0; i < m_reflInstances.size(); i++) {
                    if (m_reflInstances[i].getAllVertices().getVertexCount() > 0) {
                        viewMatrix = view.getViewMatrix().getMatrix().transpose();
                        projMatrix = view.getProjMatrix().getMatrix().transpose();
                        sReflectRefract.setParameter("viewMatrix", viewMatrix);
                        sReflectRefract.setParameter("projectionMatrix", projMatrix);
                        sReflectRefract.setParameter("cameraPos", view.getPosition().x, view.getPosition().y, view.getPosition().z);
                        vb.clear();
                        vb.setPrimitiveType(m_reflInstances[i].getVertexArrays()[0]->getPrimitiveType());
                        matrices.clear();
                        std::vector<TransformMatrix*> tm = m_reflInstances[i].getTransforms();
                        for (unsigned int j = 0; j < tm.size(); j++) {
                            tm[j]->update();
                            std::array<float, 16> matrix = tm[j]->getMatrix().transpose().toGlMatrix();
                            for (unsigned int n = 0; n < 16; n++) {
                                matrices.push_back(matrix[n]);
                            }
                        }
                        glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboWorldMatrices));
                        glCheck(glBufferData(GL_ARRAY_BUFFER, matrices.size() * sizeof(float), &matrices[0], GL_DYNAMIC_DRAW));
                        glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
                        if (m_reflInstances[i].getVertexArrays().size() > 0) {
                            for (unsigned int j = 0; j < m_reflInstances[i].getVertexArrays()[0]->getVertexCount(); j++) {
                                vb.append((*m_reflInstances[i].getVertexArrays()[0])[j]);
                            }
                            vb.update();
                        }
                        currentStates.blendMode = sf::BlendNone;
                        currentStates.shader = &sReflectRefract;
                        currentStates.texture = &environmentMap.getTexture();
                        reflectRefractTex.drawInstanced(vb, m_reflInstances[i].getVertexArrays()[0]->getPrimitiveType(), 0, m_reflInstances[i].getVertexArrays()[0]->getVertexCount(), tm.size(), currentStates, vboWorldMatrices);
                    }
                }
                for (unsigned int i = 0; i < m_reflNormals.size(); i++) {
                    if (m_reflNormals[i].getAllVertices().getVertexCount() > 0) {
                        viewMatrix = view.getViewMatrix().getMatrix().transpose();
                        projMatrix = view.getProjMatrix().getMatrix().transpose();
                        sReflectRefractNormal.setParameter("viewMatrix", viewMatrix);
                        sReflectRefractNormal.setParameter("projectionMatrix", projMatrix);
                        sReflectRefractNormal.setParameter("cameraPos", view.getPosition().x, view.getPosition().y, view.getPosition().z);
                        vb.clear();
                        vb.setPrimitiveType(m_reflNormals[i].getAllVertices().getPrimitiveType());
                        for (unsigned int j = 0; j < m_reflNormals[i].getAllVertices().getVertexCount(); j++) {
                            vb.append(m_reflNormals[i].getAllVertices()[j]);
                        }
                        vb.update();
                        currentStates.blendMode = sf::BlendNone;
                        currentStates.shader = &sReflectRefractNormal;
                        currentStates.texture = &environmentMap.getTexture();
                        reflectRefractTex.drawVertexBuffer(vb, currentStates);
                    }
                }
                reflectRefractTex.display();
            }
        }

I don’t have this problem with the PerPixelLinkedListRenderComponent class and everything is displayed well.

I’ve called glMemoryBarrier and glFinish but no way.

Normaly it should wait the cubemap is drawn before drawing in the refraction FBO.

I don’t see where is the problem it takes random colour of the cubemap.

I tried to add this after drawing the linked list :

glCheck(glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT));

But it doesn’t work, when I draw the cubemap faces on the screen they are drawing well, but when I want to use my cubemap into a shader, there is the synchronisation problem.

That’s for SSBOs. Are you accessing the data through buffer variables? If not, there’s no point to that. For texture access, the relevant bit is GL_TEXTURE_FETCH_BARRIER_BIT. But to be on the safe side, you might try using GL_ALL_BARRIER_BITS. If that doesn’t fix it, it’s not a memory coherence issue.

I’ve tried this GL_ALL_BARRIER_BITS but that doesn’t solve the problem so it’s not a memory coherence issue. I block on that issue I don’t know what kind of issue it might be and so I also don’t know how to solve it.
But it’s sure that the cubemap colour is not always good when I draw it in the refraction shader.

There is a fatal error when I run this with RenderDoc, the driver fails to allocate memory.

I’ve 6 GB of VRAM so it shouldn’t be a problem.

Ok I reduced the depth of the linked list buffer from 20 to 10 and now the allocation memory problem disappeared, but I can’t capture frames to see what’s wrong when I want to capture a frame the application close.

It seems to be a driver bug, I don’t know why but my cubemap texture is not bind to the fragment shader.

I’m trying to debug with the main function and trying to draw a skybox to an FBO with an attached cubemap texture but that doesn’t draw anything to the FBO :

#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;    
// 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,
    UP,
    DOWN
};

// 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);
    }
    glm::mat4 lookAt (Camera_Movement direction) {
        if (direction == FORWARD) {
            return glm::lookAt(Position, Position + Front, Up);
        }
        if (direction == BACKWARD) {
            return glm::lookAt(Position, Position - Front, Up);
        }
        if (direction == LEFT) {
            return glm::lookAt(Position, Position - Right, Up);
        }
        if (direction == RIGHT) {
            return glm::lookAt(Position, Position + Right, Up);
        }
        if (direction == UP) {
            return glm::lookAt(Position, Position + Up, Up);
        }
        if (direction == DOWN) {
            return glm::lookAt(Position, Position - Up, 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);
Matrix4f glmToODFAEGMatrix(glm::mat4 mat);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
Camera camera2;
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(24, 0, 4, 4, 6));
    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 460
                                    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 460
                                        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 460
                                    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 460
                                    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
    };
    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    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, cubeMapFBOTex;
    cubeMapTex.createCubeMap(width, height, images);
    glEnable(GL_TEXTURE_CUBE_MAP);
    sf::Context context(sf::ContextSettings(0, 0, 4, 4, 6), SCR_WIDTH, SCR_WIDTH);
    context.setActive(true);
    unsigned int skyboxVAOFBO;
    glGenVertexArrays(1, &skyboxVAOFBO);
    cubeMapFBOTex.createCubeMap(SCR_WIDTH, SCR_WIDTH);


    GLuint frameBufferID;
    glGenFramebuffers(1, &frameBufferID);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubeMapFBOTex.getNativeHandle(), 0);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        std::cerr << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
        return false;
    }
   // shader configuration
    // --------------------
    shader.setParameter("skybox", cubeMapFBOTex);
    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
        // ------
        window.setActive(true);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        context.setActive(true);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        for (unsigned int i = 0; i < 6; i++) {
            glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubeMapFBOTex.getNativeHandle(), 0);
            glViewport(0, 0, SCR_WIDTH, SCR_WIDTH);
            glm::mat4 view;
            if (i == 0) {
                view = camera2.lookAt(FORWARD);
            }
            if (i == 1) {
                view = camera2.lookAt(BACKWARD);
            }
            if (i == 2) {
                view = camera2.lookAt(UP);
            }
            if (i == 3) {
                view = camera2.lookAt(DOWN);
            }
            if (i == 4) {
                view = camera2.lookAt(RIGHT);
            }
            if (i == 5) {
                view = camera2.lookAt(LEFT);
            }
            glm::mat4 projection = glm::perspective(glm::radians(camera2.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
            odfaeg::graphic::Shader::bind(&skyboxShader);
            Matrix4f viewMatrix = glmToODFAEGMatrix(view);
            Matrix4f projectionMatrix = glmToODFAEGMatrix(projection);
            skyboxShader.setParameter("view", viewMatrix);
            skyboxShader.setParameter("projection", projectionMatrix);
            // skybox cube
            glBindVertexArray(skyboxVAOFBO);
            glActiveTexture(GL_TEXTURE0);
            odfaeg::graphic::Texture::bind(&cubeMapTex, odfaeg::graphic::Texture::Normalized);
            glDrawArrays(GL_TRIANGLES, 0, 36);
            glBindVertexArray(0);

        }
        glFlush();
        window.setActive(true);
        glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
        // 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 = glmToODFAEGMatrix(model);
        odfaeg::math::Matrix4f viewMatrix = glmToODFAEGMatrix(view);
        odfaeg::math::Matrix4f projectionMatrix = glmToODFAEGMatrix(projection);
        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(&cubeMapFBOTex, 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 = glmToODFAEGMatrix(view);
        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);
    glDeleteVertexArrays(1, &skyboxVAOFBO);
    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;
}
Matrix4f glmToODFAEGMatrix(glm::mat4 mat) {
    Matrix4f odfaegMatrix(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
                         mat[1][0], mat[1][1], mat[1][2], mat[1][3],
                         mat[2][0], mat[2][1], mat[2][2], mat[2][3],
                         mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
    return odfaegMatrix;
}

What’s wrong why it doesn’t draw the skybox in the FBO.
It draws the skybox on the window but not on the FBO.
EDIT : I’ve found why, we must to redefine vertexAttribPointers to the other opengl context.

sf::Context context(sf::ContextSettings(0, 0, 4, 4, 6), SCR_WIDTH, SCR_WIDTH);
    context.setActive(true);
    unsigned int skyboxVAOFBO;
    glGenVertexArrays(1, &skyboxVAOFBO);
    glBindVertexArray(skyboxVAOFBO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

I think the problem is because I’ve a GL_OUT_OF_MEMORY error because I don’t have this problem when I reflect a simple skybox. So I guess I use too much memory so this is why sometimes my refraction texture doesn’t draw things well :

viewMatrix = view.getViewMatrix().getMatrix().transpose();
                projMatrix = view.getProjMatrix().getMatrix().transpose();
                sReflectRefract.setParameter("viewMatrix", viewMatrix);
                sReflectRefract.setParameter("projectionMatrix", projMatrix);
                sReflectRefract.setParameter("cameraPos", view.getPosition().x, view.getPosition().y, view.getPosition().z);
                for (unsigned int i = 0; i < m_reflInstances.size(); i++) {
                    if (m_reflInstances[i].getAllVertices().getVertexCount() > 0) {
                        vb.clear();
                        vb.setPrimitiveType(m_reflInstances[i].getVertexArrays()[0]->getPrimitiveType());
                        matrices.clear();
                        std::vector<TransformMatrix*> tm = m_reflInstances[i].getTransforms();
                        for (unsigned int j = 0; j < tm.size(); j++) {
                            tm[j]->update();
                            std::array<float, 16> matrix = tm[j]->getMatrix().transpose().toGlMatrix();
                            for (unsigned int n = 0; n < 16; n++) {
                                matrices.push_back(matrix[n]);
                            }
                        }
                        glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboWorldMatrices));
                        glCheck(glBufferData(GL_ARRAY_BUFFER, matrices.size() * sizeof(float), &matrices[0], GL_DYNAMIC_DRAW));
                        glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
                        if (m_reflInstances[i].getVertexArrays().size() > 0) {
                            for (unsigned int j = 0; j < m_reflInstances[i].getVertexArrays()[0]->getVertexCount(); j++) {
                                vb.append((*m_reflInstances[i].getVertexArrays()[0])[j]);
                            }
                            vb.update();
                        }
                        currentStates.blendMode = sf::BlendNone;
                        currentStates.shader = &sReflectRefract;
                        currentStates.texture = &environmentMap.getTexture();
                        reflectRefractTex.drawInstanced(vb, m_reflInstances[i].getVertexArrays()[0]->getPrimitiveType(), 0, m_reflInstances[i].getVertexArrays()[0]->getVertexCount(), tm.size(), currentStates, vboWorldMatrices);
                    }
                }
                viewMatrix = view.getViewMatrix().getMatrix().transpose();
                projMatrix = view.getProjMatrix().getMatrix().transpose();
                sReflectRefractNormal.setParameter("viewMatrix", viewMatrix);
                sReflectRefractNormal.setParameter("projectionMatrix", projMatrix);
                sReflectRefractNormal.setParameter("cameraPos", view.getPosition().x, view.getPosition().y, view.getPosition().z);
                for (unsigned int i = 0; i < m_reflNormals.size(); i++) {
                    if (m_reflNormals[i].getAllVertices().getVertexCount() > 0) {
                        vb.clear();
                        vb.setPrimitiveType(m_reflNormals[i].getAllVertices().getPrimitiveType());
                        for (unsigned int j = 0; j < m_reflNormals[i].getAllVertices().getVertexCount(); j++) {
                            vb.append(m_reflNormals[i].getAllVertices()[j]);
                        }
                        vb.update();
                        currentStates.blendMode = sf::BlendNone;
                        currentStates.shader = &sReflectRefractNormal;
                        currentStates.texture = &environmentMap.getTexture();
                        reflectRefractTex.drawVertexBuffer(vb, currentStates);
                    }
                }
                reflectRefractTex.display();

I’ve 6 GB vram but I’ve the impression to be very limited with the VRAM I can use.

GL_OUT_OF_MEMORY

There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded.

When an error flag is set, results of a GL operation are undefined only if GL_OUT_OF_MEMORY has occurred. In all other cases, the command generating the error is ignored and has no effect on the GL state or frame buffer contents. If the generating command returns a value, it returns 0.

How to solve this…

I tried to put a glFinish or a glFlush for waiting the command opengl buffer is empty before calling an other opengl command but this doesn’t work I’ve always that GL_OUT_OF_MEMORY error returned. Can’t we increase the size of the opengl command buffer ?

it’s written on wikipedia : The simplest to understand is glFinish. It will not return, stopping the current CPU thread, until all rendering commands that have been sent have completed .

But it doesn’t seems to work.

You don’t have to deal with the OpenGL command buffer. This is managed by the driver.
How much VRAM do you dispose ? How much are you trying to allocate ? Are you freeing unused resources ?

When I have a look at your code and see 5 or 6 nested for loops and also see a [quote]environmentMap.drawInstanced[/quote] deeply nested in your loops, I’m pretty sure the problem lies somewhere over there.

I’ve found the problem for the GL_OUT_OF_MEMORY error but it doesn’t solve the initial bug with the refraction texture which doesn’t display well at each execution.

Something strange happens, I displayed the i vector and the normal n and they are good, but when I display r, the vector is not good from the refract function, so, the problem is in this shader :

R"(#version 460
                                                                in vec4 frontColor;
                                                                in vec3 normal;
                                                                in vec3 pos;
                                                                uniform vec3 cameraPos;
                                                                uniform samplerCube sceneBox;
                                                                uniform sampler2D depthBuffer;
                                                                uniform vec3 resolution;
                                                                layout (location = 0) out vec4 fColor;
                                                                void main () {
                                                                    vec2 position = (gl_FragCoord.xy / resolution.xy);
                                                                    vec4 depth = texture2D(depthBuffer, position);
                                                                    float ratio = 1.00 / 1.33;
                                                                    vec3 i = normalize(pos - cameraPos);
                                                                    vec3 r = refract (i, normalize(normal), ratio);
                                                                    vec3 n = normalize(normal);
                                                                    r = normalize(r);
                                                                    if (depth.z > 0) {
                                                                        fColor = vec4(abs(r.r), abs(r.g), abs(r.b), 1);/*texture(sceneBox, r) * (1 - depth.a);*/
                                                                    } else {
                                                                        fColor = vec4(abs(r.r), abs(r.g), abs(r.b), 1);/*texture(sceneBox, r);*/
                                                                    }
                                                                }
                                                              )";

The colour is black everywhere, so, it means that the r vector is always null.

Ok I coded the reflect and refract function by myself and I see that sometimes the values of the r vector are null, sometimes not, so, I guess this is a driver bug because it’s not normal that the values of the r vector are varying at each shader execution.

nvidia driver bug

R"(#version 460
                                                                in vec4 frontColor;
                                                                in vec3 normal;
                                                                in vec3 pos;
                                                                uniform vec3 cameraPos;
                                                                uniform samplerCube sceneBox;
                                                                uniform sampler2D depthBuffer;
                                                                uniform vec3 resolution;
                                                                layout (location = 0) out vec4 fColor;
                                                                vec3 refl(vec3 i, vec3 n) {
                                                                    return i - 2.0 * dot (n, i) * n;
                                                                }
                                                                vec3 refr(vec3 i, vec3 n, float eta) {
                                                                   float k = 1.0 - eta * eta * (1.0 - dot(n, i) * dot(n, i));
                                                                   if (k < 0.0) {
                                                                       return vec3(0, 0, 0);
                                                                   } else {
                                                                       return eta * i - (eta * dot(n, i) + sqrt(k)) * n;
                                                                   }
                                                                }
                                                                void main () {
                                                                    vec2 position = (gl_FragCoord.xy / resolution.xy);
                                                                    vec4 depth = texture2D(depthBuffer, position);
                                                                    float ratio = 1.00 / 1.33;
                                                                    vec3 i = (pos - cameraPos);
                                                                    vec3 r = refr (i, normalize(normal), ratio);
                                                                    vec3 n = normalize(normal);
                                                                    r = normalize(r);
                                                                    if (depth.z > 0) {
                                                                        fColor = vec4(abs(r.r), abs(r.g), abs(r.b), 1);/*texture(sceneBox, r) * (1 - depth.a);*/
                                                                    } else {
                                                                        fColor = vec4(abs(r.r), abs(r.g), abs(r.b), 1);/*texture(sceneBox, r);*/
                                                                    }
                                                                }
                                                              )";

Here is a more simple source code with reproduce the problem :

#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;
// 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,
    UP,
    DOWN
};

// 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);
    }
    glm::mat4 lookAt (Camera_Movement direction) {
        if (direction == FORWARD) {
            return glm::lookAt(Position, Position + Front, Up);
        }
        if (direction == BACKWARD) {
            return glm::lookAt(Position, Position - Front, Up);
        }
        if (direction == LEFT) {
            return glm::lookAt(Position, Position - Right, Up);
        }
        if (direction == RIGHT) {
            return glm::lookAt(Position, Position + Right, Up);
        }
        if (direction == UP) {
            return glm::lookAt(Position, Position + Up, Up);
        }
        if (direction == DOWN) {
            return glm::lookAt(Position, Position - Up, 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);
Matrix4f glmToODFAEGMatrix(glm::mat4 mat);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
Camera camera2;
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;
float speed = 10.f;
float sensivity = 0.1f;
float oldX = (float)SCR_WIDTH / 2.0;
float oldY = (float)SCR_HEIGHT / 2.0;

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(24, 0, 4, 4, 6));
    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 refractCubeVS = R"(#version 460
                                         layout (location = 0) in vec3 aPos;
                                         layout (location = 1) in vec2 aTexCoords;
                                         uniform mat4 model;
                                         uniform mat4 view;
                                         uniform mat4 projection;
                                         out vec2 texCoords;
                                         void main() {
                                             gl_Position = projection * view * model * vec4(aPos, 1.0);
                                             texCoords = aTexCoords;
                                         }
                                         )";
    const std::string refractCubeFS = R"(#version 460
                                         uniform sampler2D texture;
                                         in vec2 texCoords;
                                         out vec4 FragColor;
                                         void main() {
                                            FragColor = texture2D (texture, texCoords);
                                         })";
    const std::string cubeMapsVS = R"(#version 460
                                    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 460
                                        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));
                                            R = normalize(R);
                                            FragColor = vec4(abs(R.r), abs(R.g), abs(R.b), 1); /*vec4(texture(skybox, R).rgb, 1.0);*/
                                        }
                                   )";
    const std::string skyboxVS = R"(#version 460
                                    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 460
                                    out vec4 FragColor;
                                    in vec3 TexCoords;
                                    uniform samplerCube skybox;
                                    void main()
                                    {
                                        FragColor = texture(skybox, TexCoords);
                                    }
                                    )";
    odfaeg::graphic::Shader shader, skyboxShader, refractCubeShader;
    shader.loadFromMemory(cubeMapsVS, cubeMapsFS);
    skyboxShader.loadFromMemory(skyboxVS, skyboxFS);
    refractCubeShader.loadFromMemory(refractCubeVS, refractCubeFS);
    // 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
    };
    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    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
    };
    float fullScreenQuadVertices2[] = {
        // positions        //TexCoords
        -1.0f,  1.0f, 0.0f, 0.0f, 1.0f,
        -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
         1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
         1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
         1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
        -1.0f,  1.0f, 0.0f, 0.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, cubeMapFBOTex, refractTex;
    cubeMapTex.createCubeMap(width, height, images);
    cubeMapFBOTex.createCubeMap(SCR_WIDTH, SCR_WIDTH);
    refractTex.create(SCR_WIDTH, SCR_HEIGHT);
    glEnable(GL_TEXTURE_CUBE_MAP);
    sf::Context context(sf::ContextSettings(0, 0, 4, 4, 6), SCR_WIDTH, SCR_WIDTH);
    context.setActive(true);
    unsigned int skyboxVAOFBO;
    glGenVertexArrays(1, &skyboxVAOFBO);
    glBindVertexArray(skyboxVAOFBO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);


    GLuint frameBufferID;
    glGenFramebuffers(1, &frameBufferID);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubeMapFBOTex.getNativeHandle(), 0);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        std::cerr << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
        return false;
    }
    sf::Context context2(sf::ContextSettings(0, 0, 4, 4, 6), SCR_WIDTH, SCR_WIDTH);
    context2.setActive(true);
    unsigned int fsQuadVAOFBO, fsQuadVBOFBO;
    glGenVertexArrays(1, &fsQuadVAOFBO);
    glBindVertexArray(fsQuadVAOFBO);
    glGenBuffers(1, &fsQuadVBOFBO);
    glBindBuffer(GL_ARRAY_BUFFER, fsQuadVBOFBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(fullScreenQuadVertices2), &fullScreenQuadVertices2, 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)));
    GLuint frameBufferID2;
    glGenFramebuffers(1, &frameBufferID2);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID2);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, refractTex.getNativeHandle(), 0);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        std::cerr << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
        return false;
    }
   // shader configuration
    // --------------------
    shader.setParameter("skybox", cubeMapFBOTex);
    skyboxShader.setParameter("skybox", cubeMapTex);
    refractCubeShader.setParameter("texture", refractTex);
    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
        // ------
        window.setActive(true);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        context2.setActive(true);
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        context.setActive(true);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        for (unsigned int i = 0; i < 6; i++) {
            glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubeMapFBOTex.getNativeHandle(), 0);
            glViewport(0, 0, SCR_WIDTH, SCR_WIDTH);
            glm::mat4 view;
            if (i == 0) {
                view = camera2.lookAt(FORWARD);
            }
            if (i == 1) {
                view = camera2.lookAt(BACKWARD);
            }
            if (i == 2) {
                view = camera2.lookAt(UP);
            }
            if (i == 3) {
                view = camera2.lookAt(DOWN);
            }
            if (i == 4) {
                view = camera2.lookAt(RIGHT);
            }
            if (i == 5) {
                view = camera2.lookAt(LEFT);
            }
            glm::mat4 projection = glm::perspective(glm::radians(camera2.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
            odfaeg::graphic::Shader::bind(&skyboxShader);
            Matrix4f viewMatrix = glmToODFAEGMatrix(view);
            Matrix4f projectionMatrix = glmToODFAEGMatrix(projection);
            skyboxShader.setParameter("view", viewMatrix);
            skyboxShader.setParameter("projection", projectionMatrix);
            // skybox cube
            glBindVertexArray(skyboxVAOFBO);
            glActiveTexture(GL_TEXTURE0);
            odfaeg::graphic::Texture::bind(&cubeMapTex, odfaeg::graphic::Texture::Normalized);
            glDrawArrays(GL_TRIANGLES, 0, 36);
            glBindVertexArray(0);
        }
        glMemoryBarrier(GL_ALL_BARRIER_BITS);
        glFlush();
        //window.setActive(true);
        context2.setActive(true);
        glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
        // 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);
        Matrix4f modelMatrix = glmToODFAEGMatrix(model);
        Matrix4f viewMatrix = glmToODFAEGMatrix(view);
        Matrix4f projectionMatrix = glmToODFAEGMatrix(projection);
        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(&cubeMapFBOTex, odfaeg::graphic::Texture::Normalized);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        window.setActive(true);
        //Draw skybox.
        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
        projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        viewMatrix = glmToODFAEGMatrix(view);
        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);
        // refract cube.
        glDepthFunc(GL_LESS);
        model = glm::mat4(1.0f);
        view = camera2.GetViewMatrix();
        projection = glm::ortho(-1, 1, -1, 1);
        modelMatrix = glmToODFAEGMatrix(model);
        viewMatrix = glmToODFAEGMatrix(view);
        projectionMatrix = glmToODFAEGMatrix(projection);
        refractCubeShader.setParameter("model", modelMatrix);
        refractCubeShader.setParameter("view", viewMatrix);
        refractCubeShader.setParameter("projection", projectionMatrix);
        odfaeg::graphic::Shader::bind(&refractCubeShader);
        glBindVertexArray(fsQuadVAOFBO);
        glActiveTexture(GL_TEXTURE0);
        odfaeg::graphic::Texture::bind(&refractTex, odfaeg::graphic::Texture::Normalized);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glBindVertexArray(0);

        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);
    glDeleteVertexArrays(1, &skyboxVAOFBO);
    glDeleteBuffers(1, &cubeVBO);
    glDeleteBuffers(1, &skyboxVAO);
    // release resources...

    return 0;
}
Matrix4f glmToODFAEGMatrix(glm::mat4 mat) {
    Matrix4f odfaegMatrix(mat[0][0], mat[0][1], mat[0][2], mat[0][3],
                         mat[1][0], mat[1][1], mat[1][2], mat[1][3],
                         mat[2][0], mat[2][1], mat[2][2], mat[2][3],
                         mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
    return odfaegMatrix;
}

It’s when I want to draw the cube which refract the skybox in a FBO that the problem occurs.

It seems when I use a single context for all my FBO and not one context per FBO it works better so the bug is when we use several opengl contexts. SFML have a shared context so all my shaders and textures should be shared between every contexts.

Ok I’ve found the problem, it’s when I do instanced rendering here :

void RenderTarget::drawInstanced(VertexBuffer& vertexBuffer, enum sf::PrimitiveType type, unsigned int start, unsigned int nb, unsigned int nbInstances, RenderStates states, unsigned int vboMatrix1, unsigned int vboMatrix2) {
                if (vertexBuffer.getVertexCount() == 0) {
                    return;
                }

                if (activate(true))
                {
                    if (!m_cache.glStatesSet)
                        resetGLStates();
                    // Apply the view
                    if (m_cache.viewChanged)
                        applyCurrentView();

                    if (states.blendMode != m_cache.lastBlendMode)
                        applyBlendMode(states.blendMode);

                    // Apply the texture
                    sf::Uint64 textureId = states.texture ? states.texture->getNativeHandle() : 0;
                    if (textureId != m_cache.lastTextureId)
                        applyTexture(states.texture);
                    // Apply the shader
                    if (states.shader)
                        applyShader(states.shader);
                    if (m_versionMajor > 3 || m_versionMajor == 3 && m_versionMinor >= 3)
                        glCheck(glBindVertexArray(m_vao));
                    if (m_cache.lastVboBuffer != &vertexBuffer) {
                        if (m_versionMajor > 3 || m_versionMajor == 3 && m_versionMinor >= 3) {
                            glCheck(glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.vboVertexBuffer));
                            glCheck(glEnableVertexAttribArray(0));
                            glCheck(glEnableVertexAttribArray(1));
                            glCheck(glEnableVertexAttribArray(2));
                            glCheck(glEnableVertexAttribArray(3));
                            glCheck(glVertexAttribPointer(0, 3,GL_FLOAT,GL_FALSE,sizeof(Vertex), (GLvoid*) 0));
                            glCheck(glVertexAttribPointer(1, 4,GL_UNSIGNED_BYTE,GL_TRUE,sizeof(Vertex),(GLvoid*) 12));
                            glCheck(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) 16));
                            glCheck(glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.vboNormalBuffer));
                            glCheck(glVertexAttribPointer(3, 3, GL_FLOAT,GL_FALSE,sizeof(sf::Vector3f), (GLvoid*) 0));
                            glCheck(glDisableVertexAttribArray(0));
                            glCheck(glDisableVertexAttribArray(1));
                            glCheck(glDisableVertexAttribArray(2));
                            glCheck(glDisableVertexAttribArray(3));
                            glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));

                            /*va_list args;
                            va_start(args, n);
                            for (unsigned int i = 0; i < n; i++) {
                                unsigned int vboMatrices = va_arg(args, unsigned int);
                                for (unsigned int j = 0; j < 4; j++) {
                                    glCheck(glEnableVertexAttribArray(i * 4 + j + 3));
                                    glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboMatrices));
                                    glCheck(glVertexAttribPointer(i * 4 + j + 3, 4, GL_FLOAT, GL_FALSE, sizeof(math::Matrix4f),
                                                            (const GLvoid*)(sizeof(GLfloat) * i * 4)));
                                    glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
                                    glCheck(glVertexAttribDivisor(i * 4 + j + 3, 1));
                                    glCheck(glDisableVertexAttribArray(i * 4 + j + 3));
                                }
                            }
                            va_end(args);*/
                            if (vboMatrix1 != 0) {
                                for (unsigned int i = 0; i < 4; i++) {
                                    glCheck(glEnableVertexAttribArray(i + 4));
                                    glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboMatrix1));
                                    glCheck(glVertexAttribPointer(i + 4, 4, GL_FLOAT, GL_FALSE, sizeof(math::Matrix4f),
                                                            (const GLvoid*)(sizeof(GLfloat) * i * 4)));
                                    glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
                                    glCheck(glVertexAttribDivisor(i + 4, 1));
                                    glCheck(glDisableVertexAttribArray(i + 4));
                                }
                            }
                            if (vboMatrix2 != 0) {
                                for (unsigned int i = 0; i < 4; i++) {
                                    glCheck(glEnableVertexAttribArray(i + 8));
                                    glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboMatrix2));
                                    glCheck(glVertexAttribPointer(i + 8, 4, GL_FLOAT, GL_FALSE, sizeof(math::Matrix4f),
                                                            (const GLvoid*)(sizeof(GLfloat) * i * 4)));
                                    glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
                                    glCheck(glVertexAttribDivisor(i + 8, 1));
                                    glCheck(glDisableVertexAttribArray(i + 8));
                                }
                            }
                        }
                        m_cache.lastVboBuffer = &vertexBuffer;

                    }
                    if (m_versionMajor > 3 || m_versionMajor == 3 && m_versionMinor >= 3) {
                        glCheck(glEnableVertexAttribArray(0));
                        glCheck(glEnableVertexAttribArray(1));
                        glCheck(glEnableVertexAttribArray(2));
                        glCheck(glEnableVertexAttribArray(3));
                        if (vboMatrix1 != 0) {
                            for (unsigned int i = 0; i < 4 ; i++) {
                                glCheck(glEnableVertexAttribArray(4 + i));
                            }
                        }
                        if (vboMatrix2 != 0) {
                            for (unsigned int i = 0; i < 4 ; i++) {
                                glCheck(glEnableVertexAttribArray(8 + i));
                            }
                        }
                        static const GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES,
                                                           GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS};
                        GLenum mode = modes[type];
                        glCheck(glBindFramebuffer(GL_FRAMEBUFFER, m_framebufferId));
                        glCheck(glDrawArraysInstanced(mode,start,nb,nbInstances));
                        glCheck(glDisableVertexAttribArray(0));
                        glCheck(glDisableVertexAttribArray(1));
                        glCheck(glDisableVertexAttribArray(2));
                        glCheck(glDisableVertexAttribArray(3));
                        if (vboMatrix1 != 0) {
                            for (unsigned int i = 0; i < 4 ; i++) {
                                glCheck(glDisableVertexAttribArray(4 + i));
                            }
                        }
                        if (vboMatrix2 != 0) {
                            for (unsigned int i = 0; i < 4 ; i++) {
                                glCheck(glDisableVertexAttribArray(8 + i));
                            }
                        }
                        glCheck(glBindVertexArray(0));

                    }
                }
            }

Sometimes the normal is null in this shader :

    const std::string buildFramebufferShader = R"(#version 460
                                                                    in vec4 frontColor;
                                                                    in vec3 normal;
                                                                    in vec3 pos;
                                                                    uniform vec3 cameraPos;
                                                                    uniform samplerCube sceneBox;
                                                                    uniform sampler2D depthBuffer;
                                                                    uniform vec3 resolution;
                                                                    layout (location = 0) out vec4 fColor;
                                                                    void main () {
                                                                        vec2 position = (gl_FragCoord.xy / resolution.xy);
                                                                        vec4 depth = texture2D(depthBuffer, position);
                                                                        float ratio = 1.00 / 1.33;
                                                                        vec3 i = (pos - cameraPos);
                                                                        vec3 r = refract (i, normalize(normal), ratio);
                                                                        vec3 n = normalize(normal);
                                                                        r = normalize(r);
                                                                        if (depth.z > 0) {
                                                                            fColor = texture(sceneBox, r) * (1 - depth.a);
                                                                        } else {
                                                                            fColor = texture(sceneBox, r);
                                                                        }
                                                                    }

But when I don’t do instanced rendering it’s working fine.
With instanced rendering I draw only the four first vertices and I pass the four first normals so I’ve a question should I pass each vertices normals or only the four first normals ?
Will opengl instanciate the normals like the others attributes (the colors and the texcoords) or not ?
And I use two VBO, one for vertices position, color and tex coords and one for the normals.

When I read this the normal should be instanced like other vertices attributes but it deosn’t seems to be always the case.

Ok! I’ve found the problem it was here : if (n-1 <= 0) in the function which compute normals.
n is an unsigned int so it if n = 0, n-1 is invalid. I corrected it by if (n==0)

SOLVED