Jump to content
  • Advertisement
Sign in to follow this  
Synex

Alpha Blending... Again!

This topic is 5143 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

Ok... bit of a tricksy problem here. I've got a whole load of textured quads flying around which is all cool and nice and what not. And I have them alpha blended (using an alpha channel from a DDS). However, all of the alpha blending i've done so far has been against straight lines. When I came to do something a bit more complex it hit the fan. That is my problem. Image 1 shows the output I see on screen. Image 2 is the DDS file viewed in Adobe Photoshop. Image 3 is the result of me selecting the alpha channel and copying it onto another image with Photoshop. This is the same result I get when I used the Sprite helper class. It works fine, but using my own rendering code with a VertexBuffer it doesn't blend properly.
// setup vertex stream
			d_3DDevice.SetStreamSource(0, d_buffer, 0);

			// alpha blending 
			d_3DDevice.RenderState.AlphaTestEnable = true; 
			d_3DDevice.RenderState.ReferenceAlpha = 0x02; 
			d_3DDevice.RenderState.AlphaFunction = Compare.GreaterEqual; 

			d_3DDevice.RenderState.AlphaBlendEnable = true; 
			d_3DDevice.RenderState.AlphaSourceBlend = Blend.SourceAlpha; 
			d_3DDevice.RenderState.AlphaDestinationBlend = Blend.InvSourceAlpha; 

			d_3DDevice.TextureState[0].ColorOperation = TextureOperation.Modulate; 
			d_3DDevice.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; 
			d_3DDevice.TextureState[0].ColorArgument2 = TextureArgument.Current; 

			d_3DDevice.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;
			d_3DDevice.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; 
			d_3DDevice.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse; 
			
			d_3DDevice.RenderState.ZBufferEnable = true;
			d_3DDevice.RenderState.ZBufferFunction = Compare.Less;
			
			d_3DDevice.SetTexture(0, d_texture);

			// render the sprites
			d_3DDevice.VertexFormat = CustomVertex.TransformedColoredTextured.Format;
			d_3DDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (d_bufferPos / VERTEX_PER_TRIANGLE));







That is the texture stages and what not I'm using. Any ideas where I am going wrong? Cheers, Tech Dude Code Monkey

Share this post


Link to post
Share on other sites
Advertisement
Can you show an screen output? Can you send your vertex declaration? Are you using TLVertices? Are you filling your vertex color with an appropiate color? (white?) If you are using TLVertices, are you computing the w component by hand?

Luck!
Guimo


Share this post


Link to post
Share on other sites
Image 1 is a screen output - I'll throw together a textured quad demo doodah tomorrow for you all to pull apart.

Share this post


Link to post
Share on other sites
1) What format is the texture inside your DDS file? - it looks like a format with only a 1-bit alpha channel. Try using a different format within the DDS.

2) Try disabling the alpha test.

[edit]
3) Aha, what Namethatnobodyelsetook said is actually most likely. I totally missed that (bedtime soon methinks).
[/edit]

Share this post


Link to post
Share on other sites
Ok here is a quick demo I threw togther:


using System;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Drawing;

