topical media & game development

talk show tell print


  
  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.