mirror of
https://github.com/borgesdan/xn65
synced 2024-12-29 21:54:47 +01:00
Corrige BlendState
This commit is contained in:
parent
3e026233a0
commit
1d21955efb
@ -1,9 +1,7 @@
|
||||
#ifndef XNA_GRAPHICS_BLENDSTATE_HPP
|
||||
#define XNA_GRAPHICS_BLENDSTATE_HPP
|
||||
|
||||
#include "../types.hpp"
|
||||
#include "../forward.hpp"
|
||||
#include "../enums.hpp"
|
||||
#include "../default.hpp"
|
||||
|
||||
namespace xna {
|
||||
struct BlendRenderTarget {
|
||||
@ -24,13 +22,17 @@ namespace xna {
|
||||
class IBlendState {
|
||||
public:
|
||||
virtual ~IBlendState() {}
|
||||
virtual bool Initialize(GraphicsDevice& device, xna_error_nullarg) = 0;
|
||||
virtual void AlphaToCoverageEnable(bool value) = 0;
|
||||
virtual void IndependentBlendEnable(bool value) = 0;
|
||||
virtual void RenderTargets(std::vector<BlendRenderTarget> const& value) = 0;
|
||||
|
||||
virtual bool Apply(GraphicsDevice& device, xna_error_nullarg) = 0;
|
||||
|
||||
static PBlendState Opaque();
|
||||
static PBlendState AlphaBlend();
|
||||
static PBlendState Additive();
|
||||
static PBlendState NonPremultiplied();
|
||||
|
||||
virtual bool Apply(GraphicsDevice* device) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2,81 +2,80 @@
|
||||
#include "device-dx.hpp"
|
||||
|
||||
namespace xna {
|
||||
BlendState::BlendState(GraphicsDevice* device) {
|
||||
_device = device;
|
||||
}
|
||||
|
||||
bool BlendState::Apply(GraphicsDevice* device) {
|
||||
|
||||
D3D11_BLEND_DESC blendDesc{};
|
||||
blendDesc.AlphaToCoverageEnable = AlphaToCoverage;
|
||||
blendDesc.IndependentBlendEnable = IndependentBlendEnable;
|
||||
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
if (RenderTargets[i] == nullptr)
|
||||
break;
|
||||
|
||||
blendDesc.RenderTarget[0].BlendEnable = RenderTargets[0]->Enabled;
|
||||
blendDesc.RenderTarget[0].SrcBlend = BlendMapper::ConvertBlend(RenderTargets[0]->Source);
|
||||
blendDesc.RenderTarget[0].DestBlend = BlendMapper::ConvertBlend(RenderTargets[0]->Destination);
|
||||
blendDesc.RenderTarget[0].BlendOp = BlendMapper::ConvertOperation(RenderTargets[0]->Operation);
|
||||
blendDesc.RenderTarget[0].SrcBlendAlpha = BlendMapper::ConvertBlend(RenderTargets[0]->SourceAlpha);
|
||||
blendDesc.RenderTarget[0].DestBlendAlpha = BlendMapper::ConvertBlend(RenderTargets[0]->DestinationAlpha);
|
||||
blendDesc.RenderTarget[0].BlendOpAlpha = BlendMapper::ConvertOperation(RenderTargets[0]->OperationAlpha);
|
||||
blendDesc.RenderTarget[0].RenderTargetWriteMask = BlendMapper::ConvertColorWrite(RenderTargets[0]->WriteMask);
|
||||
bool BlendState::Initialize(GraphicsDevice& device, xna_error_ptr_arg)
|
||||
{
|
||||
if (!device._device) {
|
||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_device == nullptr || _device != device)
|
||||
_device = device;
|
||||
if (_blendState) {
|
||||
_blendState->Release();
|
||||
_blendState = nullptr;
|
||||
}
|
||||
|
||||
if FAILED(_device->_device->CreateBlendState(&blendDesc, &_blendState))
|
||||
return false;
|
||||
const auto hr = device._device->CreateBlendState(&_description, &_blendState);
|
||||
|
||||
_device->_context->OMSetBlendState(_blendState, nullptr, 0xffffffff);
|
||||
if (FAILED(hr)) {
|
||||
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlendState::Apply(GraphicsDevice& device, xna_error_ptr_arg) {
|
||||
if (!device._context) {
|
||||
xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_blendState) {
|
||||
const auto init = Initialize(device, err);
|
||||
if (!init) return false;
|
||||
}
|
||||
|
||||
device._context->OMSetBlendState(_blendState, nullptr, 0xffffffff);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PBlendState IBlendState::Opaque() {
|
||||
auto blendState = New<BlendState>(nullptr);
|
||||
blendState->RenderTargets[0] = New<BlendRenderTarget>();
|
||||
blendState->RenderTargets[0]->Source = Blend::SourceAlpha;
|
||||
blendState->RenderTargets[0]->SourceAlpha = Blend::SourceAlpha;
|
||||
blendState->RenderTargets[0]->Destination = Blend::Zero;
|
||||
blendState->RenderTargets[0]->DestinationAlpha = Blend::Zero;
|
||||
auto blendState = New<BlendState>();
|
||||
blendState->_description.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||
blendState->_description.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
blendState->_description.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_ALPHA;
|
||||
blendState->_description.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
|
||||
return blendState;
|
||||
}
|
||||
|
||||
PBlendState IBlendState::AlphaBlend() {
|
||||
auto blendState = New<BlendState>(nullptr);
|
||||
blendState->RenderTargets[0] = New<BlendRenderTarget>();
|
||||
blendState->RenderTargets[0]->Source = Blend::One;
|
||||
blendState->RenderTargets[0]->SourceAlpha = Blend::One;
|
||||
blendState->RenderTargets[0]->Destination = Blend::InverseSourceAlpha;
|
||||
blendState->RenderTargets[0]->DestinationAlpha = Blend::InverseSourceAlpha;
|
||||
auto blendState = New<BlendState>();
|
||||
blendState->_description.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||
blendState->_description.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||
blendState->_description.RenderTarget[0].DestBlend = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
blendState->_description.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
|
||||
return blendState;
|
||||
}
|
||||
|
||||
PBlendState IBlendState::Additive() {
|
||||
auto blendState = New<BlendState>(nullptr);
|
||||
blendState->RenderTargets[0] = New<BlendRenderTarget>();
|
||||
blendState->RenderTargets[0]->Source = Blend::SourceAlpha;
|
||||
blendState->RenderTargets[0]->SourceAlpha = Blend::SourceAlpha;
|
||||
blendState->RenderTargets[0]->Destination = Blend::One;
|
||||
blendState->RenderTargets[0]->DestinationAlpha = Blend::One;
|
||||
auto blendState = New<BlendState>();
|
||||
blendState->_description.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||
blendState->_description.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
blendState->_description.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
|
||||
blendState->_description.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
|
||||
|
||||
return blendState;
|
||||
}
|
||||
|
||||
PBlendState IBlendState::NonPremultiplied() {
|
||||
auto blendState = New<BlendState>(nullptr);
|
||||
blendState->RenderTargets[0] = New<BlendRenderTarget>();
|
||||
blendState->RenderTargets[0]->Source = Blend::SourceAlpha;
|
||||
blendState->RenderTargets[0]->SourceAlpha = Blend::SourceAlpha;
|
||||
blendState->RenderTargets[0]->Destination = Blend::InverseSourceAlpha;
|
||||
blendState->RenderTargets[0]->DestinationAlpha = Blend::InverseSourceAlpha;
|
||||
auto blendState = New<BlendState>();
|
||||
blendState->_description.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||
blendState->_description.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
blendState->_description.RenderTarget[0].DestBlend = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
blendState->_description.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
|
||||
return blendState;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace xna {
|
||||
class BlendState : public IBlendState {
|
||||
public:
|
||||
BlendState(GraphicsDevice* device);
|
||||
BlendState() = default;
|
||||
|
||||
virtual ~BlendState() override {
|
||||
if (_blendState) {
|
||||
@ -16,21 +16,39 @@ namespace xna {
|
||||
_blendState = nullptr;
|
||||
}
|
||||
}
|
||||
virtual bool Initialize(GraphicsDevice& device, xna_error_nullarg) override;
|
||||
|
||||
virtual constexpr void AlphaToCoverageEnable(bool value) override {
|
||||
_description.AlphaToCoverageEnable = value;
|
||||
}
|
||||
|
||||
virtual bool Apply(GraphicsDevice* device) override;
|
||||
virtual constexpr void IndependentBlendEnable(bool value) override {
|
||||
_description.IndependentBlendEnable = value;
|
||||
}
|
||||
|
||||
virtual void RenderTargets(std::vector<BlendRenderTarget> const& value) override {
|
||||
for (size_t i = 0; i < value.size() && i < 8; ++i) {
|
||||
_description.RenderTarget[i].BlendEnable = value[i].Enabled;
|
||||
_description.RenderTarget[i].SrcBlend = ConvertBlend(value[i].Source);
|
||||
_description.RenderTarget[i].DestBlend = ConvertBlend(value[i].Destination);
|
||||
_description.RenderTarget[i].BlendOp = ConvertOperation(value[i].Operation);
|
||||
_description.RenderTarget[i].SrcBlendAlpha = ConvertBlend(value[i].SourceAlpha);
|
||||
_description.RenderTarget[i].DestBlendAlpha = ConvertBlend(value[i].DestinationAlpha);
|
||||
_description.RenderTarget[i].BlendOpAlpha = ConvertOperation(value[i].OperationAlpha);
|
||||
_description.RenderTarget[i].RenderTargetWriteMask = ConvertColorWrite(value[i].WriteMask);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool Apply(GraphicsDevice& device, xna_error_nullarg) override;
|
||||
|
||||
public:
|
||||
ID3D11BlendState* _blendState{ nullptr };
|
||||
GraphicsDevice* _device{ nullptr };
|
||||
bool AlphaToCoverage{ false };
|
||||
bool IndependentBlendEnable{ false };
|
||||
PBlendRenderTarget RenderTargets[8];
|
||||
};
|
||||
ID3D11BlendState* _blendState{ nullptr };
|
||||
D3D11_BLEND_DESC _description{};
|
||||
|
||||
struct BlendMapper {
|
||||
public:
|
||||
static constexpr D3D11_BLEND ConvertBlend(Blend blend) {
|
||||
switch (blend)
|
||||
{
|
||||
{
|
||||
case xna::Blend::Zero:
|
||||
return D3D11_BLEND_ZERO;
|
||||
case xna::Blend::One:
|
||||
@ -105,7 +123,7 @@ namespace xna {
|
||||
return D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -82,7 +82,7 @@ namespace xna {
|
||||
|
||||
_context->RSSetViewports(1, &view);
|
||||
|
||||
_blendState->Apply(this);
|
||||
_blendState->Apply(*this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user