# OpenGL Context is not active

**URL:** <https://forum.juce.com/t/opengl-context-is-not-active/26758>\
**Category:** General JUCE discussion\
**Created:** [March 12, 2018, 3:59am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758 "2018-03-12T03:59:13Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![luisvaldivia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@luisvaldivia](https://forum.juce.com/u/luisvaldivia)\
**Post date:** [March 12, 2018, 3:59am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/1 "2018-03-12T03:59:13Z")

</div>

I’m trying to do my first OpenGL Programm with JUCE. The openGLContext is not active, for this reason it exits when I come into the render() method. I don’t exactly how I have to activate the OpenGL context, my shaders are right, they are very easy. I’m working with core profile 3.3. The Code is the following:

```auto
class CursorGL : public OpenGLAppComponent {
public:
    CursorGL(std::shared_ptr<coord> _coords, glm::mat4& _projection, glm::mat4& _model) {              
        coords = _coords->shared_from_this();
        setSize (600, 300);
        setVisible(true);
        position.x = coords->x1;
        position.y = coords->y1;
        target.x = coords->x2;
        target.y = coords->y2;
        thickness = 75.f;
        projection = _projection;
        model = _model;
        coordTemp = coords->x1;        
        openGLContext.makeActive();
        openGLContext.setMultisamplingEnabled(true);
        if(!openGLContext.isActive())
            std::cout<<"Could not activate OpenGl Context:"<<openGLContext.isActive()<<std::endl;
    }
    ~CursorGL() {        
        shutdownOpenGL();
    }
    void initialise() override {        
        GLfloat colors[] = {0.5f, 0.5f, 0.5f, 0.5f};
        //openGLContext.setOpenGLVersionRequired(openGLContext.openGL3_2);
        createShader();        
        openGLContext.extensions.glUseProgram(shaderProgram);
        glViewport(0,0, 300, 600);
         openGLContext.extensions.glUniformMatrix4fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
        openGLContext.extensions.glUniformMatrix4fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
        openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "position"), 1, glm::value_ptr(position)); openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "target"), 1, glm::value_ptr(target));        

   openGLContext.extensions.glUniform1f(openGLContext.extensions.glGetUniformLocation(shaderProgram, "thickness"), thickness);        
        openGLContext.extensions.glGenBuffers(1, &VBO);
        openGLContext.extensions.glGenVertexArrays(1, &VAO);
        openGLContext.extensions.glBindVertexArray(VAO);
        openGLContext.extensions.glBindBuffer(GL_ARRAY_BUFFER, VBO);
        openGLContext.extensions.glBufferData(GL_ARRAY_BUFFER, sizeof(colors), &colors, GL_STATIC_DRAW);
        openGLContext.extensions.glEnableVertexAttribArray(0);
        openGLContext.extensions.glVertexAttribPointer(0,4, GL_FLOAT, GL_FALSE, 4* sizeof(GL_FLOAT), 0);
        openGLContext.extensions.glBindVertexArray(0);
        openGLContext.extensions.glDeleteBuffers(1, &VBO);
    }
    void shutdown() override {        
        openGLContext.extensions.glUseProgram(0);              
        openGLContext.extensions.glDeleteShader(fragmentShader);
        openGLContext.extensions.glDeleteShader(geomShader);
        openGLContext.extensions.glDeleteShader(vertexShader);
        openGLContext.extensions.glDeleteProgram(shaderProgram);
        openGLContext.extensions.glDeleteVertexArrays(1, &VAO);
        
    }
    void render() override {
        //openGLContext.makeActive();
        jassert (OpenGLHelpers::isContextActive());
        //OpenGLHelpers::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        OpenGLHelpers::clear (juce::Colours::white);
        glEnable (GL_BLEND);
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        if(coords->isPlaying && coordTemp != coords->x1) {            
            openGLContext.extensions.glUseProgram(shaderProgram);
            coordTemp = coords->x1;
            position.x = coords->x1;
            position.y = coords->y1;
            target.x = coords->x2;
            target.y = coords->y2;
            openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "position"), 1, glm::value_ptr(position));
            openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "target"), 1, glm::value_ptr(target));
        }
        openGLContext.extensions.glBindVertexArray(VAO);
        glDrawArrays(GL_POINTS, 0, 1);
        openGLContext.extensions.glBindVertexArray(0);
    }
    
    void paint(Graphics& g) override {        
    }
    
    void resized() override {       
    }
    void createShader() {
         
        vertexShaderSource = "#version 330 core\n"
        "layout (location = 0) in vec4 color\n"
        "uniform vec2 position\n"
        "out VS_OUT {\n"
        " vec2 pos;\n"
        " vec4 color;\n"
        "} vs_out;\n"
        "void main() {\n"
        " vs_out.pos = position;\n"
        " vs_out.color = color;\n"
        "}\n";
        fragmentShaderSource = "#version 330 core\n"
        "in vec4 fColor;\n"
        "out vec4 outColor;\n"
        "void main() {\n"
        " outColor = fColor;\n"
        "}\n";
        geomShaderSource = "#version 330 core\n"
        "uniform float thickness;\n"
        "uniform vec2 win_scale;\n"
        "in VS_OUT {\n"
        " vec2 pos;\n"
        " vec4 color;\n"
        "} gs_in[]\n"
        "uniform mat4 projection;\n"
        "uniform mat4 model;\n"
        "out vec4 fColor\n"
        "vec2 screen_space(vec4 vertex) {\n"
        " return vec2(vertex.xy/vertex.w) * win_scale;\n"
        "}\n"
        "void main() {\n"
        " fColor = gs_in[0].color;\n"
        " vec2 p0 = gs_in[0].pos;\n"
        " vec2 p1 = target;\n"
        " vec2 v0 = normalize(p1-p0);\n"
        " vec2 n0 = vec2(-v0.y, v0.x);\n"
        " gl_Position = projection * model * vec4(p0 - thickness * n0, 0.0, 1.0);\n"
        " EmitVertex();\n"
        " gl_Position = projection * model * vec4(p0 + thickness * n0, 0.0, 1.0);\n"
        " EmitVertex();\n"
        " gl_Position = projection * model * vec4(p1 - thickness * n0, 0.0, 1.0);\n"
        " EmitVertex();\n"
        " gl_Position = projection * model * vec4(p1 + thickness * n0, 0.0, 1.0);\n"
        " EmitVertex();\n"
        " EndPrimitive();\n"
        "}\n";      
        vertexShader = openGLContext.extensions.glCreateShader(GL_VERTEX_SHADER);
        openGLContext.extensions.glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
        openGLContext.extensions.glCompileShader(vertexShader);
        if (!checkShaderCompileStatus(vertexShader)) {
            std::cout<< "Vertex shader did not compile"<<std::endl;
            //exit(EXIT_FAILURE);
        }
        fragmentShader = openGLContext.extensions.glCreateShader(GL_FRAGMENT_SHADER);
        openGLContext.extensions.glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        openGLContext.extensions.glCompileShader(fragmentShader);
        if (!checkShaderCompileStatus(fragmentShader)) {
            std::cout<< "Fragment shader did not compile"<<std::endl;            
        }
        
        geomShader = openGLContext.extensions.glCreateShader(GL_GEOMETRY_SHADER);
        openGLContext.extensions.glShaderSource(geomShader, 1, &geomShaderSource, NULL);
        openGLContext.extensions.glCompileShader(geomShader);
        if (!checkShaderCompileStatus(geomShader)) {
            std::cout<< "Geometry shader did not compile"<<std::endl;
            //exit(EXIT_FAILURE);
        }
        shaderProgram = openGLContext.extensions.glCreateProgram();
        openGLContext.extensions.glAttachShader(shaderProgram, vertexShader);
        openGLContext.extensions.glAttachShader(shaderProgram, fragmentShader);
        openGLContext.extensions.glAttachShader(shaderProgram, geomShader);
        openGLContext.extensions.glLinkProgram(shaderProgram);
        if (!checkShaderProgramLinkStatus(shaderProgram)) {
            std::cout<< "Shader did not link"<<std::endl;
            //exit(EXIT_FAILURE);
        }
        openGLContext.extensions.glUseProgram(shaderProgram);       
    }
    bool checkShaderCompileStatus(GLuint shaderID) {
        GLint status;
        openGLContext.extensions.glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status);
        if(status == GL_FALSE) {
            GLint length;
            openGLContext.extensions.glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length);
            GLchar* log = new char[length + 1];
            openGLContext.extensions.glGetShaderInfoLog(shaderID, length, &length, &log[0]);
            std::cout<<"Error by shader compilation:"<<log;
            return false;
        }
        return true;
    }
    bool checkShaderProgramLinkStatus(GLuint programID){
        GLint status;
        openGLContext.extensions.glGetProgramiv(programID, GL_LINK_STATUS, &status);
        if(status == GL_FALSE) {
            GLint length;
            openGLContext.extensions.glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length);
            GLchar* log = new char[length + 1];
            openGLContext.extensions.glGetProgramInfoLog(programID, length, &length, &log[0]);
            std::cout<<"Error by shader linking:"<<log;
            return false;
        }
        return true;
    }
    
private:
    const char* vertexShaderSource;
    const char* fragmentShaderSource;
    const char* geomShaderSource;    
    std::shared_ptr<coord> coords;
    juce::String statusText;
    glm::mat4 projection, model;
    glm::vec2 position, target;
    float coordTemp;
    GLfloat thickness;
    GLuint VBO, VAO;
    GLuint shaderProgram;
    GLuint vertexShader, fragmentShader, geomShader;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CursorGL)
};

```

I could see Juce don’t have the extension

```auto
glUniform2fv

```

available, only glUniform1fv.  
I’m instantiating and stoping the class inside another, in the following way:

```auto
void JuceDevice::startCursorGL() {
    cursorGL = std::make_unique<CursorGL>(coords,projection, model);    
    cursorGL->initialise();
    cursorGL->render();
}

void JuceDevice::stopCursorGL() {
    cursorGL->shutdown();
    cursorGL.reset();
}

```

The Programm exits when I call the method render(), at the assertion jassert (OpenGLHelpers::isContextActive()); , how should I activate the OpenGL Context?  
Regards

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [March 12, 2018, 8:26am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/2 "2018-03-12T08:26:47Z")

</div>

You must never call `initialise`, `shutdown` or `render` yourself. These methods will be called by JUCE on an active OpenGL context.

As you are using an `OpenGLAppComponent`, `initialise`, `shutdown` and `render` will be called automatically. You can also force a render call with [`OpenGLContext::triggerRepaint`](https://juce.com/doc/classOpenGLContext#acc0fc11c02ebbe4af1cc234eb5d8b84a). If you want to continuously call `repaint` then you can call `OpenGLContext:: setContinuousRepainting (true)` and adjust the swap interval with `OpenGLContext::setSwapInterval`.

---

<div class="post-metadata">

**Author:** ![luisvaldivia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@luisvaldivia](https://forum.juce.com/u/luisvaldivia)\
**Post date:** [March 13, 2018, 4:34am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/3 "2018-03-13T04:34:18Z")

</div>

Thanks for your answer. I added setContinuousRepainting(true) openGLContext.setSwapInterval(1) and to the Class Constructor:

```auto
CursorGL(std::shared_ptr<coord> _coords, glm::mat4& _projection, glm::mat4& _model) {
        coords = _coords->shared_from_this();
        setSize (600, 300);
        setVisible(true);
        openGLContext.setContinuousRepainting(true);
        openGLContext.setSwapInterval(1);
        position.x = coords->x1;
        position.y = coords->y1;
        target.x = coords->x2;
        target.y = coords->y2;
        thickness = 75.f;
        projection = _projection;
        model = _model;
        coordTemp = coords->x1;
        openGLContext.setMultisamplingEnabled(true);
        if(!openGLContext.isActive())
            std::cout<<"OpenGl Contextes is not active:"<<openGLContext.isActive()<<std::endl;
    }

```

But the OpenGL context is still not active, initialize, render and shutdown are not called. I can see it over the if branch at the end of Constructor.  
If I call `OpenGLContext:: setContinuousRepainting (true)` in Constructor or in another place, I become always an error.  
These class, CursorGL is not the “MainContentComponent” class, CursorGL is instantiated (created) inside another class called “JuceDevice”. Again, this is not the MainContentComponent, JuceDevice is instantiated inside the MainContentComponent class, called “GuidoComponent”, this class is not an OpenGLAppComponent. I think this could be the problem, I’m painting the others elements with Juce:Graphics, I want to add some animations with OpenGL to it. There is another way to create an OpenGL context and activate it for my self, other should I Instantiate the class GLCursor inside the MainComponent class, or should this class (GLCursor) be inherited from the MainComponent class in order to activate the OpenGL context?

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [March 13, 2018, 8:20am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/4 "2018-03-13T08:20:50Z")

</div>

The `OpenGLContext` will only ever be active within the `initialise`, `shutdown` or `render` calls. This means that if you call your `CursorGL` constructor outside one of these calls then the context will not be active.

---

<div class="post-metadata">

**Author:** ![luisvaldivia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@luisvaldivia](https://forum.juce.com/u/luisvaldivia)\
**Post date:** [March 13, 2018, 4:20pm UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/5 "2018-03-13T16:20:30Z")

</div>

@fabian I don’t understand what are you meaning. The class CursorGL is inherited from OpenGLAppComponent, as you can see before: `class CursorGL : public OpenGLAppComponent` therefore initialize(), render() and shutdown are methods from the class CursorGL. Did you men I should call the CursorGL constructor inside their own methods ?:

```auto
void CursorGL::initialise() {
          CursorGL(...) //class constructor

```

That looks very strange. The compiler don’t allows this kind of declarations.  
That would be a recursive call, if I do it in this way that could lead to an infinite recursion.  
Regards

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [March 13, 2018, 5:46pm UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/6 "2018-03-13T17:46:43Z")

</div>

You are expecting the context to be active in your `CursorGL` constructor but, as I said, the context is only active in the `initialize`, `render` and `shutdown` callbacks.

---

<div class="post-metadata">

**Author:** ![luisvaldivia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@luisvaldivia](https://forum.juce.com/u/luisvaldivia)\
**Post date:** [March 14, 2018, 3:53am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/7 "2018-03-14T03:53:13Z")

</div>

@fabian thanks again for your reply. I made the class CursorGL a child from the class GuidoComponent: `class CursorGL : public OpenGLAppComponent, GuidoComponent { ...more` and I instantiated it inside GuidoComponent in the following way:

```auto
//Creation
void GuidoComponent::initializeCursor() {
    computeCoordinates(LineCoordinates, pn);
    manager = std::make_unique<PdManager>(coords, LineCoordinates);
    coordTemp = coords->x1;
    manager->startMetronome();
    glm::mat4 projection = gDevice.getProjectionMatrix();
    glm::mat4 model = gDevice.getModelMatrix();
    cursorGL = std::make_shared<CursorGL>(coords, projection, model);    
    this->addAndMakeVisible((juce::OpenGLAppComponent*)cursorGL.get(), -1);    
    startTimer(5);
    //repaint();
}
//destruction
bool GuidoComponent::deleteCursor() {
    if(manager) {
        stopTimer();
        manager->stopMetronome();        
        this->removeChildComponent((juce::OpenGLAppComponent*)cursorGL.get());        
        cursorGL.reset();        
        manager.reset();        
    }
    repaint();
    return true;
}

```

Now is the OpenGL context created and activated. There is still a problem, apparently Juce doesn’t support the `#version 330 core` because i become the following message from the method `checkShaderCompileStatus(GLuint shaderID)`:

```auto
Error by shader compilation:ERROR: 0:1: '' : version '330' is not supported 
ERROR: 0:1: '' : syntax error: #version ...more
Vertex shader did not compile

```

The same by the fragment shader and geometry shader, There is a way to use the core profile 3.3 or higher in Juce? Are geometry shaders supported?  
Regards.

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [March 14, 2018, 11:12am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/8 "2018-03-14T11:12:20Z")

</div>

OpenGL 3.2 is the newest supported by JUCE currently. And we don’t support geometry shaders.

---

<div class="post-metadata">

**Author:** ![luisvaldivia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@luisvaldivia](https://forum.juce.com/u/luisvaldivia)\
**Post date:** [March 15, 2018, 12:44am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/9 "2018-03-15T00:44:50Z")

</div>

@fabian That’s a bit old (2009). Actually OpenGL 3.2 (version 150) supports Geometry Shaders. Are you planing to adding support for modern OpenGL (Geometry Shaders, Tessellation) or Vulkan Support in the near Future? Vulkan supports now OSX and iOS (from iOS 9) too. Vulkan’s performance is better as OpenGL. Geometry Shaders and Tessellation are very useful specially working in 3D.  
Regards

---

<div class="post-metadata">

**Author:** ![luisvaldivia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@luisvaldivia](https://forum.juce.com/u/luisvaldivia)\
**Post date:** [March 26, 2018, 3:58am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/10 "2018-03-26T03:58:27Z")

</div>

@fabian I changed the shaders in order to work with OpenGL 3.2. The modified code is placed under. First I want to do only a very easy thing, to draw a rectangle on the screen. The code compiles, but when I instantiate (create) the OpenGL class I become the following error: `Main Thread Checker: UI API called on a background thread: ...more`  
` ***** GL_INVALID_OPERATION at juce_OpenGLContext.cpp : 242 JUCE Assertion failure in juce_opengl.cpp:216`  
or:  
` **** GL_INVALID_ENUM at juce_OpenGLContext.cpp : 242 JUCE Assertion failure in juce_opengl.cpp:216`  
I looked at the file jute\_openGLContext.cpp at the line 242 and 216, but I don’t know exactly what that’s means.  
Another Problem is that Juce initialize a 2.1 Context, I placed this line `openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);` but apparently doesn’t have any effect, I put after in the Code the following line: `std::cout<<"OpenGl Context is active:"<<openGLContext.isActive()<<" Version:"<<glGetString(GL_VERSION)<<", Vendor:"<<glGetString(GL_VENDOR)<<", Renderer:"<<glGetString(GL_RENDERER) <<std::endl;`and I become `Version:2.1` , my graphic cards supports OpenGL 4.1, I have already made Programs working with OpenGL 4.1. How can I enforce the context creation, other why Juce doesn’t creates the right context?  
The actual Code is the following:

```auto
CursorGL::CursorGL(std::shared_ptr<coord> _coords, glm::mat4& _projection, glm::mat4& _model) {
    coords = _coords->shared_from_this();
    setSize (500, 600);    
    //setVisible(true);    
    projection = _projection;
    model = _model;
    coordTemp = coords->x1;
    openGLContext.setMultisamplingEnabled(true);    
}

CursorGL::~CursorGL() {
     shutdownOpenGL();
}

void CursorGL::initialise() {
    openGLContext.makeActive();
    openGLContext.setContinuousRepainting(true);
    openGLContext.setSwapInterval(1); openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);
    
    if(!openGLContext.isActive())
        std::cout<<"OpenGl Context is not active:"<<openGLContext.isActive()<<std::endl;
    else {
        openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);
        std::cout<<"OpenGl Context is active:"<<openGLContext.isActive()<<" Version:"<<glGetString(GL_VERSION)<<", Vendor:"<<glGetString(GL_VENDOR)<<", Renderer:"<<glGetString(GL_RENDERER) <<std::endl;
    }
    GLfloat vertices[] = {
        // positions //colors //alpha
        340.0f, 340.0f, 0.15f, 0.75f, 0.55f, 0.5f, // top right
        340.0f, 220.0f, 0.15f, 0.75f, 0.55f, 0.5f, // bottom right
        220.0f, 220.0f, 0.15f, 0.75f, 0.55f, 0.5f, // bottom left
        220.0f, 340.0f, 0.15f, 0.75f, 0.55f, 0.5f // top left
    };
    GLuint elements[] = {
        0, 1, 3,
        1, 2, 3
    };
    //openGLContext.setOpenGLVersionRequired(openGLContext.openGL3_2);
    createShader();
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_MULTISAMPLE);    
    openGLContext.extensions.glUseProgram(shaderProgram);
    glViewport(0,0, 500, 600);
    openGLContext.extensions.glUniformMatrix4fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
    openGLContext.extensions.glUniformMatrix4fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
    openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "position"), 1, glm::value_ptr(position));     
    openGLContext.extensions.glGenBuffers(1, &VBO);
    openGLContext.extensions.glGenBuffers(1, &EBO);
    openGLContext.extensions.glGenVertexArrays(1, &VAO);
    openGLContext.extensions.glBindVertexArray(VAO);
    openGLContext.extensions.glBindBuffer(GL_ARRAY_BUFFER, VBO);
    openGLContext.extensions.glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
    openGLContext.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    openGLContext.extensions.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
    GLint posAttrib = openGLContext.extensions.glGetAttribLocation(shaderProgram, "aPos");
    openGLContext.extensions.glEnableVertexAttribArray(posAttrib);
    openGLContext.extensions.glVertexAttribPointer(posAttrib,2, GL_FLOAT, GL_FALSE, 6* sizeof(GL_FLOAT), (void*)0);
    GLint colAttrib = glGetAttribLocation(shaderProgram, "aColor");
    openGLContext.extensions.glEnableVertexAttribArray(colAttrib);
    openGLContext.extensions.glVertexAttribPointer(colAttrib,4, GL_FLOAT, GL_FALSE, 6* sizeof(GL_FLOAT), (void*)(2 * sizeof(float)));
    
    openGLContext.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
    openGLContext.extensions.glBindVertexArray(0);
    
}

void CursorGL::render() {
    std::cout<<"CursorGl render"<<std::endl;
    //openGLContext.makeActive();
    jassert (OpenGLHelpers::isContextActive());
    //OpenGLHelpers::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    OpenGLHelpers::clear (juce::Colours::white);
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    if(coords->isPlaying && coordTemp != coords->x1) {       
        openGLContext.extensions.glUseProgram(shaderProgram);
        coordTemp = coords->x1;
        
    }
    openGLContext.extensions.glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);    
    //openGLContext.extensions.glBindVertexArray(0);
    
}

void CursorGL::shutdown() {
    openGLContext.extensions.glUseProgram(0);
    openGLContext.extensions.glDeleteShader(fragmentShader);
    openGLContext.extensions.glDeleteShader(geomShader);
    openGLContext.extensions.glDeleteShader(vertexShader);
    openGLContext.extensions.glDeleteProgram(shaderProgram);
    openGLContext.extensions.glDeleteVertexArrays(1, &VAO);
    openGLContext.extensions.glDeleteBuffers(1, &VBO);
    openGLContext.extensions.glDeleteBuffers(1, &EBO);
}

void CursorGL::createShader() {   
    vertexShaderSource = "attribute vec2 aPos;\n"
    "attribute vec4 aColor;\n"
    "uniform mat4 projection;\n"
    "uniform mat4 model;\n"
    "varying vec4 ourColor;\n"
    "void main() {\n"
    " gl_Position = projection * model * vec4(aPos, 0.0, 1.0);\n"
    " ourColor = aColor;\n"
    "}\n";
    fragmentShaderSource = "varying vec4 ourColor;\n"
    "//varying vec4 FragColor;\n"
    "void main() {\n"
    " gl_FragColor = ourColor;\n"
    "}\n";    
    openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);
    vertexShader = openGLContext.extensions.glCreateShader(GL_VERTEX_SHADER);
    openGLContext.extensions.glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    openGLContext.extensions.glCompileShader(vertexShader);
    if (!checkShaderCompileStatus(vertexShader)) {
        std::cout<< "Vertex shader did not compile"<<std::endl;
        //exit(EXIT_FAILURE);
    }
    fragmentShader = openGLContext.extensions.glCreateShader(GL_FRAGMENT_SHADER);
    openGLContext.extensions.glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    openGLContext.extensions.glCompileShader(fragmentShader);
    if (!checkShaderCompileStatus(fragmentShader)) {
        std::cout<< "Fragment shader did not compile"<<std::endl;
        //exit(EXIT_FAILURE);
    }
    shaderProgram = openGLContext.extensions.glCreateProgram();
    openGLContext.extensions.glAttachShader(shaderProgram, vertexShader);
    openGLContext.extensions.glAttachShader(shaderProgram, fragmentShader);
    //openGLContext.extensions.glAttachShader(shaderProgram, geomShader);
    //openGLContext.extensions.glBindFragDataLocation(shaderProgram, 0, "outColor");
    openGLContext.extensions.glLinkProgram(shaderProgram);
    if (!checkShaderProgramLinkStatus(shaderProgram)) {
        std::cout<< "Shader did not link"<<std::endl;
        //exit(EXIT_FAILURE);
    }
    openGLContext.extensions.glUseProgram(shaderProgram);
    
    std::cout<<"CursorGL, createShader isContextActive:"<<openGLContext.isActive()<<", GLSL Version:"<<glGetString ( GL_SHADING_LANGUAGE_VERSION )<<std::endl;
}

bool CursorGL::checkShaderCompileStatus(GLuint shaderID) {
    GLint status;
    openGLContext.extensions.glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status);
    if(status == GL_FALSE) {
        GLint length;
        openGLContext.extensions.glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length);
        GLchar* log = new char[length + 1];
        openGLContext.extensions.glGetShaderInfoLog(shaderID, length, &length, &log[0]);
        std::cout<<"Error by shader compilation:"<<log;
        return false;
    }
    return true;
}

bool CursorGL::checkShaderProgramLinkStatus(GLuint programID){
    GLint status;
    openGLContext.extensions.glGetProgramiv(programID, GL_LINK_STATUS, &status);
    if(status == GL_FALSE) {
        GLint length;
        openGLContext.extensions.glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length);
        GLchar* log = new char[length + 1];
        openGLContext.extensions.glGetProgramInfoLog(programID, length, &length, &log[0]);
        std::cout<<"Error by shader linking:"<<log;
        return false;
    }
    return true;
}

```

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [March 26, 2018, 8:51pm UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/11 "2018-03-26T20:51:48Z")

</div>

Again, as I’ve stated above, you can only use opengl calls on the open gl thread. This means you can only call them on the following OpenGLAppComponent callbacks:

initialise, shutdown and render.

Who is invoking your CursorGL::initialize?

---

<div class="post-metadata">

**Author:** ![luisvaldivia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@luisvaldivia](https://forum.juce.com/u/luisvaldivia)\
**Post date:** [March 27, 2018, 2:15am UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/12 "2018-03-27T02:15:07Z")

</div>

@fabian CursorGL::initialize is not invoked at all. I thought I don’t have to invoke it. I declared the class inside another called GuidoComponent in the following way:

```auto
void GuidoComponent::initializeCursor() {
    //...some code ...
    glm::mat4 projection = gDevice.getProjectionMatrix();
    glm::mat4 model = gDevice.getModelMatrix();
    cursorGL = std::make_shared<CursorGL>(coords, projection, model);    
    this->addAndMakeVisible(cursorGL.get(), -1);
    //more code ...
    startTimer(5);
    repaint();
}

```

The class GuidoComponent is a child of Component and Timer.  
That’s no the actual problem. I placed a `glGetError()` call inside the method initialize() and I become error messages at the following places:

```auto
openGLContext.extensions.glGenVertexArrays(1, &VAO);
    if((err = glGetError()) != GL_NO_ERROR) {
        std::cerr << "OpenGL error after genVAO: " << err << std::endl;
    }
    openGLContext.extensions.glBindVertexArray(VAO);
    if((err = glGetError()) != GL_NO_ERROR) {
        std::cerr << "OpenGL error after bindVAO: " << err << std::endl;
    }

```

The error 1282 GL\_INVALID\_OPERATION appears there, because glGenVertexArrays and glBindVertexArray are available since OpenGL 3, and Juce is creating an OpenGL 2.1 context. Could you please tell me how I can create or enforce at least a OpenGL 3 context? Or why is not possible to do that in Juce? As I say, I have already used OpenGL 3.3, 4.0 and 4.1 on my Computer. OpenGL 2.1 is really very old.  
The call `openGLContext.setOpenGLVersionRequired(juce::OpenGLContext::openGL3_2);` apparently doesn’t have any effect. Where should be placed it, inside render()?

---

<div class="post-metadata">

**Author:** ![serena1](https://avatars.discourse-cdn.com/v4/letter/s/ce73a5/32.png) [@serena1](https://forum.juce.com/u/serena1)\
**Post date:** [May 12, 2020, 5:54pm UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/13 "2020-05-12T17:54:51Z")

</div>

My friend told me to install [open al](https://techtargetplus.com/what-is-openal-program) with open gl. But I want to what is the difference between these two. Can anyone tell me this?

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [May 12, 2020, 5:58pm UTC](https://forum.juce.com/t/opengl-context-is-not-active/26758/14 "2020-05-12T17:58:50Z")

</div>

That is a completely different topic, but to give you an answer:  
[OpenAL](http://openal.org) is a library for spatial audio. It is completely separate from OpenGL, just has a similar syntax like the original OpenGL of the early days.  
Also OpenAL is not directly compatible with juce. At least I am not aware of any bindings.
