Signed-off-by: falkTX <falktx@falktx.com>pull/272/head
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -22,103 +22,8 @@ | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| /** | |||
| OpenGL Image class. | |||
| This is an Image class that handles raw image data in pixels. | |||
| You can init the image data on the contructor or later on by calling loadFromMemory(). | |||
| To generate raw data useful for this class see the utils/png2rgba.py script. | |||
| Be careful when using a PNG without alpha channel, for those the format is 'GL_BGR' | |||
| instead of the default 'GL_BGRA'. | |||
| Images are drawn on screen via 2D textures. | |||
| */ | |||
| class Image : public ImageBase | |||
| { | |||
| public: | |||
| /** | |||
| Constructor for a null Image. | |||
| */ | |||
| Image(); | |||
| /** | |||
| Constructor using raw image data. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| Image(const char* const rawData, | |||
| const uint width, | |||
| const uint height, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE); | |||
| /** | |||
| Constructor using raw image data. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| Image(const char* const rawData, | |||
| const Size<uint>& size, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE); | |||
| /** | |||
| Constructor using another image data. | |||
| */ | |||
| Image(const Image& image); | |||
| /** | |||
| Destructor. | |||
| */ | |||
| ~Image() override; | |||
| /** | |||
| Load image data from memory. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| void loadFromMemory(const char* const rawData, | |||
| const uint width, | |||
| const uint height, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE) noexcept; | |||
| /** | |||
| Load image data from memory. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| void loadFromMemory(const char* const rawData, | |||
| const Size<uint>& size, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE) noexcept; | |||
| /** | |||
| Get the image format. | |||
| */ | |||
| GLenum getFormat() const noexcept; | |||
| /** | |||
| Get the image type. | |||
| */ | |||
| GLenum getType() const noexcept; | |||
| /** | |||
| TODO document this. | |||
| */ | |||
| Image& operator=(const Image& image) noexcept; | |||
| protected: | |||
| /** @internal */ | |||
| void _drawAt(const Point<int>& pos) override; | |||
| private: | |||
| GLenum fFormat; | |||
| GLenum fType; | |||
| GLuint fTextureId; | |||
| bool fIsReady; | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // TODO mark as deprecated | |||
| typedef OpenGLImage Image; | |||
| END_NAMESPACE_DGL | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -21,7 +21,7 @@ | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| Base DGL Image class. | |||
| @@ -68,6 +68,11 @@ public: | |||
| */ | |||
| bool isValid() const noexcept; | |||
| /** | |||
| Check if this image is not valid. | |||
| */ | |||
| bool isInvalid() const noexcept; | |||
| /** | |||
| Get width. | |||
| */ | |||
| @@ -89,19 +94,19 @@ public: | |||
| const char* getRawData() const noexcept; | |||
| /** | |||
| Draw this image at (0, 0) point. | |||
| Draw this image at (0, 0) point using the current OpenGL context. | |||
| */ | |||
| void draw(); | |||
| void draw(const GraphicsContext& context); | |||
| /** | |||
| Draw this image at (x, y) point. | |||
| Draw this image at (x, y) point using the current OpenGL context. | |||
| */ | |||
| void drawAt(const int x, const int y); | |||
| void drawAt(const GraphicsContext& context, const int x, const int y); | |||
| /** | |||
| Draw this image at position @a pos. | |||
| Draw this image at position @a pos using the current OpenGL context. | |||
| */ | |||
| void drawAt(const Point<int>& pos); | |||
| virtual void drawAt(const GraphicsContext& context, const Point<int>& pos) = 0; | |||
| /** | |||
| TODO document this. | |||
| @@ -111,14 +116,11 @@ public: | |||
| bool operator!=(const ImageBase& image) const noexcept; | |||
| protected: | |||
| /** @internal */ | |||
| virtual void _drawAt(const Point<int>& pos) = 0; | |||
| const char* fRawData; | |||
| Size<uint> fSize; | |||
| const char* rawData; | |||
| Size<uint> size; | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -116,6 +116,135 @@ struct OpenGLGraphicsContext : GraphicsContext | |||
| // ----------------------------------------------------------------------- | |||
| /** | |||
| OpenGL Image class. | |||
| This is an Image class that handles raw image data in pixels. | |||
| You can init the image data on the contructor or later on by calling loadFromMemory(). | |||
| To generate raw data useful for this class see the utils/png2rgba.py script. | |||
| Be careful when using a PNG without alpha channel, for those the format is 'GL_BGR' | |||
| instead of the default 'GL_BGRA'. | |||
| Images are drawn on screen via 2D textures. | |||
| */ | |||
| class OpenGLImage : public ImageBase | |||
| { | |||
| public: | |||
| /** | |||
| Constructor for a null Image. | |||
| */ | |||
| OpenGLImage(); | |||
| /** | |||
| Constructor using raw image data. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| OpenGLImage(const char* const rawData, | |||
| const uint width, | |||
| const uint height, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE); | |||
| /** | |||
| Constructor using raw image data. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| OpenGLImage(const char* const rawData, | |||
| const Size<uint>& size, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE); | |||
| /** | |||
| Constructor using another image data. | |||
| */ | |||
| OpenGLImage(const OpenGLImage& image); | |||
| /** | |||
| Destructor. | |||
| */ | |||
| ~OpenGLImage() override; | |||
| /** | |||
| Load image data from memory. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| void loadFromMemory(const char* const rawData, | |||
| const uint width, | |||
| const uint height, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE) noexcept; | |||
| /** | |||
| Load image data from memory. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| */ | |||
| void loadFromMemory(const char* const rawData, | |||
| const Size<uint>& size, | |||
| const GLenum format = GL_BGRA, | |||
| const GLenum type = GL_UNSIGNED_BYTE) noexcept; | |||
| /** | |||
| TODO document this. | |||
| */ | |||
| void setup(); | |||
| /** | |||
| TODO document this. | |||
| */ | |||
| void cleanup(); | |||
| /** | |||
| Get the image format. | |||
| */ | |||
| GLenum getFormat() const noexcept; | |||
| /** | |||
| Get the image type. | |||
| */ | |||
| GLenum getType() const noexcept; | |||
| /** | |||
| Draw this image at position @a pos using the graphics context @a context. | |||
| */ | |||
| void drawAt(const GraphicsContext& context, const Point<int>& pos) override; | |||
| /** | |||
| TODO document this. | |||
| */ | |||
| OpenGLImage& operator=(const OpenGLImage& image) noexcept; | |||
| /** | |||
| Draw this image at (0, 0) point using the current OpenGL context. | |||
| */ | |||
| // TODO mark as deprecated | |||
| void draw(); | |||
| /** | |||
| Draw this image at (x, y) point using the current OpenGL context. | |||
| */ | |||
| // TODO mark as deprecated | |||
| void drawAt(const int x, const int y); | |||
| /** | |||
| Draw this image at position @a pos using the current OpenGL context. | |||
| */ | |||
| // TODO mark as deprecated | |||
| void drawAt(const Point<int>& pos); | |||
| protected: | |||
| /** @internal */ | |||
| // void _drawAt(const Point<int>& pos) override; | |||
| private: | |||
| GLenum fFormat; | |||
| GLenum fType; | |||
| GLuint fTextureId; | |||
| bool setupCalled; | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| #endif | |||
| @@ -1,150 +0,0 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| * permission notice appear in all copies. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #include "../Image.hpp" | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| Image::Image() | |||
| : ImageBase(), | |||
| fFormat(0), | |||
| fType(0), | |||
| fTextureId(0), | |||
| fIsReady(false) | |||
| { | |||
| glGenTextures(1, &fTextureId); | |||
| } | |||
| Image::Image(const Image& image) | |||
| : ImageBase(image), | |||
| fFormat(image.fFormat), | |||
| fType(image.fType), | |||
| fTextureId(0), | |||
| fIsReady(false) | |||
| { | |||
| glGenTextures(1, &fTextureId); | |||
| } | |||
| Image::Image(const char* const rawData, const uint width, const uint height, const GLenum format, const GLenum type) | |||
| : ImageBase(rawData, width, height), | |||
| fFormat(format), | |||
| fType(type), | |||
| fTextureId(0), | |||
| fIsReady(false) | |||
| { | |||
| glGenTextures(1, &fTextureId); | |||
| } | |||
| Image::Image(const char* const rawData, const Size<uint>& size, const GLenum format, const GLenum type) | |||
| : ImageBase(rawData, size), | |||
| fFormat(format), | |||
| fType(type), | |||
| fTextureId(0), | |||
| fIsReady(false) | |||
| { | |||
| glGenTextures(1, &fTextureId); | |||
| } | |||
| Image::~Image() | |||
| { | |||
| if (fTextureId != 0) | |||
| { | |||
| #ifndef DISTRHO_OS_MAC // FIXME | |||
| glDeleteTextures(1, &fTextureId); | |||
| #endif | |||
| fTextureId = 0; | |||
| } | |||
| } | |||
| void Image::loadFromMemory(const char* const rawData, | |||
| const uint width, | |||
| const uint height, | |||
| const GLenum format, | |||
| const GLenum type) noexcept | |||
| { | |||
| loadFromMemory(rawData, Size<uint>(width, height), format, type); | |||
| } | |||
| void Image::loadFromMemory(const char* const rawData, | |||
| const Size<uint>& size, | |||
| const GLenum format, | |||
| const GLenum type) noexcept | |||
| { | |||
| fRawData = rawData; | |||
| fSize = size; | |||
| fFormat = format; | |||
| fType = type; | |||
| fIsReady = false; | |||
| } | |||
| GLenum Image::getFormat() const noexcept | |||
| { | |||
| return fFormat; | |||
| } | |||
| GLenum Image::getType() const noexcept | |||
| { | |||
| return fType; | |||
| } | |||
| Image& Image::operator=(const Image& image) noexcept | |||
| { | |||
| fRawData = image.fRawData; | |||
| fSize = image.fSize; | |||
| fFormat = image.fFormat; | |||
| fType = image.fType; | |||
| fIsReady = false; | |||
| return *this; | |||
| } | |||
| void Image::_drawAt(const Point<int>& pos) | |||
| { | |||
| if (fTextureId == 0 || ! isValid()) | |||
| return; | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, fTextureId); | |||
| if (! fIsReady) | |||
| { | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); | |||
| static const float trans[] = { 0.0f, 0.0f, 0.0f, 0.0f }; | |||
| glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, trans); | |||
| glPixelStorei(GL_PACK_ALIGNMENT, 1); | |||
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
| static_cast<GLsizei>(fSize.getWidth()), static_cast<GLsizei>(fSize.getHeight()), 0, | |||
| fFormat, fType, fRawData); | |||
| fIsReady = true; | |||
| } | |||
| Rectangle<int>(pos, static_cast<int>(fSize.getWidth()), static_cast<int>(fSize.getHeight())).draw(); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_TEXTURE_2D); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -18,82 +18,83 @@ | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // protected constructors | |||
| ImageBase::ImageBase() | |||
| : fRawData(nullptr), | |||
| fSize(0, 0) {} | |||
| : rawData(nullptr), | |||
| size(0, 0) {} | |||
| ImageBase::ImageBase(const char* const rawData, const uint width, const uint height) | |||
| : fRawData(rawData), | |||
| fSize(width, height) {} | |||
| ImageBase::ImageBase(const char* const rdata, const uint width, const uint height) | |||
| : rawData(rdata), | |||
| size(width, height) {} | |||
| ImageBase::ImageBase(const char* const rawData, const Size<uint>& size) | |||
| : fRawData(rawData), | |||
| fSize(size) {} | |||
| ImageBase::ImageBase(const char* const rdata, const Size<uint>& s) | |||
| : rawData(rdata), | |||
| size(s) {} | |||
| ImageBase::ImageBase(const ImageBase& image) | |||
| : fRawData(image.fRawData), | |||
| fSize(image.fSize) {} | |||
| : rawData(image.rawData), | |||
| size(image.size) {} | |||
| ImageBase::~ImageBase() {} | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // public methods | |||
| // ----------------------------------------------------------------------- | |||
| ImageBase::~ImageBase() {} | |||
| bool ImageBase::isValid() const noexcept | |||
| { | |||
| return (fRawData != nullptr && fSize.isValid()); | |||
| return (rawData != nullptr && size.isValid()); | |||
| } | |||
| bool ImageBase::isInvalid() const noexcept | |||
| { | |||
| return (rawData == nullptr || size.isInvalid()); | |||
| } | |||
| uint ImageBase::getWidth() const noexcept | |||
| { | |||
| return fSize.getWidth(); | |||
| return size.getWidth(); | |||
| } | |||
| uint ImageBase::getHeight() const noexcept | |||
| { | |||
| return fSize.getHeight(); | |||
| return size.getHeight(); | |||
| } | |||
| const Size<uint>& ImageBase::getSize() const noexcept | |||
| { | |||
| return fSize; | |||
| return size; | |||
| } | |||
| const char* ImageBase::getRawData() const noexcept | |||
| { | |||
| return fRawData; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| void ImageBase::draw() | |||
| { | |||
| _drawAt(Point<int>()); | |||
| return rawData; | |||
| } | |||
| void ImageBase::drawAt(const int x, const int y) | |||
| void ImageBase::draw(const GraphicsContext& context) | |||
| { | |||
| _drawAt(Point<int>(x, y)); | |||
| drawAt(context, Point<int>(0, 0)); | |||
| } | |||
| void ImageBase::drawAt(const Point<int>& pos) | |||
| void ImageBase::drawAt(const GraphicsContext& context, const int x, const int y) | |||
| { | |||
| _drawAt(pos); | |||
| drawAt(context, Point<int>(x, y)); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // public operators | |||
| ImageBase& ImageBase::operator=(const ImageBase& image) noexcept | |||
| { | |||
| fRawData = image.fRawData; | |||
| fSize = image.fSize; | |||
| rawData = image.rawData; | |||
| size = image.size; | |||
| return *this; | |||
| } | |||
| bool ImageBase::operator==(const ImageBase& image) const noexcept | |||
| { | |||
| return (fRawData == image.fRawData && fSize == image.fSize); | |||
| return (rawData == image.rawData && size == image.size); | |||
| } | |||
| bool ImageBase::operator!=(const ImageBase& image) const noexcept | |||
| @@ -101,6 +102,6 @@ bool ImageBase::operator!=(const ImageBase& image) const noexcept | |||
| return !operator==(image); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -111,6 +111,185 @@ void Rectangle<T>::_draw(const bool outline) | |||
| // ----------------------------------------------------------------------- | |||
| OpenGLImage::OpenGLImage() | |||
| : ImageBase(), | |||
| fFormat(0), | |||
| fType(0), | |||
| fTextureId(0), | |||
| setupCalled(false) {} | |||
| OpenGLImage::OpenGLImage(const OpenGLImage& image) | |||
| : ImageBase(image), | |||
| fFormat(image.fFormat), | |||
| fType(image.fType), | |||
| fTextureId(0), | |||
| setupCalled(false) {} | |||
| OpenGLImage::OpenGLImage(const char* const rawData, const uint width, const uint height, const GLenum format, const GLenum type) | |||
| : ImageBase(rawData, width, height), | |||
| fFormat(format), | |||
| fType(type), | |||
| fTextureId(0), | |||
| setupCalled(false) {} | |||
| OpenGLImage::OpenGLImage(const char* const rawData, const Size<uint>& size, const GLenum format, const GLenum type) | |||
| : ImageBase(rawData, size), | |||
| fFormat(format), | |||
| fType(type), | |||
| fTextureId(0), | |||
| setupCalled(false) {} | |||
| OpenGLImage::~OpenGLImage() | |||
| { | |||
| if (setupCalled) { | |||
| // FIXME test if this is still necessary with new pugl | |||
| #ifndef DISTRHO_OS_MAC | |||
| if (fTextureId != 0) | |||
| cleanup(); | |||
| #endif | |||
| DISTRHO_SAFE_ASSERT(fTextureId == 0); | |||
| } | |||
| } | |||
| void OpenGLImage::loadFromMemory(const char* const rawData, | |||
| const uint width, | |||
| const uint height, | |||
| const GLenum format, | |||
| const GLenum type) noexcept | |||
| { | |||
| loadFromMemory(rawData, Size<uint>(width, height), format, type); | |||
| } | |||
| void OpenGLImage::loadFromMemory(const char* const rdata, | |||
| const Size<uint>& s, | |||
| const GLenum format, | |||
| const GLenum type) noexcept | |||
| { | |||
| rawData = rdata; | |||
| size = s; | |||
| fFormat = format; | |||
| fType = type; | |||
| setupCalled = false; | |||
| } | |||
| void OpenGLImage::setup() | |||
| { | |||
| setupCalled = true; | |||
| DISTRHO_SAFE_ASSERT_RETURN(fTextureId == 0,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(isValid(),); | |||
| glGenTextures(1, &fTextureId); | |||
| DISTRHO_SAFE_ASSERT_RETURN(fTextureId != 0,); | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, fTextureId); | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); | |||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); | |||
| static const float trans[] = { 0.0f, 0.0f, 0.0f, 0.0f }; | |||
| glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, trans); | |||
| glPixelStorei(GL_PACK_ALIGNMENT, 1); | |||
| glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
| static_cast<GLsizei>(size.getWidth()), static_cast<GLsizei>(size.getHeight()), 0, | |||
| fFormat, fType, rawData); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_TEXTURE_2D); | |||
| } | |||
| void OpenGLImage::cleanup() | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fTextureId != 0,); | |||
| glDeleteTextures(1, &fTextureId); | |||
| fTextureId = 0; | |||
| } | |||
| GLenum OpenGLImage::getFormat() const noexcept | |||
| { | |||
| return fFormat; | |||
| } | |||
| GLenum OpenGLImage::getType() const noexcept | |||
| { | |||
| return fType; | |||
| } | |||
| void OpenGLImage::drawAt(const GraphicsContext&, const Point<int>& pos) | |||
| { | |||
| drawAt(pos); | |||
| } | |||
| OpenGLImage& OpenGLImage::operator=(const OpenGLImage& image) noexcept | |||
| { | |||
| rawData = image.rawData; | |||
| size = image.size; | |||
| fFormat = image.fFormat; | |||
| fType = image.fType; | |||
| setupCalled = false; | |||
| return *this; | |||
| } | |||
| void OpenGLImage::draw() | |||
| { | |||
| drawAt(Point<int>(0, 0)); | |||
| } | |||
| void OpenGLImage::drawAt(const int x, const int y) | |||
| { | |||
| drawAt(Point<int>(x, y)); | |||
| } | |||
| void OpenGLImage::drawAt(const Point<int>& pos) | |||
| { | |||
| if (isInvalid()) | |||
| return; | |||
| if (! setupCalled) | |||
| { | |||
| // TODO check if this is valid, give warning about needing to call setup/cleanup manually | |||
| setup(); | |||
| } | |||
| if (fTextureId == 0) | |||
| return; | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, fTextureId); | |||
| glBegin(GL_QUADS); | |||
| { | |||
| const int x = pos.getX(); | |||
| const int y = pos.getY(); | |||
| const int w = static_cast<int>(size.getWidth()); | |||
| const int h = static_cast<int>(size.getHeight()); | |||
| glTexCoord2f(0.0f, 0.0f); | |||
| glVertex2d(x, y); | |||
| glTexCoord2f(1.0f, 0.0f); | |||
| glVertex2d(x+w, y); | |||
| glTexCoord2f(1.0f, 1.0f); | |||
| glVertex2d(x+w, y+h); | |||
| glTexCoord2f(0.0f, 1.0f); | |||
| glVertex2d(x, y+h); | |||
| } | |||
| glEnd(); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_TEXTURE_2D); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| #if 0 | |||
| void Widget::PrivateData::display(const uint width, | |||
| const uint height, | |||
| @@ -25,6 +25,7 @@ | |||
| #include "dgl/src/Application.cpp" | |||
| #include "dgl/src/ApplicationPrivateData.cpp" | |||
| #include "dgl/src/Geometry.cpp" | |||
| #include "dgl/src/ImageBase.cpp" | |||
| #include "dgl/src/OpenGL.cpp" | |||
| #include "dgl/src/SubWidget.cpp" | |||
| #include "dgl/src/SubWidgetPrivateData.cpp" | |||
| @@ -37,9 +38,13 @@ | |||
| #include "dgl/StandaloneWindow.hpp" | |||
| #include "widgets/ExampleColorWidget.hpp" | |||
| #include "widgets/ExampleImagesWidget.hpp" | |||
| #include "widgets/ExampleRectanglesWidget.hpp" | |||
| #include "widgets/ExampleShapesWidget.hpp" | |||
| #include "demo_res/DemoArtwork.cpp" | |||
| #include "images_res/CatPics.cpp" | |||
| START_NAMESPACE_DGL | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -66,6 +71,7 @@ public: | |||
| #if 0 | |||
| // for text | |||
| font = nvg.createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf"); | |||
| #endif | |||
| using namespace DemoArtwork; | |||
| img1.loadFromMemory(ico1Data, ico1Width, ico1Height, GL_BGR); | |||
| @@ -73,7 +79,6 @@ public: | |||
| img3.loadFromMemory(ico3Data, ico3Width, ico2Height, GL_BGR); | |||
| img4.loadFromMemory(ico4Data, ico4Width, ico4Height, GL_BGR); | |||
| img5.loadFromMemory(ico5Data, ico5Width, ico5Height, GL_BGR); | |||
| #endif | |||
| } | |||
| protected: | |||
| @@ -110,7 +115,6 @@ protected: | |||
| // reset color | |||
| glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
| #if 0 | |||
| const int pad = iconSize/2 - DemoArtwork::ico1Width/2; | |||
| img1.drawAt(pad, pad); | |||
| @@ -119,6 +123,7 @@ protected: | |||
| img4.drawAt(pad, pad + 9 + iconSize*3); | |||
| img5.drawAt(pad, pad + 12 + iconSize*4); | |||
| #if 0 | |||
| // draw some text | |||
| nvg.beginFrame(this); | |||
| @@ -215,9 +220,9 @@ private: | |||
| int curPage, curHover; | |||
| Rectangle<double> bgIcon; | |||
| Line<int> lineSep; | |||
| #if 0 | |||
| Image img1, img2, img3, img4, img5; | |||
| OpenGLImage img1, img2, img3, img4, img5; | |||
| #if 0 | |||
| // for text | |||
| NanoVG nvg;D | |||
| NanoVG::FontId font; | |||
| @@ -238,20 +243,21 @@ public: | |||
| DemoWindow(Application& app) | |||
| : StandaloneWindow(app), | |||
| wColor(this), | |||
| wImages(this), | |||
| wRects(this), | |||
| wShapes(this), | |||
| wLeft(this, this), | |||
| curWidget(nullptr) | |||
| { | |||
| wColor.hide(); | |||
| // wImages.hide(); | |||
| wImages.hide(); | |||
| wRects.hide(); | |||
| wShapes.hide(); | |||
| // wText.hide(); | |||
| // //wPerf.hide(); | |||
| wColor.setAbsoluteX(kSidebarWidth); | |||
| // wImages.setAbsoluteX(kSidebarWidth); | |||
| wImages.setAbsoluteX(kSidebarWidth); | |||
| wRects.setAbsoluteX(kSidebarWidth); | |||
| wShapes.setAbsoluteX(kSidebarWidth); | |||
| // wText.setAbsoluteX(kSidebarWidth); | |||
| @@ -275,9 +281,9 @@ protected: | |||
| case 0: | |||
| curWidget = &wColor; | |||
| break; | |||
| // case 1: | |||
| // curWidget = &wImages; | |||
| // break; | |||
| case 1: | |||
| curWidget = &wImages; | |||
| break; | |||
| case 2: | |||
| curWidget = &wRects; | |||
| break; | |||
| @@ -309,7 +315,7 @@ protected: | |||
| Size<uint> size(width-kSidebarWidth, height); | |||
| wColor.setSize(size); | |||
| // wImages.setSize(size); | |||
| wImages.setSize(size); | |||
| wRects.setSize(size); | |||
| wShapes.setSize(size); | |||
| // wText.setSize(size); | |||
| @@ -323,7 +329,7 @@ protected: | |||
| private: | |||
| ExampleColorSubWidget wColor; | |||
| // ExampleImagesWidget wImages; | |||
| ExampleImagesSubWidget wImages; | |||
| ExampleRectanglesSubWidget wRects; | |||
| ExampleShapesSubWidget wShapes; | |||
| // ExampleTextWidget wText; | |||
| @@ -364,6 +370,8 @@ int main(int argc, char* argv[]) | |||
| /**/ if (std::strcmp(argv[1], "color") == 0) | |||
| createAndShowExampleWidgetStandaloneWindow<ExampleColorStandaloneWindow>(app); | |||
| else if (std::strcmp(argv[1], "images") == 0) | |||
| createAndShowExampleWidgetStandaloneWindow<ExampleImagesStandaloneWindow>(app); | |||
| else if (std::strcmp(argv[1], "rectangles") == 0) | |||
| createAndShowExampleWidgetStandaloneWindow<ExampleRectanglesStandaloneWindow>(app); | |||
| else if (std::strcmp(argv[1], "shapes") == 0) | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| @@ -20,22 +20,25 @@ | |||
| // ------------------------------------------------------ | |||
| // DGL Stuff | |||
| #include "Image.hpp" | |||
| #include "Widget.hpp" | |||
| #include "Window.hpp" | |||
| #include "../../dgl/Image.hpp" | |||
| #include "../../dgl/SubWidget.hpp" | |||
| #include "../../dgl/TopLevelWidget.hpp" | |||
| // ------------------------------------------------------ | |||
| // Images | |||
| #include "../images_res/CatPics.hpp" | |||
| START_NAMESPACE_DGL | |||
| // ------------------------------------------------------ | |||
| // our widget | |||
| class ExampleImagesWidget : public Widget, | |||
| template <class BaseWidget> | |||
| class ExampleImagesWidget : public BaseWidget, | |||
| public IdleCallback | |||
| { | |||
| public: | |||
| static const int kImg1y = 0; | |||
| static const int kImg2y = 500/2-CatPics::cat2Height/2; | |||
| static const int kImg3x = 400/3-CatPics::cat3Width/3; | |||
| @@ -44,160 +47,207 @@ public: | |||
| static const int kImg2max = 500-CatPics::cat2Width; | |||
| static const int kImg3max = 400-CatPics::cat3Height; | |||
| ExampleImagesWidget(Window& parent, const bool setParentSize = false) | |||
| : Widget(parent), | |||
| fImgTop1st(1), | |||
| fImgTop2nd(2), | |||
| fImgTop3rd(3), | |||
| fImg1x(0), | |||
| fImg2x(kImg2max), | |||
| fImg3y(kImg3max), | |||
| fImg1rev(false), | |||
| fImg2rev(true), | |||
| fImg3rev(true), | |||
| fImg1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), | |||
| fImg2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), | |||
| fImg3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) | |||
| int imgTop1st, imgTop2nd, imgTop3rd; | |||
| int img1x, img2x, img3y; | |||
| bool img1rev, img2rev, img3rev; | |||
| Image img1, img2, img3; | |||
| public: | |||
| static constexpr const char* kExampleWidgetName = "Images"; | |||
| // SubWidget | |||
| ExampleImagesWidget(Widget* const parent) | |||
| : BaseWidget(parent), | |||
| imgTop1st(1), | |||
| imgTop2nd(2), | |||
| imgTop3rd(3), | |||
| img1x(0), | |||
| img2x(kImg2max), | |||
| img3y(kImg3max), | |||
| img1rev(false), | |||
| img2rev(true), | |||
| img3rev(true), | |||
| img1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), | |||
| img2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), | |||
| img3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) | |||
| { | |||
| setSize(500, 400); | |||
| BaseWidget::setSize(500, 400); | |||
| parent.addIdleCallback(this); | |||
| parent->getApp().addIdleCallback(this); | |||
| } | |||
| if (setParentSize) | |||
| { | |||
| parent.setSize(500, 400); | |||
| parent.setResizable(false); | |||
| } | |||
| // TopLevelWidget | |||
| ExampleImagesWidget(Window& windowToMapTo) | |||
| : BaseWidget(windowToMapTo), | |||
| imgTop1st(1), | |||
| imgTop2nd(2), | |||
| imgTop3rd(3), | |||
| img1x(0), | |||
| img2x(kImg2max), | |||
| img3y(kImg3max), | |||
| img1rev(false), | |||
| img2rev(true), | |||
| img3rev(true), | |||
| img1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), | |||
| img2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), | |||
| img3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) | |||
| { | |||
| BaseWidget::setSize(500, 400); | |||
| windowToMapTo.getApp().addIdleCallback(this); | |||
| } | |||
| private: | |||
| // StandaloneWindow | |||
| ExampleImagesWidget(Application& app) | |||
| : BaseWidget(app), | |||
| imgTop1st(1), | |||
| imgTop2nd(2), | |||
| imgTop3rd(3), | |||
| img1x(0), | |||
| img2x(kImg2max), | |||
| img3y(kImg3max), | |||
| img1rev(false), | |||
| img2rev(true), | |||
| img3rev(true), | |||
| img1(CatPics::cat1Data, CatPics::cat1Width, CatPics::cat1Height, GL_BGR), | |||
| img2(CatPics::cat2Data, CatPics::cat2Width, CatPics::cat2Height, GL_BGR), | |||
| img3(CatPics::cat3Data, CatPics::cat3Width, CatPics::cat3Height, GL_BGR) | |||
| { | |||
| BaseWidget::setSize(500, 400); | |||
| app.addIdleCallback(this); | |||
| } | |||
| protected: | |||
| void idleCallback() noexcept override | |||
| { | |||
| if (fImg1rev) | |||
| if (img1rev) | |||
| { | |||
| fImg1x -= 2; | |||
| if (fImg1x <= -50) | |||
| img1x -= 2; | |||
| if (img1x <= -50) | |||
| { | |||
| fImg1rev = false; | |||
| img1rev = false; | |||
| setNewTopImg(1); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| fImg1x += 2; | |||
| if (fImg1x >= kImg1max+50) | |||
| img1x += 2; | |||
| if (img1x >= kImg1max+50) | |||
| { | |||
| fImg1rev = true; | |||
| img1rev = true; | |||
| setNewTopImg(1); | |||
| } | |||
| } | |||
| if (fImg2rev) | |||
| if (img2rev) | |||
| { | |||
| fImg2x -= 1; | |||
| if (fImg2x <= -50) | |||
| img2x -= 1; | |||
| if (img2x <= -50) | |||
| { | |||
| fImg2rev = false; | |||
| img2rev = false; | |||
| setNewTopImg(2); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| fImg2x += 4; | |||
| if (fImg2x >= kImg2max+50) | |||
| img2x += 4; | |||
| if (img2x >= kImg2max+50) | |||
| { | |||
| fImg2rev = true; | |||
| img2rev = true; | |||
| setNewTopImg(2); | |||
| } | |||
| } | |||
| if (fImg3rev) | |||
| if (img3rev) | |||
| { | |||
| fImg3y -= 3; | |||
| if (fImg3y <= -50) | |||
| img3y -= 3; | |||
| if (img3y <= -50) | |||
| { | |||
| fImg3rev = false; | |||
| img3rev = false; | |||
| setNewTopImg(3); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| fImg3y += 3; | |||
| if (fImg3y >= kImg3max+50) | |||
| img3y += 3; | |||
| if (img3y >= kImg3max+50) | |||
| { | |||
| fImg3rev = true; | |||
| img3rev = true; | |||
| setNewTopImg(3); | |||
| } | |||
| } | |||
| repaint(); | |||
| BaseWidget::repaint(); | |||
| } | |||
| void onDisplay() override | |||
| { | |||
| switch (fImgTop3rd) | |||
| switch (imgTop3rd) | |||
| { | |||
| case 1: | |||
| fImg1.drawAt(fImg1x, kImg1y); | |||
| img1.drawAt(img1x, kImg1y); | |||
| break; | |||
| case 2: | |||
| fImg2.drawAt(fImg2x, kImg2y); | |||
| img2.drawAt(img2x, kImg2y); | |||
| break; | |||
| case 3: | |||
| fImg3.drawAt(kImg3x, fImg3y); | |||
| img3.drawAt(kImg3x, img3y); | |||
| break; | |||
| }; | |||
| switch (fImgTop2nd) | |||
| switch (imgTop2nd) | |||
| { | |||
| case 1: | |||
| fImg1.drawAt(fImg1x, kImg1y); | |||
| img1.drawAt(img1x, kImg1y); | |||
| break; | |||
| case 2: | |||
| fImg2.drawAt(fImg2x, kImg2y); | |||
| img2.drawAt(img2x, kImg2y); | |||
| break; | |||
| case 3: | |||
| fImg3.drawAt(kImg3x, fImg3y); | |||
| img3.drawAt(kImg3x, img3y); | |||
| break; | |||
| }; | |||
| switch (fImgTop1st) | |||
| switch (imgTop1st) | |||
| { | |||
| case 1: | |||
| fImg1.drawAt(fImg1x, kImg1y); | |||
| img1.drawAt(img1x, kImg1y); | |||
| break; | |||
| case 2: | |||
| fImg2.drawAt(fImg2x, kImg2y); | |||
| img2.drawAt(img2x, kImg2y); | |||
| break; | |||
| case 3: | |||
| fImg3.drawAt(kImg3x, fImg3y); | |||
| img3.drawAt(kImg3x, img3y); | |||
| break; | |||
| }; | |||
| } | |||
| private: | |||
| void setNewTopImg(const int imgId) noexcept | |||
| { | |||
| if (fImgTop1st == imgId) | |||
| if (imgTop1st == imgId) | |||
| return; | |||
| if (fImgTop2nd == imgId) | |||
| if (imgTop2nd == imgId) | |||
| { | |||
| fImgTop2nd = fImgTop1st; | |||
| fImgTop1st = imgId; | |||
| imgTop2nd = imgTop1st; | |||
| imgTop1st = imgId; | |||
| return; | |||
| } | |||
| fImgTop3rd = fImgTop2nd; | |||
| fImgTop2nd = fImgTop1st; | |||
| fImgTop1st = imgId; | |||
| imgTop3rd = imgTop2nd; | |||
| imgTop2nd = imgTop1st; | |||
| imgTop1st = imgId; | |||
| } | |||
| int fImgTop1st, fImgTop2nd, fImgTop3rd; | |||
| int fImg1x, fImg2x, fImg3y; | |||
| bool fImg1rev, fImg2rev, fImg3rev; | |||
| Image fImg1, fImg2, fImg3; | |||
| }; | |||
| typedef ExampleImagesWidget<SubWidget> ExampleImagesSubWidget; | |||
| typedef ExampleImagesWidget<TopLevelWidget> ExampleImagesTopLevelWidget; | |||
| typedef ExampleImagesWidget<StandaloneWindow> ExampleImagesStandaloneWindow; | |||
| // ------------------------------------------------------ | |||
| END_NAMESPACE_DGL | |||
| #endif // EXAMPLE_IMAGES_WIDGET_HPP_INCLUDED | |||