using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace TestProgram {
class TestForm : Form {
Mesh mesh1;
Mesh mesh2;
Device device;
public TestForm() {
PresentParameters present;
present = new PresentParameters();
present.Windowed = true;
present.AutoDepthStencilFormat = DepthFormat.D16;
present.EnableAutoDepthStencil = true;
present.SwapEffect = SwapEffect.Discard;
present.MultiSample = MultiSampleType.TwoSamples;
present.BackBufferWidth = 1280;
present.BackBufferHeight = 1024;
present.BackBufferFormat = Format.R5G6B5;
device = new Device(0, DeviceType.Hardware, this,
CreateFlags.HardwareVertexProcessing, present);
device.DeviceReset += new EventHandler(OnDeviceReset);
OnDeviceReset(null, EventArgs.Empty);
mesh1 = Mesh.Box(device, 100.0f, 100.0f, 100.0f);
mesh2 = Mesh.Box(device, 50.0f, 50.0f, 50.0f);
}
private void OnDeviceReset(object sender, EventArgs e) {
device.Transform.Projection = Matrix.PerspectiveFovRH(
(float)Math.PI / 4.0F,
(float)this.ClientSize.Width / (float)this.ClientSize.Height,
0.001f, 1000);
device.Transform.View = Matrix.LookAtRH(new Vector3(90, 0, 300),
new Vector3(0, 0, 0), new Vector3(0, 1, 0));
device.RenderState.Lighting = true;
device.Lights[0].Diffuse = Color.White;
device.Lights[0].Specular = Color.White;
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Direction = new Vector3(-19, -5, -40);
device.Lights[0].Enabled = true;
device.Lights[0].Attenuation0 = 1000.0f;
device.RenderState.CullMode = Cull.None;
device.RenderState.Ambient = System.Drawing.Color.White;
}
protected override void OnPaint(PaintEventArgs e) {
Material material = new Material();
device.BeginScene();
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer,
Color.White, 1.0f, 0);
material.Ambient = Color.FromArgb(255, 0, 0, 255);
material.Diffuse = Color.FromArgb(255, 0, 0, 255);
material.Emissive = Color.FromArgb(255, 0, 0, 255);
material.Specular = Color.FromArgb(255, 0, 0, 255);
device.RenderState.AlphaBlendEnable = false;
device.Material = material;
mesh2.DrawSubset(0);
material.Ambient = Color.FromArgb(30, 255, 0, 0);
material.Diffuse = Color.FromArgb(30, 255, 0, 0);
material.Emissive = Color.FromArgb(30, 255, 0, 0);
material.Specular = Color.FromArgb(30, 255, 0, 0);
device.RenderState.AlphaBlendEnable = true;
device.RenderState.DiffuseMaterialSource = ColorSource.Material;
device.Material = material;
mesh1.DrawSubset(0);
device.EndScene();
device.Present();
}
static void Main() {
Application.Run(new TestForm());
}
}
}
Material alpha blending in managed DirectX
I have the following code:
It must draw transparent red cube and blue cube seen through it.
But I have a following picture:
Where I mistaken?
For one thing, you first draw a solid red cube. Once that's drawn, nothing inside that cube will be rendered.
It sounds like you should render the inside cube first, with alpha=1. Then render the red cube with alpha < 1.
It sounds like you should render the inside cube first, with alpha=1. Then render the red cube with alpha < 1.
After enabling alpha blending you must choose how to blend.
What you're doing is done via:
pDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
This says to multiply the new (src) pixels by the new alpha,
Multiply the old (dest) pixels by (1-new alpha)
Add the results
color = newcolor*newalpha + oldcolor*(1-newalpha);
You may also need to adjust the texture stages to use vertex/material alpha. I'll show using color without texture here)
pDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
pDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
pDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
This sets up a simple single stage which just takes the diffuse color and outputs to the blending stage.
What you're doing is done via:
pDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
This says to multiply the new (src) pixels by the new alpha,
Multiply the old (dest) pixels by (1-new alpha)
Add the results
color = newcolor*newalpha + oldcolor*(1-newalpha);
You may also need to adjust the texture stages to use vertex/material alpha. I'll show using color without texture here)
pDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
pDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
pDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
This sets up a simple single stage which just takes the diffuse color and outputs to the blending stage.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement