Signed-off-by: falkTX <falktx@falktx.com>pull/506/head
| @@ -98,24 +98,52 @@ jobs: | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} | |||
| - name: With OpenGL 3.x | |||
| - name: Without Cairo | |||
| env: | |||
| CFLAGS: -Werror | |||
| CXXFLAGS: -Werror | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} USE_OPENGL3=true | |||
| - name: Without Cairo | |||
| make -j ${{ env.JOBS }} HAVE_CAIRO=false | |||
| - name: Without OpenGL | |||
| env: | |||
| CFLAGS: -Werror | |||
| CXXFLAGS: -Werror | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} HAVE_CAIRO=false | |||
| - name: Without OpenGL | |||
| make -j ${{ env.JOBS }} HAVE_OPENGL=false | |||
| - name: With UI_TYPE=generic | |||
| env: | |||
| CFLAGS: -Werror | |||
| CXXFLAGS: -Werror | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} HAVE_OPENGL=false | |||
| make -j ${{ env.JOBS }} -C examples/Parameters UI_TYPE=generic | |||
| - name: With UI_TYPE=gles2 | |||
| env: | |||
| CFLAGS: -Werror | |||
| CXXFLAGS: -Werror | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} -C examples/Parameters UI_TYPE=gles2 | |||
| - name: With UI_TYPE=gles3 | |||
| env: | |||
| CFLAGS: -Werror | |||
| CXXFLAGS: -Werror | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} -C examples/Parameters UI_TYPE=gles3 | |||
| - name: With UI_TYPE=opengl | |||
| env: | |||
| CFLAGS: -Werror | |||
| CXXFLAGS: -Werror | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} -C examples/Parameters UI_TYPE=opengl | |||
| - name: With UI_TYPE=opengl3 | |||
| env: | |||
| CFLAGS: -Werror | |||
| CXXFLAGS: -Werror | |||
| run: | | |||
| make clean >/dev/null | |||
| make -j ${{ env.JOBS }} -C examples/Parameters UI_TYPE=opengl3 | |||
| @@ -9,7 +9,7 @@ | |||
| # extra useful variables to define before including this file: | |||
| # - DPF_BUILD_DIR: where to place temporary build files | |||
| # - DPF_TARGET_DIR: where to place final binary files | |||
| # - UI_TYPE: one of cairo, gles2, gles3, opengl, opengl3 or external, with opengl being default | |||
| # - UI_TYPE: one of cairo, external, gles2, gles3, opengl, opengl3 or webview, with opengl being default | |||
| # ("generic" is also allowed if only using basic DPF classes like image widgets) | |||
| # override the "all" target after including this file to define which plugin formats to build, like so: | |||
| @@ -1003,6 +1003,7 @@ function(dpf__add_dgl_gles2 SHARED_RESOURCES USE_FILE_BROWSER USE_WEB_VIEW) | |||
| "${DPF_ROOT_DIR}/dgl/src/Window.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL3.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | |||
| if(SHARED_RESOURCES) | |||
| target_sources(dgl-gles2 PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | |||
| @@ -1101,6 +1102,7 @@ function(dpf__add_dgl_gles3 SHARED_RESOURCES USE_FILE_BROWSER USE_WEB_VIEW) | |||
| "${DPF_ROOT_DIR}/dgl/src/Window.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL3.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | |||
| if(SHARED_RESOURCES) | |||
| target_sources(dgl-gles3 PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | |||
| @@ -1194,6 +1196,7 @@ function(dpf__add_dgl_opengl SHARED_RESOURCES USE_FILE_BROWSER USE_WEB_VIEW) | |||
| "${DPF_ROOT_DIR}/dgl/src/Window.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL2.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | |||
| if(SHARED_RESOURCES) | |||
| target_sources(dgl-opengl PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | |||
| @@ -1289,6 +1292,7 @@ function(dpf__add_dgl_opengl3 SHARED_RESOURCES USE_FILE_BROWSER USE_WEB_VIEW) | |||
| "${DPF_ROOT_DIR}/dgl/src/Window.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL3.cpp" | |||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | |||
| if(SHARED_RESOURCES) | |||
| target_sources(dgl-opengl3 PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | |||
| @@ -49,6 +49,10 @@ | |||
| # error DGL_FILE_BROWSER_DISABLED has been replaced by DGL_USE_FILE_BROWSER (opt-in vs opt-out) | |||
| #endif | |||
| #ifndef DGL_ALLOW_DEPRECATED_METHODS | |||
| # define DGL_ALLOW_DEPRECATED_METHODS 1 | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Define namespace | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 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 | |||
| @@ -165,10 +165,9 @@ private: | |||
| Widget display function. | |||
| Implemented internally to pass context into the drawing function. | |||
| */ | |||
| void onDisplay() override | |||
| void onDisplay() final | |||
| { | |||
| const CairoGraphicsContext& context((const CairoGraphicsContext&)BaseWidget::getGraphicsContext()); | |||
| onCairoDisplay(context); | |||
| onCairoDisplay(static_cast<const CairoGraphicsContext&>(BaseWidget::getGraphicsContext())); | |||
| } | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoBaseWidget); | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 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 | |||
| @@ -360,25 +360,23 @@ public: | |||
| */ | |||
| bool isNotNull() const noexcept; | |||
| #ifndef DPF_TEST_POINT_CPP | |||
| /** | |||
| Draw this line using the provided graphics context, optionally specifying line width. | |||
| */ | |||
| void draw(const GraphicsContext& context, T width = 1); | |||
| #endif | |||
| Line<T>& operator=(const Line<T>& line) noexcept; | |||
| bool operator==(const Line<T>& line) const noexcept; | |||
| bool operator!=(const Line<T>& line) const noexcept; | |||
| #ifndef DPF_TEST_POINT_CPP | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| /** | |||
| Draw this line using the current OpenGL state.@n | |||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | |||
| */ | |||
| DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)") | |||
| void draw(); | |||
| #endif | |||
| #endif | |||
| private: | |||
| Point<T> posStart, posEnd; | |||
| @@ -489,7 +487,7 @@ public: | |||
| bool operator==(const Circle<T>& cir) const noexcept; | |||
| bool operator!=(const Circle<T>& cir) const noexcept; | |||
| #ifndef DPF_TEST_POINT_CPP | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| /** | |||
| Draw this circle using the current OpenGL state.@n | |||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | |||
| @@ -503,7 +501,7 @@ public: | |||
| */ | |||
| DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | |||
| void drawOutline(); | |||
| #endif | |||
| #endif | |||
| private: | |||
| Point<T> fPos; | |||
| @@ -582,7 +580,7 @@ public: | |||
| bool operator==(const Triangle<T>& tri) const noexcept; | |||
| bool operator!=(const Triangle<T>& tri) const noexcept; | |||
| #ifndef DPF_TEST_POINT_CPP | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| /** | |||
| Draw this triangle using the current OpenGL state.@n | |||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | |||
| @@ -596,7 +594,7 @@ public: | |||
| */ | |||
| DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | |||
| void drawOutline(); | |||
| #endif | |||
| #endif | |||
| private: | |||
| Point<T> pos1, pos2, pos3; | |||
| @@ -813,6 +811,7 @@ public: | |||
| bool operator==(const Rectangle<T>& size) const noexcept; | |||
| bool operator!=(const Rectangle<T>& size) const noexcept; | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| /** | |||
| Draw this rectangle using the current OpenGL state.@n | |||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | |||
| @@ -826,6 +825,7 @@ public: | |||
| */ | |||
| DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | |||
| void drawOutline(); | |||
| #endif | |||
| private: | |||
| Point<T> pos; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 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 | |||
| @@ -17,17 +17,21 @@ | |||
| #ifndef DGL_IMAGE_HPP_INCLUDED | |||
| #define DGL_IMAGE_HPP_INCLUDED | |||
| #ifdef DGL_CAIRO | |||
| #include "Cairo.hpp" | |||
| #if defined(DGL_CAIRO) | |||
| # include "Cairo.hpp" | |||
| #elif defined(DGL_OPENGL) | |||
| # include "OpenGL.hpp" | |||
| #elif defined(DGL_VULKAN) | |||
| # include "Vulkan.hpp" | |||
| #else | |||
| #include "OpenGL.hpp" | |||
| # include "Base.hpp" | |||
| #endif | |||
| START_NAMESPACE_DGL | |||
| #ifdef DGL_CAIRO | |||
| #if defined(DGL_CAIRO) | |||
| typedef CairoImage Image; | |||
| #else | |||
| #elif defined(DGL_OPENGL) | |||
| typedef OpenGLImage Image; | |||
| #endif | |||
| @@ -73,6 +73,7 @@ endif | |||
| OBJS_gles2 = $(OBJS_common) \ | |||
| $(BUILD_DIR)/dgl/OpenGL.cpp.gles2.o \ | |||
| $(BUILD_DIR)/dgl/OpenGL3.cpp.gles2.o \ | |||
| $(BUILD_DIR)/dgl/NanoVG.cpp.gles2.o | |||
| ifeq ($(MACOS),true) | |||
| @@ -85,6 +86,7 @@ endif | |||
| OBJS_gles3 = $(OBJS_common) \ | |||
| $(BUILD_DIR)/dgl/OpenGL.cpp.gles3.o \ | |||
| $(BUILD_DIR)/dgl/OpenGL3.cpp.gles3.o \ | |||
| $(BUILD_DIR)/dgl/NanoVG.cpp.gles3.o | |||
| ifeq ($(MACOS),true) | |||
| @@ -97,6 +99,7 @@ endif | |||
| OBJS_opengl = $(OBJS_common) \ | |||
| $(BUILD_DIR)/dgl/OpenGL.cpp.opengl.o \ | |||
| $(BUILD_DIR)/dgl/OpenGL2.cpp.opengl.o \ | |||
| $(BUILD_DIR)/dgl/NanoVG.cpp.opengl.o | |||
| ifeq ($(MACOS),true) | |||
| @@ -109,6 +112,7 @@ endif | |||
| OBJS_opengl3 = $(OBJS_common) \ | |||
| $(BUILD_DIR)/dgl/OpenGL.cpp.opengl3.o \ | |||
| $(BUILD_DIR)/dgl/OpenGL3.cpp.opengl3.o \ | |||
| $(BUILD_DIR)/dgl/NanoVG.cpp.opengl3.o | |||
| ifeq ($(MACOS),true) | |||
| @@ -146,7 +150,10 @@ TARGETS += $(BUILD_DIR)/libdgl-cairo.a | |||
| endif | |||
| ifeq ($(HAVE_OPENGL),true) | |||
| TARGETS += $(BUILD_DIR)/libdgl-gles2.a | |||
| TARGETS += $(BUILD_DIR)/libdgl-gles3.a | |||
| TARGETS += $(BUILD_DIR)/libdgl-opengl.a | |||
| TARGETS += $(BUILD_DIR)/libdgl-opengl3.a | |||
| endif | |||
| ifeq ($(HAVE_STUB),true) | |||
| @@ -24,18 +24,7 @@ | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| /** | |||
| OpenGL Graphics context. | |||
| */ | |||
| struct OpenGLGraphicsContext : GraphicsContext | |||
| { | |||
| #ifdef DGL_USE_OPENGL3 | |||
| #endif | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static inline | |||
| ImageFormat asDISTRHOImageFormat(const GLenum format) | |||
| @@ -87,7 +76,7 @@ GLenum asOpenGLImageFormat(const ImageFormat format) | |||
| return 0x0; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| OpenGL Image class. | |||
| @@ -157,6 +146,7 @@ public: | |||
| inline void drawAt(const GraphicsContext& context, int x, int y) | |||
| { drawAt(context, Point<int>(x, y)); } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| /** | |||
| Constructor using raw image data, specifying an OpenGL image format. | |||
| @note @a rawData must remain valid for the lifetime of this Image. | |||
| @@ -200,6 +190,7 @@ public: | |||
| */ | |||
| DISTRHO_DEPRECATED | |||
| GLenum getType() const noexcept { return GL_UNSIGNED_BYTE; } | |||
| #endif // DGL_ALLOW_DEPRECATED_METHODS | |||
| private: | |||
| bool setupCalled; | |||
| @@ -207,7 +198,7 @@ private: | |||
| GLuint textureId; | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| typedef ImageBaseAboutWindow<OpenGLImage> OpenGLImageAboutWindow; | |||
| typedef ImageBaseButton<OpenGLImage> OpenGLImageButton; | |||
| @@ -215,7 +206,7 @@ typedef ImageBaseKnob<OpenGLImage> OpenGLImageKnob; | |||
| typedef ImageBaseSlider<OpenGLImage> OpenGLImageSlider; | |||
| typedef ImageBaseSwitch<OpenGLImage> OpenGLImageSwitch; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -32,16 +32,38 @@ | |||
| // templated classes | |||
| #include "ImageBaseWidgets.cpp" | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Check for correct build config | |||
| #ifndef DGL_CAIRO | |||
| # error Build config error, Cairo was NOT requested while building Cairo code | |||
| #endif | |||
| #ifdef DGL_OPENGL | |||
| # error Build config error, OpenGL requested while building Cairo code | |||
| #endif | |||
| #ifdef DGL_VULKAN | |||
| # error Build config error, Vulkan requested while building Cairo code | |||
| #endif | |||
| #ifdef DGL_USE_GLES2 | |||
| # error Build config error, GLESv2 requested while building Cairo code | |||
| #endif | |||
| #ifdef DGL_USE_GLES3 | |||
| # error Build config error, GLESv3 requested while building Cairo code | |||
| #endif | |||
| #ifdef DGL_USE_OPENGL3 | |||
| # error Build config error, OpenGL3 requested while building Cairo code | |||
| #endif | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static void notImplemented(const char* const name) | |||
| { | |||
| d_stderr2("Cairo function not implemented: %s", name); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Color | |||
| void Color::setFor(const GraphicsContext& context, const bool includeAlpha) | |||
| @@ -54,7 +76,7 @@ void Color::setFor(const GraphicsContext& context, const bool includeAlpha) | |||
| cairo_set_source_rgb(handle, red, green, blue); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Line | |||
| template<typename T> | |||
| @@ -71,11 +93,13 @@ void Line<T>::draw(const GraphicsContext& context, const T width) | |||
| cairo_stroke(handle); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Line<T>::draw() | |||
| { | |||
| notImplemented("Line::draw"); | |||
| } | |||
| #endif | |||
| template class Line<double>; | |||
| template class Line<float>; | |||
| @@ -145,6 +169,7 @@ void Circle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| drawCircle<T>(handle, fPos, fNumSegments, fSize, fSin, fCos, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Circle<T>::draw() | |||
| { | |||
| @@ -156,6 +181,7 @@ void Circle<T>::drawOutline() | |||
| { | |||
| notImplemented("Circle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Circle<double>; | |||
| template class Circle<float>; | |||
| @@ -206,6 +232,7 @@ void Triangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| drawTriangle<T>(handle, pos1, pos2, pos3, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Triangle<T>::draw() | |||
| { | |||
| @@ -217,6 +244,7 @@ void Triangle<T>::drawOutline() | |||
| { | |||
| notImplemented("Triangle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Triangle<double>; | |||
| template class Triangle<float>; | |||
| @@ -261,6 +289,7 @@ void Rectangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth | |||
| drawRectangle(handle, *this, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Rectangle<T>::draw() | |||
| { | |||
| @@ -272,6 +301,7 @@ void Rectangle<T>::drawOutline() | |||
| { | |||
| notImplemented("Rectangle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Rectangle<double>; | |||
| template class Rectangle<float>; | |||
| @@ -20,7 +20,6 @@ | |||
| #endif | |||
| #include "../OpenGL.hpp" | |||
| #include "../Color.hpp" | |||
| #include "../ImageWidgets.hpp" | |||
| #include "SubWidgetPrivateData.hpp" | |||
| @@ -28,660 +27,11 @@ | |||
| #include "WidgetPrivateData.hpp" | |||
| #include "WindowPrivateData.hpp" | |||
| // templated classes | |||
| #include "ImageBaseWidgets.cpp" | |||
| START_NAMESPACE_DGL | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| #ifdef DGL_USE_OPENGL3 | |||
| # if defined(DGL_USE_GLES2) && defined(DGL_USE_GLES3) | |||
| # error Build config error, both GLESv2 and GLESv3 requested at the same time | |||
| # endif | |||
| struct OpenGL3GraphicsContext : GraphicsContext | |||
| { | |||
| mutable int prog, color, pos, tex, texok; | |||
| mutable uint w, h; | |||
| }; | |||
| static void notImplemented(const char* const name) | |||
| { | |||
| #if defined(DGL_USE_GLES2) | |||
| #define DGL_OPENGL3_NAME "GLESv2" | |||
| #elif defined(DGL_USE_GLES3) | |||
| #define DGL_OPENGL3_NAME "GLESv3" | |||
| #else | |||
| #define DGL_OPENGL3_NAME "OpenGL3" | |||
| #endif | |||
| d_stderr2(DGL_OPENGL3_NAME " function not implemented: %s", name); | |||
| #undef DGL_OPENGL3_NAME | |||
| } | |||
| #else | |||
| # if defined(DGL_USE_GLES2) || defined(DGL_USE_GLES3) | |||
| # error Build config error, GLES requested while using OpenGL compat mode | |||
| # endif | |||
| # define DGL_USE_COMPAT_OPENGL | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Color | |||
| void Color::setFor(const GraphicsContext& context, const bool includeAlpha) | |||
| { | |||
| #ifdef DGL_USE_OPENGL3 | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat color[4] = { red, green, blue, includeAlpha ? alpha : 1.f }; | |||
| glUniform4fv(gl3context.color, 1, color); | |||
| #else | |||
| if (includeAlpha) | |||
| glColor4f(red, green, blue, alpha); | |||
| else | |||
| glColor3f(red, green, blue); | |||
| // unused | |||
| (void)context; | |||
| #endif | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Line | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| template<typename T> | |||
| static void drawLine(const Point<T>& posStart, const Point<T>& posEnd) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(posStart != posEnd,); | |||
| glBegin(GL_LINES); | |||
| { | |||
| glVertex2d(posStart.getX(), posStart.getY()); | |||
| glVertex2d(posEnd.getX(), posEnd.getY()); | |||
| } | |||
| glEnd(); | |||
| } | |||
| #endif | |||
| template<typename T> | |||
| void Line<T>::draw(const GraphicsContext& context, const T width) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(width != 0,); | |||
| glLineWidth(static_cast<GLfloat>(width)); | |||
| #ifdef DGL_USE_OPENGL3 | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat x1 = (static_cast<double>(posStart.x) / gl3context.w) * 2 - 1; | |||
| const GLfloat y1 = (static_cast<double>(posStart.y) / gl3context.h) * -2 + 1; | |||
| const GLfloat x2 = (static_cast<double>(posEnd.x) / gl3context.w) * 2 - 1; | |||
| const GLfloat y2 = (static_cast<double>(posEnd.y) / gl3context.h) * -2 + 1; | |||
| const GLfloat vertices[] = { x1, y1, x2, y2, }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| const GLubyte order[] = { 0, 1 }; | |||
| glDrawElements(GL_LINES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| #else | |||
| drawLine<T>(posStart, posEnd); | |||
| // unused | |||
| (void)context; | |||
| #endif | |||
| } | |||
| // deprecated calls | |||
| template<typename T> | |||
| void Line<T>::draw() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawLine<T>(posStart, posEnd); | |||
| #else | |||
| notImplemented("Line::draw"); | |||
| #endif | |||
| } | |||
| template class Line<double>; | |||
| template class Line<float>; | |||
| template class Line<int>; | |||
| template class Line<uint>; | |||
| template class Line<short>; | |||
| template class Line<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Circle | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| template<typename T> | |||
| static void drawCircle(const Point<T>& pos, | |||
| const uint numSegments, | |||
| const float size, | |||
| const float sin, | |||
| const float cos, | |||
| const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(numSegments >= 3 && size > 0.0f,); | |||
| const double origx = static_cast<double>(pos.getX()); | |||
| const double origy = static_cast<double>(pos.getY()); | |||
| double t; | |||
| double x = size; | |||
| double y = 0.0; | |||
| glBegin(outline ? GL_LINE_LOOP : GL_POLYGON); | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| glVertex2d(x + origx, y + origy); | |||
| t = x; | |||
| x = cos * x - sin * y; | |||
| y = sin * t + cos * y; | |||
| } | |||
| glEnd(); | |||
| } | |||
| #endif | |||
| template<typename T> | |||
| static void drawCircle(const GraphicsContext& context, | |||
| const Point<T>& pos, | |||
| const uint numSegments, | |||
| const float size, | |||
| const float sin, | |||
| const float cos, | |||
| const bool outline) | |||
| { | |||
| #ifdef DGL_USE_OPENGL3 | |||
| #define MAX_CIRCLE_SEGMENTS 512 | |||
| DISTRHO_SAFE_ASSERT_RETURN(numSegments >= 3 && size > 0.0f,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(numSegments <= MAX_CIRCLE_SEGMENTS,); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const double origx = static_cast<double>(pos.getX()); | |||
| const double origy = static_cast<double>(pos.getY()); | |||
| double t; | |||
| double x = size; | |||
| double y = 0.0; | |||
| GLfloat vertices[(MAX_CIRCLE_SEGMENTS + 1) * 2]; | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| vertices[i * 2 + 0] = ((x + origx) / gl3context.w) * 2 - 1; | |||
| vertices[i * 2 + 1] = ((y + origy) / gl3context.h) * -2 + 1; | |||
| t = x; | |||
| x = cos * x - sin * y; | |||
| y = sin * t + cos * y; | |||
| } | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| if (outline) | |||
| { | |||
| GLushort order[MAX_CIRCLE_SEGMENTS * 2]; | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| order[i * 2 + 0] = i; | |||
| order[i * 2 + 1] = i + 1; | |||
| } | |||
| order[numSegments * 2 - 1] = 0; | |||
| glDrawElements(GL_LINES, numSegments * 2, GL_UNSIGNED_SHORT, order); | |||
| } | |||
| else | |||
| { | |||
| // center position | |||
| vertices[numSegments * 2 + 0] = (origx / gl3context.w) * 2 - 1; | |||
| vertices[numSegments * 2 + 1] = (origy / gl3context.h) * -2 + 1; | |||
| GLushort order[MAX_CIRCLE_SEGMENTS * 3]; | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| order[i * 3 + 0] = i; | |||
| order[i * 3 + 1] = i + 1; | |||
| order[i * 3 + 2] = numSegments; | |||
| } | |||
| order[numSegments * 3 - 2] = 0; | |||
| glDrawElements(GL_TRIANGLES, numSegments * 3, GL_UNSIGNED_SHORT, order); | |||
| } | |||
| #else | |||
| drawCircle<T>(pos, numSegments, size, sin, cos, outline); | |||
| // unused | |||
| (void)context; | |||
| #endif | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawCircle<T>(context, fPos, fNumSegments, fSize, fSin, fCos, false); | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawCircle<T>(context, fPos, fNumSegments, fSize, fSin, fCos, true); | |||
| } | |||
| // deprecated calls | |||
| template<typename T> | |||
| void Circle<T>::draw() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawCircle<T>(fPos, fNumSegments, fSize, fSin, fCos, false); | |||
| #else | |||
| notImplemented("Circle::draw"); | |||
| #endif | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::drawOutline() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawCircle<T>(fPos, fNumSegments, fSize, fSin, fCos, true); | |||
| #else | |||
| notImplemented("Circle::drawOutline"); | |||
| #endif | |||
| } | |||
| template class Circle<double>; | |||
| template class Circle<float>; | |||
| template class Circle<int>; | |||
| template class Circle<uint>; | |||
| template class Circle<short>; | |||
| template class Circle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Triangle | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| template<typename T> | |||
| static void drawTriangle(const Point<T>& pos1, | |||
| const Point<T>& pos2, | |||
| const Point<T>& pos3, | |||
| const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pos1 != pos2 && pos1 != pos3,); | |||
| glBegin(outline ? GL_LINE_LOOP : GL_TRIANGLES); | |||
| { | |||
| glVertex2d(pos1.getX(), pos1.getY()); | |||
| glVertex2d(pos2.getX(), pos2.getY()); | |||
| glVertex2d(pos3.getX(), pos3.getY()); | |||
| } | |||
| glEnd(); | |||
| } | |||
| #endif | |||
| template<typename T> | |||
| static void drawTriangle(const GraphicsContext& context, | |||
| const Point<T>& pos1, | |||
| const Point<T>& pos2, | |||
| const Point<T>& pos3, | |||
| const bool outline) | |||
| { | |||
| #ifdef DGL_USE_OPENGL3 | |||
| DISTRHO_SAFE_ASSERT_RETURN(pos1 != pos2 && pos1 != pos3,); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat x1 = (static_cast<double>(pos1.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y1 = (static_cast<double>(pos1.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat x2 = (static_cast<double>(pos2.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y2 = (static_cast<double>(pos2.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat x3 = (static_cast<double>(pos3.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y3 = (static_cast<double>(pos3.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat vertices[] = { x1, y1, x2, y2, x3, y3 }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| if (outline) | |||
| { | |||
| const GLubyte order[] = { 0, 1, 1, 2, 2, 0 }; | |||
| glDrawElements(GL_LINES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| } | |||
| else | |||
| { | |||
| glDrawArrays(GL_TRIANGLES, 0, 3); | |||
| } | |||
| #else | |||
| drawTriangle<T>(pos1, pos2, pos3, outline); | |||
| // unused | |||
| (void)context; | |||
| #endif | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawTriangle<T>(context, pos1, pos2, pos3, false); | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawTriangle<T>(context, pos1, pos2, pos3, true); | |||
| } | |||
| // deprecated calls | |||
| template<typename T> | |||
| void Triangle<T>::draw() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawTriangle<T>(pos1, pos2, pos3, false); | |||
| #else | |||
| notImplemented("Triangle::draw"); | |||
| #endif | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::drawOutline() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawTriangle<T>(pos1, pos2, pos3, true); | |||
| #else | |||
| notImplemented("Triangle::drawOutline"); | |||
| #endif | |||
| } | |||
| template class Triangle<double>; | |||
| template class Triangle<float>; | |||
| template class Triangle<int>; | |||
| template class Triangle<uint>; | |||
| template class Triangle<short>; | |||
| template class Triangle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Rectangle | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| template<typename T> | |||
| static void drawRectangle(const Rectangle<T>& rect, const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(rect.isValid(),); | |||
| glBegin(outline ? GL_LINE_LOOP : GL_QUADS); | |||
| { | |||
| const T x = rect.getX(); | |||
| const T y = rect.getY(); | |||
| const T w = rect.getWidth(); | |||
| const T h = rect.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(); | |||
| } | |||
| #endif | |||
| template<typename T> | |||
| static void drawRectangle(const GraphicsContext& context, const Rectangle<T>& rect, const bool outline) | |||
| { | |||
| #ifdef DGL_USE_OPENGL3 | |||
| DISTRHO_SAFE_ASSERT_RETURN(rect.isValid(),); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat x = (static_cast<double>(rect.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y = (static_cast<double>(rect.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat w = (static_cast<double>(rect.getWidth()) / gl3context.w) * 2; | |||
| const GLfloat h = (static_cast<double>(rect.getHeight()) / gl3context.h) * -2; | |||
| const GLfloat vertices[] = { x, y, x, y + h, x + w, y + h, x + w, y }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| if (outline) | |||
| { | |||
| const GLubyte order[] = { 0, 1, 1, 2, 2, 3, 3, 0 }; | |||
| glDrawElements(GL_LINES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| } | |||
| else | |||
| { | |||
| const GLubyte order[] = { 0, 1, 2, 0, 2, 3 }; | |||
| glDrawElements(GL_TRIANGLES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| } | |||
| #else | |||
| drawRectangle<T>(rect, outline); | |||
| // unused | |||
| (void)context; | |||
| #endif | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawRectangle<T>(context, *this, false); | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawRectangle<T>(context, *this, true); | |||
| } | |||
| // deprecated calls | |||
| template<typename T> | |||
| void Rectangle<T>::draw() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawRectangle<T>(*this, false); | |||
| #else | |||
| notImplemented("Rectangle::draw"); | |||
| #endif | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::drawOutline() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawRectangle<T>(*this, true); | |||
| #else | |||
| notImplemented("Rectangle::drawOutline"); | |||
| #endif | |||
| } | |||
| template class Rectangle<double>; | |||
| template class Rectangle<float>; | |||
| template class Rectangle<int>; | |||
| template class Rectangle<uint>; | |||
| template class Rectangle<short>; | |||
| template class Rectangle<ushort>; | |||
| // ----------------------------------------------------------------------- | |||
| // OpenGLImage | |||
| static void setupOpenGLImage(const OpenGLImage& image, GLuint textureId) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(image.isValid(),); | |||
| const ImageFormat imageFormat = image.getFormat(); | |||
| GLint intformat = GL_RGBA; | |||
| #ifdef DGL_USE_GLES2 | |||
| // GLESv2 does not support BGR | |||
| DISTRHO_SAFE_ASSERT_RETURN(imageFormat != kImageFormatBGR && imageFormat != kImageFormatBGRA,); | |||
| #endif | |||
| #ifdef DGL_USE_OPENGL3 | |||
| switch (imageFormat) | |||
| { | |||
| case kImageFormatBGR: | |||
| case kImageFormatRGB: | |||
| intformat = GL_RGB; | |||
| break; | |||
| case kImageFormatGrayscale: | |||
| #if defined(DGL_USE_GLES3) | |||
| intformat = GL_R8; | |||
| #elif defined(DGL_USE_OPENGL3) | |||
| intformat = GL_RED; | |||
| #else | |||
| intformat = GL_LUMINANCE; | |||
| #endif | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| #else | |||
| glEnable(GL_TEXTURE_2D); | |||
| #endif | |||
| glBindTexture(GL_TEXTURE_2D, textureId); | |||
| 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, | |||
| intformat, | |||
| static_cast<GLsizei>(image.getWidth()), | |||
| static_cast<GLsizei>(image.getHeight()), | |||
| 0, | |||
| asOpenGLImageFormat(imageFormat), | |||
| GL_UNSIGNED_BYTE, | |||
| image.getRawData()); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| glDisable(GL_TEXTURE_2D); | |||
| #endif | |||
| } | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| static void drawOpenGLImage(const OpenGLImage& image, const Point<int>& pos, const GLuint textureId, bool& setupCalled) | |||
| { | |||
| if (textureId == 0 || image.isInvalid()) | |||
| return; | |||
| if (! setupCalled) | |||
| { | |||
| setupOpenGLImage(image, textureId); | |||
| setupCalled = true; | |||
| } | |||
| glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, textureId); | |||
| glBegin(GL_QUADS); | |||
| { | |||
| const int x = pos.getX(); | |||
| const int y = pos.getY(); | |||
| const int w = static_cast<int>(image.getWidth()); | |||
| const int h = static_cast<int>(image.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); | |||
| } | |||
| #endif | |||
| static void drawOpenGLImage(const GraphicsContext& context, | |||
| const OpenGLImage& image, | |||
| const Point<int>& pos, | |||
| const GLuint textureId, | |||
| bool& setupCalled) | |||
| { | |||
| #ifdef DGL_USE_OPENGL3 | |||
| if (textureId == 0 || image.isInvalid()) | |||
| return; | |||
| if (! setupCalled) | |||
| { | |||
| setupOpenGLImage(image, textureId); | |||
| setupCalled = true; | |||
| } | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; | |||
| glUniform4fv(gl3context.color, 1, color); | |||
| const GLfloat x = (static_cast<double>(pos.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y = (static_cast<double>(pos.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat w = (static_cast<double>(image.getWidth()) / gl3context.w) * 2; | |||
| const GLfloat h = (static_cast<double>(image.getHeight()) / gl3context.h) * -2; | |||
| glActiveTexture(GL_TEXTURE0); | |||
| glBindTexture(GL_TEXTURE_2D, textureId); | |||
| glUniform1i(gl3context.texok, 1); | |||
| const GLfloat vertices[] = { x, y, x, y + h, x + w, y + h, x + w, y }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| const GLfloat vtex[] = { 0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f, 0.f }; | |||
| glVertexAttribPointer(gl3context.tex, 2, GL_FLOAT, GL_FALSE, 0, vtex); | |||
| glEnableVertexAttribArray(gl3context.tex); | |||
| const GLubyte order[] = { 0, 1, 2, 0, 2, 3 }; | |||
| glDrawElements(GL_TRIANGLES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| glUniform1i(gl3context.texok, 0); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| #else | |||
| drawOpenGLImage(image, pos, textureId, setupCalled); | |||
| // unused | |||
| (void)context; | |||
| #endif | |||
| } | |||
| OpenGLImage::OpenGLImage() | |||
| : ImageBase(), | |||
| setupCalled(false), | |||
| @@ -738,11 +88,6 @@ void OpenGLImage::loadFromMemory(const char* const rdata, const Size<uint>& s, c | |||
| ImageBase::loadFromMemory(rdata, s, fmt); | |||
| } | |||
| void OpenGLImage::drawAt(const GraphicsContext& context, const Point<int>& pos) | |||
| { | |||
| drawOpenGLImage(context, *this, pos, textureId, setupCalled); | |||
| } | |||
| OpenGLImage& OpenGLImage::operator=(const OpenGLImage& image) noexcept | |||
| { | |||
| rawData = image.rawData; | |||
| @@ -760,7 +105,7 @@ OpenGLImage& OpenGLImage::operator=(const OpenGLImage& image) noexcept | |||
| return *this; | |||
| } | |||
| // deprecated calls | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| OpenGLImage::OpenGLImage(const char* const rdata, const uint w, const uint h, const GLenum fmt) | |||
| : ImageBase(rdata, w, h, asDISTRHOImageFormat(fmt)), | |||
| setupCalled(false), | |||
| @@ -780,163 +125,9 @@ OpenGLImage::OpenGLImage(const char* const rdata, const Size<uint>& s, const GLe | |||
| glGenTextures(1, &textureId); | |||
| DISTRHO_SAFE_ASSERT(textureId != 0); | |||
| } | |||
| void OpenGLImage::draw() | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawOpenGLImage(*this, Point<int>(0, 0), textureId, setupCalled); | |||
| #else | |||
| notImplemented("OpenGLImage::draw"); | |||
| #endif | |||
| } | |||
| void OpenGLImage::drawAt(const int x, const int y) | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawOpenGLImage(*this, Point<int>(x, y), textureId, setupCalled); | |||
| #else | |||
| notImplemented("OpenGLImage::drawAt"); | |||
| #endif | |||
| } | |||
| void OpenGLImage::drawAt(const Point<int>& pos) | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| drawOpenGLImage(*this, pos, textureId, setupCalled); | |||
| #else | |||
| notImplemented("OpenGLImage::drawAt"); | |||
| #endif | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseAboutWindow | |||
| #if 0 | |||
| template <> | |||
| void ImageBaseAboutWindow<OpenGLImage>::onDisplay() | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| img.draw(context); | |||
| } | |||
| #endif | |||
| template class ImageBaseAboutWindow<OpenGLImage>; | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseButton | |||
| template class ImageBaseButton<OpenGLImage>; | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseKnob | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::PrivateData::init() | |||
| { | |||
| glTextureId = 0; | |||
| glGenTextures(1, &glTextureId); | |||
| } | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::PrivateData::cleanup() | |||
| { | |||
| if (glTextureId == 0) | |||
| return; | |||
| glDeleteTextures(1, &glTextureId); | |||
| glTextureId = 0; | |||
| } | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::onDisplay() | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| const float normValue = getNormalizedValue(); | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, pData->glTextureId); | |||
| if (! pData->isReady) | |||
| { | |||
| 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); | |||
| uint imageDataOffset = 0; | |||
| if (pData->rotationAngle == 0) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pData->imgLayerCount > 0,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(normValue >= 0.0f,); | |||
| const uint& v1(pData->isImgVertical ? pData->imgLayerWidth : pData->imgLayerHeight); | |||
| const uint& v2(pData->isImgVertical ? pData->imgLayerHeight : pData->imgLayerWidth); | |||
| // TODO kImageFormatGreyscale | |||
| const uint layerDataSize = v1 * v2 * ((pData->image.getFormat() == kImageFormatBGRA || | |||
| pData->image.getFormat() == kImageFormatRGBA) ? 4 : 3); | |||
| /* */ imageDataOffset = layerDataSize * uint(normValue * float(pData->imgLayerCount-1)); | |||
| } | |||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
| static_cast<GLsizei>(getWidth()), static_cast<GLsizei>(getHeight()), 0, | |||
| asOpenGLImageFormat(pData->image.getFormat()), GL_UNSIGNED_BYTE, pData->image.getRawData() + imageDataOffset); | |||
| pData->isReady = true; | |||
| } | |||
| const int w = static_cast<int>(getWidth()); | |||
| const int h = static_cast<int>(getHeight()); | |||
| if (pData->rotationAngle != 0) | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| glPushMatrix(); | |||
| #endif | |||
| const int w2 = w/2; | |||
| const int h2 = h/2; | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| glTranslatef(static_cast<float>(w2), static_cast<float>(h2), 0.0f); | |||
| glRotatef(normValue*static_cast<float>(pData->rotationAngle), 0.0f, 0.0f, 1.0f); | |||
| #endif | |||
| Rectangle<int>(-w2, -h2, w, h).draw(context); | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| glPopMatrix(); | |||
| #endif | |||
| } | |||
| else | |||
| { | |||
| Rectangle<int>(0, 0, w, h).draw(context); | |||
| } | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_TEXTURE_2D); | |||
| } | |||
| template class ImageBaseKnob<OpenGLImage>; | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseSlider | |||
| template class ImageBaseSlider<OpenGLImage>; | |||
| // ----------------------------------------------------------------------- | |||
| // ImageBaseSwitch | |||
| template class ImageBaseSwitch<OpenGLImage>; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| void SubWidget::PrivateData::display(const uint width, const uint height, const double autoScaleFactor) | |||
| { | |||
| @@ -997,7 +188,7 @@ void SubWidget::PrivateData::display(const uint width, const uint height, const | |||
| selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| void TopLevelWidget::PrivateData::display() | |||
| { | |||
| @@ -1018,7 +209,7 @@ void TopLevelWidget::PrivateData::display() | |||
| selfw->pData->displaySubWidgets(width, height, window.pData->autoScaleFactor); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| void Window::PrivateData::renderToPicture(const char* const filename, | |||
| const GraphicsContext&, | |||
| @@ -1050,101 +241,4 @@ void Window::PrivateData::renderToPicture(const char* const filename, | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| #ifdef DGL_USE_OPENGL3 | |||
| const GraphicsContext& contextCreationFail(const OpenGL3GraphicsContext& gl3context) | |||
| { | |||
| gl3context.prog = -1; | |||
| return gl3context; | |||
| } | |||
| #endif | |||
| const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept | |||
| { | |||
| GraphicsContext& context = reinterpret_cast<GraphicsContext&>(graphicsContext); | |||
| #ifdef DGL_USE_OPENGL3 | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| // previous context creation failed | |||
| if (gl3context.prog == -1) | |||
| return context; | |||
| // create new context | |||
| if (gl3context.prog == 0) | |||
| { | |||
| int status; | |||
| const GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER); | |||
| DISTRHO_SAFE_ASSERT_RETURN(fragment != 0, contextCreationFail(gl3context)); | |||
| const GLuint vertex = glCreateShader(GL_VERTEX_SHADER); | |||
| DISTRHO_SAFE_ASSERT_RETURN(vertex != 0, contextCreationFail(gl3context)); | |||
| const GLuint program = glCreateProgram(); | |||
| DISTRHO_SAFE_ASSERT_RETURN(program != 0, contextCreationFail(gl3context)); | |||
| #if defined(DGL_USE_GLES2) | |||
| #define DGL_SHADER_HEADER "#version 100\n" | |||
| #elif defined(DGL_USE_GLES3) | |||
| #define DGL_SHADER_HEADER "#version 300 es\n" | |||
| #else | |||
| #define DGL_SHADER_HEADER "#version 150 core\n" | |||
| #endif | |||
| { | |||
| static constexpr const char* const src = DGL_SHADER_HEADER | |||
| "precision mediump float;" | |||
| "uniform vec4 color;" | |||
| "uniform sampler2D stex;" | |||
| "uniform bool texok;" | |||
| "varying vec2 vtex;" | |||
| "void main() { gl_FragColor = texok ? texture2D(stex, vtex) : color; }"; | |||
| glShaderSource(fragment, 1, &src, nullptr); | |||
| glCompileShader(fragment); | |||
| glGetShaderiv(fragment, GL_COMPILE_STATUS, &status); | |||
| DISTRHO_SAFE_ASSERT_RETURN(status != 0, contextCreationFail(gl3context)); | |||
| } | |||
| { | |||
| static constexpr const char* const src = DGL_SHADER_HEADER | |||
| "attribute vec4 pos;" | |||
| "attribute vec2 tex;" | |||
| "varying vec2 vtex;" | |||
| "void main() { gl_Position = pos; vtex = tex; }"; | |||
| glShaderSource(vertex, 1, &src, nullptr); | |||
| glCompileShader(vertex); | |||
| glGetShaderiv(vertex, GL_COMPILE_STATUS, &status); | |||
| DISTRHO_SAFE_ASSERT_RETURN(status != 0, contextCreationFail(gl3context)); | |||
| } | |||
| glAttachShader(program, fragment); | |||
| glAttachShader(program, vertex); | |||
| glLinkProgram(program); | |||
| glGetProgramiv(program, GL_LINK_STATUS, &status); | |||
| DISTRHO_SAFE_ASSERT_RETURN(status != 0, contextCreationFail(gl3context)); | |||
| gl3context.prog = program; | |||
| gl3context.color = glGetUniformLocation(program, "color"); | |||
| gl3context.texok = glGetUniformLocation(program, "texok"); | |||
| gl3context.pos = glGetAttribLocation(program, "pos"); | |||
| gl3context.tex = glGetAttribLocation(program, "tex"); | |||
| } | |||
| const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE); | |||
| gl3context.w = size.width; | |||
| gl3context.h = size.height; | |||
| glUseProgram(gl3context.prog); | |||
| #endif | |||
| return context; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -0,0 +1,559 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2025 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. | |||
| */ | |||
| #ifdef _MSC_VER | |||
| // instantiated template classes whose methods are defined elsewhere | |||
| # pragma warning(disable:4661) | |||
| #endif | |||
| #include "../OpenGL.hpp" | |||
| #include "../Color.hpp" | |||
| #include "../ImageWidgets.hpp" | |||
| // #include "SubWidgetPrivateData.hpp" | |||
| // #include "TopLevelWidgetPrivateData.hpp" | |||
| // #include "WidgetPrivateData.hpp" | |||
| #include "WindowPrivateData.hpp" | |||
| // templated classes | |||
| #include "ImageBaseWidgets.cpp" | |||
| START_NAMESPACE_DGL | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Check for correct build config | |||
| #ifndef DGL_OPENGL | |||
| # error Build config error, OpenGL was NOT requested while building OpenGL2 code | |||
| #endif | |||
| #ifdef DGL_CAIRO | |||
| # error Build config error, Cairo requested while building OpenGL2 code | |||
| #endif | |||
| #ifdef DGL_VULKAN | |||
| # error Build config error, Vulkan requested while building OpenGL2 code | |||
| #endif | |||
| #ifdef DGL_USE_GLES2 | |||
| # error Build config error, GLESv2 requested while building OpenGL2 code | |||
| #endif | |||
| #ifdef DGL_USE_GLES3 | |||
| # error Build config error, GLESv3 requested while building OpenGL2 code | |||
| #endif | |||
| #ifdef DGL_USE_OPENGL3 | |||
| # error Build config error, OpenGL3 requested while building OpenGL2 code | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Color | |||
| void Color::setFor(const GraphicsContext&, const bool includeAlpha) | |||
| { | |||
| if (includeAlpha) | |||
| glColor4f(red, green, blue, alpha); | |||
| else | |||
| glColor3f(red, green, blue); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Line | |||
| template<typename T> | |||
| static void drawLine(const Point<T>& posStart, const Point<T>& posEnd) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(posStart != posEnd,); | |||
| glBegin(GL_LINES); | |||
| { | |||
| glVertex2d(posStart.getX(), posStart.getY()); | |||
| glVertex2d(posEnd.getX(), posEnd.getY()); | |||
| } | |||
| glEnd(); | |||
| } | |||
| template<typename T> | |||
| void Line<T>::draw(const GraphicsContext&, const T width) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(width != 0,); | |||
| glLineWidth(static_cast<GLfloat>(width)); | |||
| drawLine<T>(posStart, posEnd); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Line<T>::draw() | |||
| { | |||
| drawLine<T>(posStart, posEnd); | |||
| } | |||
| #endif | |||
| template class Line<double>; | |||
| template class Line<float>; | |||
| template class Line<int>; | |||
| template class Line<uint>; | |||
| template class Line<short>; | |||
| template class Line<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Circle | |||
| template<typename T> | |||
| static void drawCircle(const Point<T>& pos, | |||
| const uint numSegments, | |||
| const float size, | |||
| const float sin, | |||
| const float cos, | |||
| const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(numSegments >= 3 && size > 0.0f,); | |||
| const double origx = static_cast<double>(pos.getX()); | |||
| const double origy = static_cast<double>(pos.getY()); | |||
| double t; | |||
| double x = size; | |||
| double y = 0.0; | |||
| glBegin(outline ? GL_LINE_LOOP : GL_POLYGON); | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| glVertex2d(x + origx, y + origy); | |||
| t = x; | |||
| x = cos * x - sin * y; | |||
| y = sin * t + cos * y; | |||
| } | |||
| glEnd(); | |||
| } | |||
| template<typename T> | |||
| static void drawCircle(const GraphicsContext&, | |||
| const Point<T>& pos, | |||
| const uint numSegments, | |||
| const float size, | |||
| const float sin, | |||
| const float cos, | |||
| const bool outline) | |||
| { | |||
| drawCircle<T>(pos, numSegments, size, sin, cos, outline); | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawCircle<T>(context, fPos, fNumSegments, fSize, fSin, fCos, false); | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawCircle<T>(context, fPos, fNumSegments, fSize, fSin, fCos, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Circle<T>::draw() | |||
| { | |||
| drawCircle<T>(fPos, fNumSegments, fSize, fSin, fCos, false); | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::drawOutline() | |||
| { | |||
| drawCircle<T>(fPos, fNumSegments, fSize, fSin, fCos, true); | |||
| } | |||
| #endif | |||
| template class Circle<double>; | |||
| template class Circle<float>; | |||
| template class Circle<int>; | |||
| template class Circle<uint>; | |||
| template class Circle<short>; | |||
| template class Circle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Triangle | |||
| template<typename T> | |||
| static void drawTriangle(const Point<T>& pos1, | |||
| const Point<T>& pos2, | |||
| const Point<T>& pos3, | |||
| const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pos1 != pos2 && pos1 != pos3,); | |||
| glBegin(outline ? GL_LINE_LOOP : GL_TRIANGLES); | |||
| { | |||
| glVertex2d(pos1.getX(), pos1.getY()); | |||
| glVertex2d(pos2.getX(), pos2.getY()); | |||
| glVertex2d(pos3.getX(), pos3.getY()); | |||
| } | |||
| glEnd(); | |||
| } | |||
| template<typename T> | |||
| static void drawTriangle(const GraphicsContext&, | |||
| const Point<T>& pos1, | |||
| const Point<T>& pos2, | |||
| const Point<T>& pos3, | |||
| const bool outline) | |||
| { | |||
| drawTriangle<T>(pos1, pos2, pos3, outline); | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::draw(const GraphicsContext&) | |||
| { | |||
| drawTriangle<T>(pos1, pos2, pos3, false); | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::drawOutline(const GraphicsContext&, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawTriangle<T>(pos1, pos2, pos3, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Triangle<T>::draw() | |||
| { | |||
| drawTriangle<T>(pos1, pos2, pos3, false); | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::drawOutline() | |||
| { | |||
| drawTriangle<T>(pos1, pos2, pos3, true); | |||
| } | |||
| #endif | |||
| template class Triangle<double>; | |||
| template class Triangle<float>; | |||
| template class Triangle<int>; | |||
| template class Triangle<uint>; | |||
| template class Triangle<short>; | |||
| template class Triangle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Rectangle | |||
| template<typename T> | |||
| static void drawRectangle(const Rectangle<T>& rect, const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(rect.isValid(),); | |||
| glBegin(outline ? GL_LINE_LOOP : GL_QUADS); | |||
| { | |||
| const T x = rect.getX(); | |||
| const T y = rect.getY(); | |||
| const T w = rect.getWidth(); | |||
| const T h = rect.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(); | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawRectangle<T>(*this, false); | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawRectangle<T>(*this, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Rectangle<T>::draw() | |||
| { | |||
| drawRectangle<T>(*this, false); | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::drawOutline() | |||
| { | |||
| drawRectangle<T>(*this, true); | |||
| } | |||
| #endif | |||
| template class Rectangle<double>; | |||
| template class Rectangle<float>; | |||
| template class Rectangle<int>; | |||
| template class Rectangle<uint>; | |||
| template class Rectangle<short>; | |||
| template class Rectangle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // OpenGLImage | |||
| static void setupOpenGLImage(const OpenGLImage& image, GLuint textureId) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(image.isValid(),); | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, textureId); | |||
| 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>(image.getWidth()), | |||
| static_cast<GLsizei>(image.getHeight()), | |||
| 0, | |||
| asOpenGLImageFormat(image.getFormat()), | |||
| GL_UNSIGNED_BYTE, | |||
| image.getRawData()); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_TEXTURE_2D); | |||
| } | |||
| static void drawOpenGLImage(const OpenGLImage& image, const Point<int>& pos, const GLuint textureId, bool& setupCalled) | |||
| { | |||
| if (textureId == 0 || image.isInvalid()) | |||
| return; | |||
| if (! setupCalled) | |||
| { | |||
| setupOpenGLImage(image, textureId); | |||
| setupCalled = true; | |||
| } | |||
| glColor4f(1.0f, 1.0f, 1.0f, 1.0f); | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, textureId); | |||
| glBegin(GL_QUADS); | |||
| { | |||
| const int x = pos.getX(); | |||
| const int y = pos.getY(); | |||
| const int w = static_cast<int>(image.getWidth()); | |||
| const int h = static_cast<int>(image.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); | |||
| } | |||
| void OpenGLImage::drawAt(const GraphicsContext&, const Point<int>& pos) | |||
| { | |||
| drawOpenGLImage(*this, pos, textureId, setupCalled); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| void OpenGLImage::draw() | |||
| { | |||
| drawOpenGLImage(*this, Point<int>(0, 0), textureId, setupCalled); | |||
| } | |||
| void OpenGLImage::drawAt(const int x, const int y) | |||
| { | |||
| drawOpenGLImage(*this, Point<int>(x, y), textureId, setupCalled); | |||
| } | |||
| void OpenGLImage::drawAt(const Point<int>& pos) | |||
| { | |||
| drawOpenGLImage(*this, pos, textureId, setupCalled); | |||
| } | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseAboutWindow | |||
| #if 0 | |||
| template <> | |||
| void ImageBaseAboutWindow<OpenGLImage>::onDisplay() | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| img.draw(context); | |||
| } | |||
| #endif | |||
| template class ImageBaseAboutWindow<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseButton | |||
| template class ImageBaseButton<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseKnob | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::PrivateData::init() | |||
| { | |||
| glTextureId = 0; | |||
| glGenTextures(1, &glTextureId); | |||
| } | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::PrivateData::cleanup() | |||
| { | |||
| if (glTextureId == 0) | |||
| return; | |||
| glDeleteTextures(1, &glTextureId); | |||
| glTextureId = 0; | |||
| } | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::onDisplay() | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| const float normValue = getNormalizedValue(); | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, pData->glTextureId); | |||
| if (! pData->isReady) | |||
| { | |||
| 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); | |||
| uint imageDataOffset = 0; | |||
| if (pData->rotationAngle == 0) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pData->imgLayerCount > 0,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(normValue >= 0.0f,); | |||
| const uint& v1(pData->isImgVertical ? pData->imgLayerWidth : pData->imgLayerHeight); | |||
| const uint& v2(pData->isImgVertical ? pData->imgLayerHeight : pData->imgLayerWidth); | |||
| // TODO kImageFormatGreyscale | |||
| const uint layerDataSize = v1 * v2 * ((pData->image.getFormat() == kImageFormatBGRA || | |||
| pData->image.getFormat() == kImageFormatRGBA) ? 4 : 3); | |||
| /* */ imageDataOffset = layerDataSize * uint(normValue * float(pData->imgLayerCount-1)); | |||
| } | |||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
| static_cast<GLsizei>(getWidth()), static_cast<GLsizei>(getHeight()), 0, | |||
| asOpenGLImageFormat(pData->image.getFormat()), GL_UNSIGNED_BYTE, pData->image.getRawData() + imageDataOffset); | |||
| pData->isReady = true; | |||
| } | |||
| const int w = static_cast<int>(getWidth()); | |||
| const int h = static_cast<int>(getHeight()); | |||
| if (pData->rotationAngle != 0) | |||
| { | |||
| glPushMatrix(); | |||
| const int w2 = w/2; | |||
| const int h2 = h/2; | |||
| glTranslatef(static_cast<float>(w2), static_cast<float>(h2), 0.0f); | |||
| glRotatef(normValue*static_cast<float>(pData->rotationAngle), 0.0f, 0.0f, 1.0f); | |||
| Rectangle<int>(-w2, -h2, w, h).draw(context); | |||
| glPopMatrix(); | |||
| } | |||
| else | |||
| { | |||
| Rectangle<int>(0, 0, w, h).draw(context); | |||
| } | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_TEXTURE_2D); | |||
| } | |||
| template class ImageBaseKnob<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseSlider | |||
| template class ImageBaseSlider<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseSwitch | |||
| template class ImageBaseSwitch<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept | |||
| { | |||
| return reinterpret_cast<GraphicsContext&>(graphicsContext); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -0,0 +1,710 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2025 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. | |||
| */ | |||
| #ifdef _MSC_VER | |||
| // instantiated template classes whose methods are defined elsewhere | |||
| # pragma warning(disable:4661) | |||
| #endif | |||
| #include "../OpenGL.hpp" | |||
| #include "../Color.hpp" | |||
| #include "../ImageWidgets.hpp" | |||
| // #include "SubWidgetPrivateData.hpp" | |||
| // #include "TopLevelWidgetPrivateData.hpp" | |||
| // #include "WidgetPrivateData.hpp" | |||
| #include "WindowPrivateData.hpp" | |||
| // templated classes | |||
| #include "ImageBaseWidgets.cpp" | |||
| START_NAMESPACE_DGL | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Check for correct build config | |||
| #ifndef DGL_OPENGL | |||
| # error Build config error, OpenGL was NOT requested while building OpenGL3 code | |||
| #endif | |||
| #ifndef DGL_USE_OPENGL3 | |||
| # error Build config error, OpenGL3 not requested while building OpenGL3 code | |||
| #endif | |||
| #ifdef DGL_CAIRO | |||
| # error Build config error, Cairo requested while building OpenGL3 code | |||
| #endif | |||
| #ifdef DGL_VULKAN | |||
| # error Build config error, Vulkan requested while building OpenGL3 code | |||
| #endif | |||
| #if defined(DGL_USE_GLES2) && defined(DGL_USE_GLES3) | |||
| # error Build config error, both GLESv2 and GLESv3 requested at the same time | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| struct OpenGL3GraphicsContext : GraphicsContext | |||
| { | |||
| mutable int prog, color, pos, tex, texok; | |||
| mutable uint w, h; | |||
| }; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static void notImplemented(const char* const name) | |||
| { | |||
| d_stderr2("OpenGL3 function not implemented: %s", name); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Color | |||
| void Color::setFor(const GraphicsContext& context, const bool includeAlpha) | |||
| { | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat color[4] = { red, green, blue, includeAlpha ? alpha : 1.f }; | |||
| glUniform4fv(gl3context.color, 1, color); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Line | |||
| template<typename T> | |||
| void Line<T>::draw(const GraphicsContext& context, const T width) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(width != 0,); | |||
| glLineWidth(static_cast<GLfloat>(width)); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat x1 = (static_cast<double>(posStart.x) / gl3context.w) * 2 - 1; | |||
| const GLfloat y1 = (static_cast<double>(posStart.y) / gl3context.h) * -2 + 1; | |||
| const GLfloat x2 = (static_cast<double>(posEnd.x) / gl3context.w) * 2 - 1; | |||
| const GLfloat y2 = (static_cast<double>(posEnd.y) / gl3context.h) * -2 + 1; | |||
| const GLfloat vertices[] = { x1, y1, x2, y2, }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| const GLubyte order[] = { 0, 1 }; | |||
| glDrawElements(GL_LINES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Line<T>::draw() | |||
| { | |||
| notImplemented("Line::draw"); | |||
| } | |||
| #endif | |||
| template class Line<double>; | |||
| template class Line<float>; | |||
| template class Line<int>; | |||
| template class Line<uint>; | |||
| template class Line<short>; | |||
| template class Line<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Circle | |||
| template<typename T> | |||
| static void drawCircle(const GraphicsContext& context, | |||
| const Point<T>& pos, | |||
| const uint numSegments, | |||
| const float size, | |||
| const float sin, | |||
| const float cos, | |||
| const bool outline) | |||
| { | |||
| #define MAX_CIRCLE_SEGMENTS 512 | |||
| DISTRHO_SAFE_ASSERT_RETURN(numSegments >= 3 && size > 0.0f,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(numSegments <= MAX_CIRCLE_SEGMENTS,); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const double origx = static_cast<double>(pos.getX()); | |||
| const double origy = static_cast<double>(pos.getY()); | |||
| double t; | |||
| double x = size; | |||
| double y = 0.0; | |||
| GLfloat vertices[(MAX_CIRCLE_SEGMENTS + 1) * 2]; | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| vertices[i * 2 + 0] = ((x + origx) / gl3context.w) * 2 - 1; | |||
| vertices[i * 2 + 1] = ((y + origy) / gl3context.h) * -2 + 1; | |||
| t = x; | |||
| x = cos * x - sin * y; | |||
| y = sin * t + cos * y; | |||
| } | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| if (outline) | |||
| { | |||
| GLushort order[MAX_CIRCLE_SEGMENTS * 2]; | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| order[i * 2 + 0] = i; | |||
| order[i * 2 + 1] = i + 1; | |||
| } | |||
| order[numSegments * 2 - 1] = 0; | |||
| glDrawElements(GL_LINES, numSegments * 2, GL_UNSIGNED_SHORT, order); | |||
| } | |||
| else | |||
| { | |||
| // center position | |||
| vertices[numSegments * 2 + 0] = (origx / gl3context.w) * 2 - 1; | |||
| vertices[numSegments * 2 + 1] = (origy / gl3context.h) * -2 + 1; | |||
| GLushort order[MAX_CIRCLE_SEGMENTS * 3]; | |||
| for (uint i = 0; i < numSegments; ++i) | |||
| { | |||
| order[i * 3 + 0] = i; | |||
| order[i * 3 + 1] = i + 1; | |||
| order[i * 3 + 2] = numSegments; | |||
| } | |||
| order[numSegments * 3 - 2] = 0; | |||
| glDrawElements(GL_TRIANGLES, numSegments * 3, GL_UNSIGNED_SHORT, order); | |||
| } | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawCircle<T>(context, fPos, fNumSegments, fSize, fSin, fCos, false); | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawCircle<T>(context, fPos, fNumSegments, fSize, fSin, fCos, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Circle<T>::draw() | |||
| { | |||
| notImplemented("Circle::draw"); | |||
| } | |||
| template<typename T> | |||
| void Circle<T>::drawOutline() | |||
| { | |||
| notImplemented("Circle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Circle<double>; | |||
| template class Circle<float>; | |||
| template class Circle<int>; | |||
| template class Circle<uint>; | |||
| template class Circle<short>; | |||
| template class Circle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Triangle | |||
| template<typename T> | |||
| static void drawTriangle(const GraphicsContext& context, | |||
| const Point<T>& pos1, | |||
| const Point<T>& pos2, | |||
| const Point<T>& pos3, | |||
| const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pos1 != pos2 && pos1 != pos3,); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat x1 = (static_cast<double>(pos1.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y1 = (static_cast<double>(pos1.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat x2 = (static_cast<double>(pos2.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y2 = (static_cast<double>(pos2.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat x3 = (static_cast<double>(pos3.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y3 = (static_cast<double>(pos3.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat vertices[] = { x1, y1, x2, y2, x3, y3 }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| if (outline) | |||
| { | |||
| const GLubyte order[] = { 0, 1, 1, 2, 2, 0 }; | |||
| glDrawElements(GL_LINES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| } | |||
| else | |||
| { | |||
| glDrawArrays(GL_TRIANGLES, 0, 3); | |||
| } | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawTriangle<T>(context, pos1, pos2, pos3, false); | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawTriangle<T>(context, pos1, pos2, pos3, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Triangle<T>::draw() | |||
| { | |||
| notImplemented("Triangle::draw"); | |||
| } | |||
| template<typename T> | |||
| void Triangle<T>::drawOutline() | |||
| { | |||
| notImplemented("Triangle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Triangle<double>; | |||
| template class Triangle<float>; | |||
| template class Triangle<int>; | |||
| template class Triangle<uint>; | |||
| template class Triangle<short>; | |||
| template class Triangle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Rectangle | |||
| template<typename T> | |||
| static void drawRectangle(const GraphicsContext& context, const Rectangle<T>& rect, const bool outline) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(rect.isValid(),); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat x = (static_cast<double>(rect.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y = (static_cast<double>(rect.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat w = (static_cast<double>(rect.getWidth()) / gl3context.w) * 2; | |||
| const GLfloat h = (static_cast<double>(rect.getHeight()) / gl3context.h) * -2; | |||
| const GLfloat vertices[] = { x, y, x, y + h, x + w, y + h, x + w, y }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| if (outline) | |||
| { | |||
| const GLubyte order[] = { 0, 1, 1, 2, 2, 3, 3, 0 }; | |||
| glDrawElements(GL_LINES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| } | |||
| else | |||
| { | |||
| const GLubyte order[] = { 0, 1, 2, 0, 2, 3 }; | |||
| glDrawElements(GL_TRIANGLES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| } | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::draw(const GraphicsContext& context) | |||
| { | |||
| drawRectangle<T>(context, *this, false); | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(lineWidth != 0,); | |||
| glLineWidth(static_cast<GLfloat>(lineWidth)); | |||
| drawRectangle<T>(context, *this, true); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Rectangle<T>::draw() | |||
| { | |||
| notImplemented("Rectangle::draw"); | |||
| } | |||
| template<typename T> | |||
| void Rectangle<T>::drawOutline() | |||
| { | |||
| notImplemented("Rectangle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Rectangle<double>; | |||
| template class Rectangle<float>; | |||
| template class Rectangle<int>; | |||
| template class Rectangle<uint>; | |||
| template class Rectangle<short>; | |||
| template class Rectangle<ushort>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // OpenGLImage | |||
| static void setupOpenGLImage(const OpenGLImage& image, GLuint textureId) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(image.isValid(),); | |||
| const ImageFormat imageFormat = image.getFormat(); | |||
| GLint intformat = GL_RGBA; | |||
| #ifdef DGL_USE_GLES2 | |||
| // GLESv2 does not support BGR | |||
| DISTRHO_SAFE_ASSERT_RETURN(imageFormat != kImageFormatBGR && imageFormat != kImageFormatBGRA,); | |||
| #endif | |||
| switch (imageFormat) | |||
| { | |||
| case kImageFormatBGR: | |||
| case kImageFormatRGB: | |||
| intformat = GL_RGB; | |||
| break; | |||
| case kImageFormatGrayscale: | |||
| #if defined(DGL_USE_GLES3) | |||
| intformat = GL_R8; | |||
| #elif defined(DGL_USE_OPENGL3) | |||
| intformat = GL_RED; | |||
| #else | |||
| intformat = GL_LUMINANCE; | |||
| #endif | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| glBindTexture(GL_TEXTURE_2D, textureId); | |||
| 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, | |||
| intformat, | |||
| static_cast<GLsizei>(image.getWidth()), | |||
| static_cast<GLsizei>(image.getHeight()), | |||
| 0, | |||
| asOpenGLImageFormat(imageFormat), | |||
| GL_UNSIGNED_BYTE, | |||
| image.getRawData()); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| } | |||
| // static void drawOpenGLImage(const GraphicsContext& context, | |||
| // const OpenGLImage& image, | |||
| // const Point<int>& pos, | |||
| // const GLuint textureId, | |||
| // bool& setupCalled) | |||
| // { | |||
| // } | |||
| void OpenGLImage::drawAt(const GraphicsContext& context, const Point<int>& pos) | |||
| { | |||
| // drawOpenGLImage(context, *this, pos, textureId, setupCalled); | |||
| if (textureId == 0 || isInvalid()) | |||
| return; | |||
| if (! setupCalled) | |||
| { | |||
| setupOpenGLImage(*this, textureId); | |||
| setupCalled = true; | |||
| } | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| const GLfloat color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; | |||
| glUniform4fv(gl3context.color, 1, color); | |||
| const GLfloat x = (static_cast<double>(pos.getX()) / gl3context.w) * 2 - 1; | |||
| const GLfloat y = (static_cast<double>(pos.getY()) / gl3context.h) * -2 + 1; | |||
| const GLfloat w = (static_cast<double>(getWidth()) / gl3context.w) * 2; | |||
| const GLfloat h = (static_cast<double>(getHeight()) / gl3context.h) * -2; | |||
| glActiveTexture(GL_TEXTURE0); | |||
| glBindTexture(GL_TEXTURE_2D, textureId); | |||
| glUniform1i(gl3context.texok, 1); | |||
| const GLfloat vertices[] = { x, y, x, y + h, x + w, y + h, x + w, y }; | |||
| glVertexAttribPointer(gl3context.pos, 2, GL_FLOAT, GL_FALSE, 0, vertices); | |||
| glEnableVertexAttribArray(gl3context.pos); | |||
| const GLfloat vtex[] = { 0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f, 0.f }; | |||
| glVertexAttribPointer(gl3context.tex, 2, GL_FLOAT, GL_FALSE, 0, vtex); | |||
| glEnableVertexAttribArray(gl3context.tex); | |||
| const GLubyte order[] = { 0, 1, 2, 0, 2, 3 }; | |||
| glDrawElements(GL_TRIANGLES, ARRAY_SIZE(order), GL_UNSIGNED_BYTE, order); | |||
| glUniform1i(gl3context.texok, 0); | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| void OpenGLImage::draw() | |||
| { | |||
| notImplemented("OpenGLImage::draw"); | |||
| } | |||
| void OpenGLImage::drawAt(const int x, const int y) | |||
| { | |||
| notImplemented("OpenGLImage::drawAt"); | |||
| } | |||
| void OpenGLImage::drawAt(const Point<int>& pos) | |||
| { | |||
| notImplemented("OpenGLImage::drawAt"); | |||
| } | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseAboutWindow | |||
| #if 0 | |||
| template <> | |||
| void ImageBaseAboutWindow<OpenGLImage>::onDisplay() | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| img.draw(context); | |||
| } | |||
| #endif | |||
| template class ImageBaseAboutWindow<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseButton | |||
| template class ImageBaseButton<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseKnob | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::PrivateData::init() | |||
| { | |||
| glTextureId = 0; | |||
| glGenTextures(1, &glTextureId); | |||
| } | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::PrivateData::cleanup() | |||
| { | |||
| if (glTextureId == 0) | |||
| return; | |||
| glDeleteTextures(1, &glTextureId); | |||
| glTextureId = 0; | |||
| } | |||
| template <> | |||
| void ImageBaseKnob<OpenGLImage>::onDisplay() | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| const float normValue = getNormalizedValue(); | |||
| glEnable(GL_TEXTURE_2D); | |||
| glBindTexture(GL_TEXTURE_2D, pData->glTextureId); | |||
| if (! pData->isReady) | |||
| { | |||
| 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); | |||
| uint imageDataOffset = 0; | |||
| if (pData->rotationAngle == 0) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(pData->imgLayerCount > 0,); | |||
| DISTRHO_SAFE_ASSERT_RETURN(normValue >= 0.0f,); | |||
| const uint& v1(pData->isImgVertical ? pData->imgLayerWidth : pData->imgLayerHeight); | |||
| const uint& v2(pData->isImgVertical ? pData->imgLayerHeight : pData->imgLayerWidth); | |||
| // TODO kImageFormatGreyscale | |||
| const uint layerDataSize = v1 * v2 * ((pData->image.getFormat() == kImageFormatBGRA || | |||
| pData->image.getFormat() == kImageFormatRGBA) ? 4 : 3); | |||
| /* */ imageDataOffset = layerDataSize * uint(normValue * float(pData->imgLayerCount-1)); | |||
| } | |||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
| static_cast<GLsizei>(getWidth()), static_cast<GLsizei>(getHeight()), 0, | |||
| asOpenGLImageFormat(pData->image.getFormat()), GL_UNSIGNED_BYTE, pData->image.getRawData() + imageDataOffset); | |||
| pData->isReady = true; | |||
| } | |||
| const int w = static_cast<int>(getWidth()); | |||
| const int h = static_cast<int>(getHeight()); | |||
| if (pData->rotationAngle != 0) | |||
| { | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| glPushMatrix(); | |||
| #endif | |||
| const int w2 = w/2; | |||
| const int h2 = h/2; | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| glTranslatef(static_cast<float>(w2), static_cast<float>(h2), 0.0f); | |||
| glRotatef(normValue*static_cast<float>(pData->rotationAngle), 0.0f, 0.0f, 1.0f); | |||
| #endif | |||
| Rectangle<int>(-w2, -h2, w, h).draw(context); | |||
| #ifdef DGL_USE_COMPAT_OPENGL | |||
| glPopMatrix(); | |||
| #endif | |||
| } | |||
| else | |||
| { | |||
| Rectangle<int>(0, 0, w, h).draw(context); | |||
| } | |||
| glBindTexture(GL_TEXTURE_2D, 0); | |||
| glDisable(GL_TEXTURE_2D); | |||
| } | |||
| template class ImageBaseKnob<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseSlider | |||
| template class ImageBaseSlider<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // ImageBaseSwitch | |||
| template class ImageBaseSwitch<OpenGLImage>; | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static const GraphicsContext& contextCreationFail(const OpenGL3GraphicsContext& gl3context) | |||
| { | |||
| gl3context.prog = -1; | |||
| return gl3context; | |||
| } | |||
| const GraphicsContext& Window::PrivateData::getGraphicsContext() const noexcept | |||
| { | |||
| GraphicsContext& context = reinterpret_cast<GraphicsContext&>(graphicsContext); | |||
| const OpenGL3GraphicsContext& gl3context = static_cast<const OpenGL3GraphicsContext&>(context); | |||
| // previous context creation failed | |||
| if (gl3context.prog == -1) | |||
| return context; | |||
| // create new context | |||
| if (gl3context.prog == 0) | |||
| { | |||
| int status; | |||
| const GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER); | |||
| DISTRHO_SAFE_ASSERT_RETURN(fragment != 0, contextCreationFail(gl3context)); | |||
| const GLuint vertex = glCreateShader(GL_VERTEX_SHADER); | |||
| DISTRHO_SAFE_ASSERT_RETURN(vertex != 0, contextCreationFail(gl3context)); | |||
| const GLuint program = glCreateProgram(); | |||
| DISTRHO_SAFE_ASSERT_RETURN(program != 0, contextCreationFail(gl3context)); | |||
| #if defined(DGL_USE_GLES2) | |||
| #define DGL_SHADER_HEADER "#version 100\n" | |||
| #elif defined(DGL_USE_GLES3) | |||
| #define DGL_SHADER_HEADER "#version 300 es\n" | |||
| #else | |||
| #define DGL_SHADER_HEADER "#version 150 core\n" | |||
| #endif | |||
| { | |||
| static constexpr const char* const src = DGL_SHADER_HEADER | |||
| "precision mediump float;" | |||
| "uniform vec4 color;" | |||
| "uniform sampler2D stex;" | |||
| "uniform bool texok;" | |||
| "varying vec2 vtex;" | |||
| "void main() { gl_FragColor = texok ? texture2D(stex, vtex) : color; }"; | |||
| glShaderSource(fragment, 1, &src, nullptr); | |||
| glCompileShader(fragment); | |||
| glGetShaderiv(fragment, GL_COMPILE_STATUS, &status); | |||
| DISTRHO_SAFE_ASSERT_RETURN(status != 0, contextCreationFail(gl3context)); | |||
| } | |||
| { | |||
| static constexpr const char* const src = DGL_SHADER_HEADER | |||
| "attribute vec4 pos;" | |||
| "attribute vec2 tex;" | |||
| "varying vec2 vtex;" | |||
| "void main() { gl_Position = pos; vtex = tex; }"; | |||
| glShaderSource(vertex, 1, &src, nullptr); | |||
| glCompileShader(vertex); | |||
| glGetShaderiv(vertex, GL_COMPILE_STATUS, &status); | |||
| DISTRHO_SAFE_ASSERT_RETURN(status != 0, contextCreationFail(gl3context)); | |||
| } | |||
| glAttachShader(program, fragment); | |||
| glAttachShader(program, vertex); | |||
| glLinkProgram(program); | |||
| glGetProgramiv(program, GL_LINK_STATUS, &status); | |||
| DISTRHO_SAFE_ASSERT_RETURN(status != 0, contextCreationFail(gl3context)); | |||
| gl3context.prog = program; | |||
| gl3context.color = glGetUniformLocation(program, "color"); | |||
| gl3context.texok = glGetUniformLocation(program, "texok"); | |||
| gl3context.pos = glGetAttribLocation(program, "pos"); | |||
| gl3context.tex = glGetAttribLocation(program, "tex"); | |||
| } | |||
| const PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE); | |||
| gl3context.w = size.width; | |||
| gl3context.h = size.height; | |||
| glUseProgram(gl3context.prog); | |||
| return context; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DGL | |||
| @@ -19,7 +19,9 @@ | |||
| # pragma warning(disable:4661) | |||
| #endif | |||
| #include "Color.hpp" | |||
| #include "../Color.hpp" | |||
| #include "../ImageBaseWidgets.hpp" | |||
| #include "SubWidgetPrivateData.hpp" | |||
| #include "TopLevelWidgetPrivateData.hpp" | |||
| #include "WidgetPrivateData.hpp" | |||
| @@ -27,6 +29,28 @@ | |||
| START_NAMESPACE_DGL | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Check for correct build config | |||
| #ifdef DGL_CAIRO | |||
| # error Build config error, Cairo requested while building Stub code | |||
| #endif | |||
| #ifdef DGL_OPENGL | |||
| # error Build config error, OpenGL requested while building Stub code | |||
| #endif | |||
| #ifdef DGL_VULKAN | |||
| # error Build config error, Vulkan requested while building Stub code | |||
| #endif | |||
| #ifdef DGL_USE_GLES2 | |||
| # error Build config error, GLESv2 requested while building Stub code | |||
| #endif | |||
| #ifdef DGL_USE_GLES3 | |||
| # error Build config error, GLESv3 requested while building Stub code | |||
| #endif | |||
| #ifdef DGL_USE_OPENGL3 | |||
| # error Build config error, OpenGL3 requested while building Stub code | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static void notImplemented(const char* const name) | |||
| @@ -51,11 +75,13 @@ void Line<T>::draw(const GraphicsContext& context, T) | |||
| notImplemented("Line::draw"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Line<T>::draw() | |||
| { | |||
| notImplemented("Line::draw"); | |||
| } | |||
| #endif | |||
| template class Line<double>; | |||
| template class Line<float>; | |||
| @@ -79,6 +105,7 @@ void Circle<T>::drawOutline(const GraphicsContext&, T) | |||
| notImplemented("Circle::drawOutline"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Circle<T>::draw() | |||
| { | |||
| @@ -90,6 +117,7 @@ void Circle<T>::drawOutline() | |||
| { | |||
| notImplemented("Circle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Circle<double>; | |||
| template class Circle<float>; | |||
| @@ -113,6 +141,7 @@ void Triangle<T>::drawOutline(const GraphicsContext&, T) | |||
| notImplemented("Triangle::drawOutline"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Triangle<T>::draw() | |||
| { | |||
| @@ -124,6 +153,7 @@ void Triangle<T>::drawOutline() | |||
| { | |||
| notImplemented("Triangle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Triangle<double>; | |||
| template class Triangle<float>; | |||
| @@ -147,6 +177,7 @@ void Rectangle<T>::drawOutline(const GraphicsContext&, T) | |||
| notImplemented("Rectangle::drawOutline"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Rectangle<T>::draw() | |||
| { | |||
| @@ -158,6 +189,7 @@ void Rectangle<T>::drawOutline() | |||
| { | |||
| notImplemented("Rectangle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Rectangle<double>; | |||
| template class Rectangle<float>; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2025 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 | |||
| @@ -14,8 +14,14 @@ | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #ifdef _MSC_VER | |||
| // instantiated template classes whose methods are defined elsewhere | |||
| # pragma warning(disable:4661) | |||
| #endif | |||
| #include "../Vulkan.hpp" | |||
| #include "../Color.hpp" | |||
| #include "../ImageBaseWidgets.hpp" | |||
| #include "SubWidgetPrivateData.hpp" | |||
| #include "TopLevelWidgetPrivateData.hpp" | |||
| @@ -24,14 +30,36 @@ | |||
| START_NAMESPACE_DGL | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Check for correct build config | |||
| #ifndef DGL_VULKAN | |||
| # error Build config error, Vulkan was NOT requested while building Vulkan code | |||
| #endif | |||
| #ifdef DGL_CAIRO | |||
| # error Build config error, Cairo requested while building Vulkan code | |||
| #endif | |||
| #ifdef DGL_OPENGL | |||
| # error Build config error, OpenGL requested while building Vulkan code | |||
| #endif | |||
| #ifdef DGL_USE_GLES2 | |||
| # error Build config error, GLESv2 requested while building Vulkan code | |||
| #endif | |||
| #ifdef DGL_USE_GLES3 | |||
| # error Build config error, GLESv3 requested while building Vulkan code | |||
| #endif | |||
| #ifdef DGL_USE_OPENGL3 | |||
| # error Build config error, OpenGL3 requested while building Vulkan code | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static void notImplemented(const char* const name) | |||
| { | |||
| d_stderr2("vulkan function not implemented: %s", name); | |||
| d_stderr2("Vulkan function not implemented: %s", name); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Color | |||
| void Color::setFor(const GraphicsContext&, bool) | |||
| @@ -48,11 +76,13 @@ void Line<T>::draw(const GraphicsContext&, T) | |||
| notImplemented("Line::draw"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Line<T>::draw() | |||
| { | |||
| notImplemented("Line::draw"); | |||
| } | |||
| #endif | |||
| template class Line<double>; | |||
| template class Line<float>; | |||
| @@ -76,6 +106,7 @@ void Circle<T>::drawOutline(const GraphicsContext&, T) | |||
| notImplemented("Circle::drawOutline"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Circle<T>::draw() | |||
| { | |||
| @@ -87,6 +118,7 @@ void Circle<T>::drawOutline() | |||
| { | |||
| notImplemented("Circle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Circle<double>; | |||
| template class Circle<float>; | |||
| @@ -110,6 +142,7 @@ void Triangle<T>::drawOutline(const GraphicsContext&, T) | |||
| notImplemented("Triangle::drawOutline"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Triangle<T>::draw() | |||
| { | |||
| @@ -121,6 +154,7 @@ void Triangle<T>::drawOutline() | |||
| { | |||
| notImplemented("Triangle::drawOutline"); | |||
| } | |||
| #endif | |||
| template class Triangle<double>; | |||
| template class Triangle<float>; | |||
| @@ -129,7 +163,6 @@ template class Triangle<uint>; | |||
| template class Triangle<short>; | |||
| template class Triangle<ushort>; | |||
| // ----------------------------------------------------------------------- | |||
| // Rectangle | |||
| @@ -145,11 +178,13 @@ void Rectangle<T>::drawOutline(const GraphicsContext&, T) | |||
| notImplemented("Rectangle::drawOutline"); | |||
| } | |||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||
| template<typename T> | |||
| void Rectangle<T>::draw() | |||
| { | |||
| notImplemented("Rectangle::draw"); | |||
| } | |||
| #endif | |||
| template<typename T> | |||
| void Rectangle<T>::drawOutline() | |||
| @@ -3,6 +3,7 @@ | |||
| dpf_add_plugin(d_parameters | |||
| TARGETS jack ladspa dssi lv2 vst2 vst3 clap | |||
| UI_TYPE gles2 | |||
| FILES_DSP | |||
| ExamplePluginParameters.cpp | |||
| FILES_UI | |||
| @@ -21,6 +21,7 @@ FILES_UI = \ | |||
| # -------------------------------------------------------------- | |||
| # Do some magic | |||
| UI_TYPE = gles2 | |||
| include ../../Makefile.plugins.mk | |||
| # -------------------------------------------------------------- | |||