Browse Source

OpenGL: removed the fixed-function rendering code, replacing it with a simple software renderer that blits its results to the GL context. Removed the public OpenGLGraphicsContext class, replacing it with a createOpenGLGraphicsContext() function which returns an appropriate shader-based or software-based renderer object.

tags/2021-05-28
jules 13 years ago
parent
commit
b338698e34
11 changed files with 425 additions and 1471 deletions
  1. +3
    -2
      extras/JuceDemo/Source/demos/OpenGLDemo.cpp
  2. +1
    -1
      modules/juce_gui_basics/windows/juce_ResizableWindow.h
  3. +64
    -25
      modules/juce_opengl/opengl/juce_OpenGLComponent.cpp
  4. +1
    -1
      modules/juce_opengl/opengl/juce_OpenGLComponent.h
  5. +15
    -13
      modules/juce_opengl/opengl/juce_OpenGLContext.cpp
  6. +6
    -1
      modules/juce_opengl/opengl/juce_OpenGLContext.h
  7. +14
    -9
      modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp
  8. +3
    -0
      modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h
  9. +302
    -1367
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
  10. +14
    -50
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h
  11. +2
    -2
      modules/juce_opengl/opengl/juce_OpenGLImage.cpp

+ 3
- 2
extras/JuceDemo/Source/demos/OpenGLDemo.cpp View File

