2

我试图让“SharpDX.Direct3D11.DeviceContext.OutputMerger.Blendstate”工作。没有这个,我有很好的场景(带有纹理的多边形,用于 Spaceshooter)。我在过去三年中完成了 OpenGL 图形,所以我认为它可能和 OpenGL 一样简单——只需启用混合并设置正确的 Dst/Src 模式。但是如果我设置一个新的 BlendStateDescription,所有的输出都是黑色的,即使“RenderTarget[x].IsBlendEnabled”设置为“false”。我搜索了一个教程或其他东西,找到了一个 - 但它使用了效果。所以我的问题很简单——我必须在 SharpDX 中使用技术和效果吗?没有其他方法可以进行简单的混合吗?

这就是我所做的:

mBackBuffer = Texture2D.FromSwapChain<Texture2D>(mSwapChain, 0);
mRenderView = new RenderTargetView(mDevice, mBackBuffer);
mContext.OutputMerger.SetTargets(mDepthStencilView, mRenderView);
mContext.OutputMerger.SetBlendState(new BlendState(mDevice, new BlendStateDescription()), new SharpDX.Color4(1.0f), -1);

mContext.OutputMerger.BlendState.Description.RenderTarget[0].IsBlendEnabled = true;
mContext.OutputMerger.BlendState.Description.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha;
mContext.OutputMerger.BlendState.Description.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;
mContext.OutputMerger.BlendState.Description.RenderTarget[0].BlendOperation = BlendOperation.Add;           
mContext.OutputMerger.BlendState.Description.RenderTarget[0].SourceAlphaBlend = BlendOption.One;            
mContext.OutputMerger.BlendState.Description.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;          
mContext.OutputMerger.BlendState.Description.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;          
mContext.OutputMerger.BlendState.Description.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;           

而且,即使只是简单地做:

mContext.OutputMerger.SetBlendState(new BlendState(mDevice, new BlendStateDescription()), new SharpDX.Color4(1.0f), -1);
mContext.OutputMerger.BlendState.Description.RenderTarget[0].IsBlendEnabled = false;

输出全黑..也许我只需要更改像素着色器中的某些内容?

4

1 回答 1

5

Direct3D11 中的所有资源都是不可变的,因此当您创建新的 Blendstate(mDevice, new BlendStateDescription()) 时,您以后无法更改描述。正常的工作流程是:

var blendDescription = new BlendDescription();
blendDescription.RenderTarget[0].IsBlendEnabled = .. // 设置所有值
[...]
var blendState = new BlendState(device, blendDescription);
context.OutputMerger.SetBlendState(blendState, ...);

此外,资源对象需要存储在某个地方并在您完全使用它们时进行处置(大多数时间用于混合状态,在您的应用程序结束时),否则您将出现内存泄漏。

当您不确定 API 的使用情况时,我建议您更仔细地查看一些 Direct3D11 C++ 示例。另外,我建议您阅读 Frank.D.Luna 撰写的“使用 DirectX 11 进行 3D 游戏编程介绍”之类的书,非常适合开始和学习 Direct3D11 API。

于 2012-10-12T11:20:02.203 回答