1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-15 00:24:19 +00:00

OpenGL refactoring.

This commit is contained in:
jules 2011-10-24 21:02:56 +01:00
parent d4b041ad91
commit 04c35b28e6
12 changed files with 81 additions and 174 deletions

View file

@ -37,36 +37,14 @@ public:
delta (1.0f)
{
startTimer (20);
// Just for demo purposes, let's dump a list of all the available pixel formats..
OwnedArray <OpenGLPixelFormat> availablePixelFormats;
OpenGLPixelFormat::getAvailablePixelFormats (this, availablePixelFormats);
for (int i = 0; i < availablePixelFormats.size(); ++i)
{
const OpenGLPixelFormat* const pixFormat = availablePixelFormats[i];
DBG (i << ": RGBA=(" << pixFormat->redBits
<< ", " << pixFormat->greenBits
<< ", " << pixFormat->blueBits
<< ", " << pixFormat->alphaBits
<< "), depth=" << pixFormat->depthBufferBits
<< ", stencil=" << pixFormat->stencilBufferBits
<< ", accum RGBA=(" << pixFormat->accumulationBufferRedBits
<< ", " << pixFormat->accumulationBufferGreenBits
<< ", " << pixFormat->accumulationBufferBlueBits
<< ", " << pixFormat->accumulationBufferAlphaBits
<< "), full-scene AA="
<< (int) pixFormat->fullSceneAntiAliasingNumSamples);
}
}
// when the component creates a new internal context, this is called, and
// we'll use the opportunity to create the textures needed.
void newOpenGLContextCreated()
{
texture1 = createImage1();
texture2 = createImage2();
texture1.load (createImage1());
texture2.load (createImage2());
// (no need to call makeCurrentContextActive(), as that will have
// been done for us before the method call).
@ -89,20 +67,17 @@ public:
void renderOpenGL()
{
OpenGLHelpers::clear (Colours::darkgrey.withAlpha (0.0f));
OpenGLHelpers::clear (Colours::darkgrey.withAlpha (1.0f));
OpenGLHelpers::prepareFor2D (getWidth(), getHeight());
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
OpenGLFrameBuffer& frameBuffer1 = dynamic_cast <OpenGLFrameBufferImage*> (texture1.getSharedImage())->frameBuffer;
OpenGLFrameBuffer& frameBuffer2 = dynamic_cast <OpenGLFrameBufferImage*> (texture2.getSharedImage())->frameBuffer;
frameBuffer1.draw2D (50.0f, getHeight() - 50.0f,
getWidth() - 50.0f, getHeight() - 50.0f,
getWidth() - 50.0f, 50.0f,
50.0f, 50.0f,
Colours::white.withAlpha (fabsf (::sinf (rotation / 100.0f))));
texture1.draw2D (50.0f, getHeight() - 50.0f,
getWidth() - 50.0f, getHeight() - 50.0f,
getWidth() - 50.0f, 50.0f,
50.0f, 50.0f,
Colours::white.withAlpha (fabsf (::sinf (rotation / 100.0f))));
glClear (GL_DEPTH_BUFFER_BIT);
@ -112,12 +87,12 @@ public:
glRotatef (rotation, 0.5f, 1.0f, 0.0f);
// this draws the sides of our spinning cube..
frameBuffer1.draw3D (-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, Colours::white);
frameBuffer1.draw3D (-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, Colours::white);
frameBuffer1.draw3D (-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, Colours::white);
frameBuffer2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, Colours::white);
frameBuffer2.draw3D ( 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, Colours::white);
frameBuffer2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, Colours::white);
texture1.draw3D (-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, Colours::white);
texture1.draw3D (-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, Colours::white);
texture1.draw3D (-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, Colours::white);
texture2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, Colours::white);
texture2.draw3D ( 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, Colours::white);
texture2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, Colours::white);
}
void timerCallback()
@ -127,13 +102,13 @@ public:
}
private:
Image texture1, texture2;
OpenGLTexture texture1, texture2;
float rotation, delta;
// Functions to create a couple of images to use as textures..
static Image createImage1()
{
Image image (new OpenGLFrameBufferImage (256, 256));
Image image (Image::ARGB, 256, 256, true);
Graphics g (image);
@ -148,7 +123,7 @@ private:
static Image createImage2()
{
Image image (new OpenGLFrameBufferImage (128, 128));
Image image (Image::ARGB, 128, 128, true);
Graphics g (image);
g.fillAll (Colours::darkred.withAlpha (0.7f));

View file

@ -158,7 +158,7 @@ public:
/** Returns a rectangle with the same size as this image.
The rectangle's origin is always (0, 0).
*/
const Rectangle<int> getBounds() const noexcept { return image == nullptr ? Rectangle<int>() : Rectangle<int> (image->width, image->height); }
Rectangle<int> getBounds() const noexcept { return image == nullptr ? Rectangle<int>() : Rectangle<int> (image->width, image->height); }
/** Returns the image's pixel format. */
PixelFormat getFormat() const noexcept { return image == nullptr ? UnknownFormat : image->format; }

View file

@ -34,10 +34,9 @@ void* OpenGLComponent::getNativeWindowHandle() const
return nullptr;
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
OwnedArray <OpenGLPixelFormat>& results)
void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
{
Component::internalRepaint (x, y, w, h);
}
bool OpenGLHelpers::isContextActive()

View file

@ -143,10 +143,6 @@ public:
return numFrames;
}
void repaint()
{
}
//==============================================================================
void createGLBuffers()
{
@ -231,9 +227,15 @@ OpenGLContext* OpenGLComponent::createContext()
return nullptr;
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
OwnedArray <OpenGLPixelFormat>& /*results*/)
void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
{
Component::internalRepaint (x, y, w, h);
}
void OpenGLComponent::updateEmbeddedPosition (const Rectangle<int>& bounds)
{
if (context != nullptr)
static_cast <GLESContext*> (context.get())->updateWindowPosition (bounds);
}
//==============================================================================

View file

@ -151,13 +151,6 @@ public:
return 0;
}
void updateWindowPosition (const Rectangle<int>& bounds)
{
ScopedXLock xlock;
XMoveResizeWindow (display, embeddedWindow,
bounds.getX(), bounds.getY(), jmax (1, bounds.getWidth()), jmax (1, bounds.getHeight()));
}
void swapBuffers()
{
ScopedXLock xlock;
@ -179,13 +172,12 @@ public:
}
int getSwapInterval() const { return swapInterval; }
void repaint() {}
//==============================================================================
GLXContext renderContext;
Window embeddedWindow;
private:
Window embeddedWindow;
OpenGLPixelFormat pixelFormat;
int swapInterval;
@ -201,9 +193,21 @@ OpenGLContext* OpenGLComponent::createContext()
return (c->renderContext != 0) ? c.release() : nullptr;
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* component, OwnedArray <OpenGLPixelFormat>& results)
void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
{
results.add (new OpenGLPixelFormat()); // xxx
Component::internalRepaint (x, y, w, h);
}
void OpenGLComponent::updateEmbeddedPosition (const Rectangle<int>& bounds)
{
if (context != nullptr)
{
Window embeddedWindow = static_cast<WindowedGLContext*> (context.get())->embeddedWindow;
ScopedXLock xlock;
XMoveResizeWindow (display, embeddedWindow,
bounds.getX(), bounds.getY(), jmax (1, bounds.getWidth()), jmax (1, bounds.getHeight()));
}
}
//==============================================================================

View file

