diff --git a/framework/platform-dx/effect.cpp b/framework/platform-dx/effect.cpp index 9744ee2..2ae99e0 100644 --- a/framework/platform-dx/effect.cpp +++ b/framework/platform-dx/effect.cpp @@ -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 const& device, std::vector const& effectCode) : - GraphicsResource(device) { - - if (!device) - throw std::invalid_argument("Effect::Effect: invalid argument (device)."); - - impl = unew(); - - 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(); - technique->impl->dxContext = m_device->impl->_context; - technique->impl->dxContext->AddRef(); - - tech->Release(); - tech = nullptr; - - return technique; - } - - EffectAnnotation::EffectAnnotation() { + Effect::Effect(sptr const& device) : GraphicsResource(device) { impl = unew(); } - 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(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(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(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 const& device) : Effect(device) { impl = unew(); + + uptr fxFactory = unew(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(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(); - - std::vector list(annotCount); - - for (size_t i = 0; i < annotCount; ++i) { - auto current = impl->dxPass->GetAnnotationByIndex(i); - auto annotation = snew(); - annotation->impl->dxVariable = current; - annotation->impl->dxVariable->AddRef(); - - current->Release(); - current = nullptr; - - list[i] = annotation; - } - - auto collection = snew(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(); + 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(); - - std::vector list(annotCount); - - for (size_t i = 0; i < annotCount; ++i) { - auto current = impl->dxTechnique->GetAnnotationByIndex(i); - auto annotation = snew(); - annotation->impl->dxVariable = current; - annotation->impl->dxVariable->AddRef(); - - current->Release(); - current = nullptr; - - list[i] = annotation; - } - - auto collection = snew(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(); - - std::vector list(passCount); - - for (size_t i = 0; i < passCount; ++i) { - auto current = impl->dxTechnique->GetPassByIndex(i); - - auto pass = snew(); - pass->impl->dxPass.Attach(current); - - current->Release(); - current = nullptr; - - pass->impl->dxContext = impl->dxContext; - - list[i] = pass; - } - - auto collection = snew(list); - return collection; + void BasicEffect::FogEnd(float value) { + impl->dxBasicEffect->SetFogEnd(value); } - EffectParameter::EffectParameter() { - impl = unew(); + 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(); - - std::vector list(annotCount); - - for (size_t i = 0; i < annotCount; ++i) { - auto current = impl->dxVariable->GetAnnotationByIndex(i); - auto annotation = snew(); - annotation->impl->dxVariable = current; - annotation->impl->dxVariable->AddRef(); - - current->Release(); - current = nullptr; - - list[i] = annotation; - } - - auto collection = snew(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(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(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 EffectParameter::Elements() const { - uint32_t index = 0; + void BasicEffect::Texture(sptr const& value) { + if (!value || !value->impl || !value->impl->dxShaderResource) + Exception::Throw(ExMessage::ArgumentIsNull); - auto collection = snew(); - - while (true) { - auto el = impl->dxVariable->GetElement(index); - - if (!el) - break; - - auto efparam = snew(); - efparam->impl->dxVariable.Attach(el); - - el->Release(); - el = nullptr; - } - - - return collection; + impl->dxBasicEffect->SetTexture(value->impl->dxShaderResource.Get()); } - sptr EffectParameter::StructureMembers() const { - uint32_t index = 0; - - auto collection = snew(); - - while (true) { - auto member = impl->dxVariable->GetMemberByIndex(index); - - if (!member) - break; - - auto efparam = snew(); - 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 EffectParameter::GetValueBooleanArray(size_t count) const { - auto scalar = impl->dxVariable->AsScalar(); - auto arr = std::make_unique(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 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 EffectParameter::GetValueInt32Array(size_t count) const { - auto scalar = impl->dxVariable->AsScalar(); - std::vector 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 EffectParameter::GetValueMatrixArray(size_t count) const { - auto matrix = impl->dxVariable->AsMatrix(); - const auto elements = count * 16; - auto arr = std::make_unique(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 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); } } \ No newline at end of file diff --git a/inc/xna/common/math.hpp b/inc/xna/common/math.hpp index af36ec2..afaec53 100644 --- a/inc/xna/common/math.hpp +++ b/inc/xna/common/math.hpp @@ -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; diff --git a/inc/xna/exception.hpp b/inc/xna/exception.hpp index 36144b2..66425a2 100644 --- a/inc/xna/exception.hpp +++ b/inc/xna/exception.hpp @@ -1,4 +1,4 @@ -#ifndef XNA_EXCEPTION_HPP +#ifndef XNA_EXCEPTION_HPP #define XNA_EXCEPTION_HPP #include @@ -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 diff --git a/inc/xna/graphics/effect.hpp b/inc/xna/graphics/effect.hpp index 9cc4f30..a2ca929 100644 --- a/inc/xna/graphics/effect.hpp +++ b/inc/xna/graphics/effect.hpp @@ -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 impl; - - public: - EffectAnnotation(); - }; - using PEffectAnnotation = sptr; - - class EffectAnnotationCollection { - public: - EffectAnnotationCollection() {} - - EffectAnnotationCollection(std::vector 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 data; - }; - using PEffectAnnotationCollection = sptr; - - 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 impl; - - public: - EffectPass(); - }; - using PEffectPass = sptr; - - class EffectPassCollection { - public: - EffectPassCollection() {} - - EffectPassCollection(std::vector 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 data; - }; - using PEffectPassCollection = sptr; - - class EffectTechnique { - public: - PEffectAnnotationCollection Annotations() const; - String Name() const; - PEffectPassCollection Passes() const; - - public: - struct PlatformImplementation; - uptr impl; - - public: - EffectTechnique(); - }; - using PEffectTechnique = sptr; - - 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 Elements() const; - //Gets the collection of structure members. - sptr StructureMembers() const; - - bool GetValueBoolean() const; - std::vector GetValueBooleanArray(size_t count) const; - Int GetValueInt32() const; - std::vector GetValueInt32Array(size_t count) const; - Matrix GetValueMatrix() const; - std::vector GetValueMatrixArray(size_t count) const; - Matrix GetValueMatrixTranspose() const; - std::vector GetValueMatrixTransposeArray(size_t count) const; - Quaternion GetValueQuaternion() const; - std::vector GetValueQuaternionArray() const; - float GetValueSingle() const; - std::vector GetValueSingleArray() const; - String GetValueString() const; - sptr GetValueTexture2D() const; - sptr GetValueTexture3D() const; - sptr GetValueTextureCube() const; - Vector2 GetValueVector2() const; - std::vector GetValueVector2Array() const; - Vector3 GetValueVector3() const; - std::vector GetValueVector3Array() const; - Vector4 GetValueVector4() const; - std::vector GetValueVector4Array() const; - - void SetValue(bool value); - void SetValue(std::vector const& value); - void SetValue(Int value); - void SetValue(std::vector const& value); - void SetValue(float value); - void SetValue(std::vector const& value); - void SetValue(Matrix const& value); - void SetValue(std::vector const& value); - void SetValue(Quaternion const& value); - void SetValue(std::vector const& value); - void SetValue(Vector2 const& value); - void SetValue(std::vector const& value); - void SetValue(Vector3 const& value); - void SetValue(std::vector const& value); - void SetValue(Vector4 const& value); - void SetValue(std::vector const& value); - void SetValue(String const& value); - void SetValue(sptr const& value); - - void SetValueTranspose(Matrix const& value); - void SetValueTranspose(std::vector const& value); - - public: - struct PlatformImplementation; - uptr impl; - - public: - EffectParameter(); - }; - using PEffectParameter = sptr; - - class EffectParameterCollection { - public: - EffectParameterCollection() {} - - EffectParameterCollection(std::vector 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 data; - }; - using PEffectPassCollection = sptr; - - class Effect : public GraphicsResource { - Effect(sptr const& device, std::vector const& effectCode); - - PEffectTechnique CurrentTechnique() const; - - public: - struct PlatformImplementation; - uptr 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 const& device); + + virtual ~Effect() {} + + public: + struct PlatformImplementation; + uptr impl; + }; + + //Contains a basic rendering effect. + class BasicEffect : public Effect, public IEffectMatrices, public IEffectLights, public IEffectFog { + public: + BasicEffect(sptr 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 Texture() const { return texture; } + //Gets or sets a texture to be applied by this effect. + void Texture(sptr 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 texture{ nullptr }; + + public: + struct PlatformImplementation; + uptr impl; }; } diff --git a/inc/xna/platform-dx/dx.hpp b/inc/xna/platform-dx/dx.hpp index ff0ee79..eefb0aa 100644 --- a/inc/xna/platform-dx/dx.hpp +++ b/inc/xna/platform-dx/dx.hpp @@ -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(static_cast(value)); } @@ -829,25 +894,11 @@ namespace xna { }; struct Effect::PlatformImplementation { - comptr dxEffect = nullptr; + sptr dxEffect = nullptr; }; - struct EffectAnnotation::PlatformImplementation { - comptr dxVariable = nullptr; + struct BasicEffect::PlatformImplementation { + sptr dxBasicEffect = nullptr; }; - - struct EffectPass::PlatformImplementation { - comptr dxPass = nullptr; - comptr dxContext = nullptr; - }; - - struct EffectTechnique::PlatformImplementation { - comptr dxTechnique = nullptr; - comptr dxContext = nullptr; - }; - - struct EffectParameter::PlatformImplementation { - comptr dxVariable = nullptr; - }; } #endif \ No newline at end of file diff --git a/inc/xna/types.hpp b/inc/xna/types.hpp index 12c673a..2fffd95 100644 --- a/inc/xna/types.hpp +++ b/inc/xna/types.hpp @@ -67,6 +67,10 @@ namespace xna { template using sptr = std::shared_ptr; + //Same as std::weak_ptr + template + using wptr = std::weak_ptr; + //Same as std::unique_ptr template using uptr = std::unique_ptr;