Hi Roli team !
Thanks a lot for your last Juce 4.3 enhancements.
juce_opengl module seems to not have moved since a long time.
It could be great if Windows platforms users of this module could benefit of the JUCE_OPENGL3 and OpenGLVersion::openGL3_2 modern core context support.
This is already the case on OSX plateforms (juce_OpenGL_osx.h)
Here my juce_OpenGL_win32.h NativeContext class changes proposal to make it possible:
First of all the NativeContext constructor to take those macro and version enum in account:
NativeContext (Component& component,
const OpenGLPixelFormat& pixelFormat,
void* contextToShareWith,
bool /useMultisampling/,
OpenGLVersion version)
: context (nullptr)
{
dummyComponent = new DummyComponent (*this);
createNativeWindow (component);
PIXELFORMATDESCRIPTOR pfd; initialisePixelFormatDescriptor (pfd, pixelFormat);
const int pixFormat = ChoosePixelFormat (dc, &pfd); if (pixFormat != 0) SetPixelFormat (dc, pixFormat, &pfd);
renderContext = wglCreateContext (dc);
if (renderContext != 0) { makeActive(); initialiseGLExtensions();
const int wglFormat = wglChoosePixelFormatExtension (pixelFormat); deactivateCurrentContext();
#ifndef JUCE_OPENGL3 // D/Labs: enforce delete old context and create a new one according to specified version if (wglFormat != pixFormat && wglFormat != 0) #endif // JUCE_OPENGL3 D/Labs { // can't change the pixel format of a window, so need to delete the // old one and create a new one.. releaseDC(); nativeWindow = nullptr; createNativeWindow (component);
if (SetPixelFormat (dc, wglFormat, &pfd)) { deleteRenderContext(); renderContext = createVersionnedContext(dc, (HGLRC)contextToShareWith, version); /* D/Labs */ } }
#ifdef JUCE_OPENGL3 // D/Labs createVersionnedContext could manage context sharing if (version != openGL3_2) #endif // JUCE_OPENGL3 if (contextToShareWith != nullptr) wglShareLists ((HGLRC) contextToShareWith, renderContext);
component.getTopLevelComponent()->repaint(); component.repaint(); } }
Then the new function pointer initialization
JUCE_DECLARE_WGL_EXTENSION_FUNCTION (wglChoosePixelFormatARB, BOOL, (HDC, const int*, const FLOAT*, UINT, int*, UINT*))
JUCE_DECLARE_WGL_EXTENSION_FUNCTION (wglSwapIntervalEXT, BOOL, (int))
JUCE_DECLARE_WGL_EXTENSION_FUNCTION (wglGetSwapIntervalEXT, int, ())
JUCE_DECLARE_WGL_EXTENSION_FUNCTION (wglCreateContextAttribsARB, HGLRC, (HDC, HGLRC, const int *)) /**D/Labs*/
#undef JUCE_DECLARE_WGL_EXTENSION_FUNCTION
void initialiseGLExtensions()
{
#define JUCE_INIT_WGL_FUNCTION(name) name = (type_ ## name) OpenGLHelpers::getExtensionFunction (#name);
JUCE_INIT_WGL_FUNCTION (wglChoosePixelFormatARB);
JUCE_INIT_WGL_FUNCTION (wglSwapIntervalEXT);
JUCE_INIT_WGL_FUNCTION (wglGetSwapIntervalEXT);
JUCE_INIT_WGL_FUNCTION (wglCreateContextAttribsARB); /**D/Labs*/
#undef JUCE_INIT_WGL_FUNCTION
}
and the new createVersionnedContext method:
HGLRC createVersionnedContext(HDC dc, HGLRC contextToShareWith, OpenGLVersion version) // D/Labs
{
#ifdef JUCE_OPENGL3
if (version == openGL3_2)
{
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_FLAGS_ARB 0x2094
int attribs[64];
int numAttribs = 0;
attribs[numAttribs++] = WGL_CONTEXT_MAJOR_VERSION_ARB; attribs[numAttribs++] = 3;
attribs[numAttribs++] = WGL_CONTEXT_MINOR_VERSION_ARB; attribs[numAttribs++] = 2;
attribs[numAttribs++] = WGL_CONTEXT_PROFILE_MASK_ARB; attribs[numAttribs++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
attribs[numAttribs++] = WGL_CONTEXT_FLAGS_ARB; attribs[numAttribs++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
#ifdef JUCE_DEBUG
| WGL_CONTEXT_DEBUG_BIT_ARB
#endif //JUCE_DEBUG
;
attribs[numAttribs++] = 0;
HGLRC arbRC = wglCreateContextAttribsARB(dc, contextToShareWith, attribs);
jassert(arbRC != NULL);
return arbRC;
}
else
#endif // JUCE_OPENGL3
return wglCreateContext (dc);
}
Of course defines should be moved into juce_MissingGLDefinitions.h.
Note that in debug build, I create a debug GL context. May be juce::OpenGLPixelFormat should be extended to let choose this at runtime.
May be hard coded context version 3.2 should also be part of the juce::OpenGLPixelFormat structure.
Note that to be really core profile compliant, the following deprecated code
#if ! JUCE_ANDROID glEnable (GL_TEXTURE_2D); #endif
should be replaced by
#if ! JUCE_ANDROID && ! JUCE_OPENGL3 glEnable (GL_TEXTURE_2D); #endif
This can be found one one in juce_OpenGLContext.cpp, one time in juce_OpenGLFrameBuffer.cpp, two time in juce_OpenGLGraphicsContext.cpp
Note that for juce_opengl module DLL build, there is the following missing JUCE_API marco in
juce_OpenGLAppComponent.h line 37.
juce_OpenGLShaderProgram.h line 128
juce_OpenGLShaderProgram.h line 173
Last request: To be able to quickly create a modern OpenGL sandbox, It should be great that OpenGLAppComponent constructor have additional parameters let select the setContinuousRepainting with true by default and the OpenGLVersion with OpenGLContext::defaultGLVersion by default.
Thanks a lot for your concern about this long issue.
Keep me in touch if you need helps for similar patch on Linux platforms.
The best,