mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-10 22:05:06 +00:00
gs: Wrap OBS Graphics Subsystem in proper C++ classes
This commit is contained in:
parent
52b70ff6de
commit
eb1612c6ee
15 changed files with 1313 additions and 133 deletions
|
@ -30,6 +30,14 @@ SET(obs-stream-effects_HEADERS
|
|||
"${PROJECT_SOURCE_DIR}/source/filter-shape.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/filter-transform.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-helper.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-effect.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-indexbuffer.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-mipmapper.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-rendertarget.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-texture.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-vertex.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-vertexbuffer.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-mipmapper.h"
|
||||
"${PROJECT_BINARY_DIR}/source/version.h"
|
||||
"${PROJECT_SOURCE_DIR}/source/strings.h"
|
||||
)
|
||||
|
@ -40,6 +48,25 @@ SET(obs-stream-effects_SOURCES
|
|||
"${PROJECT_SOURCE_DIR}/source/filter-shape.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filter-transform.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-helper.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-effect.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-indexbuffer.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-mipmapper.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-rendertarget.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-texture.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-vertex.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-vertexbuffer.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gs-mipmapper.cpp"
|
||||
)
|
||||
SET(obs-stream-effects_LOCALE
|
||||
"${PROJECT_SOURCE_DIR}/data/locale/en-US.ini"
|
||||
)
|
||||
SET(obs-stream-effects_EFFECTS
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/bilateral-blur.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/box-blur.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/gaussian-blur.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/displace.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/color-conversion.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/mip-mapper.effect"
|
||||
)
|
||||
SET(obs-stream-effects_LOCALE
|
||||
"${PROJECT_SOURCE_DIR}/data/locale/en-US.ini"
|
||||
|
|
228
source/gs-effect.cpp
Normal file
228
source/gs-effect.cpp
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "gs-effect.h"
|
||||
#include <stdexcept>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/obs.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
GS::Effect::Effect(std::string file) {
|
||||
obs_enter_graphics();
|
||||
char* errorMessage = nullptr;
|
||||
m_effect = gs_effect_create_from_file(file.c_str(), &errorMessage);
|
||||
if (!m_effect || errorMessage) {
|
||||
std::string error(errorMessage);
|
||||
bfree((void*)errorMessage);
|
||||
obs_leave_graphics();
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
GS::Effect::Effect(std::string code, std::string name) {
|
||||
obs_enter_graphics();
|
||||
char* errorMessage = nullptr;
|
||||
m_effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage);
|
||||
if (!m_effect || errorMessage) {
|
||||
std::string error(errorMessage);
|
||||
bfree((void*)errorMessage);
|
||||
obs_leave_graphics();
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
GS::Effect::~Effect() {
|
||||
obs_enter_graphics();
|
||||
gs_effect_destroy(m_effect);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
gs_effect_t* GS::Effect::GetObject() {
|
||||
return m_effect;
|
||||
}
|
||||
|
||||
std::vector<GS::EffectParameter> GS::Effect::GetParameters() {
|
||||
size_t num = gs_effect_get_num_params(m_effect);
|
||||
std::vector<GS::EffectParameter> ps;
|
||||
ps.reserve(num);
|
||||
for (size_t idx = 0; idx < num; idx++) {
|
||||
ps.emplace_back(EffectParameter(gs_effect_get_param_by_idx(m_effect, idx)));
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
||||
GS::EffectParameter GS::Effect::GetParameterByName(std::string name) {
|
||||
gs_eparam_t* param = gs_effect_get_param_by_name(m_effect, name.c_str());
|
||||
if (!param)
|
||||
throw std::invalid_argument("parameter with name not found");
|
||||
return EffectParameter(param);
|
||||
}
|
||||
|
||||
GS::EffectParameter::EffectParameter(gs_eparam_t* param) {
|
||||
if (!param)
|
||||
throw std::invalid_argument("param is null");
|
||||
|
||||
m_param = param;
|
||||
gs_effect_get_param_info(m_param, &m_paramInfo);
|
||||
}
|
||||
|
||||
GS::EffectParameter::Type GS::EffectParameter::GetType() {
|
||||
switch (m_paramInfo.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::EffectParameter::SetBoolean(bool v) {
|
||||
if (GetType() != Type::Boolean)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_bool(m_param, v);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetBooleanArray(bool v[], size_t sz) {
|
||||
if (GetType() != Type::Boolean)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_val(m_param, v, sz);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloat(float_t x) {
|
||||
if (GetType() != Type::Float)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_float(m_param, x);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloat2(vec2& v) {
|
||||
if (GetType() != Type::Float2)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_vec2(m_param, &v);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloat2(float_t x, float_t y) {
|
||||
if (GetType() != Type::Float2)
|
||||
throw std::bad_cast();
|
||||
float_t v[] = { x, y };
|
||||
SetFloatArray(v, 2);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloat3(vec3& v) {
|
||||
if (GetType() != Type::Float3)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_vec3(m_param, &v);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloat3(float_t x, float_t y, float_t z) {
|
||||
if (GetType() != Type::Float3)
|
||||
throw std::bad_cast();
|
||||
float_t v[] = { x, y, z };
|
||||
SetFloatArray(v, 3);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloat4(vec4& v) {
|
||||
if (GetType() != Type::Float4)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_vec4(m_param, &v);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloat4(float_t x, float_t y, float_t z, float_t w) {
|
||||
if (GetType() != Type::Float4)
|
||||
throw std::bad_cast();
|
||||
float_t v[] = { x, y, z, w };
|
||||
SetFloatArray(v, 4);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetFloatArray(float_t v[], size_t sz) {
|
||||
if (GetType() != Type::Float)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_val(m_param, v, sz);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetInteger(int32_t x) {
|
||||
if (GetType() != Type::Integer)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_int(m_param, x);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetInteger2(int32_t x, int32_t y) {
|
||||
if (GetType() != Type::Integer2)
|
||||
throw std::bad_cast();
|
||||
int32_t v[] = { x, y };
|
||||
gs_effect_set_val(m_param, v, 2);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetInteger3(int32_t x, int32_t y, int32_t z) {
|
||||
if (GetType() != Type::Integer3)
|
||||
throw std::bad_cast();
|
||||
int32_t v[] = { x, y, z };
|
||||
gs_effect_set_val(m_param, v, 3);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetInteger4(int32_t x, int32_t y, int32_t z, int32_t w) {
|
||||
if (GetType() != Type::Integer4)
|
||||
throw std::bad_cast();
|
||||
int32_t v[] = { x, y, z, w };
|
||||
gs_effect_set_val(m_param, v, 4);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetIntegerArray(int32_t v[], size_t sz) {
|
||||
if (GetType() != Type::Integer)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_val(m_param, v, sz);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetMatrix(matrix4& v) {
|
||||
if (GetType() != Type::Matrix)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_matrix4(m_param, &v);
|
||||
}
|
||||
|
||||
void GS::EffectParameter::SetTexture(std::shared_ptr<GS::Texture> v) {
|
||||
if (GetType() != Type::Texture)
|
||||
throw std::bad_cast();
|
||||
gs_effect_set_texture(m_param, v->GetObject());
|
||||
}
|
100
source/gs-effect.h
Normal file
100
source/gs-effect.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "gs-texture.h"
|
||||
#include <inttypes.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/graphics/graphics.h>
|
||||
#include <libobs/graphics/matrix4.h>
|
||||
#include <libobs/graphics/vec4.h>
|
||||
#include <libobs/graphics/vec3.h>
|
||||
#include <libobs/graphics/vec2.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
namespace GS {
|
||||
class EffectParameter {
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
Unknown,
|
||||
Boolean,
|
||||
Float,
|
||||
Float2,
|
||||
Float3,
|
||||
Float4,
|
||||
Integer,
|
||||
Integer2,
|
||||
Integer3,
|
||||
Integer4,
|
||||
Matrix,
|
||||
String,
|
||||
Texture,
|
||||
};
|
||||
|
||||
public:
|
||||
EffectParameter(gs_eparam_t* param);
|
||||
|
||||
Type GetType();
|
||||
|
||||
void SetBoolean(bool v);
|
||||
void SetBooleanArray(bool v[], size_t sz);
|
||||
void SetFloat(float_t x);
|
||||
void SetFloat2(vec2& v);
|
||||
void SetFloat2(float_t x, float_t y);
|
||||
void SetFloat3(vec3& v);
|
||||
void SetFloat3(float_t x, float_t y, float_t z);
|
||||
void SetFloat4(vec4& v);
|
||||
void SetFloat4(float_t x, float_t y, float_t z, float_t w);
|
||||
void SetFloatArray(float_t v[], size_t sz);
|
||||
void SetInteger(int32_t x);
|
||||
void SetInteger2(int32_t x, int32_t y);
|
||||
void SetInteger3(int32_t x, int32_t y, int32_t z);
|
||||
void SetInteger4(int32_t x, int32_t y, int32_t z, int32_t w);
|
||||
void SetIntegerArray(int32_t v[], size_t sz);
|
||||
void SetMatrix(matrix4& v);
|
||||
void SetTexture(std::shared_ptr<GS::Texture> v);
|
||||
void SetTextureSampler();
|
||||
|
||||
private:
|
||||
gs_eparam_t* m_param;
|
||||
gs_effect_param_info m_paramInfo;
|
||||
};
|
||||
|
||||
class Effect {
|
||||
public:
|
||||
Effect(std::string file);
|
||||
Effect(std::string code, std::string name);
|
||||
virtual ~Effect();
|
||||
|
||||
gs_effect_t* GetObject();
|
||||
|
||||
std::vector<EffectParameter> GetParameters();
|
||||
EffectParameter GetParameterByName(std::string name);
|
||||
|
||||
|
||||
protected:
|
||||
gs_effect_t* m_effect;
|
||||
};
|
||||
}
|
|
@ -18,96 +18,3 @@
|
|||
*/
|
||||
|
||||
#include "gs-helper.h"
|
||||
|
||||
Helper::VertexBuffer::VertexBuffer(size_t maxVertices) {
|
||||
m_positions.resize(maxVertices);
|
||||
m_normals.resize(maxVertices);
|
||||
m_tangents.resize(maxVertices);
|
||||
m_colors.resize(maxVertices);
|
||||
m_uvs.resize(8);
|
||||
m_uvArrays.resize(8);
|
||||
for (size_t idx = 0; idx < 8; idx++) {
|
||||
m_uvs[idx].resize(maxVertices);
|
||||
m_uvArrays[idx].width = 2;
|
||||
m_uvArrays[idx].array = m_uvs[idx].data();
|
||||
}
|
||||
|
||||
m_vertexData = gs_vbdata_create();
|
||||
m_vertexData->num = maxVertices;
|
||||
m_vertexData->points = m_positions.data();
|
||||
m_vertexData->normals = m_normals.data();
|
||||
m_vertexData->tangents = m_normals.data();
|
||||
m_vertexData->colors = m_colors.data();
|
||||
m_vertexData->num_tex = m_uvs.size();
|
||||
m_vertexData->tvarray = m_uvArrays.data();
|
||||
|
||||
m_vertexBuffer = gs_vertexbuffer_create(m_vertexData, GS_DYNAMIC);
|
||||
}
|
||||
|
||||
Helper::VertexBuffer::~VertexBuffer() {
|
||||
std::memset(m_vertexData, 0, sizeof(gs_vb_data));
|
||||
gs_vertexbuffer_destroy(m_vertexBuffer);
|
||||
}
|
||||
|
||||
void Helper::VertexBuffer::set_uv_layers(size_t count) {
|
||||
size_t realcount = count > 8 ? 8 : count;
|
||||
m_uvs.resize(realcount);
|
||||
}
|
||||
|
||||
size_t Helper::VertexBuffer::get_uv_layers() {
|
||||
return m_uvs.size();
|
||||
}
|
||||
|
||||
gs_vertbuffer_t* Helper::VertexBuffer::update() {
|
||||
// Update Buffers
|
||||
size_t verts = this->size();
|
||||
m_positions.resize(verts);
|
||||
m_normals.resize(verts);
|
||||
m_tangents.resize(verts);
|
||||
m_colors.resize(verts);
|
||||
for (size_t layer = 0; layer < m_uvs.size(); layer++) {
|
||||
m_uvs[layer].resize(verts);
|
||||
m_uvArrays[layer].width = 2;
|
||||
m_uvArrays[layer].array = m_uvs[layer].data();
|
||||
}
|
||||
|
||||
// Prepare Vertex Data
|
||||
for (size_t vert = 0; vert < verts; vert++) {
|
||||
Vertex& v = this->at(vert);
|
||||
|
||||
vec3_copy(&(m_positions.at(vert)), &v.position);
|
||||
vec3_copy(&(m_normals.at(vert)), &v.normal);
|
||||
vec3_copy(&(m_tangents.at(vert)), &v.tangent);
|
||||
m_colors[vert] = v.color;
|
||||
for (size_t layer = 0; layer < m_uvs.size(); layer++) {
|
||||
vec2_copy(&m_uvs[layer][vert], &v.uv[layer]);
|
||||
}
|
||||
}
|
||||
|
||||
// Upload to GPU
|
||||
m_vertexData->num = verts;
|
||||
m_vertexData->points = m_positions.data();
|
||||
m_vertexData->normals = m_normals.data();
|
||||
m_vertexData->tangents = m_normals.data();
|
||||
m_vertexData->colors = m_colors.data();
|
||||
m_vertexData->num_tex = m_uvArrays.size();
|
||||
m_vertexData->tvarray = m_uvArrays.data();
|
||||
gs_vertexbuffer_flush(m_vertexBuffer);
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
Helper::Vertex::Vertex() {
|
||||
position.x =
|
||||
position.y =
|
||||
position.z =
|
||||
normal.x =
|
||||
normal.y =
|
||||
normal.z =
|
||||
tangent.x =
|
||||
tangent.y =
|
||||
tangent.z = 0;
|
||||
color = 0;
|
||||
for (size_t idx = 0; idx < 8; idx++) {
|
||||
uv[idx].x = uv[idx].y = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,45 +19,85 @@
|
|||
|
||||
#pragma once
|
||||
#include "plugin.h"
|
||||
|
||||
extern "C" {
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4201)
|
||||
#include "libobs/graphics/graphics.h"
|
||||
#pragma warning (pop)
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Helper {
|
||||
struct Vertex {
|
||||
Vertex();
|
||||
|
||||
vec3
|
||||
position,
|
||||
normal,
|
||||
tangent;
|
||||
vec2 uv[8];
|
||||
uint32_t
|
||||
color;
|
||||
};
|
||||
|
||||
class VertexBuffer : public std::vector<Vertex> {
|
||||
public:
|
||||
VertexBuffer(size_t maxVertices);
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
void set_uv_layers(size_t count);
|
||||
size_t get_uv_layers();
|
||||
|
||||
gs_vertbuffer_t* update();
|
||||
|
||||
private:
|
||||
gs_vb_data *m_vertexData;
|
||||
gs_vertbuffer_t *m_vertexBuffer;
|
||||
std::vector<gs_tvertarray> m_uvArrays;
|
||||
std::vector<vec3> m_positions, m_normals, m_tangents;
|
||||
std::vector<uint32_t> m_colors;
|
||||
std::vector<std::vector<vec2>> m_uvs;
|
||||
};
|
||||
extern "C" {
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4201)
|
||||
#include "libobs/graphics/graphics.h"
|
||||
#pragma warning (pop)
|
||||
}
|
||||
|
||||
|
||||
gs_effect_param* gs_effect_get_param(gs_effect_t* effect, const char* name) {
|
||||
gs_effect_param* p = gs_effect_get_param_by_name(effect, name);
|
||||
if (!p)
|
||||
P_LOG_ERROR("Failed to find parameter %s in effect.", name);
|
||||
return p;
|
||||
}
|
||||
|
||||
bool gs_set_param_int(gs_effect_t* effect, const char* name, int value) {
|
||||
gs_effect_param* p = nullptr;
|
||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
||||
gs_effect_set_int(p, value);
|
||||
return true;
|
||||
}
|
||||
P_LOG_ERROR("Failed to set value %d for parameter %s in"
|
||||
" effect.", value, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gs_set_param_float(gs_effect_t* effect, const char* name, float value) {
|
||||
gs_effect_param* p = nullptr;
|
||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
||||
gs_effect_set_float(p, value);
|
||||
return true;
|
||||
}
|
||||
P_LOG_ERROR("Failed to set value %f for parameter %s in"
|
||||
" effect.", value, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gs_set_param_float2(gs_effect_t* effect, const char* name, vec2* value) {
|
||||
gs_effect_param* p = nullptr;
|
||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
||||
gs_effect_set_vec2(p, value);
|
||||
return true;
|
||||
}
|
||||
P_LOG_ERROR("Failed to set value {%f,%f} for parameter %s"
|
||||
" in effect.", value->x, value->y, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gs_set_param_float3(gs_effect_t* effect, const char* name, vec3* value) {
|
||||
gs_effect_param* p = nullptr;
|
||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
||||
gs_effect_set_vec3(p, value);
|
||||
return true;
|
||||
}
|
||||
P_LOG_ERROR("Failed to set value {%f,%f,%f} for parameter"
|
||||
"%s in effect.", value->x, value->y, value->z, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gs_set_param_float4(gs_effect_t* effect, const char* name, vec4* value) {
|
||||
gs_effect_param* p = nullptr;
|
||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
||||
gs_effect_set_vec4(p, value);
|
||||
return true;
|
||||
}
|
||||
P_LOG_ERROR("Failed to set value {%f,%f,%f,%f} for"
|
||||
" parameter %s in effect.", value->x, value->y, value->z,
|
||||
value->w, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gs_set_param_texture(gs_effect_t* effect, const char* name, gs_texture_t* value) {
|
||||
gs_effect_param* p = nullptr;
|
||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
||||
gs_effect_set_texture(p, value);
|
||||
return true;
|
||||
}
|
||||
P_LOG_ERROR("Failed to set texture for"
|
||||
" parameter %s in effect.", name);
|
||||
return false;
|
||||
}
|
||||
|
|
65
source/gs-indexbuffer.cpp
Normal file
65
source/gs-indexbuffer.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "gs-indexbuffer.h"
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/obs.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
const uint32_t defaultMaximumVertices = 65535u;
|
||||
|
||||
GS::IndexBuffer::IndexBuffer(uint32_t maximumVertices) {
|
||||
this->reserve(maximumVertices);
|
||||
|
||||
obs_enter_graphics();
|
||||
m_indexBuffer = gs_indexbuffer_create(gs_index_type::GS_UNSIGNED_LONG, this->data(), maximumVertices, GS_DYNAMIC);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
GS::IndexBuffer::IndexBuffer() : IndexBuffer(defaultMaximumVertices) {}
|
||||
|
||||
GS::IndexBuffer::IndexBuffer(IndexBuffer& other) : IndexBuffer(other.size()) {
|
||||
std::copy(other.begin(), other.end(), this->end());
|
||||
}
|
||||
|
||||
GS::IndexBuffer::IndexBuffer(std::vector<uint32_t>& other) : IndexBuffer(other.size()) {
|
||||
std::copy(other.begin(), other.end(), this->end());
|
||||
}
|
||||
|
||||
GS::IndexBuffer::~IndexBuffer() {
|
||||
obs_enter_graphics();
|
||||
gs_indexbuffer_destroy(m_indexBuffer);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
gs_indexbuffer_t* GS::IndexBuffer::get() {
|
||||
return get(true);
|
||||
}
|
||||
|
||||
gs_indexbuffer_t* GS::IndexBuffer::get(bool refreshGPU) {
|
||||
if (refreshGPU) {
|
||||
obs_enter_graphics();
|
||||
gs_indexbuffer_flush(m_indexBuffer);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
return m_indexBuffer;
|
||||
}
|
46
source/gs-indexbuffer.h
Normal file
46
source/gs-indexbuffer.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <inttypes.h>
|
||||
#include <vector>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/graphics/graphics.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
namespace GS {
|
||||
class IndexBuffer : public std::vector<uint32_t> {
|
||||
public:
|
||||
IndexBuffer(uint32_t maximumVertices);
|
||||
IndexBuffer();
|
||||
IndexBuffer(IndexBuffer& other);
|
||||
IndexBuffer(std::vector<uint32_t>& other);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
gs_indexbuffer_t* get();
|
||||
|
||||
gs_indexbuffer_t* get(bool refreshGPU);
|
||||
|
||||
protected:
|
||||
gs_indexbuffer_t* m_indexBuffer;
|
||||
};
|
||||
}
|
77
source/gs-rendertarget.cpp
Normal file
77
source/gs-rendertarget.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "gs-rendertarget.h"
|
||||
#include <stdexcept>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/obs.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
GS::RenderTarget::RenderTarget(gs_color_format colorFormat, gs_zstencil_format zsFormat) {
|
||||
obs_enter_graphics();
|
||||
m_renderTarget = gs_texrender_create(colorFormat, zsFormat);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
GS::RenderTarget::~RenderTarget() {
|
||||
obs_enter_graphics();
|
||||
gs_texrender_destroy(m_renderTarget);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
GS::RenderTargetOp GS::RenderTarget::Render(uint32_t width, uint32_t height) {
|
||||
return { this, width, height };
|
||||
}
|
||||
|
||||
gs_texture_t* GS::RenderTarget::GetTextureObject() {
|
||||
obs_enter_graphics();
|
||||
return gs_texrender_get_texture(m_renderTarget);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
GS::RenderTargetOp::RenderTargetOp(GS::RenderTarget* rt, uint32_t width, uint32_t height) : m_renderTarget(rt) {
|
||||
if (m_renderTarget == nullptr)
|
||||
throw std::invalid_argument("rt");
|
||||
if (m_renderTarget->m_isBeingRendered)
|
||||
throw std::logic_error("Can't start rendering to the same render target twice.");
|
||||
obs_enter_graphics();
|
||||
if (!gs_texrender_begin(m_renderTarget->m_renderTarget, width, height)) {
|
||||
obs_leave_graphics();
|
||||
throw std::runtime_error("Failed to begin rendering to render target.");
|
||||
}
|
||||
obs_leave_graphics();
|
||||
m_renderTarget->m_isBeingRendered = true;
|
||||
}
|
||||
|
||||
GS::RenderTargetOp::RenderTargetOp(GS::RenderTargetOp&& r) {
|
||||
this->m_renderTarget = r.m_renderTarget;
|
||||
r.m_renderTarget = nullptr;
|
||||
}
|
||||
|
||||
GS::RenderTargetOp::~RenderTargetOp() {
|
||||
if (m_renderTarget == nullptr)
|
||||
return;
|
||||
obs_enter_graphics();
|
||||
gs_texrender_end(m_renderTarget->m_renderTarget);
|
||||
obs_leave_graphics();
|
||||
m_renderTarget->m_isBeingRendered = false;
|
||||
}
|
60
source/gs-rendertarget.h
Normal file
60
source/gs-rendertarget.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <inttypes.h>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/graphics/graphics.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
namespace GS {
|
||||
class RenderTarget {
|
||||
friend class RenderTargetOp;
|
||||
|
||||
public:
|
||||
RenderTarget(gs_color_format colorFormat, gs_zstencil_format zsFormat);
|
||||
virtual ~RenderTarget();
|
||||
|
||||
gs_texture_t* GetTextureObject();
|
||||
GS::RenderTargetOp Render(uint32_t width, uint32_t height);
|
||||
|
||||
protected:
|
||||
gs_texrender_t* m_renderTarget;
|
||||
bool m_isBeingRendered;
|
||||
};
|
||||
|
||||
class RenderTargetOp {
|
||||
public:
|
||||
RenderTargetOp(GS::RenderTarget* rt, uint32_t width, uint32_t height);
|
||||
virtual ~RenderTargetOp();
|
||||
|
||||
// Move Constructor
|
||||
RenderTargetOp(GS::RenderTargetOp&&);
|
||||
|
||||
// Copy Constructor
|
||||
RenderTargetOp(const GS::RenderTargetOp&) = delete;
|
||||
RenderTargetOp& operator=(const GS::RenderTargetOp& r) = delete;
|
||||
|
||||
protected:
|
||||
GS::RenderTarget* m_renderTarget;
|
||||
};
|
||||
}
|
207
source/gs-texture.cpp
Normal file
207
source/gs-texture.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "gs-texture.h"
|
||||
#include <stdexcept>
|
||||
#include <sys/stat.h>
|
||||
#include <fstream>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/util/platform.h>
|
||||
#include <libobs/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) {
|
||||
if (width == 0)
|
||||
throw std::logic_error("width must be at least 1");
|
||||
if (height == 0)
|
||||
throw std::logic_error("height must be at least 1");
|
||||
if (mip_levels == 0)
|
||||
throw std::logic_error("mip_levels must be at least 1");
|
||||
if (!mip_data)
|
||||
throw std::logic_error("mip_data is invalid");
|
||||
|
||||
if (mip_levels > 1 || flags & 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)
|
||||
throw std::logic_error("mip mapping requires power of two dimensions");
|
||||
}
|
||||
|
||||
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);
|
||||
obs_leave_graphics();
|
||||
|
||||
if (!m_texture)
|
||||
throw std::runtime_error("Failed to create texture.");
|
||||
}
|
||||
|
||||
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) {
|
||||
if (width == 0)
|
||||
throw std::logic_error("width must be at least 1");
|
||||
if (height == 0)
|
||||
throw std::logic_error("height must be at least 1");
|
||||
if (depth == 0)
|
||||
throw std::logic_error("depth must be at least 1");
|
||||
if (mip_levels == 0)
|
||||
throw std::logic_error("mip_levels must be at least 1");
|
||||
if (!mip_data)
|
||||
throw std::logic_error("mip_data is invalid");
|
||||
|
||||
if (mip_levels > 1 || flags & 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);
|
||||
if (!isPOT)
|
||||
throw std::logic_error("mip mapping requires power of two dimensions");
|
||||
}
|
||||
|
||||
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);
|
||||
obs_leave_graphics();
|
||||
|
||||
if (!m_texture)
|
||||
throw std::runtime_error("Failed to create texture.");
|
||||
}
|
||||
|
||||
GS::Texture::Texture(uint32_t size, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, uint32_t flags) {
|
||||
if (size == 0)
|
||||
throw std::logic_error("size must be at least 1");
|
||||
if (mip_levels == 0)
|
||||
throw std::logic_error("mip_levels must be at least 1");
|
||||
if (!mip_data)
|
||||
throw std::logic_error("mip_data is invalid");
|
||||
|
||||
if (mip_levels > 1 || flags & 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);
|
||||
obs_leave_graphics();
|
||||
|
||||
if (!m_texture)
|
||||
throw std::runtime_error("Failed to create texture.");
|
||||
}
|
||||
|
||||
GS::Texture::Texture(std::string file) {
|
||||
struct stat st;
|
||||
if (os_stat(file.c_str(), &st) != 0)
|
||||
throw std::ios_base::failure(file);
|
||||
|
||||
obs_enter_graphics();
|
||||
m_texture = gs_texture_create_from_file(file.c_str());
|
||||
obs_leave_graphics();
|
||||
|
||||
if (!m_texture)
|
||||
throw std::runtime_error("Failed to load texture.");
|
||||
}
|
||||
|
||||
GS::Texture::Texture(Texture& other) {
|
||||
throw std::logic_error("not yet implemented");
|
||||
//obs_enter_graphics();
|
||||
//switch (gs_get_texture_type(other.m_texture)) {
|
||||
// case GS_TEXTURE_2D:
|
||||
// uint32_t width = gs_texture_get_width(other.m_texture);
|
||||
// uint32_t height = gs_texture_get_height(other.m_texture);
|
||||
// gs_color_format format = gs_texture_get_color_format(other.m_texture);
|
||||
// uint32_t mult = 0;
|
||||
// switch (format) {
|
||||
// case GS_A8:
|
||||
// case GS_R8:
|
||||
// mult = 1;
|
||||
// break;
|
||||
// case GS_R16:
|
||||
// case GS_R16F:
|
||||
// mult = 2;
|
||||
// break;
|
||||
// case GS_RG16F:
|
||||
// case GS_R32F:
|
||||
// case GS_BGRA:
|
||||
// case GS_BGRX:
|
||||
// case GS_RGBA:
|
||||
// case GS_R10G10B10A2:
|
||||
// mult = 4;
|
||||
// break;
|
||||
// case GS_RGBA16:
|
||||
// case GS_RGBA16F:
|
||||
// case GS_RG32F:
|
||||
// mult = 8;
|
||||
// break;
|
||||
// case GS_RGBA32F:
|
||||
// mult = 16;
|
||||
// break;
|
||||
// case GS_DXT1:
|
||||
// case GS_DXT3:
|
||||
// case GS_DXT5:
|
||||
// mult = 8;
|
||||
// break;
|
||||
// }
|
||||
// uint8_t* buf = new uint8_t[width * height * mult];
|
||||
// m_texture = gs_texture_create(width, height, format,
|
||||
// 1, &buf);
|
||||
// delete buf;
|
||||
// break;
|
||||
// case GS_TEXTURE_3D:
|
||||
// uint32_t width = gs_voltexture_get_width(other.m_texture);
|
||||
// uint32_t height = gs_voltexture_get_height(other.m_texture);
|
||||
// uint32_t depth = gs_voltexture_get_height(other.m_texture);
|
||||
// gs_color_format format = gs_voltexture_get_color_format(other.m_texture);
|
||||
// break;
|
||||
// case GS_TEXTURE_CUBE:
|
||||
// uint32_t size = gs_cubetexture_get_size(other.m_texture);
|
||||
// gs_color_format format = gs_cubetexture_get_color_format(other.m_texture);
|
||||
// gs_copy_texture()
|
||||
// break;
|
||||
//}
|
||||
//obs_leave_graphics();
|
||||
}
|
||||
|
||||
GS::Texture::~Texture() {
|
||||
if (m_texture) {
|
||||
obs_enter_graphics();
|
||||
switch (gs_get_texture_type(m_texture)) {
|
||||
case GS_TEXTURE_2D:
|
||||
gs_texture_destroy(m_texture);
|
||||
break;
|
||||
case GS_TEXTURE_3D:
|
||||
gs_voltexture_destroy(m_texture);
|
||||
break;
|
||||
case GS_TEXTURE_CUBE:
|
||||
gs_cubetexture_destroy(m_texture);
|
||||
break;
|
||||
}
|
||||
obs_leave_graphics();
|
||||
}
|
||||
m_texture = nullptr;
|
||||
}
|
||||
|
||||
void GS::Texture::Load(int unit) {
|
||||
obs_enter_graphics();
|
||||
gs_load_texture(m_texture, unit);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
gs_texture_t* GS::Texture::GetObject() {
|
||||
return m_texture;
|
||||
}
|
148
source/gs-texture.h
Normal file
148
source/gs-texture.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/graphics/graphics.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
namespace GS {
|
||||
class Texture {
|
||||
public:
|
||||
enum Type : uint8_t {
|
||||
Normal,
|
||||
Volume,
|
||||
Cube
|
||||
};
|
||||
|
||||
enum Flags : uint32_t {
|
||||
Dynamic,
|
||||
BuildMipMaps,
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Create a new texture from data
|
||||
*
|
||||
*
|
||||
*
|
||||
* \param width
|
||||
* \param height
|
||||
* \param format
|
||||
* \param mip_levels
|
||||
* \param mip_data
|
||||
* \param flags
|
||||
*/
|
||||
Texture(uint32_t width, uint32_t height, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, uint32_t flags);
|
||||
|
||||
/*!
|
||||
* \brief Create a new volume texture from data
|
||||
*
|
||||
*
|
||||
*
|
||||
* \param width
|
||||
* \param height
|
||||
* \param depth
|
||||
* \param format
|
||||
* \param mip_levels
|
||||
* \param mip_data
|
||||
* \param 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);
|
||||
|
||||
/*!
|
||||
* \brief Create a new cube texture from data
|
||||
*
|
||||
*
|
||||
*
|
||||
* \param size
|
||||
* \param format
|
||||
* \param mip_levels
|
||||
* \param mip_data
|
||||
* \param flags
|
||||
*/
|
||||
Texture(uint32_t size, gs_color_format format, uint32_t mip_levels, const uint8_t **mip_data, uint32_t flags);
|
||||
|
||||
/*!
|
||||
* \brief Load a texture from a file
|
||||
*
|
||||
* Creates a new #GS::Texture from a file located on disk. If the
|
||||
* file can not be found, accessed or read, a #Plugin::file_not_found_error
|
||||
* will be thrown. If there is an error reading the file, a
|
||||
* #Plugin::io_error will be thrown.
|
||||
*
|
||||
* \param file File to create the texture from.
|
||||
*/
|
||||
Texture(std::string file);// { LoadFromFile(file); }
|
||||
|
||||
/*!
|
||||
* \brief Copy an existing texture
|
||||
*
|
||||
* Create a Texture instance from an existing texture.
|
||||
* This will not take ownership of the underlying gs_texture_t object.
|
||||
*
|
||||
* \param other
|
||||
* \return
|
||||
*/
|
||||
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* GetObject();
|
||||
|
||||
protected:
|
||||
gs_texture_t* m_texture;
|
||||
|
||||
void DestroyTexture();
|
||||
};
|
||||
}
|
20
source/gs-vertex.cpp
Normal file
20
source/gs-vertex.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "gs-vertexbuffer.h"
|
39
source/gs-vertex.h
Normal file
39
source/gs-vertex.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <inttypes.h>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/graphics/vec3.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
namespace GS {
|
||||
const uint32_t MAXIMUM_UVW_LAYERS = 8u;
|
||||
// ToDo: Optimize for use with GS::VertexBuffer so that it doesn't require in-memory copy.
|
||||
struct Vertex {
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
vec3 tangent;
|
||||
vec4 uv[MAXIMUM_UVW_LAYERS];
|
||||
uint32_t color;
|
||||
};
|
||||
}
|
123
source/gs-vertexbuffer.cpp
Normal file
123
source/gs-vertexbuffer.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "gs-vertexbuffer.h"
|
||||
#include <stdexcept>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/obs.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
const uint32_t defaultMaximumVertices = 65535u;
|
||||
|
||||
GS::VertexBuffer::VertexBuffer(uint32_t maximumVertices) {
|
||||
m_maximumVertices = maximumVertices;
|
||||
m_uvwLayers = MAXIMUM_UVW_LAYERS;
|
||||
|
||||
// Reserve Space
|
||||
m_vertexbufferdata.num = m_maximumVertices;
|
||||
m_data.positions.resize(m_maximumVertices);
|
||||
m_vertexbufferdata.points = m_data.positions.data();
|
||||
m_data.normals.resize(m_maximumVertices);
|
||||
m_vertexbufferdata.normals = m_data.normals.data();
|
||||
m_data.tangents.resize(m_maximumVertices);
|
||||
m_vertexbufferdata.tangents = m_data.tangents.data();
|
||||
m_data.colors.resize(m_maximumVertices);
|
||||
m_vertexbufferdata.colors = m_data.colors.data();
|
||||
m_vertexbufferdata.num_tex = m_uvwLayers;
|
||||
m_data.uvws.resize(m_uvwLayers);
|
||||
m_data.uvwdata.resize(m_uvwLayers);
|
||||
for (uint32_t n = 0; n < m_uvwLayers; n++) {
|
||||
m_data.uvws[n].resize(m_maximumVertices);
|
||||
m_data.uvwdata[n].width = 4;
|
||||
m_data.uvwdata[n].array = m_data.uvws[n].data();
|
||||
}
|
||||
m_vertexbufferdata.tvarray = m_data.uvwdata.data();
|
||||
|
||||
// Allocate GPU
|
||||
obs_enter_graphics();
|
||||
m_vertexbuffer = gs_vertexbuffer_create(&m_vertexbufferdata, GS_DYNAMIC);
|
||||
obs_leave_graphics();
|
||||
if (!m_vertexbuffer) {
|
||||
throw std::runtime_error("Failed to create vertex buffer.");
|
||||
}
|
||||
}
|
||||
|
||||
GS::VertexBuffer::VertexBuffer(gs_vertbuffer_t* vb) {
|
||||
m_vertexbuffer = vb;
|
||||
}
|
||||
|
||||
GS::VertexBuffer::VertexBuffer() : VertexBuffer(defaultMaximumVertices) {}
|
||||
|
||||
GS::VertexBuffer::VertexBuffer(std::vector<Vertex>& other) : VertexBuffer((uint32_t)other.capacity()) {
|
||||
std::copy(other.begin(), other.end(), this->end());
|
||||
}
|
||||
|
||||
GS::VertexBuffer::VertexBuffer(VertexBuffer& other) : VertexBuffer(other.m_maximumVertices) {
|
||||
std::copy(other.begin(), other.end(), this->end());
|
||||
}
|
||||
|
||||
GS::VertexBuffer::~VertexBuffer() {
|
||||
if (m_vertexbuffer) {
|
||||
std::memset(&m_vertexbufferdata, 0, sizeof(m_vertexbufferdata));
|
||||
obs_enter_graphics();
|
||||
gs_vertexbuffer_destroy(m_vertexbuffer);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
m_vertexbuffer = nullptr;
|
||||
}
|
||||
|
||||
void GS::VertexBuffer::set_uv_layers(uint32_t layers) {
|
||||
m_uvwLayers = layers;
|
||||
}
|
||||
|
||||
uint32_t GS::VertexBuffer::uv_layers() {
|
||||
return m_uvwLayers;
|
||||
}
|
||||
|
||||
gs_vertbuffer_t* GS::VertexBuffer::get(bool refreshGPU) {
|
||||
if (refreshGPU) {
|
||||
if (size() > m_maximumVertices)
|
||||
throw std::runtime_error("Too many vertices in Vertex Buffer.");
|
||||
|
||||
for (size_t vertexIdx = 0; vertexIdx < size(); vertexIdx++) {
|
||||
Vertex& v = this->at(vertexIdx);
|
||||
vec3_copy(&m_data.positions[vertexIdx], &(v.position));
|
||||
vec3_copy(&m_data.normals[vertexIdx], &(v.normal));
|
||||
vec3_copy(&m_data.tangents[vertexIdx], &(v.tangent));
|
||||
for (size_t texcoordIdx = 0; texcoordIdx < m_uvwLayers; texcoordIdx++) {
|
||||
vec4_copy(&m_data.uvws[texcoordIdx][vertexIdx], &(v.uv[texcoordIdx]));
|
||||
}
|
||||
m_data.colors[vertexIdx] = v.color;
|
||||
}
|
||||
m_vertexbufferdata.num = size();
|
||||
m_vertexbufferdata.num_tex = m_uvwLayers;
|
||||
|
||||
obs_enter_graphics();
|
||||
gs_vertexbuffer_flush(m_vertexbuffer);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
return m_vertexbuffer;
|
||||
}
|
||||
|
||||
gs_vertbuffer_t* GS::VertexBuffer::get() {
|
||||
return get(true);
|
||||
}
|
93
source/gs-vertexbuffer.h
Normal file
93
source/gs-vertexbuffer.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "gs-vertex.h"
|
||||
#include <inttypes.h>
|
||||
#include <vector>
|
||||
extern "C" {
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4201 )
|
||||
#include <libobs/graphics/graphics.h>
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
namespace GS {
|
||||
class VertexBuffer : public std::vector<Vertex> {
|
||||
public:
|
||||
/*!
|
||||
* \brief Create a Vertex Buffer with specific size
|
||||
*
|
||||
* \param maximumVertices Maximum amount of vertices to store.
|
||||
*/
|
||||
VertexBuffer(uint32_t maximumVertices);
|
||||
|
||||
/*!
|
||||
* \brief Create a Vertex Buffer with default size
|
||||
* This will create a new vertex buffer with the default maximum size.
|
||||
*
|
||||
*/
|
||||
VertexBuffer();
|
||||
|
||||
/*!
|
||||
* \brief Create a copy of a Vertex Buffer
|
||||
* Full Description below
|
||||
*
|
||||
* \param other The Vertex Buffer to copy
|
||||
*/
|
||||
VertexBuffer(VertexBuffer& other);
|
||||
|
||||
/*!
|
||||
* \brief Create a Vertex Buffer from a Vertex array
|
||||
* Full Description below
|
||||
*
|
||||
* \param other The Vertex array to use
|
||||
*/
|
||||
VertexBuffer(std::vector<Vertex>& other);
|
||||
|
||||
|
||||
VertexBuffer(gs_vertbuffer_t* vb);
|
||||
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
void set_uv_layers(uint32_t layers);
|
||||
|
||||
uint32_t uv_layers();
|
||||
|
||||
gs_vertbuffer_t* get();
|
||||
|
||||
gs_vertbuffer_t* get(bool refreshGPU);
|
||||
|
||||
protected:
|
||||
uint32_t m_maximumVertices;
|
||||
uint32_t m_uvwLayers;
|
||||
gs_vb_data m_vertexbufferdata;
|
||||
gs_vertbuffer_t* m_vertexbuffer;
|
||||
|
||||
// Data Storage
|
||||
struct {
|
||||
std::vector<vec3> positions;
|
||||
std::vector<vec3> normals;
|
||||
std::vector<vec3> tangents;
|
||||
std::vector<uint32_t> colors;
|
||||
std::vector<std::vector<vec4>> uvws;
|
||||
std::vector<gs_tvertarray> uvwdata;
|
||||
} m_data;
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue