当我将两个纹理渲染到更大的纹理上时。
考虑一下:
- ID3D10Texture2D A
- ID3D10Texture2D B
- ID3D10Texture2D C
如果我第一次绘制纹理B,纹理A的全宽和则仅在纹理的一半上绘制纹理C. A 即可。 为什么纹理C正在从纹理B中删除自身区域?
然后我将纹理A绘制到后备缓冲区上以查看结果。
blendDesc.BlendEnable[0] = TRUE;
blendDesc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
blendDesc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
blendDesc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
blendDesc.BlendOp = D3D10_BLEND_OP_ADD;
blendDesc.SrcBlendAlpha = D3D10_BLEND_ONE;
blendDesc.DestBlendAlpha = D3D10_BLEND_ZERO;
blendDesc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
hr = aDXDevice->CreateBlendState(&blendDesc, &this->g_pBlendState);
注意:纹理B跨越整个宽度,但纹理C仅放置在纹理B的顶部中间。由于纹理B是纯红色图像,纹理C +纹理B不应该是透明的。
答案 0 :(得分:1)
不要假装是一个答案,这只是猜测。
混合问题的可能原因是状态激增到下一次抽签调用。
所有DirectX(以及GL)状态都不会在帧结束时重置,它们会一直存在,直到更改或上下文重置为止。
所以,可能你有一个混合状态
hr = aDXDevice->CreateBlendState(&blendDesc, &this->g_pBlendState);
并且在绘制B之后但在绘制C之前应用它:
DrawB();
aDXDevice->OMSetBlendState(&g_pBlendState, ...);
DrawC();
第一帧按预期绘制,但在下一帧g_pBlendState
仍处于活动状态。所以B绘图只在第一帧上没有alpha。
您需要的是两种混合状态,每种混合模式一种,并且每帧都应用它:
aDXDevice->CreateBlendState(&blendDescForB, &blendStateForB); // no alpna
aDXDevice->CreateBlendState(&blendDescForC, &blendStateForC); // alpha enabled
aDXDevice->OMSetBlendState(blendStateForB, ...);
DrawB();
aDXDevice->OMSetBlendState(blendStateForC, ...);
DrawC();
要快速调试该问题,您可以尝试在Present()
之后应用ID3D10Device::ClearState。但只是为了调试。
请注意,有一点反驳我的假设:混合A未被触及。
答案 1 :(得分:0)
不确定具体细节但请记住,OpenGL是一个3D库,在确定哪个对象遮挡其他对象时会考虑深度。 OpenGL也使用浮点数表示顶点,这意味着即使数字看起来相等,那么很多也不是。确保一个物体在另一个物体前面的唯一安全方法是绘制它。对于2D绘图,一般情况下,最好确保您的对象完全不重叠。