@ -209,8 +209,6 @@ public:
void* getRawContext() const noexcept { return renderContext; }
unsigned int getFrameBufferID() const { return 0; }
void updateWindowPosition (const Rectangle<int>&) {}
void swapBuffers()
{
[renderContext flushBuffer];
@ -231,19 +229,6 @@ public:
return numFrames;
}
void repaint()
{
// we need to invalidate the juce view that holds this gl view, to make it
// cause a repaint callback
NSRect r = [view frame];
// bit of a bodge here.. if we only invalidate the area of the gl component,
// it's completely covered by the NSOpenGLView, so the OS throws away the
// repaint message, thus never causing our paint() callback, and never repainting
// the comp. So invalidating just a little bit around the edge helps..
[[view superview] setNeedsDisplayInRect: NSInsetRect (r, -2.0f, -2.0f)];
}
void* getNativeWindowHandle() const { return view; }
//==============================================================================
@ -253,7 +238,6 @@ public:
private:
OpenGLPixelFormat pixelFormat;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowedGLContext);
};
@ -268,50 +252,28 @@ OpenGLContext* OpenGLComponent::createContext()
void* OpenGLComponent::getNativeWindowHandle() const
{
return context != nullptr ? static_cast<WindowedGLContext*> (static_cast<OpenGLContext*> (context))->getNativeWindowHandle()
return context != nullptr ? static_cast<WindowedGLContext*> (context.get())->getNativeWindowHandle()
: nullptr;
}
static int getPixelFormatAttribute (NSOpenGLPixelFormat* p, NSOpenGLPixelFormatAttribute att)
void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
{
GLint val = 0;
[p getValues: &val forAttribute: att forVirtualScreen: 0];
return (int) val;
Component::internalRepaint (x, y, w, h);
if (context != nullptr)
{
NSView* const v = static_cast<WindowedGLContext*> (context.get())->view;
// bit of a bodge here.. if we only invalidate the area of the gl component,
// it's completely covered by the NSOpenGLView, so the OS throws away the
// repaint message, thus never causing our paint() callback, and never repainting
// the comp. So invalidating just a little bit around the edge helps..
[[v superview] setNeedsDisplayInRect: NSInsetRect ([v frame], -2.0f, -2.0f)];
}
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
OwnedArray <OpenGLPixelFormat>& results)
void OpenGLComponent::updateEmbeddedPosition (const Rectangle<int>&)
{
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFAWindow,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) 16,
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute) 8,
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) 24,
NSOpenGLPFAAccumSize, (NSOpenGLPixelFormatAttribute) 32,
(NSOpenGLPixelFormatAttribute) 0
};
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes: attributes];
if (format != nil)
{
OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
pf->redBits = pf->greenBits = pf->blueBits = getPixelFormatAttribute (format, NSOpenGLPFAColorSize) / 3;
pf->alphaBits = getPixelFormatAttribute (format, NSOpenGLPFAAlphaSize);
pf->depthBufferBits = getPixelFormatAttribute (format, NSOpenGLPFADepthSize);
pf->stencilBufferBits = getPixelFormatAttribute (format, NSOpenGLPFAStencilSize);
pf->accumulationBufferRedBits = pf->accumulationBufferGreenBits
= pf->accumulationBufferBlueBits = pf->accumulationBufferAlphaBits
= getPixelFormatAttribute (format, NSOpenGLPFAAccumSize) / 4;
[format release];
results.add (pf);
}
}
//==============================================================================

View file

