OpenGLGraphicsContextCustomShader adding Uniforms

I am modifying the OpenGLDemo2D code in hopes of figuring out how to get uniforms working with OpenGLGraphicsContextCustomShader as follows:

in OpenGL2DShaderDemo::paint(Graphics& g)

        //snip...
        if (shader != nullptr)
        {
            statusLabel.setText (String(), dontSendNotification);
            //@matkatmusic
            auto* prg = shader->getProgram(g.getInternalContext());
            if( prg->getUniformIDFromName("colour1") < 0 )
            {
                //jassertfalse;
            }
            else
            {
                DBG( shader->getFragmentShaderCode() );
                prg->setUniform("colour1", 1.f, 0.f, 0.f, 1.f);
            }
            //end @matkatmusic
            shader->fillRect (g.getInternalContext(), getLocalBounds());
        }

and in static Array<ShaderPreset> OpenGL2DShaderDemo::getPresets() :

            //snip...
            {
                "Simple Gradient",
                
                SHADER_DEMO_HEADER
                "uniform vec4 colour1;\n" //@matkatmusic
                "void main()\n"
                "{\n"
                "   gl_FragColor = colour1;\n"
                "}\n"
            },

This should result in a solid color when the shader is executed, but it ends up looking like this:

is OpenGLGraphicsContextCustomShader broken, in that you can’t set uniforms on it?
calling shader->getProgram(g.getInternalContext())->setUniform("colour1", 1.f, 0.f, 0.f, 1.f); should set the background to a solid red color but it doesn’t.

OpenGLGraphicsContextCustomShader does not support anything that depends on the current state of the context. The problem is that you would have to set the uniform just before the render call of the shader - however, as JUCE handles all the drawing there is no way for you to set the uniforms, textures etc. before the drawing occurs. You’ll have to do all the drawing yourself like in the OpenGLDemo.cpp.

2 Likes

So, should the documentation for the ‘getProgram()’ method be added to reflect this? i.e. if you’re using the OGLGCCustomShader inside of a renderOpenGL() call, you’re fine. but if you’re using it inside a regular paint(g) method, getProgram() won’t really work for setting uniforms etc.

IMHO There is no point in having a custom shader if you can’t send any information to it - like ‘resolution’, or ‘specular’ etc…

1 Like