Advertisement
mrDIMAS

Deferred Renderer v2

May 14th, 2014
434
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.57 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "Shader.h"
  4.  
  5. class DeferredRenderer
  6. {
  7. private:
  8.   struct QuadVertex
  9.   {
  10.     float x, y, z;
  11.     float tx, ty;
  12.  
  13.     QuadVertex( float ax, float ay, float az, float atx, float aty )
  14.     {
  15.       x = ax;
  16.       y = ay;
  17.       z = az;
  18.  
  19.       tx = atx;
  20.       ty = aty;
  21.     }
  22.   };
  23.  
  24.   IDirect3DTexture9 * depthMap;
  25.   IDirect3DTexture9 * normalMap;
  26.   IDirect3DTexture9 * diffuseMap;
  27.  
  28.   IDirect3DSurface9 * positionSurface;
  29.   IDirect3DSurface9 * normalSurface;
  30.   IDirect3DSurface9 * diffuseSurface;
  31.   IDirect3DSurface9 * backSurface;
  32.  
  33.   VertexShader * vertexShaderPassOne;
  34.   PixelShader * pixelShaderPassOne;
  35.  
  36.   VertexShader * vertexShaderPassTwo;
  37.   PixelShader * pixelShaderPassTwo;
  38.  
  39.   IDirect3DVertexBuffer9 * screenQuad;
  40.   IDirect3DVertexDeclaration9 * vertexDeclaration;
  41.  
  42.   D3DXHANDLE v1World;
  43.   D3DXHANDLE v1Proj;
  44.   D3DXHANDLE v1View;
  45.  
  46.   D3DXHANDLE v2World;
  47.   D3DXHANDLE v2Proj;
  48.   D3DXHANDLE v2View;
  49.  
  50.   D3DXHANDLE p2LightPos;
  51.   D3DXHANDLE p2LightRange;
  52.   D3DXHANDLE p2CameraPos;
  53.   D3DXHANDLE p2InvViewProj;
  54. public:
  55.  
  56.   void CreateScreenQuad()
  57.   {
  58.     g_device->CreateVertexBuffer( 6 * sizeof( QuadVertex ), D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &screenQuad, 0 );
  59.  
  60.     QuadVertex vertices[ ] = { QuadVertex( -0.5, -0.5, 0, 0, 0 ), QuadVertex( g_width - 0.5, 0 - 0.5, 0, 1, 0 ), QuadVertex ( 0 - 0.5, g_height - 0.5, 0, 0, 1 ),
  61.       QuadVertex( g_width - 0.5, 0 - 0.5, 0, 1, 0 ), QuadVertex( g_width - 0.5, g_height - 0.5, 0, 1, 1 ), QuadVertex ( 0 - 0.5, g_height - 0.5, 0, 0, 1 ) };
  62.  
  63.     void * data = 0;
  64.  
  65.     screenQuad->Lock( 0, 0, &data, 0 );
  66.     memcpy( data, vertices, sizeof( QuadVertex ) * 6 );
  67.     screenQuad->Unlock( );
  68.  
  69.     D3DVERTEXELEMENT9 quadVertexDeclation[ ] =
  70.     {
  71.       { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
  72.       { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
  73.       D3DDECL_END()
  74.     };
  75.  
  76.     g_device->CreateVertexDeclaration( quadVertexDeclation, &vertexDeclaration );
  77.   }
  78.  
  79.   void CreateRenderTargets()
  80.   {
  81.     D3DCAPS9 caps;  g_device->GetDeviceCaps( &caps );
  82.  
  83.     if( caps.NumSimultaneousRTs < 4 )
  84.       MessageBoxA( 0, "Your video card does not support MRT.", 0, MB_OK | MB_ICONERROR );
  85.  
  86.     if( FAILED( D3DXCreateTexture( g_device, g_width, g_height, 0, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &depthMap )))
  87.       MessageBoxA( 0, "Failed to create 'Depth Map' texture.", 0, MB_OK | MB_ICONERROR );
  88.     if( FAILED( D3DXCreateTexture( g_device, g_width, g_height, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &normalMap )))
  89.       MessageBoxA( 0, "Failed to create 'Normal Map' texture.", 0, MB_OK | MB_ICONERROR );
  90.     if( FAILED( D3DXCreateTexture( g_device, g_width, g_height, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A8B8G8R8, D3DPOOL_DEFAULT, &diffuseMap )))
  91.       MessageBoxA( 0, "Failed to create 'Diffuse Map' texture.", 0, MB_OK | MB_ICONERROR );
  92.  
  93.     depthMap->GetSurfaceLevel( 0, &positionSurface );
  94.     normalMap->GetSurfaceLevel( 0, &normalSurface );
  95.     diffuseMap->GetSurfaceLevel( 0, &diffuseSurface );
  96.  
  97.     g_device->GetRenderTarget( 0, &backSurface );
  98.   }
  99.  
  100.   void InitPassOneShaders()
  101.   {
  102.     // PASS 1 - Filling the G-Buffer
  103.     string vertexSourcePassOne =
  104.       "float4x4 g_world;\n"
  105.       "float4x4 g_view;\n"
  106.       "float4x4 g_projection;\n"
  107.  
  108.       "struct VS_INPUT {\n"
  109.       "  float4 position : POSITION;\n"
  110.       "  float4 normal   : NORMAL;\n"
  111.       "  float2 texCoord : TEXCOORD0;\n"
  112.       "};\n"
  113.  
  114.       "struct VS_OUTPUT {\n"
  115.       "  float4 position : POSITION;\n"
  116.       "  float4 screenPosition : TEXCOORD0;\n"
  117.       "  float3 normal : TEXCOORD1;\n"
  118.       "  float2 diffuseMapCoord : TEXCOORD2;\n"
  119.       "};\n"
  120.  
  121.       "VS_OUTPUT main(VS_INPUT input) {\n"
  122.       "  VS_OUTPUT output;\n"
  123.       "  float4x4 worldViewProj = mul(mul(g_world, g_view), g_projection);\n"
  124.       "  output.position = mul(input.position, worldViewProj);\n"
  125.       "  output.normal = normalize(mul(input.normal, (float3x3)g_world));\n"
  126.       "  output.screenPosition = output.position;\n"
  127.       "  output.diffuseMapCoord = input.texCoord;\n"
  128.       "  return output;\n"
  129.       "};\n";
  130.  
  131.     vertexShaderPassOne = new VertexShader( vertexSourcePassOne );
  132.  
  133.     v1World = vertexShaderPassOne->GetConstantTable()->GetConstantByName( 0, "g_world" );
  134.     v1Proj = vertexShaderPassOne->GetConstantTable()->GetConstantByName( 0, "g_projection" );
  135.     v1View = vertexShaderPassOne->GetConstantTable()->GetConstantByName( 0, "g_view" );
  136.  
  137.     string pixelSourcePassOne =
  138.  
  139.       "texture diffuseMap;\n"
  140.  
  141.       "sampler diffuseSampler : register(s0) = sampler_state\n"
  142.       "{\n"
  143.       "   texture = <diffuseMap>;\n"
  144.       "};\n"
  145.  
  146.       "struct PS_INPUT {\n"
  147.       "  float4 screenPos : TEXCOORD0;\n"
  148.       "  float3 normal : TEXCOORD1;\n"      
  149.       "  float2 diffuseMapCoord : TEXCOORD2;\n"
  150.       "};\n"
  151.  
  152.       "struct MRT_OUTPUT {\n"
  153.       "  float4 depth : COLOR0;\n"
  154.       "  float4 normal : COLOR1;\n"
  155.       "  float4 diffuseMap : COLOR2;\n"
  156.       "};\n"
  157.  
  158.       "MRT_OUTPUT main( PS_INPUT input )\n"      
  159.       "{\n"
  160.       "   MRT_OUTPUT output;\n"
  161.       "   float3 normal = normalize( input.normal );\n"
  162.       "   float depth = input.screenPos.z / input.screenPos.w;\n"
  163.       "   output.depth = float4( depth, depth, depth, 1.0 );\n"
  164.       "   output.normal = float4( normal.x, normal.y, normal.z, 1.0 );\n"
  165.       "   output.diffuseMap = tex2D( diffuseSampler, input.diffuseMapCoord );\n"
  166.       "   return output;"
  167.       "};\n"
  168.       ;
  169.  
  170.     pixelShaderPassOne = new PixelShader( pixelSourcePassOne );
  171.   }
  172.  
  173.   DeferredRenderer()
  174.   {
  175.     CreateScreenQuad();
  176.     CreateRenderTargets();      
  177.     InitPassOneShaders();
  178.     InitPassTwoShaders();
  179.   }
  180.  
  181.   void InitPassTwoShaders()
  182.   {
  183.     // PASS 2 - Final render
  184.     string vertexSourcePassTwo =
  185.       "float4x4 g_world;\n"
  186.       "float4x4 g_view;\n"
  187.       "float4x4 g_projection;\n"
  188.       "struct VS_INPUT {\n"
  189.       "  float4 position : POSITION;\n"
  190.       "  float3 texcoord : TEXCOORD0;\n"
  191.       "};\n"
  192.  
  193.       "struct VS_OUTPUT {\n"
  194.       "  float4 position : POSITION;\n"
  195.       "  float3 texcoord : TEXCOORD0;\n"
  196.       "};\n"
  197.  
  198.       "VS_OUTPUT main(VS_INPUT input) {\n"
  199.       "  VS_OUTPUT output;\n"
  200.       "  float4x4 worldViewProj = mul(mul(g_world, g_view), g_projection);\n"
  201.       "  output.position   = mul(input.position, worldViewProj);\n"
  202.       "  output.texcoord   = input.texcoord;\n"
  203.       "  return output;\n"
  204.       "};\n";
  205.  
  206.     vertexShaderPassTwo = new VertexShader( vertexSourcePassTwo );
  207.  
  208.     v2World = vertexShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "g_world" );
  209.     v2Proj = vertexShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "g_projection" );
  210.     v2View = vertexShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "g_view" );
  211.  
  212.     string pixelSourcePassTwo =
  213.      
  214.       "texture depthMap;\n"
  215.       "texture normalMap;\n"
  216.       "texture diffuseMap;\n"
  217.  
  218.       "sampler depthSampler : register(s0) = sampler_state\n"
  219.       "{\n"
  220.       "   texture = <depthMap>;\n"
  221.       "};\n"
  222.  
  223.       "sampler normalSampler : register(s1) = sampler_state\n"
  224.       "{\n"
  225.       "   texture = <normalMap>;\n"
  226.       "};\n"    
  227.  
  228.       "sampler diffuseSampler : register(s2) = sampler_state\n"
  229.       "{\n"
  230.       "   texture = <diffuseMap>;\n"
  231.       "};\n"
  232.  
  233.       // light props
  234.       "float3 lightPos;\n"
  235.       "float lightRange;\n"
  236.  
  237.       // camera props
  238.       "float3 cameraPosition;\n"
  239.          
  240.       "float4x4 invViewProj;\n"
  241.       "float4 main( float3 texcoord : TEXCOORD0, float3 worldPos : TEXCOORD1 ) : COLOR0\n"
  242.       "{\n"
  243.  
  244.       "   float4 diffuseTexel = tex2D( diffuseSampler, texcoord.xy );\n"
  245.  
  246.       "   float depth = tex2D( depthSampler, texcoord.xy ).r;\n"
  247.  
  248.       "   float4 screenPosition;\n"
  249.       "   screenPosition.x = texcoord.x * 2.0f - 1.0f;\n"
  250.       "   screenPosition.y = -(texcoord.y * 2.0f - 1.0f);\n"
  251.       "   screenPosition.z = depth;\n"
  252.       "   screenPosition.w = 1.0f;\n"
  253.  
  254.       // Transform position from screen space to world space
  255.       "   float4 p = mul( screenPosition, invViewProj );\n"
  256.       "   p /= p.w;\n"
  257.  
  258.       "   float3 n = tex2D( normalSampler, texcoord.xy ).xyz;\n"
  259.      
  260.       "   float3 lightDirection = lightPos - p;"
  261.       "   float3 l = normalize( lightDirection );\n"
  262.  
  263.       // specular
  264.       "   float3 v = normalize( cameraPosition - p );\n"
  265.       "   float3 r = reflect( -v, n );\n"      
  266.       "   float spec = pow( saturate( dot( l, r ) ), 20.0 );\n"
  267.  
  268.       // diffuse
  269.       "   float diff = saturate(dot( l, n ));\n"
  270.  
  271.       "   float falloff = lightRange / dot( lightDirection, lightDirection );\n"
  272.  
  273.       "   float o = falloff * ( diff + spec );\n"
  274.  
  275.       "   return float4( diffuseTexel.x * o, diffuseTexel.y * o, diffuseTexel.z * o, diffuseTexel.w );\n"
  276.       "};\n";
  277.  
  278.  
  279.     pixelShaderPassTwo = new PixelShader( pixelSourcePassTwo );
  280.  
  281.     p2LightPos = pixelShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "lightPos" );
  282.     p2LightRange = pixelShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "lightRange" );
  283.     p2CameraPos = pixelShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "cameraPosition" );
  284.     p2InvViewProj  = pixelShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "invViewProj" );
  285.   }
  286.  
  287.   ~DeferredRenderer()
  288.   {
  289.     if( depthMap )
  290.       depthMap->Release();
  291.     if( normalMap )
  292.       normalMap->Release();
  293.     if( diffuseMap )
  294.       diffuseMap->Release();
  295.  
  296.     if( positionSurface )
  297.       positionSurface->Release();
  298.     if( normalSurface )
  299.       normalSurface->Release();
  300.     if( diffuseSurface )
  301.       diffuseSurface->Release();
  302.   }
  303.  
  304.   void Begin()
  305.   {
  306.     g_device->SetRenderTarget( 0, positionSurface );
  307.     g_device->SetRenderTarget( 1, normalSurface );
  308.     g_device->SetRenderTarget( 2, diffuseSurface );
  309.  
  310.     g_device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB( 0, 0, 0 ), 1.0, 0 );
  311.     g_device->BeginScene( );
  312.  
  313.     vertexShaderPassOne->Bind();
  314.     pixelShaderPassOne->Bind();
  315.  
  316.     g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE );
  317.   }
  318.  
  319.   void RenderMesh( Mesh * mesh )
  320.   {
  321.     g_device->SetStreamSource( 0, mesh->vb, 0, sizeof( Vertex ));
  322.     g_device->SetIndices( mesh->ib );
  323.  
  324.     D3DXMATRIX view; g_device->GetTransform( D3DTS_VIEW, &view );
  325.     D3DXMATRIX proj; g_device->GetTransform( D3DTS_PROJECTION, &proj );
  326.     D3DXMATRIX world; GetD3DMatrixFromBulletTransform( mesh->parent->globalTransform, world );
  327.  
  328.     vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1View, &view );
  329.     vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1Proj, &proj );  
  330.     vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1World, &world );
  331.  
  332.     g_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, mesh->vertexCount, 0, mesh->faceCount );
  333.   }
  334.  
  335.   void End()
  336.   {
  337.     g_device->EndScene();
  338.  
  339.     g_device->SetRenderTarget( 0, backSurface );
  340.     g_device->SetRenderTarget( 1, 0 );
  341.     g_device->SetRenderTarget( 2, 0 );
  342.  
  343.     g_device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB( 0, 0, 0 ), 1.0, 0 );
  344.     g_device->BeginScene( );
  345.  
  346.     g_device->SetVertexDeclaration( vertexDeclaration );
  347.  
  348.     vertexShaderPassTwo->Bind();
  349.     pixelShaderPassTwo->Bind();
  350.  
  351.     g_device->SetRenderState( D3DRS_LIGHTING, FALSE );
  352.     g_device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  353.  
  354.     D3DXMATRIX ortho; D3DXMatrixOrthoOffCenterLH ( &ortho, 0, g_width, g_height, 0, 0, 1024 );
  355.     D3DXMATRIX identity; D3DXMatrixIdentity( &identity );
  356.  
  357.     vertexShaderPassTwo->GetConstantTable()->SetMatrix( g_device, v2World, &identity );
  358.     vertexShaderPassTwo->GetConstantTable()->SetMatrix( g_device, v2View, &identity );
  359.     vertexShaderPassTwo->GetConstantTable()->SetMatrix( g_device, v2Proj, &ortho );
  360.  
  361.     g_device->SetTexture( 0, depthMap );
  362.     g_device->SetTexture( 1, normalMap );
  363.     g_device->SetTexture( 2, diffuseMap );
  364.  
  365.     g_device->SetStreamSource( 0, screenQuad, 0, sizeof( QuadVertex ));
  366.  
  367.     g_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE );
  368.  
  369.     g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
  370.     g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE );
  371.     g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  372.  
  373.     float temp[ 3 ];
  374.  
  375.     btVector3 lightPos = g_camera->base->globalTransform.getOrigin();
  376.  
  377.     temp[ 0 ] = lightPos.x();
  378.     temp[ 1 ] = lightPos.y();
  379.     temp[ 2 ] = lightPos.z();
  380.  
  381.     pixelShaderPassTwo->GetConstantTable()->SetFloatArray( g_device, p2CameraPos, temp, 3 );
  382.  
  383.     D3DXMATRIX view; g_device->GetTransform( D3DTS_VIEW, &view );
  384.     D3DXMATRIX proj; g_device->GetTransform( D3DTS_PROJECTION, &proj );
  385.  
  386.     D3DXMATRIX viewProj;
  387.     D3DXMatrixMultiply( &viewProj, &view, &proj );
  388.  
  389.     D3DXMATRIX invViewProj;
  390.     D3DXMatrixInverse( &invViewProj, 0, &viewProj );
  391.  
  392.     pixelShaderPassTwo->GetConstantTable()->SetMatrix( g_device, p2InvViewProj, &invViewProj );
  393.  
  394.     for( int i = 0; i < g_lights.size(); i++ )
  395.     {
  396.       Light * light = g_lights.at( i );      
  397.  
  398.       btVector3 lightPos = light->base->globalTransform.getOrigin();
  399.  
  400.       temp[ 0 ] = lightPos.x();
  401.       temp[ 1 ] = lightPos.y();
  402.       temp[ 2 ] = lightPos.z();
  403.  
  404.       pixelShaderPassTwo->GetConstantTable()->SetFloatArray( g_device, p2LightPos, temp, 3 );
  405.       pixelShaderPassTwo->GetConstantTable()->SetFloat( g_device, p2LightRange, light->radius );
  406.  
  407.  
  408.       g_device->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
  409.     }    
  410.    
  411.     g_device->SetTexture( 0, 0 );
  412.     g_device->SetTexture( 1, 0 );
  413.     g_device->SetTexture( 2, 0 );
  414.   }
  415. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement