1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Implementa BasicEffect

This commit is contained in:
Danilo 2024-06-27 15:46:41 -03:00
parent 2d052a229a
commit c2048dd644
6 changed files with 355 additions and 1014 deletions

View File

@ -1,777 +1,123 @@
#include "xna/graphics/effect.hpp"
#include "xna/platform-dx/dx.hpp"
#include "xna/common/math.hpp"
using DxBasicEffect = DirectX::BasicEffect;
using DxEffectFactory = DirectX::EffectFactory;
using DxVec3 = DirectX::XMFLOAT3;
using DxVec = DirectX::XMVECTOR;
using DxMatrix = DirectX::XMMATRIX;
namespace xna {
Effect::Effect(sptr<GraphicsDevice> const& device, std::vector<Byte> const& effectCode) :
GraphicsResource(device) {
if (!device)
throw std::invalid_argument("Effect::Effect: invalid argument (device).");
impl = unew<PlatformImplementation>();
const auto result = D3DX11CreateEffectFromMemory(
//void* pData,
effectCode.data(),
//SIZE_T DataLength,
effectCode.size(),
//UINT FXFlags,
0,
//ID3D11Device * pDevice,
device->impl->_device.Get(),
//ID3DX11Effect * *ppEffect
impl->dxEffect.ReleaseAndGetAddressOf()
);
if FAILED(result)
throw std::runtime_error("Effect::Effect: Unable to create an effect with memory data.");
}
PEffectTechnique Effect::CurrentTechnique() const {
D3DX11_EFFECT_DESC desc;
impl->dxEffect->GetDesc(&desc);
auto tech = impl->dxEffect->GetTechniqueByIndex(0);
auto technique = snew<EffectTechnique>();
technique->impl->dxContext = m_device->impl->_context;
technique->impl->dxContext->AddRef();
tech->Release();
tech = nullptr;
return technique;
}
EffectAnnotation::EffectAnnotation() {
Effect::Effect(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {
impl = unew<PlatformImplementation>();
}
Int EffectAnnotation::ColumCount() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::ColumCount: error getting D3DX11_EFFECT_TYPE_DESC");
return static_cast<Int>(desc.Columns);
}
String EffectAnnotation::Name() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::Name: error getting D3DX11_EFFECT_TYPE_DESC");
return String(desc.TypeName);
}
EffectParameterClass EffectAnnotation::ParameterClass() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::ParameterClass: error getting D3DX11_EFFECT_TYPE_DESC");
switch (desc.Class)
{
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_MATRIX_COLUMNS:
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_MATRIX_ROWS:
return EffectParameterClass::Matrix;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_OBJECT:
return EffectParameterClass::Object;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_SCALAR:
return EffectParameterClass::Scalar;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_STRUCT:
return EffectParameterClass::Struct;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_VECTOR:
return EffectParameterClass::Vector;
default:
throw std::runtime_error("EffectAnnotation::ParameterClass: invalid EffectParameterClass.");
}
}
Int EffectAnnotation::RowCount() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::RowCount: error getting D3DX11_EFFECT_TYPE_DESC");
return static_cast<Int>(desc.Rows);
}
String EffectAnnotation::Semantic() const {
auto type = impl->dxVariable->GetType();
auto semantic = type->GetMemberSemantic(0);
type->Release();
type = nullptr;
return std::string(semantic);
}
bool EffectAnnotation::GetValueBoolean() const {
auto scalar = impl->dxVariable->AsScalar();
bool value;
auto hr = scalar->GetBool(&value);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueBoolean: Unable to get boolean value.");
return value;
}
Int EffectAnnotation::GetValueInt32() const {
auto scalar = impl->dxVariable->AsScalar();
int value;
auto hr = scalar->GetInt(&value);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueInt32: Unable to get interger value.");
return static_cast<Int>(value);
}
Matrix EffectAnnotation::GetValueMatrix() const {
auto matrix = impl->dxVariable->AsMatrix();
float values[16];
auto hr = matrix->GetMatrix(values);
matrix->Release();
matrix = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueMatrix: Unable to get matrix value.");
Matrix m;
m.M11 = values[0];
m.M12 = values[1];
m.M13 = values[2];
m.M14 = values[3];
m.M21 = values[4];
m.M22 = values[5];
m.M23 = values[6];
m.M24 = values[7];
m.M31 = values[8];
m.M32 = values[9];
m.M33 = values[10];
m.M34 = values[11];
m.M41 = values[12];
m.M42 = values[13];
m.M43 = values[14];
m.M44 = values[15];
return m;
}
float EffectAnnotation::GetValueSingle() const {
auto scalar = impl->dxVariable->AsScalar();
float value;
auto hr = scalar->GetFloat(&value);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueSingle: Unable to get float value.");
return value;
}
String EffectAnnotation::GetValueString() const {
auto str = impl->dxVariable->AsString();
LPCSTR data;
const auto hr = str->GetString(&data);
str->Release();
str = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueString: Unable to get string value.");
return String(data);
}
Vector2 EffectAnnotation::GetValueVector2() const {
auto scalar = impl->dxVariable->AsScalar();
float values[2];
auto hr = scalar->GetFloatArray(values, 0, 2);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueVector2: Unable to get Vector2 value.");
Vector2 v;
v.X = values[0];
v.Y = values[1];
return v;
}
Vector3 EffectAnnotation::GetValueVector3() const {
auto scalar = impl->dxVariable->AsScalar();
float values[3];
auto hr = scalar->GetFloatArray(values, 0, 3);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueVector3: Unable to get Vector3 value.");
Vector3 v;
v.X = values[0];
v.Y = values[1];
v.Z = values[2];
return v;
}
Vector4 EffectAnnotation::GetValueVector4() const {
auto scalar = impl->dxVariable->AsScalar();
float values[4];
auto hr = scalar->GetFloatArray(values, 0, 4);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectAnnotation::GetValueVector4: Unable to get Vector4 value.");
Vector4 v;
v.X = values[0];
v.Y = values[1];
v.Z = values[2];
v.W = values[3];
return v;
}
EffectPass::EffectPass() {
BasicEffect::BasicEffect(sptr<GraphicsDevice> const& device) : Effect(device) {
impl = unew<PlatformImplementation>();
uptr<DxEffectFactory> fxFactory = unew<DxEffectFactory>(device->impl->_device.Get());
DxEffectFactory::EffectInfo info;
info.name = L"basic";
info.alpha = 1.f;
info.ambientColor = DxHelpers::Vector3ToDx(ambientLightColor);
info.diffuseColor = DxHelpers::Vector3ToDx(diffuseColor);
info.specularColor = DxHelpers::Vector3ToDx(specularColor);
info.specularPower = specularPower;
Effect::impl->dxEffect = fxFactory->CreateEffect(info, device->impl->_context.Get());
impl->dxBasicEffect = reinterpret_pointer_cast<DxBasicEffect>(Effect::impl->dxEffect);
}
String EffectPass::Name() const {
if (!impl->dxPass)
throw std::runtime_error("EffectPass::Name: The class was not initialized correctly");
D3DX11_PASS_DESC desc{};
impl->dxPass->GetDesc(&desc);
return String(desc.Name);
void BasicEffect::Alpha(float value) {
const auto a = MathHelper::Clamp(value, 0.0f, 1.0);
impl->dxBasicEffect->SetAlpha(a);
}
PEffectAnnotationCollection EffectPass::Annotations() const {
if (!impl->dxPass)
throw std::runtime_error("EffectPass::Annotations: The class was not initialized correctly");
D3DX11_PASS_DESC desc{};
const auto hr = impl->dxPass->GetDesc(&desc);
if FAILED(hr)
throw std::runtime_error("EffectPass::Annotations: error getting D3DX11_PASS_DESC");
auto annotCount = desc.Annotations;
if (annotCount == 0)
return snew<EffectAnnotationCollection>();
std::vector<PEffectAnnotation> list(annotCount);
for (size_t i = 0; i < annotCount; ++i) {
auto current = impl->dxPass->GetAnnotationByIndex(i);
auto annotation = snew<EffectAnnotation>();
annotation->impl->dxVariable = current;
annotation->impl->dxVariable->AddRef();
current->Release();
current = nullptr;
list[i] = annotation;
}
auto collection = snew<EffectAnnotationCollection>(list);
return collection;
void BasicEffect::AmbientLightColor(Vector3 const& value) {
DxVec vec3 = DxHelpers::VectorToDx(value);
impl->dxBasicEffect->SetAmbientLightColor(vec3);
}
void EffectPass::Apply() {
if (!impl->dxPass)
throw std::runtime_error("EffectPass::Apply: The class was not initialized correctly");
const auto hr = impl->dxPass->Apply(0, impl->dxContext.Get());
if FAILED(hr)
throw std::runtime_error("EffectPass::Apply: error to call Apply");
void BasicEffect::DiffuseColor(Vector3 const& value) {
DxVec vec3 = DxHelpers::VectorToDx(value);
impl->dxBasicEffect->SetDiffuseColor(vec3);
}
EffectTechnique::EffectTechnique() {
impl = unew<PlatformImplementation>();
void BasicEffect::EmissiveColor(Vector3 const& value) {
DxVec vec3 = DxHelpers::VectorToDx(value);
impl->dxBasicEffect->SetEmissiveColor(vec3);
}
String EffectTechnique::Name() const {
D3DX11_TECHNIQUE_DESC desc;
const auto hr = impl->dxTechnique->GetDesc(&desc);
if FAILED(hr)
throw std::runtime_error("EffectTechnique::Name: error getting D3DX11_TECHNIQUE_DESC");
return String(desc.Name);
void BasicEffect::FogColor(Vector3 const& value) {
DxVec vec3 = DxHelpers::VectorToDx(value);
impl->dxBasicEffect->SetFogColor(vec3);
}
PEffectAnnotationCollection EffectTechnique::Annotations() const {
D3DX11_TECHNIQUE_DESC desc;
const auto hr = impl->dxTechnique->GetDesc(&desc);
if FAILED(hr)
throw std::runtime_error("EffectTechnique::Annotations: error getting D3DX11_TECHNIQUE_DESC");
auto annotCount = desc.Annotations;
if (annotCount == 0)
return snew<EffectAnnotationCollection>();
std::vector<PEffectAnnotation> list(annotCount);
for (size_t i = 0; i < annotCount; ++i) {
auto current = impl->dxTechnique->GetAnnotationByIndex(i);
auto annotation = snew<EffectAnnotation>();
annotation->impl->dxVariable = current;
annotation->impl->dxVariable->AddRef();
current->Release();
current = nullptr;
list[i] = annotation;
}
auto collection = snew<EffectAnnotationCollection>(list);
return collection;
void BasicEffect::FogEnabled(bool value) {
impl->dxBasicEffect->SetFogEnabled(value);
}
PEffectPassCollection EffectTechnique::Passes() const {
D3DX11_TECHNIQUE_DESC desc;
const auto hr = impl->dxTechnique->GetDesc(&desc);
if FAILED(hr)
throw std::runtime_error("EffectTechnique::Passes: error getting D3DX11_TECHNIQUE_DESC");
auto passCount = desc.Passes;
if (passCount == 0)
return snew<EffectPassCollection>();
std::vector<PEffectPass> list(passCount);
for (size_t i = 0; i < passCount; ++i) {
auto current = impl->dxTechnique->GetPassByIndex(i);
auto pass = snew<EffectPass>();
pass->impl->dxPass.Attach(current);
current->Release();
current = nullptr;
pass->impl->dxContext = impl->dxContext;
list[i] = pass;
}
auto collection = snew<EffectPassCollection>(list);
return collection;
void BasicEffect::FogEnd(float value) {
impl->dxBasicEffect->SetFogEnd(value);
}
EffectParameter::EffectParameter() {
impl = unew<PlatformImplementation>();
void BasicEffect::FogStart(float value) {
impl->dxBasicEffect->SetFogStart(value);
}
PEffectAnnotationCollection EffectParameter::Annotations() const {
D3DX11_EFFECT_VARIABLE_DESC desc;
const auto hr = impl->dxVariable->GetDesc(&desc);
if FAILED(hr)
throw std::runtime_error("EffectParameter::Annotations: error getting D3DX11_EFFECT_VARIABLE_DESC");
auto annotCount = desc.Annotations;
if (annotCount == 0)
return snew<EffectAnnotationCollection>();
std::vector<PEffectAnnotation> list(annotCount);
for (size_t i = 0; i < annotCount; ++i) {
auto current = impl->dxVariable->GetAnnotationByIndex(i);
auto annotation = snew<EffectAnnotation>();
annotation->impl->dxVariable = current;
annotation->impl->dxVariable->AddRef();
current->Release();
current = nullptr;
list[i] = annotation;
}
auto collection = snew<EffectAnnotationCollection>(list);
return collection;
void BasicEffect::LightingEnabled(bool value) {
impl->dxBasicEffect->SetLightingEnabled(value);
}
Int EffectParameter::ColumnCount() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::ColumnCount: error getting D3DX11_EFFECT_VARIABLE_DESC");
return static_cast<Int>(desc.Columns);
void BasicEffect::PreferPerPixelLighting(bool value) {
impl->dxBasicEffect->SetPerPixelLighting(value);
}
Int EffectParameter::RowCount() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::RowCount: error getting D3DX11_EFFECT_TYPE_DESC");
return static_cast<Int>(desc.Rows);
void BasicEffect::Projection(Matrix const& value) {
auto m = DxHelpers::MatrixToDx(value);
impl->dxBasicEffect->SetProjection(m);
}
String EffectParameter::Semantic() const {
auto type = impl->dxVariable->GetType();
auto semantic = type->GetMemberSemantic(0);
type->Release();
type = nullptr;
return std::string(semantic);
void BasicEffect::SpecularColor(Vector3 const& value) {
DxVec vec3 = DxHelpers::VectorToDx(value);
impl->dxBasicEffect->SetSpecularColor(vec3);
}
EffectParameterType EffectParameter::ParameterType() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::ParameterType: error getting D3DX11_EFFECT_TYPE_DESC");
switch (desc.Type)
{
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_BOOL:
return EffectParameterType::Bool;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_INT:
return EffectParameterType::Int32;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_FLOAT:
return EffectParameterType::Single;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_STRING:
return EffectParameterType::String;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_TEXTURE:
return EffectParameterType::Texture;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_TEXTURE1D:
return EffectParameterType::Texture1D;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_TEXTURE2D:
return EffectParameterType::Texture2D;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_TEXTURE3D:
return EffectParameterType::Texture3D;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_TEXTURECUBE:
return EffectParameterType::TextureCube;
case D3D_SHADER_VARIABLE_TYPE::D3D_SVT_VOID:
return EffectParameterType::Void;
default:
throw std::runtime_error("EffectParameter::ParameterType: invalid EffectParameterType.");
}
void BasicEffect::SpecularPower(float value) {
impl->dxBasicEffect->SetSpecularPower(value);
}
EffectParameterClass EffectParameter::ParameterClass() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::ParameterClass: error getting D3DX11_EFFECT_TYPE_DESC");
switch (desc.Class)
{
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_MATRIX_COLUMNS:
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_MATRIX_ROWS:
return EffectParameterClass::Matrix;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_OBJECT:
return EffectParameterClass::Object;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_SCALAR:
return EffectParameterClass::Scalar;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_STRUCT:
return EffectParameterClass::Struct;
case D3D_SHADER_VARIABLE_CLASS::D3D_SVC_VECTOR:
return EffectParameterClass::Vector;
default:
throw std::runtime_error("EffectParameter::ParameterClass: invalid EffectParameterClass.");
}
void BasicEffect::View(Matrix const& value) {
auto m = DxHelpers::MatrixToDx(value);
impl->dxBasicEffect->SetView(m);
}
String EffectParameter::Name() const {
auto type = impl->dxVariable->GetType();
D3DX11_EFFECT_TYPE_DESC desc{};
const auto hr = type->GetDesc(&desc);
type->Release();
type = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::Name: error getting D3DX11_EFFECT_TYPE_DESC");
return String(desc.TypeName);
void BasicEffect::World(Matrix const& value) {
auto m = DxHelpers::MatrixToDx(value);
impl->dxBasicEffect->SetWorld(m);
}
sptr<EffectParameterCollection> EffectParameter::Elements() const {
uint32_t index = 0;
void BasicEffect::Texture(sptr<xna::Texture2D> const& value) {
if (!value || !value->impl || !value->impl->dxShaderResource)
Exception::Throw(ExMessage::ArgumentIsNull);
auto collection = snew<EffectParameterCollection>();
while (true) {
auto el = impl->dxVariable->GetElement(index);
if (!el)
break;
auto efparam = snew<EffectParameter>();
efparam->impl->dxVariable.Attach(el);
el->Release();
el = nullptr;
}
return collection;
impl->dxBasicEffect->SetTexture(value->impl->dxShaderResource.Get());
}
sptr<EffectParameterCollection> EffectParameter::StructureMembers() const {
uint32_t index = 0;
auto collection = snew<EffectParameterCollection>();
while (true) {
auto member = impl->dxVariable->GetMemberByIndex(index);
if (!member)
break;
auto efparam = snew<EffectParameter>();
efparam->impl->dxVariable.Attach(member);
member->Release();
member = nullptr;
}
return collection;
void BasicEffect::TextureEnabled(bool value) {
impl->dxBasicEffect->SetTextureEnabled(value);
}
bool EffectParameter::GetValueBoolean() const {
auto scalar = impl->dxVariable->AsScalar();
bool value;
const auto hr = scalar->GetBool(&value);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::GetValueBoolean: Unable to get boolean value.");
return value;
void BasicEffect::VertexColorEnabled(bool value) {
impl->dxBasicEffect->SetVertexColorEnabled(value);
}
std::vector<bool> EffectParameter::GetValueBooleanArray(size_t count) const {
auto scalar = impl->dxVariable->AsScalar();
auto arr = std::make_unique<bool[]>(count);
void BasicEffect::SetDirectionalLight(Int index, DirectionalLight const& direction) {
DxVec vec3 = DxHelpers::VectorToDx(direction.Direction);
const auto hr = scalar->GetBoolArray(arr.get(), 0, count);
scalar->Release();
scalar = nullptr;
const auto value = (int)MathHelper::Clamp(index, 0, impl->dxBasicEffect->MaxDirectionalLights);
if FAILED(hr)
throw std::runtime_error("EffectParameter::GetValueBooleanArray: Unable to get boolean value.");
std::vector<bool> data(count);
for (size_t i = 0; i < count; ++i) {
data[i] = arr[i];
}
return data;
}
Int EffectParameter::GetValueInt32() const {
auto scalar = impl->dxVariable->AsScalar();
Int value;
const auto hr = scalar->GetInt(&value);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::GetValueInt32: Unable to get int value.");
return value;
}
std::vector<Int> EffectParameter::GetValueInt32Array(size_t count) const {
auto scalar = impl->dxVariable->AsScalar();
std::vector<Int> data(count);
const auto hr = scalar->GetIntArray(data.data(), 0, count);
scalar->Release();
scalar = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::GetValueInt32Array: Unable to get int value.");
return data;
}
Matrix EffectParameter::GetValueMatrix() const {
auto matrix = impl->dxVariable->AsMatrix();
float values[16];
auto hr = matrix->GetMatrix(values);
matrix->Release();
matrix = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::GetValueIntMatrix: Unable to get matrix value.");
Matrix m;
m.M11 = values[0];
m.M12 = values[1];
m.M13 = values[2];
m.M14 = values[3];
m.M21 = values[4];
m.M22 = values[5];
m.M23 = values[6];
m.M24 = values[7];
m.M31 = values[8];
m.M32 = values[9];
m.M33 = values[10];
m.M34 = values[11];
m.M41 = values[12];
m.M42 = values[13];
m.M43 = values[14];
m.M44 = values[15];
return m;
}
std::vector<Matrix> EffectParameter::GetValueMatrixArray(size_t count) const {
auto matrix = impl->dxVariable->AsMatrix();
const auto elements = count * 16;
auto arr = std::make_unique<float[]>(count * elements);
auto hr = matrix->GetMatrixArray(arr.get(), 0, elements);
matrix->Release();
matrix = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::GetValuetMatrixArray: Unable to get matrix value.");
auto index = 0;
std::vector<Matrix> data(count);
for (size_t i = 0; i < elements; ++i) {
Matrix m;
m.M11 = arr[i];
m.M12 = arr[++i];
m.M13 = arr[++i];
m.M14 = arr[++i];
m.M21 = arr[++i];
m.M22 = arr[++i];
m.M23 = arr[++i];
m.M24 = arr[++i];
m.M31 = arr[++i];
m.M32 = arr[++i];
m.M33 = arr[++i];
m.M34 = arr[++i];
m.M41 = arr[++i];
m.M42 = arr[++i];
m.M43 = arr[++i];
m.M44 = arr[++i];
data[index] = m;
++index;
}
return data;
}
Matrix EffectParameter::GetValueMatrixTranspose() const {
auto matrix = impl->dxVariable->AsMatrix();
float values[16];
auto hr = matrix->GetMatrixTranspose(values);
matrix->Release();
matrix = nullptr;
if FAILED(hr)
throw std::runtime_error("EffectParameter::GetValueIntMatrix: Unable to get matrix value.");
Matrix m;
m.M11 = values[0];
m.M12 = values[1];
m.M13 = values[2];
m.M14 = values[3];
m.M21 = values[4];
m.M22 = values[5];
m.M23 = values[6];
m.M24 = values[7];
m.M31 = values[8];
m.M32 = values[9];
m.M33 = values[10];
m.M34 = values[11];
m.M41 = values[12];
m.M42 = values[13];
m.M43 = values[14];
m.M44 = values[15];
return m;
impl->dxBasicEffect->SetLightDirection(value, vec3);
}
}

View File

@ -21,7 +21,7 @@ namespace xna {
value = value > max ? max : value;
value = value < min ? min : value;
return value;
}
}
static constexpr float Lerp(float value1, float value2, float amount) {
return value1 + (value2 - value1) * amount;

View File

@ -1,4 +1,4 @@
#ifndef XNA_EXCEPTION_HPP
#ifndef XNA_EXCEPTION_HPP
#define XNA_EXCEPTION_HPP
#include <stdexcept>
@ -17,6 +17,7 @@ namespace xna {
inline static const std::string MakeWindowAssociation = "Failed to create association with window";
inline static const std::string BuildObject = "Unable to build object";
inline static const std::string NotImplemented = "Not Implemented";
inline static const std::string ArgumentIsNull = "The argument or any of its internal values are null";
};
//Structure for throwing exceptions with a message and information from the source file

View File

@ -4,296 +4,235 @@
#include "../common/numerics.hpp"
#include "../default.hpp"
#include "gresource.hpp"
#include "../graphics/texture.hpp"
namespace xna {
//Represents an annotation to an EffectParameter.
class EffectAnnotation {
public:
Int ColumCount() const;
String Name() const;
EffectParameterClass ParameterClass() const;
Int RowCount() const;
String Semantic() const;
bool GetValueBoolean() const;
Int GetValueInt32() const;
Matrix GetValueMatrix() const;
float GetValueSingle() const;
String GetValueString() const;
Vector2 GetValueVector2() const;
Vector3 GetValueVector3() const;
Vector4 GetValueVector4() const;
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
public:
EffectAnnotation();
};
using PEffectAnnotation = sptr<EffectAnnotation>;
class EffectAnnotationCollection {
public:
EffectAnnotationCollection() {}
EffectAnnotationCollection(std::vector<PEffectAnnotation> const& data) : data(data)
{
}
constexpr size_t Count() const {
return data.size();
}
PEffectAnnotation operator[](size_t index) {
if (index >= data.size())
return nullptr;
return data[index];
}
PEffectAnnotation operator[](String const& name) {
for (size_t i = 0; i < data.size(); ++i) {
const auto& p = data[i];
if (p->Name() == name)
return p;
}
return nullptr;
}
public:
std::vector<PEffectAnnotation> data;
};
using PEffectAnnotationCollection = sptr<EffectAnnotationCollection>;
class EffectPass {
public:
//Gets the name of this pass.
String Name() const;
//The EffectAnnotationCollection containing EffectAnnotation objects for this EffectPass.
PEffectAnnotationCollection Annotations() const;
//Begins this pass.
void Apply();
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
public:
EffectPass();
};
using PEffectPass = sptr<EffectPass>;
class EffectPassCollection {
public:
EffectPassCollection() {}
EffectPassCollection(std::vector<PEffectPass> const& data) : data(data)
{
}
constexpr size_t Count() const {
return data.size();
}
PEffectPass operator[](size_t index) {
if (index >= data.size())
return nullptr;
return data[index];
}
PEffectPass operator[](String const& name) {
for (size_t i = 0; i < data.size(); ++i) {
const auto& p = data[i];
if (p->Name() == name)
return p;
}
return nullptr;
}
public:
std::vector<PEffectPass> data;
};
using PEffectPassCollection = sptr<EffectPassCollection>;
class EffectTechnique {
public:
PEffectAnnotationCollection Annotations() const;
String Name() const;
PEffectPassCollection Passes() const;
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
public:
EffectTechnique();
};
using PEffectTechnique = sptr<EffectTechnique>;
class EffectParameterCollection;
class EffectParameter {
public:
//Gets the collection of EffectAnnotation objects for this parameter.
PEffectAnnotationCollection Annotations() const;
//Gets the number of columns in the parameter description.
Int ColumnCount() const;
//Gets the number of rows in the parameter description.
Int RowCount() const;
//Gets the semantic meaning, or usage, of the parameter.
String Semantic() const;
//Gets the type of the parameter.
EffectParameterType ParameterType() const;
//Gets the class of the parameter.
EffectParameterClass ParameterClass() const;
//Gets the name of the parameter.
String Name() const;
//Gets the collection of effect parameters.
sptr<EffectParameterCollection> Elements() const;
//Gets the collection of structure members.
sptr<EffectParameterCollection> StructureMembers() const;
bool GetValueBoolean() const;
std::vector<bool> GetValueBooleanArray(size_t count) const;
Int GetValueInt32() const;
std::vector <Int> GetValueInt32Array(size_t count) const;
Matrix GetValueMatrix() const;
std::vector <Matrix> GetValueMatrixArray(size_t count) const;
Matrix GetValueMatrixTranspose() const;
std::vector <Matrix> GetValueMatrixTransposeArray(size_t count) const;
Quaternion GetValueQuaternion() const;
std::vector <Quaternion> GetValueQuaternionArray() const;
float GetValueSingle() const;
std::vector<float> GetValueSingleArray() const;
String GetValueString() const;
sptr<Texture2D> GetValueTexture2D() const;
sptr<Texture3D> GetValueTexture3D() const;
sptr<TextureCube> GetValueTextureCube() const;
Vector2 GetValueVector2() const;
std::vector <Vector2> GetValueVector2Array() const;
Vector3 GetValueVector3() const;
std::vector <Vector3> GetValueVector3Array() const;
Vector4 GetValueVector4() const;
std::vector <Vector4> GetValueVector4Array() const;
void SetValue(bool value);
void SetValue(std::vector<bool> const& value);
void SetValue(Int value);
void SetValue(std::vector<Int> const& value);
void SetValue(float value);
void SetValue(std::vector<float> const& value);
void SetValue(Matrix const& value);
void SetValue(std::vector<Matrix> const& value);
void SetValue(Quaternion const& value);
void SetValue(std::vector<Quaternion> const& value);
void SetValue(Vector2 const& value);
void SetValue(std::vector<Vector2> const& value);
void SetValue(Vector3 const& value);
void SetValue(std::vector<Vector3> const& value);
void SetValue(Vector4 const& value);
void SetValue(std::vector<Vector4> const& value);
void SetValue(String const& value);
void SetValue(sptr<Texture> const& value);
void SetValueTranspose(Matrix const& value);
void SetValueTranspose(std::vector<Matrix> const& value);
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
public:
EffectParameter();
};
using PEffectParameter = sptr<EffectParameter>;
class EffectParameterCollection {
public:
EffectParameterCollection() {}
EffectParameterCollection(std::vector<PEffectParameter> const& data) : data(data)
{
}
constexpr size_t Count() const {
return data.size();
}
PEffectParameter operator[](size_t index) {
if (index >= data.size())
return nullptr;
return data[index];
}
PEffectParameter operator[](String const& name) {
for (size_t i = 0; i < data.size(); ++i) {
const auto& p = data[i];
if (p->Name() == name)
return p;
}
return nullptr;
}
public:
std::vector<PEffectParameter> data;
};
using PEffectPassCollection = sptr<EffectPassCollection>;
class Effect : public GraphicsResource {
Effect(sptr<GraphicsDevice> const& device, std::vector<Byte> const& effectCode);
PEffectTechnique CurrentTechnique() const;
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
};
//Gets or sets transformation matrix parameters for the current effect.
class IEffectMatrices {
//Gets or sets the projection matrix in the current effect.
virtual Matrix World() const = 0;
//Gets or sets the view matrix in the current effect.
virtual Matrix View() const = 0;
//Gets or sets the world matrix in the current effect.
virtual Matrix Projection() const = 0;
//Gets or sets the projection matrix in the current effect.
virtual void World(Matrix const& value) = 0;
//Gets or sets the view matrix in the current effect.
virtual void View(Matrix const& value) = 0;
//Gets or sets the world matrix in the current effect.
virtual void Projection(Matrix const& value) = 0;
};
class DirectionalLight;
class IEffectLights {
virtual DirectionalLight DirectionalLight0() const = 0;
virtual DirectionalLight DirectionalLight1() const = 0;
virtual DirectionalLight DirectionalLight2() const = 0;
virtual Vector3 AmbientLightColor() const = 0;
virtual void AmbientLightColor(Vector3 const& value) = 0;
virtual bool LightingEnabled() const = 0;
virtual void LightingEnabled(bool value) = 0;
virtual void EnableDefaultLighting() = 0;
//Creates a DirectionalLight object.
struct DirectionalLight {
//Gets or sets the diffuse color of the light.
Vector3 DiffuseColor{ Vector3::Zero() };
//Gets or sets the light direction. This value must be a unit vector.
Vector3 Direction{ Vector3::Zero() };
//Gets or sets the specular color of the light.
Vector3 SpecularColor{ Vector3::Zero() };
//Gets or sets light enable flag.
bool Enabled{ false };
};
//Gets or sets lighting parameters for the current effect.
class IEffectLights {
//Gets the first directional light for the current effect.
virtual DirectionalLight DirectionalLight0() const = 0;
//Gets the second directional light for the current effect.
virtual DirectionalLight DirectionalLight1() const = 0;
//Gets the third directional light for the current effect.
virtual DirectionalLight DirectionalLight2() const = 0;
//Gets or sets a value indicating that per-pixel lighting should be used if it is available for the current adapter.
virtual bool PreferPerPixelLighting() const = 0;
//Gets or sets a value indicating that per-pixel lighting should be used if it is available for the current adapter.
virtual void PreferPerPixelLighting(bool value) = 0;
//Gets or sets the ambient light color for the current effect.
virtual Vector3 AmbientLightColor() const = 0;
//Gets or sets the ambient light color for the current effect.
virtual void AmbientLightColor(Vector3 const& value) = 0;
//Enables or disables lighting in an IEffectLights.
virtual bool LightingEnabled() const = 0;
//Enables or disables lighting in an IEffectLights.
virtual void LightingEnabled(bool value) = 0;
};
//Gets or sets fog parameters for the current effect.
class IEffectFog
{
//Enables or disables fog.
virtual bool FogEnabled() const = 0;
//Gets or sets the fog ending distance.
virtual float FogStart() const = 0;
//Gets or sets the fog ending distance.
virtual float FogEnd() const = 0;
//Gets or sets the fog color.
virtual Vector3 FogColor() const = 0;
virtual void FogEnabled(bool value) const = 0;
virtual void FogStart(float value) const = 0;
virtual void FogEnd(float value) const = 0;
virtual void FogColor(Vector3 const& value) const = 0;
//Enables or disables fog.
virtual void FogEnabled(bool value) = 0;
//Gets or sets the fog ending distance.
virtual void FogStart(float value) = 0;
//Gets or sets the fog ending distance.
virtual void FogEnd(float value) = 0;
//Gets or sets the fog color.
virtual void FogColor(Vector3 const& value) = 0;
};
class Effect : public GraphicsResource {
public:
Effect(sptr<GraphicsDevice> const& device);
virtual ~Effect() {}
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
};
//Contains a basic rendering effect.
class BasicEffect : public Effect, public IEffectMatrices, public IEffectLights, public IEffectFog {
public:
BasicEffect(sptr<GraphicsDevice> const& device);
//
// IEffectMatrices
//
//Gets or sets the world matrix.
virtual Matrix World() const override { return world; }
//Gets or sets the world matrix.
virtual void World(Matrix const& value) override;
//Gets or sets the view matrix.
virtual constexpr Matrix View() const override { return view; }
//Gets or sets the view matrix.
virtual void View(Matrix const& value) override;
//Gets or sets the projection matrix. Use this matrix to change how a 3D image is converted to a 2D image that is rendered to the computer screen.
virtual constexpr Matrix Projection() const override { return projection; }
//Gets or sets the projection matrix. Use this matrix to change how a 3D image is converted to a 2D image that is rendered to the computer screen.
virtual void Projection(Matrix const& value) override;
//
// IEffectLights
//
//Gets the first directional light for this effect.
virtual DirectionalLight DirectionalLight0() const override { return directionalLight0; }
//Gets the second directional light for this effect.
virtual DirectionalLight DirectionalLight1() const override { return directionalLight1; }
//Gets the second directional light for this effect.
virtual DirectionalLight DirectionalLight2() const override { return directionalLight2; }
//Gets or sets a value indicating that per-pixel lighting should be used if it is available for the current adapter.
virtual constexpr bool PreferPerPixelLighting() const override { return preferPerPixelLighting; }
//Gets or sets a value indicating that per-pixel lighting should be used if it is available for the current adapter.
virtual void PreferPerPixelLighting(bool value) override;
//Gets or sets the ambient color for a light, the range of color values is from 0 to 1.
virtual constexpr Vector3 AmbientLightColor() const override { return ambientLightColor; }
//Gets or sets the ambient color for a light, the range of color values is from 0 to 1.
virtual void AmbientLightColor(Vector3 const& value) override;
//Enables lighting for this effect.
virtual constexpr bool LightingEnabled() const override { return lightingEnabled; }
//Enables lighting for this effect.
virtual void LightingEnabled(bool value) override;
//
// IEffectFog
//
//Gets or sets the minimum z value for fog, which ranges from 0 to 1.
virtual constexpr float FogStart() const override { return fogStart; }
//Gets or sets the minimum z value for fog, which ranges from 0 to 1.
virtual void FogStart(float value) override;
//Gets or sets the maximum z value for fog, which ranges from 0 to 1.
virtual constexpr float FogEnd() const override { return fogEnd; }
//Gets or sets the maximum z value for fog, which ranges from 0 to 1.
virtual void FogEnd(float value) override;
//Enables fog.
virtual constexpr bool FogEnabled() const override { return fogEnabled; }
//Enables fog.
virtual void FogEnabled(bool value) override;
//Gets or sets the fog color, the range of color values is from 0 to 1.
virtual constexpr Vector3 FogColor() const override { return fogColor; }
//Gets or sets the fog color, the range of color values is from 0 to 1.
virtual void FogColor(Vector3 const& value) override;
//
// BasicEffect
//
//Gets or sets the material alpha which determines its transparency.
//Range is between 1 (fully opaque) and 0 (fully transparent).
constexpr float Alpha() const { return alpha; }
////Gets or sets the material alpha which determines its transparency.
//Range is between 1 (fully opaque) and 0 (fully transparent).
void Alpha(float value);
//Gets or sets the diffuse color for a material, the range of color values is from 0 to 1.
constexpr Vector3 DiffuseColor() const { return diffuseColor; }
//Gets or sets the diffuse color for a material, the range of color values is from 0 to 1.
void DiffuseColor(Vector3 const& value);
//Gets or sets the emissive color for a material, the range of color values is from 0 to 1.
constexpr Vector3 EmissiveColor() const { return emissiveColor; }
//Gets or sets the emissive color for a material, the range of color values is from 0 to 1.
void EmissiveColor(Vector3 const& value);
//Gets or sets the emissive color for a material, the range of color values is from 0 to 1.
constexpr Vector3 SpecularColor() const { return specularColor; }
//Gets or sets the emissive color for a material, the range of color values is from 0 to 1.
void SpecularColor(Vector3 const& value);
//Gets or sets the specular power of this effect material.
constexpr float SpecularPower() const { return specularPower; }
//Gets or sets the specular power of this effect material.
void SpecularPower(float value);
//Gets or sets a texture to be applied by this effect.
sptr<xna::Texture2D> Texture() const { return texture; }
//Gets or sets a texture to be applied by this effect.
void Texture(sptr<xna::Texture2D> const& value);
//Enables textures for this effect.
constexpr bool TextureEnabled() const { return textureEnabled; }
//Enables textures for this effect.
void TextureEnabled(bool value);
//Enables textures for this effect.
constexpr bool VertexColorEnabled() const { return vertexColorEnabled; }
//Enables textures for this effect.
void VertexColorEnabled(bool value);
void SetDirectionalLight(Int index, DirectionalLight const& direction);
private:
bool fogEnabled{ false };
bool lightingEnabled{ false };
bool preferPerPixelLighting{ false };
bool textureEnabled{ false };
bool vertexColorEnabled{ false };
float alpha{0};
float fogStart{0};
float fogEnd{0};
float specularPower{ 16.0f};
Vector3 ambientLightColor{ Vector3::Zero() };
Vector3 diffuseColor{ Vector3::One() };
Vector3 emissiveColor{ Vector3::Zero() };
Vector3 specularColor{ Vector3::One() };
Vector3 fogColor{};
Matrix projection{ Matrix::Identity() };
Matrix view{ Matrix::Identity() };
Matrix world{ Matrix::Identity() };
DirectionalLight directionalLight0{};
DirectionalLight directionalLight1{};
DirectionalLight directionalLight2{};
sptr<Texture2D> texture{ nullptr };
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
};
}

View File

@ -99,6 +99,71 @@ namespace xna {
//==============================================//
struct DxHelpers {
static constexpr DirectX::XMVECTOR VectorToDx(Vector2 const& value) {
DirectX::XMVECTOR v;
v.m128_f32[0] = value.X;
v.m128_f32[1] = value.Y;
return v;
}
static constexpr DirectX::XMVECTOR VectorToDx(Vector3 const& value) {
DirectX::XMVECTOR v;
v.m128_f32[0] = value.X;
v.m128_f32[1] = value.Y;
v.m128_f32[2] = value.Z;
return v;
}
static constexpr DirectX::XMFLOAT3 Vector3ToDx(Vector3 const& value) {
DirectX::XMFLOAT3 v;
v.x = value.X;
v.y = value.Y;
v.z = value.Z;
return v;
}
static constexpr DirectX::XMVECTOR VectorToDx(Vector4 const& value) {
DirectX::XMVECTOR v;
v.m128_f32[0] = value.X;
v.m128_f32[1] = value.Y;
v.m128_f32[2] = value.Z;
v.m128_f32[3] = value.W;
return v;
}
static constexpr DirectX::XMMATRIX MatrixToDx(Matrix const& value) {
auto m = DirectX::XMMATRIX(
value.M11,
value.M12,
value.M13,
value.M14,
value.M21,
value.M22,
value.M23,
value.M24,
value.M31,
value.M32,
value.M33,
value.M34,
value.M41,
value.M42,
value.M43,
value.M44
);
return m;
}
static constexpr DirectX::SpriteSortMode SpriteSortToDx(SpriteSortMode value) {
return static_cast<DirectX::SpriteSortMode>(static_cast<int>(value));
}
@ -829,25 +894,11 @@ namespace xna {
};
struct Effect::PlatformImplementation {
comptr<ID3DX11Effect> dxEffect = nullptr;
sptr<DirectX::IEffect> dxEffect = nullptr;
};
struct EffectAnnotation::PlatformImplementation {
comptr<ID3DX11EffectVariable> dxVariable = nullptr;
struct BasicEffect::PlatformImplementation {
sptr<DirectX::BasicEffect> dxBasicEffect = nullptr;
};
struct EffectPass::PlatformImplementation {
comptr<ID3DX11EffectPass> dxPass = nullptr;
comptr<ID3D11DeviceContext> dxContext = nullptr;
};
struct EffectTechnique::PlatformImplementation {
comptr<ID3DX11EffectTechnique> dxTechnique = nullptr;
comptr<ID3D11DeviceContext> dxContext = nullptr;
};
struct EffectParameter::PlatformImplementation {
comptr<ID3DX11EffectVariable> dxVariable = nullptr;
};
}
#endif

View File

@ -67,6 +67,10 @@ namespace xna {
template <typename T>
using sptr = std::shared_ptr<T>;
//Same as std::weak_ptr
template <typename T>
using wptr = std::weak_ptr<T>;
//Same as std::unique_ptr
template <typename T>
using uptr = std::unique_ptr<T>;