3D extension points for shaders + Hello


#1

Greets,

I am really liking Juce after evaluating several other native abstraction frameworks. To dig in and get to know a few of the internals of Juce I converted the OpenGL demo (cube rendering part) to 2.x / shaders as a standalone demo. To accomplish this I had to modify a few Juce internal files to add extension points for handling matrix uniforms. I’ll include the modified code below and it would be fantastic if this can be added to the master branch.

I created some nice abstractions around handling shaders w/ Juce including auto-parsing shader code to dynamically build a uniform and attribute map and with some generic forwarding methods this makes working with shaders easier. IE no need to create a custom builder mechanism or specific methods to alter uniform parameters like the shaders internal to Juce. I needed to include a more comprehensive math library for vector / matrix manipulation. With my shader abstraction there is a matrix stack for model/view & projection matrices too which is convenient and it auto updates uniform variables while pushing /popping the stack. I included a slightly modified version of the vmath library http://bartipan.net/vmath/ as it has all the requisite functions for ortho / perspective transforms and is more comprehensive in general. Then rewrote Draggable3DOrientation to use this library and modified the demo code.

I have all of this broken out into 3 additional Juce modules w/ a separate namespace and demo project. I’d like to share this code as it may be a quick path to getting the official Juce demo updated (I think I saw a forum post asking if anyone would like to take a stab at it) along with some nice utility classes for shader management. I suppose the only catch is that I have to clear this with my current employer (Huawei) as things go.

I’ll next be integrating Assimp as a module and a custom renderer as a module before proceeding with additional custom engine / renderer work. I must say I definitely like Introjucer and the module system as it is convenient.

Some notes on getting things to work with Android. I had to call “setOpaque(true)” for the GL Juce component for it to display and I believe this is noted in another post. I also had to change triggerRepaint in juce_OpenGLContext.cpp to get repaints to occur; the code is below. The repaint rate is really slow on Android as things go and I haven’t had time to debug it.

So here are the modifications for 3D shader support; essentially adding extensions for matrix uniforms.

juce_OpenGLExtensions.h at line ~88:
    USE_FUNCTION (glUniformMatrix2fv,       void, (GLint p1, GLsizei p2, GLboolean p3, const GLfloat* p4), (p1, p2, p3, p4))\
    USE_FUNCTION (glUniformMatrix3fv,       void, (GLint p1, GLsizei p2, GLboolean p3, const GLfloat* p4), (p1, p2, p3, p4))\
    USE_FUNCTION (glUniformMatrix4fv,       void, (GLint p1, GLsizei p2, GLboolean p3, const GLfloat* p4), (p1, p2, p3, p4))

----------

juce_OpenGLShaderProgram.cpp at line ~131:

void OpenGLShaderProgram::Uniform::setMatrix2 (const GLfloat* values, GLint count, GLboolean transpose) const noexcept { context.extensions.glUniformMatrix2fv (uniformID, count, transpose, values); }
void OpenGLShaderProgram::Uniform::setMatrix3 (const GLfloat* values, GLint count, GLboolean transpose) const noexcept { context.extensions.glUniformMatrix3fv (uniformID, count, transpose, values); }
void OpenGLShaderProgram::Uniform::setMatrix4 (const GLfloat* values, GLint count, GLboolean transpose) const noexcept { context.extensions.glUniformMatrix4fv (uniformID, count, transpose, values); }

----------

juce_OpenGLShaderProgram.h at line ~108:
        /** Sets a 2x2 matrix float uniform. */
        void setMatrix2 (const GLfloat* values, GLint count, GLboolean transpose) const noexcept;
        /** Sets a 3x3 matrix float uniform. */
        void setMatrix3 (const GLfloat* values, GLint count, GLboolean transpose) const noexcept;
        /** Sets a 4x4 matrix float uniform. */
        void setMatrix4 (const GLfloat* values, GLint count, GLboolean transpose) const noexcept;

And here is what I had to do to get GL repainting to work on Android:

juce_OpenGLContext.cpp at line 567:
void OpenGLContext::triggerRepaint()
{
    CachedImage* currentContext;

    #if JUCE_ANDROID
        NativeContext* const nc = NativeContext::getActiveContext();
        if (nc == nullptr)
            return;
    
        currentContext = CachedImage::get (nc->component);
    #else
        currentContext = dynamic_cast <CachedImage*> (Thread::getCurrentThread());
    #endif
    
    if (currentContext != nullptr)
    {
        currentContext->triggerRepaint();
        currentContext->component.repaint();
    }
}

I’m really interested in getting the Juce / Android support up to the level that the iOS and desktop performance currently is at, so I’d be glad to learn if anyone is actively looking into the GL Android issues. Jules, and co. let me know if there is interest in sharing this essential code and I’ll try and see if I can get it cleared by my employer.

Regards…


#2

Welcome!


#3

Welcome! Glad you like the library, and thanks! No problem at all adding those matrix operations, I’ll do that right away.

(Hmm, not sure what I must have been smoking when I wrote that triggerRepaint() method… in fact there’s already a getCachedImage() method to return that pointer: thanks for the heads-up on that!)


#4

Did you do such thing ? I would be very interested if that is the case :slight_smile: