Browse Source

Added a lambda callback to OpenGLGraphicsContextCustomShader to allow custom set-up when the shader is activated

tags/2021-05-28
jules 7 years ago
parent
commit
49ddaddbae
2 changed files with 52 additions and 52 deletions
  1. +41
    -45
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
  2. +11
    -7
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h

+ 41
- 45
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp View File

@@ -46,12 +46,12 @@ struct CachedImageList : public ReferenceCountedObject,
private ImagePixelData::Listener private ImagePixelData::Listener
{ {
CachedImageList (OpenGLContext& c) noexcept CachedImageList (OpenGLContext& c) noexcept
: context (c), totalSize (0), maxCacheSize (c.getImageCacheSize()) {}
: context (c), maxCacheSize (c.getImageCacheSize()) {}
static CachedImageList* get (OpenGLContext& c) static CachedImageList* get (OpenGLContext& c)
{ {
const char cacheValueID[] = "CachedImages"; const char cacheValueID[] = "CachedImages";
CachedImageList* list = static_cast<CachedImageList*> (c.getAssociatedObject (cacheValueID));
auto list = static_cast<CachedImageList*> (c.getAssociatedObject (cacheValueID));
if (list == nullptr) if (list == nullptr)
{ {
@@ -64,13 +64,12 @@ struct CachedImageList : public ReferenceCountedObject,
TextureInfo getTextureFor (const Image& image) 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 (c == nullptr)
{ {
if (OpenGLFrameBuffer* const fb = OpenGLImageType::getFrameBufferFrom (image))
if (auto fb = OpenGLImageType::getFrameBufferFrom (image))
{ {
TextureInfo t; TextureInfo t;
t.textureID = fb->getTextureID(); t.textureID = fb->getTextureID();
@@ -97,8 +96,7 @@ struct CachedImageList : public ReferenceCountedObject,
CachedImage (CachedImageList& list, ImagePixelData* im) CachedImage (CachedImageList& list, ImagePixelData* im)
: owner (list), pixelData (im), : owner (list), pixelData (im),
lastUsed (Time::getCurrentTime()), lastUsed (Time::getCurrentTime()),
imageSize ((size_t) (im->width * im->height)),
textureNeedsReloading (true)
imageSize ((size_t) (im->width * im->height))
{ {
pixelData->listeners.add (&owner); pixelData->listeners.add (&owner);
} }
@@ -126,7 +124,6 @@ struct CachedImageList : public ReferenceCountedObject,
t.fullHeightProportion = t.imageHeight / (float) texture.getHeight(); t.fullHeightProportion = t.imageHeight / (float) texture.getHeight();
lastUsed = Time::getCurrentTime(); lastUsed = Time::getCurrentTime();
return t; return t;
} }
@@ -135,7 +132,7 @@ struct CachedImageList : public ReferenceCountedObject,
OpenGLTexture texture; OpenGLTexture texture;
Time lastUsed; Time lastUsed;
const size_t imageSize; const size_t imageSize;
bool textureNeedsReloading;
bool textureNeedsReloading = true;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedImage) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedImage)
}; };
@@ -145,7 +142,8 @@ struct CachedImageList : public ReferenceCountedObject,
private: private:
OpenGLContext& context; OpenGLContext& context;
OwnedArray<CachedImage> images; OwnedArray<CachedImage> images;
size_t totalSize, maxCacheSize;
size_t totalSize = 0;
const size_t maxCacheSize;
bool canUseContext() const noexcept bool canUseContext() const noexcept
{ {
@@ -154,7 +152,7 @@ private:
void imageDataChanged (ImagePixelData* im) override void imageDataChanged (ImagePixelData* im) override
{ {
if (CachedImage* c = findCachedImage (im))
if (auto* c = findCachedImage (im))
c->textureNeedsReloading = true; c->textureNeedsReloading = true;
} }
@@ -162,7 +160,7 @@ private:
{ {
for (int i = images.size(); --i >= 0;) for (int i = images.size(); --i >= 0;)
{ {
CachedImage& ci = *images.getUnchecked(i);
auto& ci = *images.getUnchecked(i);
if (ci.pixelData == im) 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() void removeOldestItem()
{ {
CachedImage* oldest = nullptr; 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) if (oldest != nullptr)
{ {
@@ -445,9 +435,8 @@ struct ShaderPrograms : public ReferenceCountedObject
} }
OpenGLShaderProgram::Attribute positionAttribute, colourAttribute; OpenGLShaderProgram::Attribute positionAttribute, colourAttribute;
private:
OpenGLShaderProgram::Uniform screenBounds; OpenGLShaderProgram::Uniform screenBounds;
std::function<void(OpenGLShaderProgram&)> onShaderActivated;
}; };
struct MaskedShaderParams struct MaskedShaderParams
@@ -831,9 +820,7 @@ struct StateHelpers
{ {
struct BlendingMode struct BlendingMode
{ {
BlendingMode() noexcept
: blendingEnabled (false), srcFunction (0), dstFunction (0)
{}
BlendingMode() noexcept {}
void resync() noexcept void resync() noexcept
{ {
@@ -887,8 +874,8 @@ struct StateHelpers
} }
private: private:
bool blendingEnabled;
GLenum srcFunction, dstFunction;
bool blendingEnabled = false;
GLenum srcFunction = 0, dstFunction = 0;
}; };
//============================================================================== //==============================================================================
@@ -975,8 +962,7 @@ struct StateHelpers
//============================================================================== //==============================================================================
struct ActiveTextures struct ActiveTextures
{ {
ActiveTextures (const OpenGLContext& c) noexcept
: texturesEnabled (0), currentActiveTexture (-1), context (c)
ActiveTextures (const OpenGLContext& c) noexcept : context (c)
{} {}
void clear() noexcept void clear() noexcept
@@ -1048,6 +1034,7 @@ struct StateHelpers
setActiveTexture (0); setActiveTexture (0);
bindTexture (texture1); bindTexture (texture1);
} }
JUCE_CHECK_OPENGL_ERROR JUCE_CHECK_OPENGL_ERROR
} }
@@ -1083,7 +1070,7 @@ struct StateHelpers
private: private:
GLuint currentTextureID[3]; GLuint currentTextureID[3];
int texturesEnabled, currentActiveTexture;
int texturesEnabled = 0, currentActiveTexture = -1;
const OpenGLContext& context; const OpenGLContext& context;
ActiveTextures& operator= (const ActiveTextures&); ActiveTextures& operator= (const ActiveTextures&);
@@ -1330,6 +1317,9 @@ struct StateHelpers
shader.program.use(); shader.program.use();
shader.bindAttributes (context); shader.bindAttributes (context);
if (shader.onShaderActivated)
shader.onShaderActivated (shader.program);
currentBounds = bounds; currentBounds = bounds;
shader.set2DBounds (bounds.toFloat()); shader.set2DBounds (bounds.toFloat());
@@ -1860,7 +1850,8 @@ struct CustomProgram : public ReferenceCountedObject,
return nullptr; 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)) if (auto* c = get (hashName))
return c; return c;
@@ -1872,7 +1863,7 @@ struct CustomProgram : public ReferenceCountedObject,
if (errorMessage.isEmpty()) if (errorMessage.isEmpty())
{ {
if (OpenGLContext* context = OpenGLContext::getCurrentContext())
if (auto context = OpenGLContext::getCurrentContext())
{ {
context->setAssociatedObject (hashName.toRawUTF8(), c); context->setAssociatedObject (hashName.toRawUTF8(), c);
return c; return c;
@@ -1904,19 +1895,24 @@ OpenGLShaderProgram* OpenGLGraphicsContextCustomShader::getProgram (LowLevelGrap
{ {
String errorMessage; String errorMessage;
if (CustomProgram* c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage))
if (auto c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage))
return &(c->program); return &(c->program);
return nullptr;
return {};
} }
void OpenGLGraphicsContextCustomShader::fillRect (LowLevelGraphicsContext& gc, Rectangle<int> area) const void OpenGLGraphicsContextCustomShader::fillRect (LowLevelGraphicsContext& gc, Rectangle<int> area) const
{ {
String errorMessage; String errorMessage;
if (OpenGLRendering::ShaderContext* sc = dynamic_cast<OpenGLRendering::ShaderContext*> (&gc))
if (CustomProgram* c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage))
if (auto sc = dynamic_cast<OpenGLRendering::ShaderContext*> (&gc))
{
if (auto c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage))
{
c->onShaderActivated = onShaderActivated;
sc->fillRectWithCustomShader (*c, area); sc->fillRectWithCustomShader (*c, area);
}
}
} }
Result OpenGLGraphicsContextCustomShader::checkCompilation (LowLevelGraphicsContext& gc) Result OpenGLGraphicsContextCustomShader::checkCompilation (LowLevelGraphicsContext& gc)


+ 11
- 7
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h View File

@@ -30,19 +30,18 @@ namespace juce
/** 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 target.
The caller is responsible for deleting this object when no longer needed. 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. 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. The caller is responsible for deleting this object when no longer needed.
*/ */
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext& context,
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext&,
unsigned int frameBufferID, unsigned int frameBufferID,
int width, int height); int width, int height);
@@ -89,6 +88,11 @@ struct JUCE_API OpenGLGraphicsContextCustomShader
/** Returns the code that was used to create this object. */ /** Returns the code that was used to create this object. */
const String& getFragmentShaderCode() const noexcept { return code; } 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<void(OpenGLShaderProgram&)> onShaderActivated;
private: private:
String code, hashName; String code, hashName;


Loading…
Cancel
Save