mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added a lambda callback to OpenGLGraphicsContextCustomShader to allow custom set-up when the shader is activated
This commit is contained in:
parent
a85dc1c5fe
commit
49ddaddbae
2 changed files with 52 additions and 52 deletions
|
|
@ -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();
|
auto pixelData = image.getPixelData();
|
||||||
|
auto* c = findCachedImage (pixelData);
|
||||||
CachedImage* 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)),
|
imageSize ((size_t) (im->width * im->height))
|
||||||
textureNeedsReloading (true)
|
|
||||||
{
|
{
|
||||||
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)
|
for (auto& i : images)
|
||||||
{
|
if (i->pixelData == pixelData)
|
||||||
CachedImage* c = images.getUnchecked(i);
|
return i;
|
||||||
|
|
||||||
if (c->pixelData == pixelData)
|
return {};
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeOldestItem()
|
void removeOldestItem()
|
||||||
{
|
{
|
||||||
CachedImage* oldest = nullptr;
|
CachedImage* oldest = nullptr;
|
||||||
|
|
||||||
for (int i = 0; i < images.size(); ++i)
|
for (auto& i : images)
|
||||||
{
|
if (oldest == nullptr || i->lastUsed < oldest->lastUsed)
|
||||||
CachedImage* c = images.getUnchecked(i);
|
oldest = i;
|
||||||
|
|
||||||
if (oldest == nullptr || c->lastUsed < oldest->lastUsed)
|
|
||||||
oldest = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
BlendingMode() noexcept {}
|
||||||
: blendingEnabled (false), srcFunction (0), dstFunction (0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void resync() noexcept
|
void resync() noexcept
|
||||||
{
|
{
|
||||||
|
|
@ -887,8 +874,8 @@ struct StateHelpers
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool blendingEnabled;
|
bool blendingEnabled = false;
|
||||||
GLenum srcFunction, dstFunction;
|
GLenum srcFunction = 0, dstFunction = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
@ -975,8 +962,7 @@ struct StateHelpers
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
struct ActiveTextures
|
struct ActiveTextures
|
||||||
{
|
{
|
||||||
ActiveTextures (const OpenGLContext& c) noexcept
|
ActiveTextures (const OpenGLContext& c) noexcept : context (c)
|
||||||
: texturesEnabled (0), currentActiveTexture (-1), 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 (auto sc = dynamic_cast<OpenGLRendering::ShaderContext*> (&gc))
|
||||||
if (CustomProgram* c = CustomProgram::getOrCreate (gc, hashName, code, errorMessage))
|
{
|
||||||
|
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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext&, int width, int height);
|
||||||
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,
|
LowLevelGraphicsContext* createOpenGLGraphicsContext (OpenGLContext&, OpenGLFrameBuffer&);
|
||||||
OpenGLFrameBuffer& target);
|
|
||||||
|
|
||||||
/** 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…
Add table
Add a link
Reference in a new issue