Specific commit on Juce 7 develop fucks up OpenGL implementation

Hi folks,

i am not using juce:Graphics to paint anything, but my own vertex and fragment shaders. This commit totally fucks up the way things work:

OpenGL: Keep track of previously-attached VAOs and buffers when creating additional GL-backed Graphics contexts f012f8c28 reuk reuk@users.noreply.github.com 8. Jun 2023 at 16:26

In OpenGLShaderProgram::addShader after calling context.extensions.glDeleteShader (shaderID) JUCE_CHECK_OPENGL_ERROR hits an assert saying:

GL_INVALID_OPERATION at /Volumes/DATA/-Development/FA/SDKs-external/JUCE/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp : 97

I am calling OpenGLShaderProgram::addShader when needed on the OpenGL thread, avoiding races.

All the demos only use one pair of shaders, one mesh, one texture etc. at a time.

But usually GUIs are a little more complex and in my case i change shaders on the fly during the renderOpenGL() call according to what is needed. The assert happens on the second of my OpenGL elements, meaning when the second time in one render call addShader is called.

Any idea what that could be?



glDeleteShader cannot raise GL_INVALID_OPERATION, so my guess is that an earlier GL function is failing.

A good starting point would be to add JUCE_CHECK_OPENGL_ERROR after each context.extensions.gl* call in addShader, which will tell us which function call is actually producing the error.

hey reuk, good idea. did that and now it is:

context.extensions.glCreateShader (type);

glCreateShader also cannot emit GL_INVALID_OPERATION, so the error must be happening before addShader is called. By inspecting the call stack, you should be able to work out which functions were called previously - try adding JUCE_CHECK_OPENGL_ERROR there too.

Ok, tried to distribute them wherever possible.

It is now happening in the draw method of the first call, more specifically here glAttributes.enable (openGLContext);

Wait, it is definitely happening here:

openGLContext.extensions.glEnableVertexAttribArray (position->attributeID);

OK, that happens if no VAO is bound at the point of that call. If you’re not using any of JUCE’s graphics helpers, you may need to create and bind your own VAO.

                openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer);
                openGLContext.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

This has been done before successfully.

Before the above mentioned commit everything worked perfectly. After that this assert happened. What has changed?

The assert happens when trying to enable the first attribute. It has an attributeID of 2 though. For what ever reason, although it was created first. Don’t know if that has something to do with it.

Thanks for reporting. I can see that, in the OpenGLDemo, when the OpenGL version is set to 3.2 or above, the teapot no longer shows up, which is a regression.

We’ll have a fix out shortly.



That should be fixed here:


was this issue present in 7.0.5, or is this just a development branch thing?

Working lovely. Thanks.

The regression was introduced after the release of 7.0.5.

1 Like

Hi JUCE team, I’ve also run into an issue seemingly stemming from the f012f8c28 and 17deafb commits.

For context, I’m using an OpenGL compatibility profile. My editor is an OpenGLRenderer, and I directly draw into an attached OpenGLContext using OpenGLRenderer::renderOpenGL() as well as rendering some normal Components using OpenGL, via OpenGLContext::setComponentPaintingEnabled(true).

Prior to the aforementioned commits, the part of my UI rendered with renderOpenGL() looks as expected (grid lines are OpenGL, axis labels and 0dB line are juce::Components):

After the aforementioned commits, the color, placement, and orientation of the renderOpenGL() portion is wrong:

However, if I call OpenGLContext::setComponentPaintingEnabled(false), then my renderOpenGL() portion looks correct, but of course none of my Components show correctly:

Any idea what might be causing this, and what the fix might be? I’m not using shaders or a core profile, just direct OpenGL calls. Reproduced on macOS Ventura (Intel) and Windows 11.


Digging in further, it appears that the removal of this line is what’s causing the issue.

Without that line, the current program is left at the last program used by the Component drawing, and my OpenGL rendering is incorrect. If I set the program back to 0 before running my OpenGL rendering, then everything draws as expected.

My question is, was this removal intentional? I can easily fix the issue by calling glUseProgram(0) at the top of my OpenGL rendering, but I figured I would flag the removal as I could see it causing problems for others.

Thanks for reporting. I think the removal of that line was probably a mistake.

I’ve pushed a change that stores the previously-bound program, if any, and re-binds that program after calling copy texture:

I believe this should fix the issue you were seeing. Please try it out and let us know if you still encounter issues.

Thanks @reuk ! I can confirm this fixes the issue.