Browse Source

Make images work again, make Image typedef of OpenGLImage

Signed-off-by: falkTX <falktx@falktx.com>
pull/272/head
falkTX 4 years ago
parent
commit
c10f6b5438
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
8 changed files with 506 additions and 382 deletions
  1. +3
    -98
      dgl/Image.hpp
  2. +16
    -14
      dgl/ImageBase.hpp
  3. +129
    -0
      dgl/OpenGL.hpp
  4. +0
    -150
      dgl/src/Image.cpp
  5. +36
    -35
      dgl/src/ImageBase.cpp
  6. +179
    -0
      dgl/src/OpenGL.cpp
  7. +19
    -11
      tests/Demo.cpp
  8. +124
    -74
      tests/widgets/ExampleImagesWidget.hpp

+ 3
- 98
dgl/Image.hpp View File

@@ -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



+ 16
- 14
dgl/ImageBase.hpp View File

@@ -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



+ 129
- 0
dgl/OpenGL.hpp View File

@@ -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

+ 0
- 150
dgl/src/Image.cpp View File

@@ -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

+ 36
- 35
dgl/src/ImageBase.cpp View File

@@ -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

+ 179
- 0
dgl/src/OpenGL.cpp View File

@@ -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,


+ 19
- 11
tests/Demo.cpp View File

@@ -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)


+ 124
- 74
tests/widgets/ExampleImagesWidget.hpp View File

@@ -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

Loading…
Cancel
Save