@ -269,18 +269,6 @@ public:
return false;
}
void updateWindowPosition (const Rectangle<int>& bounds)
{
SetWindowPos ((HWND) nativeWindow->getNativeHandle(), 0,
bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(),
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
void repaint()
{
nativeWindow->repaint (nativeWindow->getBounds().withPosition (Point<int>()));
}
void swapBuffers()
{
SwapBuffers (dc);
@ -354,9 +342,9 @@ public:
//==============================================================================
HGLRC renderContext;
ScopedPointer<ComponentPeer> nativeWindow;
private:
ScopedPointer<ComponentPeer> nativeWindow;
Component* const component;
HDC dc;
@ -471,18 +459,29 @@ OpenGLContext* OpenGLComponent::createContext()
void* OpenGLComponent::getNativeWindowHandle() const
{
return context != nullptr ? static_cast<WindowedGLContext*> (static_cast<OpenGLContext*> (context))->getNativeWindowHandle() : nullptr;
return context != nullptr ? static_cast<WindowedGLContext*> (context.get())->getNativeWindowHandle() : nullptr;
}
void OpenGLPixelFormat::getAvailablePixelFormats (Component* component,
OwnedArray <OpenGLPixelFormat>& results)
void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
{
Component tempComp;
Component::internalRepaint (x, y, w, h);
if (context != nullptr)
{
WindowedGLContext wc (component, 0, OpenGLPixelFormat (8, 8, 16, 0));
wc.makeActive();
wc.findAlternativeOpenGLPixelFormats (results);
ComponentPeer* peer = static_cast<WindowedGLContext*> (context.get())->nativeWindow;
peer->repaint (peer->getBounds().withPosition (Point<int>()));
}
}
void OpenGLComponent::updateEmbeddedPosition (const Rectangle<int>& bounds)
{
if (context != nullptr)
{
ComponentPeer* peer = static_cast<WindowedGLContext*> (context.get())->nativeWindow;
SetWindowPos ((HWND) peer->getNativeHandle(), 0,
bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(),
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
}

View file

@ -127,7 +127,6 @@ public:
{
}
//==============================================================================
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/)
{
owner->updateContextPosition();
@ -349,9 +348,7 @@ void OpenGLComponent::updateContextPosition()
if (topComp->getPeer() != nullptr)
{
const ScopedLock sl (contextLock);
if (context != nullptr)
context->updateWindowPosition (topComp->getLocalArea (this, getLocalBounds()));
updateEmbeddedPosition (topComp->getLocalArea (this, getLocalBounds()));
}
}
}
@ -425,14 +422,6 @@ bool OpenGLComponent::renderAndSwapBuffers()
return true;
}
void OpenGLComponent::internalRepaint (int x, int y, int w, int h)
{
Component::internalRepaint (x, y, w, h);
if (context != nullptr)
context->repaint();
}
unsigned int OpenGLComponent::getFrameBufferID() const
{
return context != nullptr ? context->getFrameBufferID() : 0;

View file

@ -72,10 +72,7 @@ public:
~OpenGLComponent();
//==============================================================================
/** Changes the pixel format used by this component.
@see OpenGLPixelFormat::getAvailablePixelFormats()
*/
/** Changes the pixel format used by this component. */
void setPixelFormat (const OpenGLPixelFormat& formatToUse);
/** Returns the pixel format that this component is currently using. */
@ -261,6 +258,7 @@ private:
void stopBackgroundThread();
void recreateContextAsync();
void internalRepaint (int x, int y, int w, int h);
void updateEmbeddedPosition (const Rectangle<int>&);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent);
};

View file

@ -72,17 +72,6 @@ public:
/** Returns the pixel format being used by this context. */
virtual OpenGLPixelFormat getPixelFormat() const = 0;
/** For windowed contexts, this moves the context within the bounds of
its parent window.
*/
virtual void updateWindowPosition (const Rectangle<int>& bounds) = 0;
/** For windowed contexts, this triggers a repaint of the window.
(Not relevent on all platforms).
*/
virtual void repaint() = 0;
/** Returns an OS-dependent handle to the raw GL context.
On win32, this will be a HGLRC; on the Mac, an NSOpenGLContext; on Linux,

View file

@ -244,7 +244,7 @@ namespace
glVertexPointer (2, GL_FLOAT, 0, vertices);
glTexCoordPointer (2, GL_FLOAT, 0, textureCoords);
const Rectangle<int> targetArea (clip.transformed (transform.inverted()));
const Rectangle<int> targetArea (clip.toFloat().transformed (transform.inverted()).getSmallestIntegerContainer());
int x = targetArea.getX() - negativeAwareModulo (targetArea.getX(), textureWidth);
int y = targetArea.getY() - negativeAwareModulo (targetArea.getY(), textureHeight);
const int right = targetArea.getRight();

View file

@ -67,17 +67,7 @@ public:
uint8 fullSceneAntiAliasingNumSamples; /**< The number of samples to use in full-scene anti-aliasing (if available). */
//==============================================================================
/** Returns a list of all the pixel formats that can be used in this system.
A reference component is needed in case there are multiple screens with different
capabilities - in which case, the one that the component is on will be used.
*/
static void getAvailablePixelFormats (Component* component,
OwnedArray <OpenGLPixelFormat>& results);
private:
//==============================================================================
JUCE_LEAK_DETECTOR (OpenGLPixelFormat);
};