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 {
auto buf = reinterpret_cast<uint8_t*>(textureBuffer.data());
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) {
P_LOG_ERROR("<filter-blur> Failed to create gaussian kernel texture.");
}

View file

@ -22,14 +22,18 @@
#include <sys/stat.h>
#include <fstream>
extern "C" {
#pragma warning( push )
#pragma warning( disable: 4201 )
#include <util/platform.h>
#include <obs.h>
#pragma warning( pop )
#pragma warning( push )
#pragma warning( disable: 4201 )
#include <util/platform.h>
#include <obs.h>
#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;
}

View file

@ -20,6 +20,7 @@
#pragma once
#include <inttypes.h>
#include <string>
#include <utility.h>
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)
}