From 49ddaddbae94230a9c25b97f2637c9ed461055d2 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 8 May 2018 11:15:17 +0100 Subject: [PATCH] Added a lambda callback to OpenGLGraphicsContextCustomShader to allow custom set-up when the shader is activated --- .../opengl/juce_OpenGLGraphicsContext.cpp | 86 +++++++++---------- .../opengl/juce_OpenGLGraphicsContext.h | 18 ++-- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 869a28b728..4d49340a86 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -46,12 +46,12 @@ struct CachedImageList : public ReferenceCountedObject, private ImagePixelData::Listener { CachedImageList (OpenGLContext& c) noexcept - : context (c), totalSize (0), maxCacheSize (c.getImageCacheSize()) {} + : context (c), maxCacheSize (c.getImageCacheSize()) {} static CachedImageList* get (OpenGLContext& c) { const char cacheValueID[] = "CachedImages"; - CachedImageList* list = static_cast (c.getAssociatedObject (cacheValueID)); + auto list = static_cast (c.getAssociatedObject (cacheValueID)); if (list == nullptr) { @@ -64,13 +64,12 @@ struct CachedImageList : public ReferenceCountedObject, TextureInfo getTextureFor (const Image& image) { - ImagePixelData* const pixelData = image.getPixelData(); - - CachedImage* c = findCachedImage (pixelData); + auto pixelData = image.getPixelData(); + auto* c = findCachedImage (pixelData); if (c == nullptr) { - if (OpenGLFrameBuffer* const fb = OpenGLImageType::getFrameBufferFrom (image)) + if (auto fb = OpenGLImageType::getFrameBufferFrom (image)) { TextureInfo t; t.textureID = fb->getTextureID(); @@ -97,8 +96,7 @@ struct CachedImageList : public ReferenceCountedObject, CachedImage (CachedImageList& list, ImagePixelData* im) : owner (list), pixelData (im), lastUsed (Time::getCurrentTime()), - imageSize ((size_t) (im->width * im->height)), - textureNeedsReloading (true) + imageSize ((size_t) (im->width * im->height)) { pixelData->listeners.add (&owner); } @@ -126,7 +124,6 @@ struct CachedImageList : public ReferenceCountedObject, t.fullHeightProportion = t.imageHeight / (float) texture.getHeight(); lastUsed = Time::getCurrentTime(); - return t; } @@ -135,7 +132,7 @@ struct CachedImageList : public ReferenceCountedObject, OpenGLTexture texture; Time lastUsed; const size_t imageSize; - bool textureNeedsReloading; + bool textureNeedsReloading = true; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedImage) }; @@ -145,7 +142,8 @@ struct CachedImageList : public ReferenceCountedObject, private: OpenGLContext& context; OwnedArray images; - size_t totalSize, maxCacheSize; + size_t totalSize = 0; + const size_t maxCacheSize; bool canUseContext() const noexcept { @@ -154,7 +152,7 @@ private: void imageDataChanged (ImagePixelData* im) override { - if (CachedImage* c = findCachedImage (im)) + if (auto* c = findCachedImage (im)) c->textureNeedsReloading = true; } @@ -162,7 +160,7 @@ private: { for (int i = images.size(); --i >= 0;) { - CachedImage& ci = *images.getUnchecked(i); + auto& ci = *images.getUnchecked(i); if (ci.pixelData == im) { @@ -181,30 +179,22 @@ private: } } - CachedImage* findCachedImage (ImagePixelData* const pixelData) const + CachedImage* findCachedImage (ImagePixelData* pixelData) const { - for (int i = 0; i < images.size(); ++i) - { - CachedImage* c = images.getUnchecked(i); - - if (c->pixelData == pixelData) - return c; - } + for (auto& i : images) + if (i->pixelData == pixelData) + return i; - return nullptr; + return {}; } void removeOldestItem() { CachedImage* oldest = nullptr; - for (int i = 0; i < images.size(); ++i) - { - CachedImage* c = images.getUnchecked(i); - - if (oldest == nullptr || c->lastUsed < oldest->lastUsed) - oldest = c; - } + for (auto& i : images) + if (oldest == nullptr || i->lastUsed < oldest->lastUsed) + oldest = i; if (oldest != nullptr) { @@ -445,9 +435,8 @@ struct ShaderPrograms : public ReferenceCountedObject } OpenGLShaderProgram::Attribute positionAttribute, colourAttribute; - - private: OpenGLShaderProgram::Uniform screenBounds; + std::function onShaderActivated; }; struct MaskedShaderParams @@ -831,9 +820,7 @@ struct StateHelpers { struct BlendingMode { - BlendingMode() noexcept - : blendingEnabled (false), srcFunction (0), dstFunction (0) - {} + BlendingMode() noexcept {} void resync() noexcept { @@ -887,8 +874,8 @@ struct StateHelpers } private: - bool blendingEnabled; - GLenum srcFunction, dstFunction; + bool blendingEnabled = false; + GLenum srcFunction = 0, dstFunction = 0; }; //============================================================================== @@ -975,8 +962,7 @@ struct StateHelpers //============================================================================== struct ActiveTextures { - ActiveTextures (const OpenGLContext& c) noexcept - : texturesEnabled (0), currentActiveTexture (-1), context (c) + ActiveTextures (const OpenGLContext& c) noexcept : context (c) {} void clear() noexcept @@ -1048,6 +1034,7 @@ struct StateHelpers setActiveTexture (0); bindTexture (texture1); } + JUCE_CHECK_OPENGL_ERROR } @@ -1083,7 +1070,7 @@ struct StateHelpers private: GLuint currentTextureID[3]; - int texturesEnabled, currentActiveTexture; + int texturesEnabled = 0, currentActiveTexture = -1; const OpenGLContext& context; ActiveTextures& operator= (const ActiveTextures&); @@ -1330,6 +1317,9 @@ struct StateHelpers shader.program.use(); shader.bindAttributes (context); + if (shader.onShaderActivated) + shader.onShaderActivated (shader.program); + currentBounds = bounds; shader.set2DBounds (bounds.toFloat()); @@ -1860,7 +1850,8 @@ struct CustomProgram : public ReferenceCountedObject, return nullptr; } - static CustomProgram* getOrCreate (LowLevelGraphicsContext& gc, const String& hashName, const String& code, String& errorMessage) + static CustomProgram* getOrCreate (LowLevelGraphicsContext& gc, const String& hashName, + const String& code, String& errorMessage) { if (auto* c = get (hashName)) return c; @@ -1872,7 +1863,7 @@ struct CustomProgram : public ReferenceCountedObject, if (errorMessage.isEmpty()) { - if (OpenGLContext* context = OpenGLContext::getCurrentContext()) + if (auto context = OpenGLContext::getCurrentContext()) { context->setAssociatedObject (hashName.toRawUTF8(), c); return c; @@ -1904,19 +1895,24 @@ OpenGLShaderProgram* OpenGLGraphicsContextCustomShader::getProgram (LowLevelGrap { String errorMessage; - if (CustomProgram* c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage)) + if (auto c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage)) return &(c->program); - return nullptr; + return {}; } void OpenGLGraphicsContextCustomShader::fillRect (LowLevelGraphicsContext& gc, Rectangle area) const { String errorMessage; - if (OpenGLRendering::ShaderContext* sc = dynamic_cast (&gc)) - if (CustomProgram* c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage)) + if (auto sc = dynamic_cast (&gc)) + { + if (auto c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage)) + { + c->onShaderActivated = onShaderActivated; sc->fillRectWithCustomShader (*c, area); + } + } } Result OpenGLGraphicsContextCustomShader::checkCompilation (LowLevelGraphicsContext& gc) diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h index 8e927f8c82..25b0187b45 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h @@ -30,19 +30,18 @@ namespace juce /** 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& target, - int width, int height); +LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext&, int width, int height); -/** Creates a graphics context object that will render into the given OpenGL target. +/** Creates a graphics context object that will render into the given OpenGL framebuffer. The caller is responsible for deleting this object when no longer needed. */ -LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context, - OpenGLFrameBuffer& target); +LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext&, OpenGLFrameBuffer&); -/** Creates a graphics context object that will render into the given OpenGL target. +/** Creates a graphics context object that will render into the given OpenGL framebuffer, + with the given size. The caller is responsible for deleting this object when no longer needed. */ -LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context, +LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext&, unsigned int frameBufferID, int width, int height); @@ -89,6 +88,11 @@ struct JUCE_API OpenGLGraphicsContextCustomShader /** Returns the code that was used to create this object. */ const String& getFragmentShaderCode() const noexcept { return code; } + /** Optional lambda that will be called when the shader is activated, to allow + user code to do setup tasks. + */ + std::function onShaderActivated; + private: String code, hashName;