From c9ed74a3f90e8df6a95ecff9e802cbe401e5dd2c Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sun, 29 Apr 2018 01:03:03 +0200 Subject: [PATCH] gs-texture: Additional type safety and new methods --- source/filter-blur.cpp | 4 +- source/gs-texture.cpp | 89 +++++++++++++++++++++++++++----- source/gs-texture.h | 114 ++++++++++++++++++----------------------- 3 files changed, 128 insertions(+), 79 deletions(-) diff --git a/source/filter-blur.cpp b/source/filter-blur.cpp index 38ff706..c6473f9 100644 --- a/source/filter-blur.cpp +++ b/source/filter-blur.cpp @@ -148,7 +148,9 @@ void Filter::Blur::generate_gaussian_kernels() { try { auto buf = reinterpret_cast(textureBuffer.data()); auto rbuf = const_cast(&buf); - m_gaussianKernelTexture = std::make_shared(uint32_t(textureSizePOT), uint32_t(textureSizePOT), GS_R32F, 1, rbuf, 0); + m_gaussianKernelTexture = std::make_shared( + uint32_t(textureSizePOT), uint32_t(textureSizePOT), GS_R32F, 1, rbuf, + gs::texture::flags::None); } catch (std::runtime_error ex) { P_LOG_ERROR(" Failed to create gaussian kernel texture."); } diff --git a/source/gs-texture.cpp b/source/gs-texture.cpp index a757991..ea63a8c 100644 --- a/source/gs-texture.cpp +++ b/source/gs-texture.cpp @@ -22,14 +22,18 @@ #include #include extern "C" { - #pragma warning( push ) - #pragma warning( disable: 4201 ) - #include - #include - #pragma warning( pop ) +#pragma warning( push ) +#pragma warning( disable: 4201 ) +#include +#include +#pragma warning( pop ) } -gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, uint32_t flags) { +gs::texture::texture(uint32_t width, uint32_t height, + gs_color_format format, uint32_t mip_levels, + const uint8_t **mip_data, + gs::texture::flags texture_flags) { + if (width == 0) throw std::logic_error("width must be at least 1"); if (height == 0) @@ -39,7 +43,7 @@ gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, ui if (!mip_data) throw std::logic_error("mip_data is invalid"); - if (mip_levels > 1 || flags & flags::BuildMipMaps) { + if (mip_levels > 1 || ((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps)) { bool isPOT = (pow(2, (int64_t)floor(log(width) / log(2))) == width) && (pow(2, (int64_t)floor(log(height) / log(2))) == height); if (!isPOT) @@ -47,14 +51,22 @@ gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, ui } obs_enter_graphics(); - m_texture = gs_texture_create(width, height, format, mip_levels, mip_data, (flags & flags::Dynamic) ? GS_DYNAMIC : 0 | (flags & flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0); + m_texture = gs_texture_create(width, height, format, mip_levels, mip_data, + (((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0) + | (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0) + ); obs_leave_graphics(); if (!m_texture) throw std::runtime_error("Failed to create texture."); + + m_textureType = type::Normal; } -gs::texture::texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, uint32_t flags) { +gs::texture::texture(uint32_t width, uint32_t height, uint32_t depth, + gs_color_format format, uint32_t mip_levels, + const uint8_t **mip_data, + gs::texture::flags texture_flags) { if (width == 0) throw std::logic_error("width must be at least 1"); if (height == 0) @@ -66,7 +78,7 @@ gs::texture::texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_f if (!mip_data) throw std::logic_error("mip_data is invalid"); - if (mip_levels > 1 || flags & flags::BuildMipMaps) { + if (mip_levels > 1 || ((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps)) { bool isPOT = (pow(2, (int64_t)floor(log(width) / log(2))) == width) && (pow(2, (int64_t)floor(log(height) / log(2))) == height) && (pow(2, (int64_t)floor(log(depth) / log(2))) == depth); @@ -75,14 +87,22 @@ gs::texture::texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_f } obs_enter_graphics(); - m_texture = gs_voltexture_create(width, height, depth, format, mip_levels, mip_data, (flags & flags::Dynamic) ? GS_DYNAMIC : 0 | (flags & flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0); + m_texture = gs_voltexture_create(width, height, depth, format, mip_levels, mip_data, + (((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0) + | (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0) + ); obs_leave_graphics(); if (!m_texture) throw std::runtime_error("Failed to create texture."); + + m_textureType = type::Volume; } -gs::texture::texture(uint32_t size, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, uint32_t flags) { +gs::texture::texture(uint32_t size, gs_color_format format, uint32_t mip_levels, const + uint8_t **mip_data, + gs::texture::flags texture_flags) { + if (size == 0) throw std::logic_error("size must be at least 1"); if (mip_levels == 0) @@ -90,18 +110,23 @@ gs::texture::texture(uint32_t size, gs_color_format format, uint32_t mip_levels, if (!mip_data) throw std::logic_error("mip_data is invalid"); - if (mip_levels > 1 || flags & flags::BuildMipMaps) { + if (mip_levels > 1 || ((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps)) { bool isPOT = (pow(2, (int64_t)floor(log(size) / log(2))) == size); if (!isPOT) throw std::logic_error("mip mapping requires power of two dimensions"); } obs_enter_graphics(); - m_texture = gs_cubetexture_create(size, format, mip_levels, mip_data, (flags & flags::Dynamic) ? GS_DYNAMIC : 0 | (flags & flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0); + m_texture = gs_cubetexture_create(size, format, mip_levels, mip_data, + (((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0) + | (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0) + ); obs_leave_graphics(); if (!m_texture) throw std::runtime_error("Failed to create texture."); + + m_textureType = type::Cube; } gs::texture::texture(std::string file) { @@ -205,3 +230,39 @@ void gs::texture::load(int unit) { gs_texture_t* gs::texture::get_object() { return m_texture; } + +uint32_t gs::texture::get_width() { + switch (m_textureType) { + case type::Normal: + return gs_texture_get_width(m_texture); + case type::Volume: + return gs_voltexture_get_width(m_texture); + case type::Cube: + return gs_cubetexture_get_size(m_texture); + } + return 0; +} + +uint32_t gs::texture::get_height() { + switch (m_textureType) { + case type::Normal: + return gs_texture_get_height(m_texture); + case type::Volume: + return gs_voltexture_get_height(m_texture); + case type::Cube: + return gs_cubetexture_get_size(m_texture); + } + return 0; +} + +uint32_t gs::texture::get_depth() { + switch (m_textureType) { + case type::Normal: + return 1; + case type::Volume: + return gs_voltexture_get_depth(m_texture); + case type::Cube: + return 6; + } + return 0; +} diff --git a/source/gs-texture.h b/source/gs-texture.h index d73853a..cf492dc 100644 --- a/source/gs-texture.h +++ b/source/gs-texture.h @@ -20,6 +20,7 @@ #pragma once #include #include +#include extern "C" { #pragma warning( push ) #pragma warning( disable: 4201 ) @@ -29,67 +30,69 @@ extern "C" { namespace gs { class texture { - protected: - gs_texture_t * m_texture; - bool m_isOwner = true; - public: - enum type : uint8_t { + enum class type { Normal, Volume, Cube }; - enum flags : uint32_t { + enum class flags : size_t { + None, Dynamic, BuildMipMaps, }; + protected: + gs_texture_t * m_texture; + bool m_isOwner = true; + type m_textureType = type::Normal; + public: /*! - * \brief Create a new texture from data + * \brief Create a 2D Texture * - * - * - * \param width - * \param height - * \param format - * \param mip_levels - * \param mip_data - * \param flags + * \param width Width of the 2D Texture + * \param height Height of the 2D Texture + * \param format Color Format to use + * \param mip_levels Number of Mip Levels available + * \param mip_data Texture data including mipmaps + * \param flags Texture Flags */ - texture(uint32_t width, uint32_t height, gs_color_format format, uint32_t mip_levels, - const uint8_t **mip_data, uint32_t flags); + texture(uint32_t width, uint32_t height, + gs_color_format format, uint32_t mip_levels, + const uint8_t **mip_data, + gs::texture::flags texture_flags); /*! - * \brief Create a new volume texture from data + * \brief Create a 3D Texture * - * - * - * \param width - * \param height - * \param depth - * \param format - * \param mip_levels - * \param mip_data - * \param flags + * \param width Width of the 3D Texture + * \param height Height of the 3D Texture + * \param depth Depth of the 3D Texture + * \param format Color Format to use + * \param mip_levels Number of Mip Levels available + * \param mip_data Texture data including mipmaps + * \param flags Texture Flags */ - texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_format format, uint32_t mip_levels, - const uint8_t **mip_data, uint32_t flags); + texture(uint32_t width, uint32_t height, uint32_t depth, + gs_color_format format, uint32_t mip_levels, + const uint8_t **mip_data, + gs::texture::flags texture_flags); /*! - * \brief Create a new cube texture from data + * \brief Create a Cube Texture * - * - * - * \param size - * \param format - * \param mip_levels - * \param mip_data - * \param flags + * \param size Size of each Cube Maps face + * \param format Color Format to use + * \param mip_levels Number of Mip Levels available + * \param mip_data Texture data including mipmaps + * \param flags Texture Flags */ - texture(uint32_t size, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, - uint32_t flags); + texture(uint32_t size, + gs_color_format format, uint32_t mip_levels, + const uint8_t **mip_data, + gs::texture::flags texture_flags); /*! * \brief Load a texture from a file @@ -119,37 +122,20 @@ namespace gs { */ texture(texture& other); - /*! - * \brief Default constructor - */ texture() : m_texture(nullptr) {} - /*! - * \brief Destructor - * - * - * - * \return - */ virtual ~texture(); - /*! - * \brief - * - * - * - * \param unit - * \return void - */ void load(int unit); - /*! - * \brief - * - * - * - * \return gs_texture_t* - */ gs_texture_t* get_object(); + + uint32_t get_width(); + + uint32_t get_height(); + + uint32_t get_depth(); }; + + ENABLE_BITMASK_OPERATORS(gs::texture::flags) }