Jump to content
  • Advertisement
Sign in to follow this  
Evil Steve

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
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.

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 Namethatnobodyelsetook
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.

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.

Thanks for the reply,
Steve

Share this post


Link to post
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 this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!