gs-texture: Additional type safety and new methods

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2018-04-29 01:03:03 +02:00
parent d59b54811f
commit c9ed74a3f9
3 changed files with 128 additions and 79 deletions

View File

@ -148,7 +148,9 @@ void Filter::Blur::generate_gaussian_kernels() {
try { try {
auto buf = reinterpret_cast<uint8_t*>(textureBuffer.data()); auto buf = reinterpret_cast<uint8_t*>(textureBuffer.data());
auto rbuf = const_cast<const uint8_t**>(&buf); auto rbuf = const_cast<const uint8_t**>(&buf);
m_gaussianKernelTexture = std::make_shared<gs::texture>(uint32_t(textureSizePOT), uint32_t(textureSizePOT), GS_R32F, 1, rbuf, 0); m_gaussianKernelTexture = std::make_shared<gs::texture>(
uint32_t(textureSizePOT), uint32_t(textureSizePOT), GS_R32F, 1, rbuf,
gs::texture::flags::None);
} catch (std::runtime_error ex) { } catch (std::runtime_error ex) {
P_LOG_ERROR("<filter-blur> Failed to create gaussian kernel texture."); P_LOG_ERROR("<filter-blur> Failed to create gaussian kernel texture.");
} }

View File

@ -22,14 +22,18 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fstream> #include <fstream>
extern "C" { extern "C" {
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable: 4201 ) #pragma warning( disable: 4201 )
#include <util/platform.h> #include <util/platform.h>
#include <obs.h> #include <obs.h>
#pragma warning( pop ) #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) if (width == 0)
throw std::logic_error("width must be at least 1"); throw std::logic_error("width must be at least 1");
if (height == 0) if (height == 0)
@ -39,7 +43,7 @@ gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, ui
if (!mip_data) if (!mip_data)
throw std::logic_error("mip_data is invalid"); 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) 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(height) / log(2))) == height);
if (!isPOT) if (!isPOT)
@ -47,14 +51,22 @@ gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, ui
} }
obs_enter_graphics(); 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(); obs_leave_graphics();
if (!m_texture) if (!m_texture)
throw std::runtime_error("Failed to create 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) if (width == 0)
throw std::logic_error("width must be at least 1"); throw std::logic_error("width must be at least 1");
if (height == 0) 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) if (!mip_data)
throw std::logic_error("mip_data is invalid"); 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) 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(height) / log(2))) == height)
&& (pow(2, (int64_t)floor(log(depth) / log(2))) == depth); && (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(); 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(); obs_leave_graphics();
if (!m_texture) if (!m_texture)
throw std::runtime_error("Failed to create 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) if (size == 0)
throw std::logic_error("size must be at least 1"); throw std::logic_error("size must be at least 1");
if (mip_levels == 0) 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) if (!mip_data)
throw std::logic_error("mip_data is invalid"); 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); bool isPOT = (pow(2, (int64_t)floor(log(size) / log(2))) == size);
if (!isPOT) if (!isPOT)
throw std::logic_error("mip mapping requires power of two dimensions"); throw std::logic_error("mip mapping requires power of two dimensions");
} }
obs_enter_graphics(); 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(); obs_leave_graphics();
if (!m_texture) if (!m_texture)
throw std::runtime_error("Failed to create texture."); throw std::runtime_error("Failed to create texture.");
m_textureType = type::Cube;
} }
gs::texture::texture(std::string file) { gs::texture::texture(std::string file) {
@ -205,3 +230,39 @@ void gs::texture::load(int unit) {
gs_texture_t* gs::texture::get_object() { gs_texture_t* gs::texture::get_object() {
return m_texture; 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;
}

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include <inttypes.h> #include <inttypes.h>
#include <string> #include <string>
#include <utility.h>
extern "C" { extern "C" {
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable: 4201 ) #pragma warning( disable: 4201 )
@ -29,67 +30,69 @@ extern "C" {
namespace gs { namespace gs {
class texture { class texture {
protected:
gs_texture_t * m_texture;
bool m_isOwner = true;
public: public:
enum type : uint8_t { enum class type {
Normal, Normal,
Volume, Volume,
Cube Cube
}; };
enum flags : uint32_t { enum class flags : size_t {
None,
Dynamic, Dynamic,
BuildMipMaps, BuildMipMaps,
}; };
protected:
gs_texture_t * m_texture;
bool m_isOwner = true;
type m_textureType = type::Normal;
public: public:
/*! /*!
* \brief Create a new texture from data * \brief Create a 2D Texture
* *
* * \param width Width of the 2D Texture
* * \param height Height of the 2D Texture
* \param width * \param format Color Format to use
* \param height * \param mip_levels Number of Mip Levels available
* \param format * \param mip_data Texture data including mipmaps
* \param mip_levels * \param flags Texture Flags
* \param mip_data
* \param flags
*/ */
texture(uint32_t width, uint32_t height, gs_color_format format, uint32_t mip_levels, texture(uint32_t width, uint32_t height,
const uint8_t **mip_data, uint32_t flags); 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 Width of the 3D Texture
* * \param height Height of the 3D Texture
* \param width * \param depth Depth of the 3D Texture
* \param height * \param format Color Format to use
* \param depth * \param mip_levels Number of Mip Levels available
* \param format * \param mip_data Texture data including mipmaps
* \param mip_levels * \param flags Texture Flags
* \param mip_data
* \param flags
*/ */
texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_format format, uint32_t mip_levels, texture(uint32_t width, uint32_t height, uint32_t depth,
const uint8_t **mip_data, uint32_t flags); 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 Size of each Cube Maps face
* * \param format Color Format to use
* \param size * \param mip_levels Number of Mip Levels available
* \param format * \param mip_data Texture data including mipmaps
* \param mip_levels * \param flags Texture Flags
* \param mip_data
* \param flags
*/ */
texture(uint32_t size, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, texture(uint32_t size,
uint32_t flags); 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 * \brief Load a texture from a file
@ -119,37 +122,20 @@ namespace gs {
*/ */
texture(texture& other); texture(texture& other);
/*!
* \brief Default constructor
*/
texture() : m_texture(nullptr) {} texture() : m_texture(nullptr) {}
/*!
* \brief Destructor
*
*
*
* \return
*/
virtual ~texture(); virtual ~texture();
/*!
* \brief
*
*
*
* \param unit
* \return void
*/
void load(int unit); void load(int unit);
/*!
* \brief
*
*
*
* \return gs_texture_t*
*/
gs_texture_t* get_object(); gs_texture_t* get_object();
uint32_t get_width();
uint32_t get_height();
uint32_t get_depth();
}; };
ENABLE_BITMASK_OPERATORS(gs::texture::flags)
} }