# A hopefully simple blending question

This topic is 5464 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey all, I have a shape rendered to the backbuffer (Its a black and white textured quad), and I'd like to change the colour of it by blending another quad over it. However, I seem to only be able to draw the whole quad onto the backbuffer, instead of blending it. Here's what I have at the moment:
D3D_CHECK(m_pDevice->SetStreamSource(0,m_pVBBackgroundOverlay,0,sizeof(TLVertex)));
D3D_CHECK(m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE));
D3D_CHECK(m_pDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_CONSTANT));
D3D_CHECK(m_pDevice->SetTextureStageState(0,D3DTSS_CONSTANT,0x80ff0000));
D3D_CHECK(m_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,m_dwNumOverlayPrimitives));
D3D_CHECK(m_pDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE));
D3D_CHECK(m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE));


(D3D_CHECK is just a debug macro that asserts if the function fails) Now i'm probably doing something obviously wrong, I'm particularly good at messing up with blending and texture stages. The texture thats set is transparent where the texture is black, and opaque where its white. So it should blend the white with the red colour from the constant. Any ideas? Cheers, Steve

##### Share on other sites
How about setting the alpha arg to constant, instead of/in addition to the color arg? Without that your 0x80 level of alpha is never seen by anything. What about setting up the srcblend and destblend?

Get into the habit of setting everything, instead of hoping it's in a certain state. ie: If you set any part of a stage, set colorop, colorarg1, colorarg2, alphaop, alphararg1, alphaarg2. Also get into the habit of ending with a stage set to disable.

Why are you blending, instead of just adding in a second stage? The first stage sets up your texture modulated with lighting. Your second stage multiplies your color by your magic constant tinting color. Stage 3 is set to disable. If you use TFactor instead of Constant, this should work on all DX7 level hardware that has multitexturing (except for RagePro which screws up TFactor). It's going to render faster, and work on more hardware.

If you use material colors (and lights) instead of vertex colors, then you don't even need the second stage, just set a new material color before drawing.

##### Share on other sites
Quote:
 Original post by NamethatnobodyelsetookHow about setting the alpha arg to constant, instead of/in addition to the color arg? Without that your 0x80 level of alpha is never seen by anything. What about setting up the srcblend and destblend?Get into the habit of setting everything, instead of hoping it's in a certain state. ie: If you set any part of a stage, set colorop, colorarg1, colorarg2, alphaop, alphararg1, alphaarg2. Also get into the habit of ending with a stage set to disable.

Yeah, the 0x80 in the alpha was just to test, and you're right - I should be setting everything I rely on, I'll do that.

Quote:
 Original post by NamethatnobodyelsetookWhy are you blending, instead of just adding in a second stage? The first stage sets up your texture modulated with lighting. Your second stage multiplies your color by your magic constant tinting color. Stage 3 is set to disable. If you use TFactor instead of Constant, this should work on all DX7 level hardware that has multitexturing (except for RagePro which screws up TFactor). It's going to render faster, and work on more hardware.If you use material colors (and lights) instead of vertex colors, then you don't even need the second stage, just set a new material color before drawing.

Well, at the moment I draw my entire background with one DrawPrimitive() call, and then the overlay with one more DrawPrimitive() call. Not everything needs to be overlaid like this, so I'd have to split my DP() call up to set the states for everything that needs overlays and everything that doesn't.

I'm basicly making a side on tile based engine thing. All the tiles are in one texture, and the tiles rarely change, so I can put all the vertices in one static VB, and then draw them in one go. For things that can be overlaid (what I'm trying to do here is palette rotation effects - Think Jet Set Willy with the flashing items), they're drawn in white in the first DP(), and I do another DrawPrimitve() to change the colour.

And I'll use TFactor - I knew there was a renderstate that I could set, I just couldn't find it - which is why I went for the constant.

Steve

##### Share on other sites
I've got it sorted now, thanks. Here's what I now have:
D3D_CHECK(m_pDevice->SetStreamSource(0,m_pVBBackgroundOverlay,0,sizeof(TLVertex)));D3D_CHECK(m_pDevice->SetRenderState(D3DRS_TEXTUREFACTOR,0xffff0000));D3D_CHECK(m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE));D3D_CHECK(m_pDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA));D3D_CHECK(m_pDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ZERO));D3D_CHECK(m_pDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TFACTOR));D3D_CHECK(m_pDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE));D3D_CHECK(m_pDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_CURRENT));D3D_CHECK(m_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,m_dwNumOverlayPrimitives));D3D_CHECK(m_pDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE));D3D_CHECK(m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE));

I'm an idiot and forgot to set the D3DRS_SRCBLEND and D3DRS_DESTBLEND states :P

Cheers,
Steve

##### Share on other sites
just a tiny critique. look into state blocks. it'll make your code read more like english and i believe(anecdotal evidence) that it will execute faster.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 15
• 22
• 17
• 46