将两个较小的纹理渲染到更大的纹理上

时间:2013-11-21 10:58:15

标签: c++ c directx

当我将两个纹理渲染到更大的纹理上时。

考虑一下:

  
      
  • ID3D10Texture2D A      
        
    • ID3D10Texture2D B
    •   
    • ID3D10Texture2D C
    •   
  •   

如果我第一次绘制纹理B,纹理A的全宽仅在纹理的一半上绘制纹理C. A 即可。 为什么纹理C正在从纹理B中删除自身区域?

然后我将纹理A绘制到后备缓冲区上以查看结果。

enter image description here

我做了一些额外的测试,发现纹理C的alpha也影响纹理B的alpha,这样如果纹理C的alpha太低,你就不能真正看到纹理B.怎么会这样问题得到解决?事实上,这怎么可能是一个问题?因为,我在B. ##

之后渲染了C.
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);

enter image description here  注意:纹理B跨越整个宽度,但纹理C仅放置在纹理B的顶部中间。由于纹理B是纯红色图像,纹理C +纹理B不应该是透明的。

2 个答案:

答案 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绘图,一般情况下,最好确保您的对象完全不重叠。