topical media & game development
Here's the render loop from my code, that uses post processing:
class SceneManager ... {
GraphicsDeviceManager graphics_;
GraphicsDevice dev_;
RenderTarget2D renderTarget_;
VertexBuffer screenQuadVb_;
VertexDeclaration screenQuadVdecl_;
struct ScreenQuadVertex
{
public Vector3 pos;
public Vector2 uv;
};
Effect presentEffect_;
EffectParameter presentEffectAmount_;
EffectParameter presentEffectTexture_;
ContentManager content_;
public void LoadGraphicsContent(bool loadAllContent)
{
VertexElement[] ve = new VertexElement[2];
if (loadAllContent)
{
screenWidth_ = dev_.PresentationParameters.BackBufferWidth;
screenHeight_ = dev_.PresentationParameters.BackBufferHeight;
screenQuadVb_ = new VertexBuffer(dev_, 20 * 6, ResourceUsage.WriteOnly,
ResourceManagementMode.Manual);
ScreenQuadVertex[] data = new ScreenQuadVertexDevil;
data[0].pos = new Vector3(-1, -1, 0);
data[0].uv = new Vector2(0, 1);
data[1].pos = new Vector3(-1, 1, 0);
data[1].uv = new Vector2(0, 0);
data[2].pos = new Vector3(1, 1, 0);
data[2].uv = new Vector2(1, 0);
data[3].pos = new Vector3(1, -1, 0);
data[3].uv = new Vector2(1, 1);
data[4] = data[0];
data[5] = data[2];
screenQuadVb_.SetData(data);
ve[0].Offset = 0;
ve[0].VertexElementFormat = VertexElementFormat.Vector3;
ve[0].VertexElementUsage = VertexElementUsage.Position;
ve[1].Offset = 12;
ve[1].VertexElementFormat = VertexElementFormat.Vector2;
ve[1].VertexElementUsage = VertexElementUsage.TextureCoordinate;
screenQuadVdecl_ = new VertexDeclaration(dev_, ve);
presentEffect_ = content_.Load("content\\present");
presentEffectAmount_ = presentEffect_.Parameters["Amount"];
presentEffectTexture_ = presentEffect_.Parameters["g_MeshTexture"];
}
renderTarget_ = new RenderTarget2D(dev_, (int)screenWidth_, (int)screenHeight_, 1, SurfaceFormat.Bgr32);
}
public void Draw(GameTime gameTime)
{
RenderTarget oldTarget = dev_.GetRenderTarget(0);
dev_.SetRenderTarget(0, renderTarget_);
try
{
... render scene here ...
dev_.ResolveRenderTarget(0);
}
finally
{
dev_.SetRenderTarget(0, oldTarget as RenderTarget2D);
}
presentEffectAmount_.SetValue(grayscaleAmount_);
Texture2D tex = renderTarget_.GetTexture();
presentEffectTexture_.SetValue(tex);
dev_.Vertices[0].SetSource(screenQuadVb_, 0, 20);
dev_.VertexDeclaration = screenQuadVdecl_;
presentEffect_.Begin(SaveStateMode.None);
foreach (EffectPass ep in presentEffect_.CurrentTechnique.Passes)
{
ep.Begin();
dev_.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
ep.End();
}
presentEffect_.End();
}
...
}
I use this effect to render the 3D world in black-and-white when the game is paused. The actual effect looks as follows:
texture g_MeshTexture : DiffuseMap<
string UIName = "Diffuse Texture";
>; // Color texture for mesh
float Amount = 0.5;
sampler MeshTextureSampler =
sampler_state
{
Texture = ;
MipFilter = POINT;
MinFilter = POINT;
MagFilter = POINT;
};
struct VS_OUTPUT
{
float4 Position : POSITION; // vertex position
float2 TextureUV : TEXCOORD0; // vertex texture coords
float Fog : FOG;
};
VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
float2 vTexCoord0 : TEXCOORD0
)
{
VS_OUTPUT Output;
// Transform the position from object space to homogeneous projection space
Output.Position = vPos;
// Just copy the texture coordinate through
Output.TextureUV = vTexCoord0;
Output.Fog = 1;
return Output;
}
struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};
PS_OUTPUT RenderScenePS( VS_OUTPUT In )
{
PS_OUTPUT Output;
float4 rgba = tex2D(MeshTextureSampler, In.TextureUV);
float v = dot(rgba.rgb, float3(0.3,0.5,0.2));
Output.RGBColor = float4(lerp(rgba.rgb, float3(v, v, v), Amount), 1);
return Output;
}
technique RenderScene
{
pass P0
{
AlphaBlendEnable = false;
ZEnable = false;
CullMode = None;
FogVertexMode = NONE;
VertexShader = compile vs_2_0 RenderSceneVS();
PixelShader = compile ps_2_0 RenderScenePS();
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.