Can single shader be used in multiple glfw context?

Hi,

I have 4 rendering contexts to display different views and have single shader for across those views.
So pretty much the everything are shared across views.

Below is my codes, I’ve passed first rendering context to 3 others so that resources can be shared across views.

Each individual works properly but only the last one if I go with multiple rendering contexts.
Am I missing something here?

Thanks,

[Creating glfw Window]

if (viewPort == 0)
    glWindows[viewPort].glfwHandle = glfwCreateWindow(glWindows[viewPort].Width, glWindows[viewPort].Height, glWindows[viewPort].className, NULL, NULL);

else
    glWindows[viewPort].glfwHandle = glfwCreateWindow(glWindows[viewPort].Width, glWindows[viewPort].Height, glWindows[viewPort].className, NULL, glWindows[0].glfwHandle);

[Vertex Shader]

#version 450 core
layout (location = 0) in vec3 aPos;

out vec4 aColor;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform vec4 color;
uniform float size;

void main() {
    // Color
    aColor = color;
    
    // Position
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    gl_PointSize = size;
}

[Fragment Shader]

#version 450 core
in vec4 aColor;
out vec4 FragColor;

void main() {
    FragColor = aColor;
}

[Drawing]

// Clear background
glClearColor(glWindows[viewPort].bgColor.r, glWindows[viewPort].bgColor.g, glWindows[viewPort].bgColor.b, glWindows[viewPort].bgColor.a);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);


glWindows[viewPort].mvMatrix = glm::mat4(1.0f);
glWindows[viewPort].prjMatrix = glm::ortho(-glWindows[viewPort].scale, glWindows[viewPort].scale, -glWindows[viewPort].scale / 2.0f, glWindows[viewPort].scale / 2.0f, 0.1f, 100.0f);
glWindows[viewPort].view = glm::lookAt(glm::vec3(glWindows[viewPort].eye_x, glWindows[viewPort].eye_y, glWindows[viewPort].eye_z), glm::vec3(glWindows[viewPort].center_x, glWindows[viewPort].center_y, glWindows[viewPort].center_z), glm::vec3(glWindows[viewPort].up_x, glWindows[viewPort].up_y, glWindows[viewPort].up_z));

shader.use();
shader.setMat4("projection", glWindows[viewPort].prjMatrix);
shader.setMat4("view", glWindows[viewPort].view);

// Draw cubes
for (int i = 0; i < 3; i++) {
    glWindows[viewPort].mvMatrix = glm::mat4(1.0f);
    glWindows[viewPort].mvMatrix = glm::translate(glWindows[viewPort].mvMatrix, glWindows[viewPort].translation);
    glWindows[viewPort].mvMatrix = glm::scale(glWindows[viewPort].mvMatrix, glWindows[viewPort].scale);

    shader.setMat4("model", glWindows[viewPort].mvMatrix);

    DrawCube(i);
}

[Main]

CreateGLWindow(0);

buildObjects();

LoadShaders();

LoadOpenGLStates();

LoadTextures();

CreateGLWindow(1);
CreateGLWindow(2);
CreateGLWindow(3);

while (IsApplicationActive) {
    for (int i = 0; i < 4; i++) {
        if (!glfwWindowShouldClose(glWindows[0].glfwHandle)) {
            glfwMakeContextCurrent(glWindows[i].glfwHandle);

            DrawScene(i);

            glfwSwapBuffers(glWindows[i].glfwHandle);
            glfwPollEvents();
        }
    }
}

Is the last context (the one which is rendering correctly) the one which was bound during initialisation?

Note that container objects (VAOs, FBOs, transform feedback objects and program pipeline objects) aren’t shared between contexts. So if you’re using any of those object types, you need to create (and initialise) a separate copy for each context.

Also, changes to object state which are made with one context bound aren’t guaranteed to be visible to another context until the next time the object (or a container object which references it) is bound in that context. So if you change an object’s state, you need to rebind it in each context which uses it.

See this and this in the wiki.

Edit: to answer the title question: there is no issue with using a shader program in multiple contexts, particularly for the single-threaded case. For the multi-threaded case, you need to use uniform blocks if you want to be able to change uniform values, as default-block uniforms are part of the program object and not context state, so changing their values affects all contexts using the program.

1 Like

Thanks, I found that I missed initialization of VAOs/FBOs in every drawings on each contexts!!