namespace TestConsole
{

class CMain : System.Windows.Forms.Form
{

Device D3DDevice;
Sprite SpriteDevice;
Texture m_texture;

VertexBuffer m_buffer;

protected void InitGraphics()
{
PresentParameters pres = new PresentParameters ();

pres.Windowed = true;
pres.SwapEffect = SwapEffect.Discard ;
pres.BackBufferCount = 1;
pres.EnableAutoDepthStencil = true;
pres.AutoDepthStencilFormat = DepthFormat.D16;

D3DDevice = new Device(0, DeviceType.Hardware , this, CreateFlags.SoftwareVertexProcessing , pres);
SpriteDevice = new Sprite(D3DDevice);
m_texture = TextureLoader.FromFile(D3DDevice, "icons09.dds");

m_buffer = CreateVertexBuffer(D3DDevice);

}

protected VertexBuffer CreateVertexBuffer (Device device)
{

CustomVertex.TransformedColoredTextured [] verts =
new CustomVertex.TransformedColoredTextured [6];

verts [0] =
new CustomVertex.TransformedColoredTextured (
0 + 64 + 256, 0, 0.1F, 0.1F,
Color.White.ToArgb (),
0.0f, 0.0f);
verts [1] =
new CustomVertex.TransformedColoredTextured (
256 + 64 + 256, 0, 0.1F, 0.1F,
Color.White.ToArgb (),
1.0f, 0.0f);
verts [2] =
new CustomVertex.TransformedColoredTextured (
0 + 64 + 256, 256, 0.1F, 0.1F,
Color.White.ToArgb (),
0.0f, 1.0f);

verts [3] =
new CustomVertex.TransformedColoredTextured (
0 + 64 + 256, 256, 0.1F, 0.1F,
Color.White.ToArgb (),
0.0f, 1.0f);
verts [4] =
new CustomVertex.TransformedColoredTextured (
256 + 64 + 256, 0, 0.1F, 0.1F,
Color.White.ToArgb (),
1.0f, 0.0f);
verts [5] =
new CustomVertex.TransformedColoredTextured (
256 + 64 + 256, 256, 0.1F, 0.1F,
Color.White.ToArgb (),
1.0f, 1.0f);

VertexBuffer buf =
new VertexBuffer (
typeof ( CustomVertex.TransformedColoredTextured ),
verts.Length ,
device,
0,
CustomVertex.TransformedColoredTextured.Format ,
Pool.Default
);

GraphicsStream stm = buf.Lock (0, 0, 0);
stm.Write ( verts );
buf.Unlock ();
return buf ;


}

protected void RenderGraphics()
{

D3DDevice.VertexFormat = CustomVertex.TransformedColoredTextured.Format;

// alpha blending
D3DDevice.RenderState.AlphaTestEnable = true;
D3DDevice.RenderState.ReferenceAlpha = 0x01;
D3DDevice.RenderState.AlphaFunction = Compare.GreaterEqual;

D3DDevice.RenderState.AlphaBlendEnable = true;
D3DDevice.RenderState.AlphaSourceBlend = Blend.SourceAlpha;
D3DDevice.RenderState.AlphaDestinationBlend = Blend.InvSourceAlpha;

D3DDevice.TextureState[0].ColorOperation = TextureOperation.Modulate;
D3DDevice.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
D3DDevice.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;

D3DDevice.TextureState[0].AlphaOperation = TextureOperation.Modulate;
D3DDevice.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
D3DDevice.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse;

D3DDevice.RenderState.ZBufferEnable = true;
D3DDevice.RenderState.ZBufferFunction = Compare.LessEqual;

D3DDevice.BeginScene();
D3DDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.BlueViolet, 1.0f, 0);

D3DDevice.SetTexture(0, m_texture);
D3DDevice.SetStreamSource(0, m_buffer, 0);
D3DDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);

SpriteDevice.Begin();
SpriteDevice.Draw(m_texture, new Rectangle(0, 0, 256, 256), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 0.0f), 0.0f, new Vector2(0.0f, 0.0f), Color.White);
SpriteDevice.End();

D3DDevice.EndScene();
D3DDevice.Present();

}

// Program Entrypoint
static void Main()
{

CMain app = new CMain();

app.Width = 800;
app.Height = 600;

app.InitGraphics();

app.Text = "Managed DirectX Test Sample";
app.Show();

while(app.Created)
{
app.RenderGraphics();
Application.DoEvents();
};


}
}
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
Use srcblend and destblend to affect color, rather than the new dx9 alphasrcblend and alphadestblend which allow a second alternate blending of alpha values.


Genius! - Worked first time!

Cheers bub I've been whacking my head against a wall all evening trying to figure this out!

Share this post


Link to post
Share on other sites
Ok... so after getting that fixed, I'm now trying to make the quad translucent to a value I set when rendering the quad, say... 50% - How would I go about doing this?

Share this post


Link to post
Share on other sites
I suggested a way to do translucency using the vertex diffuse component in this thread. And then at the very bottom, Supernat02 suggested an even easier way. Hopefully either one of them will help.

Share this post


Link to post
Share on other sites
If you're using vertex colors, set the alpha part of the vertex color to the percentage you'd like (255 = 100%, 128 = 50%, etc).

If you're using lighting, you can use Diffuse.a = 0.5f.

If you're not using lighting or vertex colors, you could use D3DRS_TEXTUREFACTOR. If are using vertex colors, but don't want to change them all the time (ie: for a real model), TFACTOR comes in handy, and you can use texture*diffuse*tfactor to blend all three alphas.

In your texture stage states, do something like this:

// mix texture with vertex color or lighting
pDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
pDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);

// Mix texture alpha with vertex or material.diffuse alpha
pDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
pDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
pDev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);

// Terminate at stage 1
pDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

If you're going the TEXTUREFACTOR route, change the AlphaArg1 in stage 0, from D3DTA_DIFFUSE to D3DTA_TFACTOR.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!