mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-11 06:15:05 +00:00
gs-effect: Refactor onto std::shared_ptr
This commit is contained in:
parent
1f25b56579
commit
11a2329519
2 changed files with 100 additions and 942 deletions
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "gs-effect.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include "obs/gs/gs-helper.hpp"
|
||||
|
@ -29,120 +28,118 @@
|
|||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201)
|
||||
#endif
|
||||
#include <graphics/effect.h>
|
||||
#include <obs.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//#define OBS_LOAD_EFFECT_FILE
|
||||
#define MAX_EFFECT_SIZE 32 * 1024 * 1024;
|
||||
|
||||
gs::effect::effect(std::string file)
|
||||
static std::string load_file_as_code(std::filesystem::path file)
|
||||
{
|
||||
#ifdef OBS_LOAD_EFFECT_FILE
|
||||
char* errorMessage = nullptr;
|
||||
auto gctx = gs::context();
|
||||
m_effect = gs_effect_create_from_file(file.c_str(), &errorMessage);
|
||||
if (!m_effect || errorMessage) {
|
||||
std::string error = "Generic Error";
|
||||
if (errorMessage) {
|
||||
error = std::string(errorMessage);
|
||||
bfree((void*)errorMessage);
|
||||
}
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
#else
|
||||
std::ifstream filestream = std::ifstream(file, std::ios::binary);
|
||||
if (!filestream.is_open()) {
|
||||
throw std::runtime_error("Failed to open file.");
|
||||
uintmax_t size = std::filesystem::file_size(file);
|
||||
if (size > MAX_EFFECT_SIZE) {
|
||||
throw std::runtime_error("File is too large to be loaded.");
|
||||
}
|
||||
|
||||
filestream.ignore(std::numeric_limits<std::streamsize>::max());
|
||||
std::streamsize length = filestream.gcount();
|
||||
filestream.clear(); // Since ignore will have set eof.
|
||||
filestream.seekg(0, std::ios_base::beg);
|
||||
|
||||
if (length > 256 * 1024 * 1024) {
|
||||
throw std::runtime_error("Shader too large (>256mb)");
|
||||
std::ifstream ifs(file, std::ios::binary);
|
||||
if (!ifs.is_open() || ifs.bad()) {
|
||||
throw std::runtime_error("An unknown error occured trying to open the file.");
|
||||
}
|
||||
|
||||
std::vector<char> shader_buf(size_t(length + 1), 0);
|
||||
filestream.read(shader_buf.data(), length);
|
||||
std::vector<char> buf(size_t(size + 1), 0);
|
||||
ifs.read(buf.data(), size);
|
||||
|
||||
char* errorMessage = nullptr;
|
||||
auto gctx = gs::context();
|
||||
_effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage);
|
||||
if (!_effect || errorMessage) {
|
||||
std::string error = "Generic Error";
|
||||
if (errorMessage) {
|
||||
error = std::string(errorMessage);
|
||||
bfree((void*)errorMessage);
|
||||
}
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
#endif
|
||||
return std::string(buf.data(), buf.data() + size);
|
||||
}
|
||||
|
||||
gs::effect::effect(std::string code, std::string name)
|
||||
{
|
||||
char* errorMessage = nullptr;
|
||||
auto gctx = gs::context();
|
||||
_effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage);
|
||||
if (!_effect || errorMessage) {
|
||||
std::string error = "Generic Error";
|
||||
if (errorMessage) {
|
||||
error = std::string(errorMessage);
|
||||
bfree((void*)errorMessage);
|
||||
}
|
||||
throw std::runtime_error(error);
|
||||
auto gctx = gs::context();
|
||||
|
||||
char* error_buffer = nullptr;
|
||||
gs_effect_t* effect = gs_effect_create(code.c_str(), name.c_str(), &error_buffer);
|
||||
|
||||
if (!effect) {
|
||||
throw error_buffer ? std::runtime_error(error_buffer)
|
||||
: std::runtime_error("Unknown error during effect compile.");
|
||||
}
|
||||
|
||||
reset(effect);
|
||||
}
|
||||
|
||||
gs::effect::effect(std::filesystem::path file) : effect(load_file_as_code(file), file.string()) {}
|
||||
|
||||
gs::effect::~effect()
|
||||
{
|
||||
auto gctx = gs::context();
|
||||
gs_effect_destroy(_effect);
|
||||
gs_effect_destroy(get());
|
||||
}
|
||||
|
||||
gs_effect_t* gs::effect::get_object()
|
||||
size_t gs::effect::count_techniques()
|
||||
{
|
||||
return _effect;
|
||||
return static_cast<size_t>(get()->techniques.num);
|
||||
}
|
||||
|
||||
gs::effect_technique gs::effect::get_technique(size_t idx)
|
||||
{
|
||||
if (idx >= count_techniques()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return gs::effect_technique(get()->techniques.array + idx, this);
|
||||
}
|
||||
|
||||
gs::effect_technique gs::effect::get_technique(std::string name)
|
||||
{
|
||||
for (size_t idx = 0; idx < count_techniques(); idx++) {
|
||||
auto ptr = get()->techniques.array + idx;
|
||||
if (strcmp(ptr->name, name.c_str()) == 0) {
|
||||
return gs::effect_technique(ptr, this);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool gs::effect::has_technique(std::string name)
|
||||
{
|
||||
if (get_technique(name))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t gs::effect::count_parameters()
|
||||
{
|
||||
return (size_t)gs_effect_get_num_params(_effect);
|
||||
return get()->params.num;
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<gs::effect_parameter>> gs::effect::get_parameters()
|
||||
gs::effect_parameter gs::effect::get_parameter(size_t idx)
|
||||
{
|
||||
size_t num = gs_effect_get_num_params(_effect);
|
||||
std::list<std::shared_ptr<gs::effect_parameter>> ps;
|
||||
for (size_t idx = 0; idx < num; idx++) {
|
||||
ps.emplace_back(get_parameter(idx));
|
||||
if (idx >= count_parameters()) {
|
||||
throw std::out_of_range("Index is out of range.");
|
||||
}
|
||||
return ps;
|
||||
|
||||
return gs::effect_parameter(get()->params.array + idx, this);
|
||||
}
|
||||
|
||||
std::shared_ptr<gs::effect_parameter> gs::effect::get_parameter(size_t idx)
|
||||
gs::effect_parameter gs::effect::get_parameter(std::string name)
|
||||
{
|
||||
gs_eparam_t* param = gs_effect_get_param_by_idx(_effect, idx);
|
||||
if (!param)
|
||||
return nullptr;
|
||||
return std::make_shared<effect_parameter>(this->shared_from_this(), param);
|
||||
}
|
||||
for (size_t idx = 0; idx < count_techniques(); idx++) {
|
||||
auto ptr = get()->params.array + idx;
|
||||
if (strcmp(ptr->name, name.c_str()) == 0) {
|
||||
return gs::effect_parameter(ptr, this);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<gs::effect_parameter> gs::effect::get_parameter(std::string name)
|
||||
{
|
||||
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str());
|
||||
if (!param)
|
||||
return nullptr;
|
||||
return std::make_shared<effect_parameter>(this->shared_from_this(), param);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool gs::effect::has_parameter(std::string name)
|
||||
{
|
||||
auto eprm = get_parameter(name);
|
||||
if (eprm)
|
||||
if (get_parameter(name))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -151,635 +148,6 @@ bool gs::effect::has_parameter(std::string name, effect_parameter::type type)
|
|||
{
|
||||
auto eprm = get_parameter(name);
|
||||
if (eprm)
|
||||
return eprm->get_type() == type;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<gs::effect> gs::effect::create(std::string file)
|
||||
{
|
||||
return std::shared_ptr<gs::effect>(new gs::effect(file));
|
||||
}
|
||||
|
||||
std::shared_ptr<gs::effect> gs::effect::create(std::string code, std::string name)
|
||||
{
|
||||
return std::shared_ptr<gs::effect>(new gs::effect(code, name));
|
||||
}
|
||||
|
||||
gs::effect_parameter::effect_parameter(std::shared_ptr<gs::effect> effect, gs_eparam_t* param)
|
||||
: _effect(effect), _param(param)
|
||||
{
|
||||
if (!effect)
|
||||
throw std::invalid_argument("effect");
|
||||
if (!param)
|
||||
throw std::invalid_argument("param");
|
||||
|
||||
gs_effect_get_param_info(_param, &_param_info);
|
||||
}
|
||||
|
||||
std::string gs::effect_parameter::get_name()
|
||||
{
|
||||
return _param_info.name;
|
||||
}
|
||||
|
||||
gs::effect_parameter::type gs::effect_parameter::get_type()
|
||||
{
|
||||
switch (_param_info.type) {
|
||||
case GS_SHADER_PARAM_BOOL:
|
||||
return type::Boolean;
|
||||
case GS_SHADER_PARAM_FLOAT:
|
||||
return type::Float;
|
||||
case GS_SHADER_PARAM_VEC2:
|
||||
return type::Float2;
|
||||
case GS_SHADER_PARAM_VEC3:
|
||||
return type::Float3;
|
||||
case GS_SHADER_PARAM_VEC4:
|
||||
return type::Float4;
|
||||
case GS_SHADER_PARAM_INT:
|
||||
return type::Integer;
|
||||
case GS_SHADER_PARAM_INT2:
|
||||
return type::Integer2;
|
||||
case GS_SHADER_PARAM_INT3:
|
||||
return type::Integer3;
|
||||
case GS_SHADER_PARAM_INT4:
|
||||
return type::Integer4;
|
||||
case GS_SHADER_PARAM_MATRIX4X4:
|
||||
return type::Matrix;
|
||||
case GS_SHADER_PARAM_TEXTURE:
|
||||
return type::Texture;
|
||||
case GS_SHADER_PARAM_STRING:
|
||||
return type::String;
|
||||
default:
|
||||
case GS_SHADER_PARAM_UNKNOWN:
|
||||
return type::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_bool(bool v)
|
||||
{
|
||||
if (get_type() != type::Boolean)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_bool(_param, v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_bool(bool& v)
|
||||
{
|
||||
if (get_type() != type::Boolean)
|
||||
throw std::bad_cast();
|
||||
void* ptr = gs_effect_get_val(_param);
|
||||
if (ptr) {
|
||||
v = *reinterpret_cast<bool*>(ptr);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
v = false;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_bool(bool& v)
|
||||
{
|
||||
if (get_type() != type::Boolean)
|
||||
throw std::bad_cast();
|
||||
void* ptr = gs_effect_get_default_val(_param);
|
||||
if (ptr) {
|
||||
v = *reinterpret_cast<bool*>(ptr);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
v = false;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_bool_array(bool v[], size_t sz)
|
||||
{
|
||||
if (get_type() != type::Boolean)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_val(_param, v, sz);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float(float_t x)
|
||||
{
|
||||
if (get_type() != type::Float)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_float(_param, x);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_float(float_t& x)
|
||||
{
|
||||
if (get_type() != type::Float)
|
||||
throw std::bad_cast();
|
||||
void* ptr = gs_effect_get_val(_param);
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_float(float_t& x)
|
||||
{
|
||||
if (get_type() != type::Float)
|
||||
throw std::bad_cast();
|
||||
void* ptr = gs_effect_get_default_val(_param);
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float2(vec2 const& v)
|
||||
{
|
||||
if (get_type() != type::Float2)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_vec2(_param, &v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_float2(vec2& v)
|
||||
{
|
||||
get_float2(v.x, v.y);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_float2(vec2& v)
|
||||
{
|
||||
get_default_float2(v.x, v.y);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float2(float_t x, float_t y)
|
||||
{
|
||||
vec2 data;
|
||||
data.x = x;
|
||||
data.y = y;
|
||||
set_float2(data);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_float2(float_t& x, float_t& y)
|
||||
{
|
||||
if (get_type() != type::Float2)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t));
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_float2(float_t& x, float_t& y)
|
||||
{
|
||||
if (get_type() != type::Float2)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t));
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float3(vec3 const& v)
|
||||
{
|
||||
if (get_type() != type::Float3)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_vec3(_param, &v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_float3(vec3& v)
|
||||
{
|
||||
get_float3(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_float3(vec3& v)
|
||||
{
|
||||
get_default_float3(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float3(float_t x, float_t y, float_t z)
|
||||
{
|
||||
if (get_type() != type::Float3)
|
||||
throw std::bad_cast();
|
||||
vec3 v = {{x, y, z, 0}};
|
||||
gs_effect_set_vec3(_param, &v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_float3(float_t& x, float_t& y, float_t& z)
|
||||
{
|
||||
if (get_type() != type::Float3)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t));
|
||||
z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 2);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_float3(float_t& x, float_t& y, float_t& z)
|
||||
{
|
||||
if (get_type() != type::Float3)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t));
|
||||
z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 2);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float4(vec4 const& v)
|
||||
{
|
||||
if (get_type() != type::Float4)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_vec4(_param, &v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_float4(vec4& v)
|
||||
{
|
||||
get_float4(v.x, v.y, v.z, v.w);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_float4(vec4& v)
|
||||
{
|
||||
get_default_float4(v.x, v.y, v.z, v.w);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float4(float_t x, float_t y, float_t z, float_t w)
|
||||
{
|
||||
if (get_type() != type::Float4)
|
||||
throw std::bad_cast();
|
||||
vec4 v = {{x, y, z, w}};
|
||||
gs_effect_set_vec4(_param, &v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_float4(float_t& x, float_t& y, float_t& z, float_t& w)
|
||||
{
|
||||
if (get_type() != type::Float4)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t));
|
||||
z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 2);
|
||||
w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 3);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = w = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_float4(float_t& x, float_t& y, float_t& z, float_t& w)
|
||||
{
|
||||
if (get_type() != type::Float4)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<float_t*>(ptr);
|
||||
y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t));
|
||||
z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 2);
|
||||
w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 3);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = w = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_float_array(float_t v[], size_t sz)
|
||||
{
|
||||
if ((get_type() != type::Float) && (get_type() != type::Float2) && (get_type() != type::Float3)
|
||||
&& (get_type() != type::Float4))
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_val(_param, v, sizeof(float_t) * sz);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_int(int32_t x)
|
||||
{
|
||||
if ((get_type() != type::Integer) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_int(_param, x);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_int(int32_t& x)
|
||||
{
|
||||
if ((get_type() != type::Integer) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_int(int32_t& x)
|
||||
{
|
||||
if ((get_type() != type::Integer) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_int2(int32_t x, int32_t y)
|
||||
{
|
||||
if ((get_type() != type::Integer2) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
int32_t v[2] = {x, y};
|
||||
gs_effect_set_val(_param, v, sizeof(int) * 2);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_int2(int32_t& x, int32_t& y)
|
||||
{
|
||||
if ((get_type() != type::Integer2) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
y = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t));
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_int2(int32_t& x, int32_t& y)
|
||||
{
|
||||
if ((get_type() != type::Integer2) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
y = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t));
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_int3(int32_t x, int32_t y, int32_t z)
|
||||
{
|
||||
if ((get_type() != type::Integer3) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
int32_t v[3] = {x, y, z};
|
||||
gs_effect_set_val(_param, v, sizeof(int) * 3);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_int3(int32_t& x, int32_t& y, int32_t& z)
|
||||
{
|
||||
if ((get_type() != type::Integer3) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
y = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t));
|
||||
z = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t) * 2);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_int3(int32_t& x, int32_t& y, int32_t& z)
|
||||
{
|
||||
if ((get_type() != type::Integer3) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
y = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t));
|
||||
z = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t) * 2);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_int4(int32_t x, int32_t y, int32_t z, int32_t w)
|
||||
{
|
||||
if ((get_type() != type::Integer4) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
int32_t v[4] = {x, y, z, w};
|
||||
gs_effect_set_val(_param, v, sizeof(int) * 4);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w)
|
||||
{
|
||||
if ((get_type() != type::Integer4) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
y = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t));
|
||||
z = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t) * 2);
|
||||
w = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t) * 3);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = w = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w)
|
||||
{
|
||||
if ((get_type() != type::Integer4) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
x = *reinterpret_cast<int32_t*>(ptr);
|
||||
y = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t));
|
||||
z = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t) * 2);
|
||||
w = *reinterpret_cast<int32_t*>(ptr + sizeof(int32_t) * 3);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
x = y = z = w = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_int_array(int32_t v[], size_t sz)
|
||||
{
|
||||
if ((get_type() != type::Integer) && (get_type() != type::Integer2) && (get_type() != type::Integer3)
|
||||
&& (get_type() != type::Integer4) && (get_type() != type::Unknown))
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_val(_param, v, sizeof(int) * sz);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_matrix(matrix4 const& v)
|
||||
{
|
||||
if (get_type() != type::Matrix)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_matrix4(_param, &v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_matrix(matrix4& v)
|
||||
{
|
||||
if (get_type() != type::Matrix)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
v.x.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 0);
|
||||
v.x.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 1);
|
||||
v.x.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 2);
|
||||
v.x.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 3);
|
||||
v.y.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 4);
|
||||
v.y.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 5);
|
||||
v.y.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 6);
|
||||
v.y.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 7);
|
||||
v.z.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 8);
|
||||
v.z.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 9);
|
||||
v.z.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 10);
|
||||
v.z.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 11);
|
||||
v.t.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 12);
|
||||
v.t.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 13);
|
||||
v.t.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 14);
|
||||
v.t.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 15);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
v.x = vec4{};
|
||||
v.y = vec4{};
|
||||
v.z = vec4{};
|
||||
v.t = vec4{};
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_matrix(matrix4& v)
|
||||
{
|
||||
if (get_type() != type::Matrix)
|
||||
throw std::bad_cast();
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
v.x.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 0);
|
||||
v.x.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 1);
|
||||
v.x.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 2);
|
||||
v.x.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 3);
|
||||
v.y.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 4);
|
||||
v.y.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 5);
|
||||
v.y.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 6);
|
||||
v.y.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 7);
|
||||
v.z.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 8);
|
||||
v.z.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 9);
|
||||
v.z.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 10);
|
||||
v.z.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 11);
|
||||
v.t.x = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 12);
|
||||
v.t.y = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 13);
|
||||
v.t.z = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 14);
|
||||
v.t.w = *reinterpret_cast<float_t*>(ptr + sizeof(float_t) * 15);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
v.x = vec4{};
|
||||
v.y = vec4{};
|
||||
v.z = vec4{};
|
||||
v.t = vec4{};
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_texture(std::shared_ptr<gs::texture> v)
|
||||
{
|
||||
if (get_type() != type::Texture)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_texture(_param, v->get_object());
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_texture(gs_texture_t* v)
|
||||
{
|
||||
if (get_type() != type::Texture)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_texture(_param, v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_sampler(std::shared_ptr<gs::sampler> v)
|
||||
{
|
||||
if (get_type() != type::Texture)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_next_sampler(_param, v->get_object());
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_sampler(gs_sampler_state* v)
|
||||
{
|
||||
if (get_type() != type::Texture)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_next_sampler(_param, v);
|
||||
}
|
||||
|
||||
void gs::effect_parameter::set_string(std::string const& v)
|
||||
{
|
||||
if (get_type() != type::String)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_val(_param, v.c_str(), v.length());
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_string(std::string& v)
|
||||
{
|
||||
if (get_type() != type::String)
|
||||
throw std::bad_cast();
|
||||
size_t ptr_len = gs_effect_get_val_size(_param);
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
|
||||
if (ptr) {
|
||||
v = std::string(ptr, ptr + ptr_len - 1);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
v = "";
|
||||
}
|
||||
}
|
||||
|
||||
void gs::effect_parameter::get_default_string(std::string& v)
|
||||
{
|
||||
if (get_type() != type::String)
|
||||
throw std::bad_cast();
|
||||
size_t ptr_len = gs_effect_get_default_val_size(_param);
|
||||
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_default_val(_param));
|
||||
if (ptr) {
|
||||
v = std::string(ptr, ptr + ptr_len - 1);
|
||||
bfree(ptr);
|
||||
} else {
|
||||
v = "";
|
||||
}
|
||||
}
|
||||
|
||||
size_t gs::effect_parameter::count_annotations()
|
||||
{
|
||||
return gs_param_get_num_annotations(_param);
|
||||
}
|
||||
|
||||
std::shared_ptr<gs::effect_parameter> gs::effect_parameter::get_annotation(size_t idx)
|
||||
{
|
||||
gs_eparam_t* param = gs_param_get_annotation_by_idx(_param, idx);
|
||||
if (!param)
|
||||
return nullptr;
|
||||
return std::make_shared<effect_parameter>(_effect, param);
|
||||
}
|
||||
|
||||
std::shared_ptr<gs::effect_parameter> gs::effect_parameter::get_annotation(std::string name)
|
||||
{
|
||||
gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str());
|
||||
if (!param)
|
||||
return nullptr;
|
||||
return std::make_shared<effect_parameter>(_effect, param);
|
||||
}
|
||||
|
||||
bool gs::effect_parameter::has_annotation(std::string name)
|
||||
{
|
||||
auto eprm = get_annotation(name);
|
||||
if (eprm)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gs::effect_parameter::has_annotation(std::string name, effect_parameter::type type)
|
||||
{
|
||||
auto eprm = get_annotation(name);
|
||||
if (eprm)
|
||||
return eprm->get_type() == type;
|
||||
return eprm.get_type() == type;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -19,254 +19,44 @@
|
|||
|
||||
#pragma once
|
||||
#include <cinttypes>
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "gs-sampler.hpp"
|
||||
#include "gs-texture.hpp"
|
||||
|
||||
// OBS
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201)
|
||||
#endif
|
||||
#include <graphics/graphics.h>
|
||||
#include <graphics/matrix4.h>
|
||||
#include <graphics/vec2.h>
|
||||
#include <graphics/vec3.h>
|
||||
#include <graphics/vec4.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include "gs-effect-parameter.hpp"
|
||||
#include "gs-effect-technique.hpp"
|
||||
|
||||
namespace gs {
|
||||
class effect;
|
||||
|
||||
class effect_parameter {
|
||||
std::shared_ptr<::gs::effect> _effect;
|
||||
gs_eparam_t* _param;
|
||||
gs_effect_param_info _param_info;
|
||||
|
||||
class effect : private std::shared_ptr<gs_effect_t> {
|
||||
public:
|
||||
enum class type : uint8_t {
|
||||
Unknown,
|
||||
Boolean,
|
||||
Float,
|
||||
Float2,
|
||||
Float3,
|
||||
Float4,
|
||||
Integer,
|
||||
Integer2,
|
||||
Integer3,
|
||||
Integer4,
|
||||
Matrix,
|
||||
String,
|
||||
Texture,
|
||||
};
|
||||
|
||||
public:
|
||||
effect_parameter(std::shared_ptr<gs::effect> effect, gs_eparam_t* param);
|
||||
|
||||
std::string get_name();
|
||||
type get_type();
|
||||
|
||||
void set_bool(bool v);
|
||||
void get_bool(bool& v);
|
||||
void get_default_bool(bool& v);
|
||||
|
||||
void set_bool_array(bool v[], size_t sz);
|
||||
|
||||
void set_float(float_t x);
|
||||
void get_float(float_t& x);
|
||||
void get_default_float(float_t& x);
|
||||
|
||||
void set_float2(vec2 const& v);
|
||||
void get_float2(vec2& v);
|
||||
void get_default_float2(vec2& v);
|
||||
void set_float2(float_t x, float_t y);
|
||||
void get_float2(float_t& x, float_t& y);
|
||||
void get_default_float2(float_t& x, float_t& y);
|
||||
|
||||
void set_float3(vec3 const& v);
|
||||
void get_float3(vec3& v);
|
||||
void get_default_float3(vec3& v);
|
||||
void set_float3(float_t x, float_t y, float_t z);
|
||||
void get_float3(float_t& x, float_t& y, float_t& z);
|
||||
void get_default_float3(float_t& x, float_t& y, float_t& z);
|
||||
|
||||
void set_float4(vec4 const& v);
|
||||
void get_float4(vec4& v);
|
||||
void get_default_float4(vec4& v);
|
||||
void set_float4(float_t x, float_t y, float_t z, float_t w);
|
||||
void get_float4(float_t& x, float_t& y, float_t& z, float_t& w);
|
||||
void get_default_float4(float_t& x, float_t& y, float_t& z, float_t& w);
|
||||
|
||||
void set_float_array(float_t v[], size_t sz);
|
||||
|
||||
void set_int(int32_t x);
|
||||
void get_int(int32_t& x);
|
||||
void get_default_int(int32_t& x);
|
||||
|
||||
void set_int2(int32_t x, int32_t y);
|
||||
void get_int2(int32_t& x, int32_t& y);
|
||||
void get_default_int2(int32_t& x, int32_t& y);
|
||||
|
||||
void set_int3(int32_t x, int32_t y, int32_t z);
|
||||
void get_int3(int32_t& x, int32_t& y, int32_t& z);
|
||||
void get_default_int3(int32_t& x, int32_t& y, int32_t& z);
|
||||
|
||||
void set_int4(int32_t x, int32_t y, int32_t z, int32_t w);
|
||||
void get_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w);
|
||||
void get_default_int4(int32_t& x, int32_t& y, int32_t& z, int32_t& w);
|
||||
|
||||
void set_int_array(int32_t v[], size_t sz);
|
||||
|
||||
void set_matrix(matrix4 const& v);
|
||||
void get_matrix(matrix4& v);
|
||||
void get_default_matrix(matrix4& v);
|
||||
|
||||
void set_texture(std::shared_ptr<gs::texture> v);
|
||||
void set_texture(gs_texture_t* v);
|
||||
|
||||
void set_sampler(std::shared_ptr<gs::sampler> v);
|
||||
void set_sampler(gs_sampler_state* v);
|
||||
|
||||
void set_string(std::string const& v);
|
||||
void get_string(std::string& v);
|
||||
void get_default_string(std::string& v);
|
||||
|
||||
size_t count_annotations();
|
||||
std::shared_ptr<effect_parameter> get_annotation(size_t idx);
|
||||
std::shared_ptr<effect_parameter> get_annotation(std::string name);
|
||||
bool has_annotation(std::string name);
|
||||
bool has_annotation(std::string name, effect_parameter::type type);
|
||||
|
||||
public /* Helpers */:
|
||||
inline float_t get_bool()
|
||||
{
|
||||
bool v;
|
||||
get_bool(v);
|
||||
return v;
|
||||
};
|
||||
inline bool get_default_bool()
|
||||
{
|
||||
bool v;
|
||||
get_default_bool(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
inline float_t get_float()
|
||||
{
|
||||
float_t v;
|
||||
get_float(v);
|
||||
return v;
|
||||
};
|
||||
inline float_t get_default_float()
|
||||
{
|
||||
float_t v;
|
||||
get_default_float(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
inline vec2 get_float2()
|
||||
{
|
||||
vec2 v;
|
||||
get_float2(v);
|
||||
return v;
|
||||
};
|
||||
inline vec2 get_default_float2()
|
||||
{
|
||||
vec2 v;
|
||||
get_default_float2(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
inline vec3 get_float3()
|
||||
{
|
||||
vec3 v;
|
||||
get_float3(v);
|
||||
return v;
|
||||
};
|
||||
inline vec3 get_default_float3()
|
||||
{
|
||||
vec3 v;
|
||||
get_default_float3(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
inline vec4 get_float4()
|
||||
{
|
||||
vec4 v;
|
||||
get_float4(v);
|
||||
return v;
|
||||
};
|
||||
inline vec4 get_default_float4()
|
||||
{
|
||||
vec4 v;
|
||||
get_default_float4(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
inline int32_t get_int()
|
||||
{
|
||||
int32_t v;
|
||||
get_int(v);
|
||||
return v;
|
||||
};
|
||||
inline int32_t get_default_int()
|
||||
{
|
||||
int32_t v;
|
||||
get_default_int(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
inline matrix4 get_matrix()
|
||||
{
|
||||
matrix4 v;
|
||||
get_matrix(v);
|
||||
return v;
|
||||
};
|
||||
inline matrix4 get_default_matrix()
|
||||
{
|
||||
matrix4 v;
|
||||
get_default_matrix(v);
|
||||
return v;
|
||||
};
|
||||
|
||||
inline std::string get_string()
|
||||
{
|
||||
std::string v;
|
||||
get_string(v);
|
||||
return v;
|
||||
};
|
||||
inline std::string get_default_string()
|
||||
{
|
||||
std::string v;
|
||||
get_default_string(v);
|
||||
return v;
|
||||
};
|
||||
};
|
||||
|
||||
class effect : public std::enable_shared_from_this<::gs::effect> {
|
||||
protected:
|
||||
gs_effect_t* _effect;
|
||||
|
||||
public:
|
||||
effect(std::string file);
|
||||
effect(std::string code, std::string name);
|
||||
virtual ~effect();
|
||||
effect(std::filesystem::path file);
|
||||
~effect();
|
||||
|
||||
gs_effect_t* get_object();
|
||||
size_t count_techniques();
|
||||
gs::effect_technique get_technique(size_t idx);
|
||||
gs::effect_technique get_technique(std::string name);
|
||||
bool has_technique(std::string name);
|
||||
|
||||
size_t count_parameters();
|
||||
std::list<std::shared_ptr<effect_parameter>> get_parameters();
|
||||
std::shared_ptr<effect_parameter> get_parameter(size_t idx);
|
||||
std::shared_ptr<effect_parameter> get_parameter(std::string name);
|
||||
bool has_parameter(std::string name);
|
||||
bool has_parameter(std::string name, effect_parameter::type type);
|
||||
size_t count_parameters();
|
||||
gs::effect_parameter get_parameter(size_t idx);
|
||||
gs::effect_parameter get_parameter(std::string name);
|
||||
bool has_parameter(std::string name);
|
||||
bool has_parameter(std::string name, effect_parameter::type type);
|
||||
|
||||
public:
|
||||
static std::shared_ptr<gs::effect> create(std::string file);
|
||||
static std::shared_ptr<gs::effect> create(std::string code, std::string name);
|
||||
public /* Legacy Support */:
|
||||
inline gs_effect_t* get_object()
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
static gs::effect create(std::string file)
|
||||
{
|
||||
return gs::effect(file);
|
||||
};
|
||||
static gs::effect create(std::string code, std::string name)
|
||||
{
|
||||
return gs::effect(code, name);
|
||||
};
|
||||
};
|
||||
} // namespace gs
|
||||
|
|
Loading…
Reference in a new issue