Browse Source

Added some GL error handling and tweaks to support older PC builds.

tags/2021-05-28
jules 13 years ago
parent
commit
04c2d6cfc1
8 changed files with 90 additions and 59 deletions
  1. +1
    -1
      extras/JuceDemo/Source/MainDemoWindow.cpp
  2. +47
    -35
      extras/JuceDemo/Source/demos/OpenGLDemo.cpp
  3. +0
    -4
      modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp
  4. +4
    -3
      modules/juce_audio_formats/juce_audio_formats.cpp
  5. +8
    -3
      modules/juce_opengl/opengl/juce_OpenGLContext.cpp
  6. +8
    -4
      modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp
  7. +11
    -2
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
  8. +11
    -7
      modules/juce_opengl/opengl/juce_OpenGLImage.cpp

+ 1
- 1
extras/JuceDemo/Source/MainDemoWindow.cpp View File

@@ -160,7 +160,7 @@ public:
{ {
#if JUCE_OPENGL #if JUCE_OPENGL
if (shouldUseOpenGL && currentDemoId != showOpenGL) if (shouldUseOpenGL && currentDemoId != showOpenGL)
openGLContext.attachTo (*this);
openGLContext.attachTo (*getTopLevelComponent());
else else
openGLContext.detach(); openGLContext.detach();
#endif #endif


+ 47
- 35
extras/JuceDemo/Source/demos/OpenGLDemo.cpp View File

@@ -138,16 +138,17 @@ public:
OpenGLFrameBuffer* tex1 = OpenGLImageType::getFrameBufferFrom (logoImage); OpenGLFrameBuffer* tex1 = OpenGLImageType::getFrameBufferFrom (logoImage);
OpenGLFrameBuffer* tex2 = OpenGLImageType::getFrameBufferFrom (dynamicTextureImage); OpenGLFrameBuffer* tex2 = OpenGLImageType::getFrameBufferFrom (dynamicTextureImage);
jassert (tex1 != nullptr && tex2 != nullptr); // (this would mean that our images weren't created correctly)
// This draws the sides of our spinning cube.
// I've used some of the juce helper functions, but you can also just use normal GL calls here too.
tex1->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);
tex1->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);
tex1->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);
tex2->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);
tex2->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);
tex2->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);
if (tex1 != nullptr && tex2 != nullptr)
{
// This draws the sides of our spinning cube.
// I've used some of the juce helper functions, but you can also just use normal GL calls here too.
tex1->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);
tex1->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);
tex1->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);
tex2->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);
tex2->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);
tex2->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);
}
#endif #endif
} }
@@ -156,34 +157,41 @@ public:
// This image is a special framebuffer-backed image, so when we draw to it, the context // This image is a special framebuffer-backed image, so when we draw to it, the context
// will render directly into its framebuffer // will render directly into its framebuffer
dynamicTextureImage.clear (dynamicTextureImage.getBounds(),
Colours::red.withRotatedHue (fabsf (::sinf (rotation / 300.0f))).withAlpha (0.7f));
if (dynamicTextureImage.isValid())
{
dynamicTextureImage.clear (dynamicTextureImage.getBounds(),
Colours::red.withRotatedHue (fabsf (::sinf (rotation / 300.0f))).withAlpha (0.7f));
Graphics g (dynamicTextureImage);
Graphics g (dynamicTextureImage);
g.setFont (dynamicTextureImage.getHeight() / 3.0f);
g.setColour (Colours::black);
drawScrollingMessage (g, dynamicTextureImage.getHeight() / 2);
g.setFont (dynamicTextureImage.getHeight() / 3.0f);
g.setColour (Colours::black);
drawScrollingMessage (g, dynamicTextureImage.getHeight() / 2);
}
} }
void drawBackground2DStuff() void drawBackground2DStuff()
{ {
// Create an OpenGLGraphicsContext that will draw into this GL window.. // Create an OpenGLGraphicsContext that will draw into this GL window..
ScopedPointer<LowLevelGraphicsContext> glRenderer (createOpenGLGraphicsContext (openGLContext)); ScopedPointer<LowLevelGraphicsContext> glRenderer (createOpenGLGraphicsContext (openGLContext));
Graphics g (glRenderer);
// This stuff just creates a spinning star shape and fills it..
Path p;
const float scale = getHeight() * 0.4f;
p.addStar (Point<float> (getWidth() * 0.7f, getHeight() * 0.4f), 7,
scale * (float) sizeSlider.getValue(), scale,
rotation / 50.0f);
g.setGradientFill (ColourGradient (Colours::green.withRotatedHue (fabsf (::sinf (rotation / 300.0f))),
0, 0,
Colours::green.withRotatedHue (fabsf (::cosf (rotation / -431.0f))),
0, (float) getHeight(), false));
g.fillPath (p);
if (createOpenGLGraphicsContext != nullptr)
{
Graphics g (glRenderer);
// This stuff just creates a spinning star shape and fills it..
Path p;
const float scale = getHeight() * 0.4f;
p.addStar (Point<float> (getWidth() * 0.7f, getHeight() * 0.4f), 7,
scale * (float) sizeSlider.getValue(), scale,
rotation / 50.0f);
g.setGradientFill (ColourGradient (Colours::green.withRotatedHue (fabsf (::sinf (rotation / 300.0f))),
0, 0,
Colours::green.withRotatedHue (fabsf (::cosf (rotation / -431.0f))),
0, (float) getHeight(), false));
g.fillPath (p);
}
} }
void timerCallback() void timerCallback()
@@ -207,13 +215,17 @@ private:
{ {
Image image (Image::ARGB, 256, 256, true, OpenGLImageType()); Image image (Image::ARGB, 256, 256, true, OpenGLImageType());
Graphics g (image);
if (image.isValid())
{
Graphics g (image);
g.fillAll (Colours::lightgrey.withAlpha (0.8f));
g.drawImageWithin (ImageFileFormat::loadFrom (BinaryData::juce_png, BinaryData::juce_pngSize),
0, 0, image.getWidth(), image.getHeight(), RectanglePlacement::stretchToFit);
g.fillAll (Colours::lightgrey.withAlpha (0.8f));
g.drawImageWithin (ImageFileFormat::loadFrom (BinaryData::juce_png, BinaryData::juce_pngSize),
0, 0, image.getWidth(), image.getHeight(), RectanglePlacement::stretchToFit);
drawRandomStars (g, image.getWidth(), image.getHeight());
}
drawRandomStars (g, image.getWidth(), image.getHeight());
return image; return image;
} }


+ 0
- 4
modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp View File

@@ -23,8 +23,6 @@
============================================================================== ==============================================================================
*/ */
#if JUCE_WINDOWS
namespace WindowsMediaCodec namespace WindowsMediaCodec
{ {
@@ -345,5 +343,3 @@ AudioFormatWriter* WindowsMediaAudioFormat::createWriterFor (OutputStream* /*str
jassertfalse; // not yet implemented! jassertfalse; // not yet implemented!
return nullptr; return nullptr;
} }
#endif

+ 4
- 3
modules/juce_audio_formats/juce_audio_formats.cpp View File

@@ -98,7 +98,6 @@ namespace juce
#include "../juce_core/native/juce_win32_ComSmartPtr.h" #include "../juce_core/native/juce_win32_ComSmartPtr.h"
#endif #endif
// START_AUTOINCLUDE format/*.cpp, sampler/*.cpp, codecs/*.cpp
#include "format/juce_AudioFormat.cpp" #include "format/juce_AudioFormat.cpp"
#include "format/juce_AudioFormatManager.cpp" #include "format/juce_AudioFormatManager.cpp"
#include "format/juce_AudioFormatReader.cpp" #include "format/juce_AudioFormatReader.cpp"
@@ -113,7 +112,9 @@ namespace juce
#include "codecs/juce_OggVorbisAudioFormat.cpp" #include "codecs/juce_OggVorbisAudioFormat.cpp"
#include "codecs/juce_QuickTimeAudioFormat.cpp" #include "codecs/juce_QuickTimeAudioFormat.cpp"
#include "codecs/juce_WavAudioFormat.cpp" #include "codecs/juce_WavAudioFormat.cpp"
#include "codecs/juce_WindowsMediaAudioFormat.cpp"
// END_AUTOINCLUDE
#if JUCE_WINDOWS && JUCE_USE_WINDOWS_MEDIA_FORMAT
#include "codecs/juce_WindowsMediaAudioFormat.cpp"
#endif
} }

+ 8
- 3
modules/juce_opengl/opengl/juce_OpenGLContext.cpp View File

@@ -101,17 +101,21 @@ public:
} }
//============================================================================== //==============================================================================
void ensureFrameBufferSize (int width, int height)
bool ensureFrameBufferSize (int width, int height)
{ {
const int fbW = cachedImageFrameBuffer.getWidth(); const int fbW = cachedImageFrameBuffer.getWidth();
const int fbH = cachedImageFrameBuffer.getHeight(); const int fbH = cachedImageFrameBuffer.getHeight();
if (fbW != width || fbH != height || ! cachedImageFrameBuffer.isValid()) if (fbW != width || fbH != height || ! cachedImageFrameBuffer.isValid())
{ {
cachedImageFrameBuffer.initialise (context, width, height);
if (! cachedImageFrameBuffer.initialise (context, width, height))
return false;
validArea.clear(); validArea.clear();
JUCE_CHECK_OPENGL_ERROR JUCE_CHECK_OPENGL_ERROR
} }
return true;
} }
void clearRegionInFrameBuffer (const RectangleList& list) void clearRegionInFrameBuffer (const RectangleList& list)
@@ -169,7 +173,8 @@ public:
jassert (get (component) == this); jassert (get (component) == this);
const Rectangle<int> bounds (component.getLocalBounds()); const Rectangle<int> bounds (component.getLocalBounds());
ensureFrameBufferSize (bounds.getWidth(), bounds.getHeight());
if (! ensureFrameBufferSize (bounds.getWidth(), bounds.getHeight()))
return;
RectangleList invalid (bounds); RectangleList invalid (bounds);
invalid.subtract (validArea); invalid.subtract (validArea);


+ 8
- 4
modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp View File

@@ -35,8 +35,7 @@ public:
frameBufferID (0), frameBufferID (0),
depthOrStencilBuffer (0), depthOrStencilBuffer (0),
hasDepthBuffer (false), hasDepthBuffer (false),
hasStencilBuffer (false),
ok (true)
hasStencilBuffer (false)
{ {
// Framebuffer objects can only be created when the current thread has an active OpenGL // Framebuffer objects can only be created when the current thread has an active OpenGL
// context. You'll need to create this object in one of the OpenGLContext's callbacks. // context. You'll need to create this object in one of the OpenGLContext's callbacks.
@@ -111,6 +110,11 @@ public:
} }
} }
bool createdOk() const
{
return frameBufferID != 0 && textureID != 0;
}
void bind() void bind()
{ {
context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID); context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID);
@@ -126,7 +130,7 @@ public:
OpenGLContext& context; OpenGLContext& context;
const int width, height; const int width, height;
GLuint textureID, frameBufferID, depthOrStencilBuffer; GLuint textureID, frameBufferID, depthOrStencilBuffer;
bool hasDepthBuffer, hasStencilBuffer, ok;
bool hasDepthBuffer, hasStencilBuffer;
private: private:
bool checkStatus() noexcept bool checkStatus() noexcept
@@ -180,7 +184,7 @@ bool OpenGLFrameBuffer::initialise (OpenGLContext& context, int width, int heigh
pimpl = nullptr; pimpl = nullptr;
pimpl = new Pimpl (context, width, height, false, false); pimpl = new Pimpl (context, width, height, false, false);
if (! pimpl->ok)
if (! pimpl->createdOk())
pimpl = nullptr; pimpl = nullptr;
return pimpl != nullptr; return pimpl != nullptr;


+ 11
- 2
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp View File

@@ -52,7 +52,11 @@ struct Target
void makeActive() const noexcept void makeActive() const noexcept
{ {
context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID);
#if JUCE_WINDOWS
if (context.extensions.glBindFramebuffer != nullptr)
#endif
context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, frameBufferID);
glViewport (0, 0, bounds.getWidth(), bounds.getHeight()); glViewport (0, 0, bounds.getWidth(), bounds.getHeight());
glDisable (GL_DEPTH_TEST); glDisable (GL_DEPTH_TEST);
} }
@@ -2199,7 +2203,12 @@ public:
texture.getHeight()), texture.getHeight()),
target.bounds.getWidth(), target.bounds.getHeight()); target.bounds.getWidth(), target.bounds.getHeight());
glBindTexture (GL_TEXTURE_2D, 0); glBindTexture (GL_TEXTURE_2D, 0);
target.context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, previousFrameBufferTarget);
#if JUCE_WINDOWS
if (target.context.extensions.glBindFramebuffer != nullptr)
#endif
target.context.extensions.glBindFramebuffer (GL_FRAMEBUFFER, previousFrameBufferTarget);
JUCE_CHECK_OPENGL_ERROR JUCE_CHECK_OPENGL_ERROR
} }


+ 11
- 7
modules/juce_opengl/opengl/juce_OpenGLImage.cpp View File

@@ -32,8 +32,11 @@ public:
pixelStride (4), pixelStride (4),
lineStride (width * pixelStride) lineStride (width * pixelStride)
{ {
frameBuffer.initialise (context, width, height);
frameBuffer.clear (Colours::transparentBlack);
}
bool initialise()
{
return frameBuffer.initialise (context, width, height);
} }
LowLevelGraphicsContext* createLowLevelContext() LowLevelGraphicsContext* createLowLevelContext()
@@ -175,17 +178,18 @@ int OpenGLImageType::getTypeID() const
return 3; return 3;
} }
ImagePixelData* OpenGLImageType::create (Image::PixelFormat, int width, int height, bool shouldClearImage) const
ImagePixelData* OpenGLImageType::create (Image::PixelFormat, int width, int height, bool /*shouldClearImage*/) const
{ {
OpenGLContext* currentContext = OpenGLContext::getCurrentContext(); OpenGLContext* currentContext = OpenGLContext::getCurrentContext();
jassert (currentContext != nullptr); // an OpenGL image can only be created when a valid context is active! jassert (currentContext != nullptr); // an OpenGL image can only be created when a valid context is active!
OpenGLFrameBufferImage* im = new OpenGLFrameBufferImage (*currentContext, width, height);
ScopedPointer<OpenGLFrameBufferImage> im (new OpenGLFrameBufferImage (*currentContext, width, height));
if (shouldClearImage)
im->frameBuffer.clear (Colours::transparentBlack);
if (! im->initialise())
return nullptr;
return im;
im->frameBuffer.clear (Colours::transparentBlack);
return im.release();
} }
OpenGLFrameBuffer* OpenGLImageType::getFrameBufferFrom (const Image& image) OpenGLFrameBuffer* OpenGLImageType::getFrameBufferFrom (const Image& image)


Loading…
Cancel
Save