Signed-off-by: falkTX <falktx@falktx.com>pull/506/head
| @@ -98,24 +98,52 @@ jobs: | |||||
| run: | | run: | | ||||
| make clean >/dev/null | make clean >/dev/null | ||||
| make -j ${{ env.JOBS }} | make -j ${{ env.JOBS }} | ||||
| - name: With OpenGL 3.x | |||||
| - name: Without Cairo | |||||
| env: | env: | ||||
| CFLAGS: -Werror | CFLAGS: -Werror | ||||
| CXXFLAGS: -Werror | CXXFLAGS: -Werror | ||||
| run: | | run: | | ||||
| make clean >/dev/null | 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: | env: | ||||
| CFLAGS: -Werror | CFLAGS: -Werror | ||||
| CXXFLAGS: -Werror | CXXFLAGS: -Werror | ||||
| run: | | run: | | ||||
| make clean >/dev/null | 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: | env: | ||||
| CFLAGS: -Werror | CFLAGS: -Werror | ||||
| CXXFLAGS: -Werror | CXXFLAGS: -Werror | ||||
| run: | | run: | | ||||
| make clean >/dev/null | 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: | # extra useful variables to define before including this file: | ||||
| # - DPF_BUILD_DIR: where to place temporary build files | # - DPF_BUILD_DIR: where to place temporary build files | ||||
| # - DPF_TARGET_DIR: where to place final binary 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) | # ("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: | # 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/Window.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL3.cpp" | |||||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | ||||
| if(SHARED_RESOURCES) | if(SHARED_RESOURCES) | ||||
| target_sources(dgl-gles2 PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | 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/Window.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL3.cpp" | |||||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | ||||
| if(SHARED_RESOURCES) | if(SHARED_RESOURCES) | ||||
| target_sources(dgl-gles3 PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | 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/Window.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL2.cpp" | |||||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | ||||
| if(SHARED_RESOURCES) | if(SHARED_RESOURCES) | ||||
| target_sources(dgl-opengl PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | 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/Window.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | "${DPF_ROOT_DIR}/dgl/src/WindowPrivateData.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | "${DPF_ROOT_DIR}/dgl/src/OpenGL.cpp" | ||||
| "${DPF_ROOT_DIR}/dgl/src/OpenGL3.cpp" | |||||
| "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | "${DPF_ROOT_DIR}/dgl/src/NanoVG.cpp") | ||||
| if(SHARED_RESOURCES) | if(SHARED_RESOURCES) | ||||
| target_sources(dgl-opengl3 PRIVATE "${DPF_ROOT_DIR}/dgl/src/Resources.cpp") | 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) | # error DGL_FILE_BROWSER_DISABLED has been replaced by DGL_USE_FILE_BROWSER (opt-in vs opt-out) | ||||
| #endif | #endif | ||||
| #ifndef DGL_ALLOW_DEPRECATED_METHODS | |||||
| # define DGL_ALLOW_DEPRECATED_METHODS 1 | |||||
| #endif | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // Define namespace | // Define namespace | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -165,10 +165,9 @@ private: | |||||
| Widget display function. | Widget display function. | ||||
| Implemented internally to pass context into the drawing 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); | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CairoBaseWidget); | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -360,25 +360,23 @@ public: | |||||
| */ | */ | ||||
| bool isNotNull() const noexcept; | bool isNotNull() const noexcept; | ||||
| #ifndef DPF_TEST_POINT_CPP | |||||
| /** | /** | ||||
| Draw this line using the provided graphics context, optionally specifying line width. | Draw this line using the provided graphics context, optionally specifying line width. | ||||
| */ | */ | ||||
| void draw(const GraphicsContext& context, T width = 1); | void draw(const GraphicsContext& context, T width = 1); | ||||
| #endif | |||||
| Line<T>& operator=(const Line<T>& line) noexcept; | Line<T>& operator=(const Line<T>& line) noexcept; | ||||
| bool operator==(const Line<T>& line) const noexcept; | bool operator==(const Line<T>& line) const 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 | Draw this line using the current OpenGL state.@n | ||||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | DEPRECATED Please use draw(const GraphicsContext&) instead. | ||||
| */ | */ | ||||
| DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)") | DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)") | ||||
| void draw(); | void draw(); | ||||
| #endif | |||||
| #endif | |||||
| private: | private: | ||||
| Point<T> posStart, posEnd; | 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; | ||||
| 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 | Draw this circle using the current OpenGL state.@n | ||||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | DEPRECATED Please use draw(const GraphicsContext&) instead. | ||||
| @@ -503,7 +501,7 @@ public: | |||||
| */ | */ | ||||
| DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | ||||
| void drawOutline(); | void drawOutline(); | ||||
| #endif | |||||
| #endif | |||||
| private: | private: | ||||
| Point<T> fPos; | Point<T> fPos; | ||||
| @@ -582,7 +580,7 @@ public: | |||||
| bool operator==(const Triangle<T>& tri) const noexcept; | bool operator==(const Triangle<T>& tri) const noexcept; | ||||
| 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 | Draw this triangle using the current OpenGL state.@n | ||||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | DEPRECATED Please use draw(const GraphicsContext&) instead. | ||||
| @@ -596,7 +594,7 @@ public: | |||||
| */ | */ | ||||
| DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | ||||
| void drawOutline(); | void drawOutline(); | ||||
| #endif | |||||
| #endif | |||||
| private: | private: | ||||
| Point<T> pos1, pos2, pos3; | 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; | ||||
| 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 | Draw this rectangle using the current OpenGL state.@n | ||||
| DEPRECATED Please use draw(const GraphicsContext&) instead. | DEPRECATED Please use draw(const GraphicsContext&) instead. | ||||
| @@ -826,6 +825,7 @@ public: | |||||
| */ | */ | ||||
| DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)") | ||||
| void drawOutline(); | void drawOutline(); | ||||
| #endif | |||||
| private: | private: | ||||
| Point<T> pos; | Point<T> pos; | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -17,17 +17,21 @@ | |||||
| #ifndef DGL_IMAGE_HPP_INCLUDED | #ifndef DGL_IMAGE_HPP_INCLUDED | ||||
| #define 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 | #else | ||||
| #include "OpenGL.hpp" | |||||
| # include "Base.hpp" | |||||
| #endif | #endif | ||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| #ifdef DGL_CAIRO | |||||
| #if defined(DGL_CAIRO) | |||||
| typedef CairoImage Image; | typedef CairoImage Image; | ||||
| #else | |||||
| #elif defined(DGL_OPENGL) | |||||
| typedef OpenGLImage Image; | typedef OpenGLImage Image; | ||||
| #endif | #endif | ||||
| @@ -73,6 +73,7 @@ endif | |||||
| OBJS_gles2 = $(OBJS_common) \ | OBJS_gles2 = $(OBJS_common) \ | ||||
| $(BUILD_DIR)/dgl/OpenGL.cpp.gles2.o \ | $(BUILD_DIR)/dgl/OpenGL.cpp.gles2.o \ | ||||
| $(BUILD_DIR)/dgl/OpenGL3.cpp.gles2.o \ | |||||
| $(BUILD_DIR)/dgl/NanoVG.cpp.gles2.o | $(BUILD_DIR)/dgl/NanoVG.cpp.gles2.o | ||||
| ifeq ($(MACOS),true) | ifeq ($(MACOS),true) | ||||
| @@ -85,6 +86,7 @@ endif | |||||
| OBJS_gles3 = $(OBJS_common) \ | OBJS_gles3 = $(OBJS_common) \ | ||||
| $(BUILD_DIR)/dgl/OpenGL.cpp.gles3.o \ | $(BUILD_DIR)/dgl/OpenGL.cpp.gles3.o \ | ||||
| $(BUILD_DIR)/dgl/OpenGL3.cpp.gles3.o \ | |||||
| $(BUILD_DIR)/dgl/NanoVG.cpp.gles3.o | $(BUILD_DIR)/dgl/NanoVG.cpp.gles3.o | ||||
| ifeq ($(MACOS),true) | ifeq ($(MACOS),true) | ||||
| @@ -97,6 +99,7 @@ endif | |||||
| OBJS_opengl = $(OBJS_common) \ | OBJS_opengl = $(OBJS_common) \ | ||||
| $(BUILD_DIR)/dgl/OpenGL.cpp.opengl.o \ | $(BUILD_DIR)/dgl/OpenGL.cpp.opengl.o \ | ||||
| $(BUILD_DIR)/dgl/OpenGL2.cpp.opengl.o \ | |||||
| $(BUILD_DIR)/dgl/NanoVG.cpp.opengl.o | $(BUILD_DIR)/dgl/NanoVG.cpp.opengl.o | ||||
| ifeq ($(MACOS),true) | ifeq ($(MACOS),true) | ||||
| @@ -109,6 +112,7 @@ endif | |||||
| OBJS_opengl3 = $(OBJS_common) \ | OBJS_opengl3 = $(OBJS_common) \ | ||||
| $(BUILD_DIR)/dgl/OpenGL.cpp.opengl3.o \ | $(BUILD_DIR)/dgl/OpenGL.cpp.opengl3.o \ | ||||
| $(BUILD_DIR)/dgl/OpenGL3.cpp.opengl3.o \ | |||||
| $(BUILD_DIR)/dgl/NanoVG.cpp.opengl3.o | $(BUILD_DIR)/dgl/NanoVG.cpp.opengl3.o | ||||
| ifeq ($(MACOS),true) | ifeq ($(MACOS),true) | ||||
| @@ -146,7 +150,10 @@ TARGETS += $(BUILD_DIR)/libdgl-cairo.a | |||||
| endif | endif | ||||
| ifeq ($(HAVE_OPENGL),true) | 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-opengl.a | ||||
| TARGETS += $(BUILD_DIR)/libdgl-opengl3.a | |||||
| endif | endif | ||||
| ifeq ($(HAVE_STUB),true) | ifeq ($(HAVE_STUB),true) | ||||
| @@ -24,18 +24,7 @@ | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| // ----------------------------------------------------------------------- | |||||
| /** | |||||
| OpenGL Graphics context. | |||||
| */ | |||||
| struct OpenGLGraphicsContext : GraphicsContext | |||||
| { | |||||
| #ifdef DGL_USE_OPENGL3 | |||||
| #endif | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| static inline | static inline | ||||
| ImageFormat asDISTRHOImageFormat(const GLenum format) | ImageFormat asDISTRHOImageFormat(const GLenum format) | ||||
| @@ -87,7 +76,7 @@ GLenum asOpenGLImageFormat(const ImageFormat format) | |||||
| return 0x0; | return 0x0; | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| /** | /** | ||||
| OpenGL Image class. | OpenGL Image class. | ||||
| @@ -157,6 +146,7 @@ public: | |||||
| inline void drawAt(const GraphicsContext& context, int x, int y) | inline void drawAt(const GraphicsContext& context, int x, int y) | ||||
| { drawAt(context, Point<int>(x, y)); } | { drawAt(context, Point<int>(x, y)); } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| /** | /** | ||||
| Constructor using raw image data, specifying an OpenGL image format. | Constructor using raw image data, specifying an OpenGL image format. | ||||
| @note @a rawData must remain valid for the lifetime of this Image. | @note @a rawData must remain valid for the lifetime of this Image. | ||||
| @@ -200,6 +190,7 @@ public: | |||||
| */ | */ | ||||
| DISTRHO_DEPRECATED | DISTRHO_DEPRECATED | ||||
| GLenum getType() const noexcept { return GL_UNSIGNED_BYTE; } | GLenum getType() const noexcept { return GL_UNSIGNED_BYTE; } | ||||
| #endif // DGL_ALLOW_DEPRECATED_METHODS | |||||
| private: | private: | ||||
| bool setupCalled; | bool setupCalled; | ||||
| @@ -207,7 +198,7 @@ private: | |||||
| GLuint textureId; | GLuint textureId; | ||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| typedef ImageBaseAboutWindow<OpenGLImage> OpenGLImageAboutWindow; | typedef ImageBaseAboutWindow<OpenGLImage> OpenGLImageAboutWindow; | ||||
| typedef ImageBaseButton<OpenGLImage> OpenGLImageButton; | typedef ImageBaseButton<OpenGLImage> OpenGLImageButton; | ||||
| @@ -215,7 +206,7 @@ typedef ImageBaseKnob<OpenGLImage> OpenGLImageKnob; | |||||
| typedef ImageBaseSlider<OpenGLImage> OpenGLImageSlider; | typedef ImageBaseSlider<OpenGLImage> OpenGLImageSlider; | ||||
| typedef ImageBaseSwitch<OpenGLImage> OpenGLImageSwitch; | typedef ImageBaseSwitch<OpenGLImage> OpenGLImageSwitch; | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | END_NAMESPACE_DGL | ||||
| @@ -32,16 +32,38 @@ | |||||
| // templated classes | // templated classes | ||||
| #include "ImageBaseWidgets.cpp" | #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 | START_NAMESPACE_DGL | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| static void notImplemented(const char* const name) | static void notImplemented(const char* const name) | ||||
| { | { | ||||
| d_stderr2("Cairo function not implemented: %s", name); | d_stderr2("Cairo function not implemented: %s", name); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // Color | // Color | ||||
| void Color::setFor(const GraphicsContext& context, const bool includeAlpha) | 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); | cairo_set_source_rgb(handle, red, green, blue); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // Line | // Line | ||||
| template<typename T> | template<typename T> | ||||
| @@ -71,11 +93,13 @@ void Line<T>::draw(const GraphicsContext& context, const T width) | |||||
| cairo_stroke(handle); | cairo_stroke(handle); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Line<T>::draw() | void Line<T>::draw() | ||||
| { | { | ||||
| notImplemented("Line::draw"); | notImplemented("Line::draw"); | ||||
| } | } | ||||
| #endif | |||||
| template class Line<double>; | template class Line<double>; | ||||
| template class Line<float>; | 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); | drawCircle<T>(handle, fPos, fNumSegments, fSize, fSin, fCos, true); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Circle<T>::draw() | void Circle<T>::draw() | ||||
| { | { | ||||
| @@ -156,6 +181,7 @@ void Circle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Circle::drawOutline"); | notImplemented("Circle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Circle<double>; | template class Circle<double>; | ||||
| template class Circle<float>; | 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); | drawTriangle<T>(handle, pos1, pos2, pos3, true); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Triangle<T>::draw() | void Triangle<T>::draw() | ||||
| { | { | ||||
| @@ -217,6 +244,7 @@ void Triangle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Triangle::drawOutline"); | notImplemented("Triangle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Triangle<double>; | template class Triangle<double>; | ||||
| template class Triangle<float>; | template class Triangle<float>; | ||||
| @@ -261,6 +289,7 @@ void Rectangle<T>::drawOutline(const GraphicsContext& context, const T lineWidth | |||||
| drawRectangle(handle, *this, true); | drawRectangle(handle, *this, true); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Rectangle<T>::draw() | void Rectangle<T>::draw() | ||||
| { | { | ||||
| @@ -272,6 +301,7 @@ void Rectangle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Rectangle::drawOutline"); | notImplemented("Rectangle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Rectangle<double>; | template class Rectangle<double>; | ||||
| template class Rectangle<float>; | template class Rectangle<float>; | ||||
| @@ -20,7 +20,6 @@ | |||||
| #endif | #endif | ||||
| #include "../OpenGL.hpp" | #include "../OpenGL.hpp" | ||||
| #include "../Color.hpp" | |||||
| #include "../ImageWidgets.hpp" | #include "../ImageWidgets.hpp" | ||||
| #include "SubWidgetPrivateData.hpp" | #include "SubWidgetPrivateData.hpp" | ||||
| @@ -28,660 +27,11 @@ | |||||
| #include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
| #include "WindowPrivateData.hpp" | #include "WindowPrivateData.hpp" | ||||
| // templated classes | |||||
| #include "ImageBaseWidgets.cpp" | |||||
| START_NAMESPACE_DGL | 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 | // 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() | OpenGLImage::OpenGLImage() | ||||
| : ImageBase(), | : ImageBase(), | ||||
| setupCalled(false), | setupCalled(false), | ||||
| @@ -738,11 +88,6 @@ void OpenGLImage::loadFromMemory(const char* const rdata, const Size<uint>& s, c | |||||
| ImageBase::loadFromMemory(rdata, s, fmt); | 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 | OpenGLImage& OpenGLImage::operator=(const OpenGLImage& image) noexcept | ||||
| { | { | ||||
| rawData = image.rawData; | rawData = image.rawData; | ||||
| @@ -760,7 +105,7 @@ OpenGLImage& OpenGLImage::operator=(const OpenGLImage& image) noexcept | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| // deprecated calls | |||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| OpenGLImage::OpenGLImage(const char* const rdata, const uint w, const uint h, const GLenum fmt) | OpenGLImage::OpenGLImage(const char* const rdata, const uint w, const uint h, const GLenum fmt) | ||||
| : ImageBase(rdata, w, h, asDISTRHOImageFormat(fmt)), | : ImageBase(rdata, w, h, asDISTRHOImageFormat(fmt)), | ||||
| setupCalled(false), | setupCalled(false), | ||||
| @@ -780,163 +125,9 @@ OpenGLImage::OpenGLImage(const char* const rdata, const Size<uint>& s, const GLe | |||||
| glGenTextures(1, &textureId); | glGenTextures(1, &textureId); | ||||
| DISTRHO_SAFE_ASSERT(textureId != 0); | 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 | #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) | 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); | selfw->pData->displaySubWidgets(width, height, autoScaleFactor); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| void TopLevelWidget::PrivateData::display() | void TopLevelWidget::PrivateData::display() | ||||
| { | { | ||||
| @@ -1018,7 +209,7 @@ void TopLevelWidget::PrivateData::display() | |||||
| selfw->pData->displaySubWidgets(width, height, window.pData->autoScaleFactor); | selfw->pData->displaySubWidgets(width, height, window.pData->autoScaleFactor); | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| void Window::PrivateData::renderToPicture(const char* const filename, | void Window::PrivateData::renderToPicture(const char* const filename, | ||||
| const GraphicsContext&, | 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 | 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) | # pragma warning(disable:4661) | ||||
| #endif | #endif | ||||
| #include "Color.hpp" | |||||
| #include "../Color.hpp" | |||||
| #include "../ImageBaseWidgets.hpp" | |||||
| #include "SubWidgetPrivateData.hpp" | #include "SubWidgetPrivateData.hpp" | ||||
| #include "TopLevelWidgetPrivateData.hpp" | #include "TopLevelWidgetPrivateData.hpp" | ||||
| #include "WidgetPrivateData.hpp" | #include "WidgetPrivateData.hpp" | ||||
| @@ -27,6 +29,28 @@ | |||||
| START_NAMESPACE_DGL | 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) | static void notImplemented(const char* const name) | ||||
| @@ -51,11 +75,13 @@ void Line<T>::draw(const GraphicsContext& context, T) | |||||
| notImplemented("Line::draw"); | notImplemented("Line::draw"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Line<T>::draw() | void Line<T>::draw() | ||||
| { | { | ||||
| notImplemented("Line::draw"); | notImplemented("Line::draw"); | ||||
| } | } | ||||
| #endif | |||||
| template class Line<double>; | template class Line<double>; | ||||
| template class Line<float>; | template class Line<float>; | ||||
| @@ -79,6 +105,7 @@ void Circle<T>::drawOutline(const GraphicsContext&, T) | |||||
| notImplemented("Circle::drawOutline"); | notImplemented("Circle::drawOutline"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Circle<T>::draw() | void Circle<T>::draw() | ||||
| { | { | ||||
| @@ -90,6 +117,7 @@ void Circle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Circle::drawOutline"); | notImplemented("Circle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Circle<double>; | template class Circle<double>; | ||||
| template class Circle<float>; | template class Circle<float>; | ||||
| @@ -113,6 +141,7 @@ void Triangle<T>::drawOutline(const GraphicsContext&, T) | |||||
| notImplemented("Triangle::drawOutline"); | notImplemented("Triangle::drawOutline"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Triangle<T>::draw() | void Triangle<T>::draw() | ||||
| { | { | ||||
| @@ -124,6 +153,7 @@ void Triangle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Triangle::drawOutline"); | notImplemented("Triangle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Triangle<double>; | template class Triangle<double>; | ||||
| template class Triangle<float>; | template class Triangle<float>; | ||||
| @@ -147,6 +177,7 @@ void Rectangle<T>::drawOutline(const GraphicsContext&, T) | |||||
| notImplemented("Rectangle::drawOutline"); | notImplemented("Rectangle::drawOutline"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Rectangle<T>::draw() | void Rectangle<T>::draw() | ||||
| { | { | ||||
| @@ -158,6 +189,7 @@ void Rectangle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Rectangle::drawOutline"); | notImplemented("Rectangle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Rectangle<double>; | template class Rectangle<double>; | ||||
| template class Rectangle<float>; | template class Rectangle<float>; | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * 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 | * 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 | * 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. | * 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 "../Vulkan.hpp" | ||||
| #include "../Color.hpp" | #include "../Color.hpp" | ||||
| #include "../ImageBaseWidgets.hpp" | |||||
| #include "SubWidgetPrivateData.hpp" | #include "SubWidgetPrivateData.hpp" | ||||
| #include "TopLevelWidgetPrivateData.hpp" | #include "TopLevelWidgetPrivateData.hpp" | ||||
| @@ -24,14 +30,36 @@ | |||||
| START_NAMESPACE_DGL | 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) | static void notImplemented(const char* const name) | ||||
| { | { | ||||
| d_stderr2("vulkan function not implemented: %s", name); | |||||
| d_stderr2("Vulkan function not implemented: %s", name); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // Color | // Color | ||||
| void Color::setFor(const GraphicsContext&, bool) | void Color::setFor(const GraphicsContext&, bool) | ||||
| @@ -48,11 +76,13 @@ void Line<T>::draw(const GraphicsContext&, T) | |||||
| notImplemented("Line::draw"); | notImplemented("Line::draw"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Line<T>::draw() | void Line<T>::draw() | ||||
| { | { | ||||
| notImplemented("Line::draw"); | notImplemented("Line::draw"); | ||||
| } | } | ||||
| #endif | |||||
| template class Line<double>; | template class Line<double>; | ||||
| template class Line<float>; | template class Line<float>; | ||||
| @@ -76,6 +106,7 @@ void Circle<T>::drawOutline(const GraphicsContext&, T) | |||||
| notImplemented("Circle::drawOutline"); | notImplemented("Circle::drawOutline"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Circle<T>::draw() | void Circle<T>::draw() | ||||
| { | { | ||||
| @@ -87,6 +118,7 @@ void Circle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Circle::drawOutline"); | notImplemented("Circle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Circle<double>; | template class Circle<double>; | ||||
| template class Circle<float>; | template class Circle<float>; | ||||
| @@ -110,6 +142,7 @@ void Triangle<T>::drawOutline(const GraphicsContext&, T) | |||||
| notImplemented("Triangle::drawOutline"); | notImplemented("Triangle::drawOutline"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Triangle<T>::draw() | void Triangle<T>::draw() | ||||
| { | { | ||||
| @@ -121,6 +154,7 @@ void Triangle<T>::drawOutline() | |||||
| { | { | ||||
| notImplemented("Triangle::drawOutline"); | notImplemented("Triangle::drawOutline"); | ||||
| } | } | ||||
| #endif | |||||
| template class Triangle<double>; | template class Triangle<double>; | ||||
| template class Triangle<float>; | template class Triangle<float>; | ||||
| @@ -129,7 +163,6 @@ template class Triangle<uint>; | |||||
| template class Triangle<short>; | template class Triangle<short>; | ||||
| template class Triangle<ushort>; | template class Triangle<ushort>; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Rectangle | // Rectangle | ||||
| @@ -145,11 +178,13 @@ void Rectangle<T>::drawOutline(const GraphicsContext&, T) | |||||
| notImplemented("Rectangle::drawOutline"); | notImplemented("Rectangle::drawOutline"); | ||||
| } | } | ||||
| #ifdef DGL_ALLOW_DEPRECATED_METHODS | |||||
| template<typename T> | template<typename T> | ||||
| void Rectangle<T>::draw() | void Rectangle<T>::draw() | ||||
| { | { | ||||
| notImplemented("Rectangle::draw"); | notImplemented("Rectangle::draw"); | ||||
| } | } | ||||
| #endif | |||||
| template<typename T> | template<typename T> | ||||
| void Rectangle<T>::drawOutline() | void Rectangle<T>::drawOutline() | ||||
| @@ -3,6 +3,7 @@ | |||||
| dpf_add_plugin(d_parameters | dpf_add_plugin(d_parameters | ||||
| TARGETS jack ladspa dssi lv2 vst2 vst3 clap | TARGETS jack ladspa dssi lv2 vst2 vst3 clap | ||||
| UI_TYPE gles2 | |||||
| FILES_DSP | FILES_DSP | ||||
| ExamplePluginParameters.cpp | ExamplePluginParameters.cpp | ||||
| FILES_UI | FILES_UI | ||||
| @@ -21,6 +21,7 @@ FILES_UI = \ | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # Do some magic | # Do some magic | ||||
| UI_TYPE = gles2 | |||||
| include ../../Makefile.plugins.mk | include ../../Makefile.plugins.mk | ||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||