@@ -157,8 +157,9 @@ public:
void drawBackground2DStuff()
{
OpenGLGraphicsContext glRenderer (*this); // Create an OpenGLGraphicsContext that will draw into this GL window..
Graphics g (&glRenderer); // ..and then wrap it in a normal Graphics object so we can draw with it.
// Create an OpenGLGraphicsContext that will draw into this GL window..
ScopedPointer<LowLevelGraphicsContext> glRenderer (createOpenGLGraphicsContext (*this));
Graphics g (glRenderer);
// This stuff just creates a spinning star shape and fills it..
Path p;


+ 1
- 1
modules/juce_gui_basics/windows/juce_ResizableWindow.h View File

@@ -322,7 +322,7 @@ protected:
//==============================================================================
/** @internal */
void paint (Graphics& g);
/** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */
/** (if overriding this, make sure you call ResizableWindow::moved() in your subclass) */
void moved();
/** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */
void resized();


+ 64
- 25
modules/juce_opengl/opengl/juce_OpenGLComponent.cpp View File

@@ -121,6 +121,26 @@ public:
return frameBuffer;
}
void clearRegionInFrameBuffer (const RectangleList& list)
{
glClearColor (0, 0, 0, 0);
glEnable (GL_SCISSOR_TEST);
const GLuint previousFrameBufferTarget = OpenGLFrameBuffer::getCurrentFrameBufferTarget();
frameBuffer.makeCurrentRenderingTarget();
for (RectangleList::Iterator i (list); i.next();)
{
const Rectangle<int>& r = *i.getRectangle();
glScissor (r.getX(), owner.getHeight() - r.getBottom(), r.getWidth(), r.getHeight());
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
glDisable (GL_SCISSOR_TEST);
owner.getCurrentContext()->extensions.glBindFramebuffer (GL_FRAMEBUFFER, previousFrameBufferTarget);
JUCE_CHECK_OPENGL_ERROR
}
RectangleList validArea;
private:
@@ -152,7 +172,9 @@ public:
void componentVisibilityChanged()
{
if (! owner.isShowing())
if (owner.isShowing())
owner.triggerRepaint();
else
owner.stopRenderThread();
}
@@ -172,34 +194,54 @@ public:
{
}
void run()
virtual void initialise()
{
#if JUCE_LINUX
{
MessageManagerLock mml (this);
if (! mml.lockWasGained())
return;
MessageManagerLock mml (this);
if (mml.lockWasGained())
{
owner.updateContext();
owner.updateContextPosition();
}
#endif
}
virtual void shutdown()
{
#if JUCE_LINUX
owner.deleteContext();
#endif
}
virtual bool renderFrame()
{
return owner.performRender();
}
virtual void waitForNextFrame (const uint32 frameRenderStartTime)
{
const int defaultFPS = 60;
const int elapsed = (int) (Time::getMillisecondCounter() - frameRenderStartTime);
Thread::sleep (jmax (1, (1000 / defaultFPS) - elapsed));
}
void run()
{
initialise();
while (! threadShouldExit())
{
const uint32 startOfRendering = Time::getMillisecondCounter();
const uint32 frameRenderStartTime = Time::getMillisecondCounter();
if (! owner.performRender())
if (! renderFrame())
break;
const int elapsed = (int) (Time::getMillisecondCounter() - startOfRendering);
Thread::sleep (jmax (1, (1000 / 60) - elapsed));
waitForNextFrame (frameRenderStartTime);
}
#if JUCE_LINUX
owner.deleteContext();
#endif
shutdown();
}
private:
@@ -458,17 +500,14 @@ bool OpenGLComponent::performRender()
{
jassert (getCurrentContext() != nullptr);
cachedImage->clearRegionInFrameBuffer (invalid);
{
OpenGLGraphicsContext g (*getCurrentContext(), frameBuffer);
ScopedPointer<LowLevelGraphicsContext> g (createOpenGLGraphicsContext (*getCurrentContext(), frameBuffer));
JUCE_CHECK_OPENGL_ERROR
g.clipToRectangleList (invalid);
g.setFill (Colours::transparentBlack);
g.fillRect (bounds, true);
g.setFill (Colours::black);
JUCE_CHECK_OPENGL_ERROR
paintSelf (g);
g->clipToRectangleList (invalid);
paintSelf (*g);
JUCE_CHECK_OPENGL_ERROR
}
@@ -484,7 +523,7 @@ bool OpenGLComponent::performRender()
glBindTexture (GL_TEXTURE_2D, frameBuffer.getTextureID());
jassert (bounds.getPosition() == Point<int>());
context->copyTexture (bounds, bounds);
context->copyTexture (bounds, bounds, context->getWidth(), context->getHeight());
glBindTexture (GL_TEXTURE_2D, 0);
JUCE_CHECK_OPENGL_ERROR
}
@@ -495,9 +534,9 @@ bool OpenGLComponent::performRender()
return true;
}
void OpenGLComponent::paintSelf (OpenGLGraphicsContext& glRenderer)
void OpenGLComponent::paintSelf (LowLevelGraphicsContext& context)
{
Graphics g (&glRenderer);
Graphics g (&context);
#if JUCE_ENABLE_REPAINT_DEBUGGING
g.saveState();


+ 1
- 1
modules/juce_opengl/opengl/juce_OpenGLComponent.h View File

@@ -289,7 +289,7 @@ private:
void updateEmbeddedPosition (const Rectangle<int>&);
void startRenderThread();
bool performRender();
void paintSelf (OpenGLGraphicsContext&);
void paintSelf (LowLevelGraphicsContext&);
int renderAndSwapBuffers(); // (This method has been deprecated)


+ 15
- 13
modules/juce_opengl/opengl/juce_OpenGLContext.cpp View File

@@ -127,7 +127,8 @@ bool OpenGLContext::areShadersAvailable() const
}
void OpenGLContext::copyTexture (const Rectangle<int>& targetClipArea,
const Rectangle<int>& anchorPosAndTextureSize)
const Rectangle<int>& anchorPosAndTextureSize,
int contextWidth, int contextHeight)
{
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
@@ -138,9 +139,7 @@ void OpenGLContext::copyTexture (const Rectangle<int>& targetClipArea,
struct OverlayShaderProgram : public ReferenceCountedObject
{
OverlayShaderProgram (OpenGLContext& context)
: program (context),
builder (program),
params (program)
: program (context), builder (program), params (program)
{}
static const OverlayShaderProgram& select (OpenGLContext& context)
@@ -225,7 +224,7 @@ void OpenGLContext::copyTexture (const Rectangle<int>& targetClipArea,
const GLshort vertices[] = { left, bottom, right, bottom, left, top, right, top };
const OverlayShaderProgram& program = OverlayShaderProgram::select (*this);
program.params.set ((float) getWidth(), (float) getHeight(), anchorPosAndTextureSize.toFloat());
program.params.set ((float) contextWidth, (float) contextHeight, anchorPosAndTextureSize.toFloat());
extensions.glVertexAttribPointer (program.params.positionAttribute.attributeID, 2, GL_SHORT, GL_FALSE, 4, vertices);
extensions.glEnableVertexAttribArray (program.params.positionAttribute.attributeID);
@@ -241,26 +240,29 @@ void OpenGLContext::copyTexture (const Rectangle<int>& targetClipArea,
#if JUCE_USE_OPENGL_FIXED_FUNCTION
{
(void) anchorPosAndTextureSize; // xxx need to scissor
const GLshort left = (GLshort) targetClipArea.getX();
const GLshort right = (GLshort) targetClipArea.getRight();
const GLshort top = (GLshort) (getHeight() - targetClipArea.getY());
const GLshort bottom = (GLshort) (getHeight() - targetClipArea.getBottom());
const GLshort vertices[] = { left, bottom, right, bottom, left, top, right, top };
OpenGLHelpers::prepareFor2D (getWidth(), getHeight());
glEnable (GL_SCISSOR_TEST);
glScissor (targetClipArea.getX(), contextHeight - targetClipArea.getBottom(),
targetClipArea.getWidth(), targetClipArea.getHeight());
glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
glDisableClientState (GL_COLOR_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
OpenGLHelpers::prepareFor2D (contextWidth, contextHeight);
const GLfloat textureCoords[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f };
glTexCoordPointer (2, GL_FLOAT, 0, textureCoords);
const GLshort left = (GLshort) anchorPosAndTextureSize.getX();
const GLshort right = (GLshort) anchorPosAndTextureSize.getRight();
const GLshort top = (GLshort) (contextHeight - anchorPosAndTextureSize.getY());
const GLshort bottom = (GLshort) (contextHeight - anchorPosAndTextureSize.getBottom());
const GLshort vertices[] = { left, bottom, right, bottom, left, top, right, top };
glVertexPointer (2, GL_SHORT, 0, vertices);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
glDisable (GL_SCISSOR_TEST);
}
#endif
}

+ 6
- 1
modules/juce_opengl/opengl/juce_OpenGLContext.h View File

@@ -112,9 +112,14 @@ public:
@param anchorPosAndTextureSize the position of this rectangle is the texture's top-left
anchor position in the target space, and the size must be
the total size of the texture.
@param contextWidth the width of the context or framebuffer that is being drawn into,
used for scaling of the coordinates.
@param contextHeight the height of the context or framebuffer that is being drawn into,
used for vertical flipping of the y coordinates.
*/
void copyTexture (const Rectangle<int>& targetClipArea,
const Rectangle<int>& anchorPosAndTextureSize);
const Rectangle<int>& anchorPosAndTextureSize,
int contextWidth, int contextHeight);
protected:
//==============================================================================


+ 14
- 9
modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp View File

@@ -32,7 +32,7 @@ public:
width (width_),
height (height_),
textureID (0),
frameBufferHandle (0),
frameBufferID (0),
depthOrStencilBuffer (0),
hasDepthBuffer (false),
hasStencilBuffer (false),
@@ -47,8 +47,8 @@ public:
return;
#endif
context.extensions.glGenFramebuffers (1, &frameBufferHandle);
context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle);
context.extensions.glGenFramebuffers (1, &frameBufferID);
context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID);
JUCE_CHECK_OPENGL_ERROR
glGenTextures (1, &textureID);
@@ -102,15 +102,15 @@ public:
if (depthOrStencilBuffer != 0)
context.extensions.glDeleteRenderbuffers (1, &depthOrStencilBuffer);
if (frameBufferHandle != 0)
context.extensions.glDeleteFramebuffers (1, &frameBufferHandle);
if (frameBufferID != 0)
context.extensions.glDeleteFramebuffers (1, &frameBufferID);
JUCE_CHECK_OPENGL_ERROR
}
void bind()
{
context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferHandle);
context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID);
JUCE_CHECK_OPENGL_ERROR
}
@@ -122,7 +122,7 @@ public:
OpenGLContext& context;
const int width, height;
GLuint textureID, frameBufferHandle, depthOrStencilBuffer;
GLuint textureID, frameBufferID, depthOrStencilBuffer;
bool hasDepthBuffer, hasStencilBuffer, ok;
private:
@@ -214,7 +214,7 @@ bool OpenGLFrameBuffer::initialise (OpenGLFrameBuffer& other)
glEnable (GL_TEXTURE_2D);
#endif
glBindTexture (GL_TEXTURE_2D, p->textureID);
pimpl->context.copyTexture (area, area);
pimpl->context.copyTexture (area, area, area.getWidth(), area.getHeight());
glBindTexture (GL_TEXTURE_2D, 0);
JUCE_CHECK_OPENGL_ERROR
@@ -272,6 +272,11 @@ bool OpenGLFrameBuffer::makeCurrentRenderingTarget()
return true;
}
GLuint OpenGLFrameBuffer::getFrameBufferID() const
{
return pimpl != nullptr ? pimpl->frameBufferID : 0;
}
GLuint OpenGLFrameBuffer::getCurrentFrameBufferTarget()
{
GLint fb;
@@ -339,7 +344,7 @@ bool OpenGLFrameBuffer::writePixels (const PixelARGB* data, const Rectangle<int>
glDrawTexiOES (area.getX(), area.getY(), 1, area.getWidth(), area.getHeight());
glBindTexture (GL_TEXTURE_2D, 0);
#else
pimpl->context.copyTexture (area, area);
pimpl->context.copyTexture (area, area, pimpl->width, pimpl->height);
#endif
pimpl->context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, 0);


+ 3
- 0
modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h View File

@@ -95,6 +95,9 @@ public:
/** Deselects this buffer as the current OpenGL rendering target. */
void releaseAsRenderingTarget();
/** Returns the ID of this framebuffer, or 0 if it isn't initialised. */
GLuint getFrameBufferID() const;
/** Returns the current frame buffer ID for the current context. */
static GLuint getCurrentFrameBufferTarget();


+ 302
- 1367
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
File diff suppressed because it is too large
View File


+ 14
- 50
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h View File

@@ -28,59 +28,23 @@
//==============================================================================
/** A LowLevelGraphicsContext for rendering into an OpenGL framebuffer or window.
/** Creates a graphics context object that will render into the given OpenGL target.
The caller is responsible for deleting this object when no longer needed.
*/
class JUCE_API OpenGLGraphicsContext : public LowLevelGraphicsContext
{
public:
explicit OpenGLGraphicsContext (OpenGLComponent& target);
OpenGLGraphicsContext (OpenGLContext& context, OpenGLFrameBuffer& target);
OpenGLGraphicsContext (OpenGLContext& context, unsigned int frameBufferID, int width, int height);
~OpenGLGraphicsContext();
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLComponent& target);
bool isVectorDevice() const;
void setOrigin (int x, int y);
void addTransform (const AffineTransform&);
float getScaleFactor();
bool clipToRectangle (const Rectangle<int>&);
bool clipToRectangleList (const RectangleList&);
void excludeClipRectangle (const Rectangle<int>&);
void clipToPath (const Path& path, const AffineTransform&);
void clipToImageAlpha (const Image& sourceImage, const AffineTransform&);
bool clipRegionIntersects (const Rectangle<int>&);
Rectangle<int> getClipBounds() const;
bool isClipEmpty() const;
void saveState();
void restoreState();
void beginTransparencyLayer (float opacity);
void endTransparencyLayer();
void setFill (const FillType& fillType);
void setOpacity (float newOpacity);
void setInterpolationQuality (Graphics::ResamplingQuality);
void fillRect (const Rectangle<int>& r, bool replaceExistingContents);
void fillPath (const Path& path, const AffineTransform& transform);
void drawImage (const Image& sourceImage, const AffineTransform& transform);
void drawLine (const Line <float>& line);
void drawVerticalLine (int x, float top, float bottom);
void drawHorizontalLine (int y, float left, float right);
void setFont (const Font&);
const Font& getFont();
void drawGlyph (int glyphNumber, const AffineTransform&);
/** Creates a graphics context object that will render into the given OpenGL target.
The caller is responsible for deleting this object when no longer needed.
*/
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context,
OpenGLFrameBuffer& target);
#ifndef DOXYGEN
class SavedState;
class GLState;
#endif
/** Creates a graphics context object that will render into the given OpenGL target.
The caller is responsible for deleting this object when no longer needed.
*/
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context,
unsigned int frameBufferID,
int width, int height);
private:
ScopedPointer<GLState> glState;
RenderingHelpers::SavedStateStack<SavedState> stack;
};
#endif // __JUCE_OPENGLGRAPHICSCONTEXT_JUCEHEADER__

+ 2
- 2
modules/juce_opengl/opengl/juce_OpenGLImage.cpp View File

@@ -38,10 +38,10 @@ public:
LowLevelGraphicsContext* createLowLevelContext()
{
return new OpenGLGraphicsContext (context, frameBuffer);
return createOpenGLGraphicsContext (context, frameBuffer);
}
ImageType* createType() const { return new OpenGLImageType(); }
ImageType* createType() const { return new OpenGLImageType(); }
ImagePixelData* clone()
{


Loading…
Cancel
Save