mrDIMAS

Untitled

May 18th, 2014
421
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.85 KB | None | 0 0
  1. #include "ParticleSystemRenderer.h"
  2. #include "DeferredRenderer.h"
  3.  
  4. ParticleSystemRenderer * g_particleSystemRenderer = 0;
  5.  
  6. ParticleSystemRenderer::ParticleSystemRenderer()
  7. {
  8.   string vertexSource =
  9.     "float4x4 g_world;\n"
  10.     "float4x4 g_view;\n"
  11.     "float4x4 g_projection;\n"
  12.     "struct VS_INPUT {\n"
  13.     "  float4 position : POSITION;\n"
  14.     "  float2 texcoord : TEXCOORD0;\n"
  15.     "  float4 color : COLOR0;\n"
  16.     "};\n"
  17.  
  18.     "struct VS_OUTPUT {\n"
  19.     "  float4 position : POSITION;\n"
  20.     "  float2 texcoord : TEXCOORD0;\n"
  21.     "  float4 color : TEXCOORD1;\n"
  22.     "  float3 worldPos : TEXCOORD2;\n"
  23.     "  float4 viewPos : TEXCOORD3;\n"
  24.     "};\n"
  25.  
  26.     "VS_OUTPUT main(VS_INPUT input) {\n"
  27.     "  VS_OUTPUT output;\n"
  28.     "  float4x4 worldViewProj = mul(mul(g_world, g_view), g_projection);\n"
  29.     "  output.position = mul(input.position, worldViewProj);\n"
  30.     "  output.texcoord = input.texcoord;\n"
  31.     "  output.color = input.color;\n"
  32.     "  output.worldPos = mul(input.position, g_world );\n"
  33.     "  output.viewPos = output.position;\n"
  34.     "  return output;\n"
  35.     "};\n";
  36.  
  37.   vertexShader = new VertexShader( vertexSource );
  38.  
  39.   vView = vertexShader->GetConstantTable()->GetConstantByName( 0, "g_view" );
  40.   vProj = vertexShader->GetConstantTable()->GetConstantByName( 0, "g_projection" );
  41.   vWorld = vertexShader->GetConstantTable()->GetConstantByName( 0, "g_world" );
  42.  
  43.   string pixelSource =
  44.     "texture g_diffuseTexture ;\n"
  45.  
  46.     "sampler texsampler : register( s0 ) = sampler_state {\n"
  47.     "  Texture = <g_diffuseTexture>;\n"
  48.     "};\n"
  49.  
  50.     "texture g_depthTexture ;\n"
  51.  
  52.     "sampler depthSampler : register( s1 ) = sampler_state {\n"
  53.     "  Texture = <g_depthTexture>;\n"
  54.     "};\n"
  55.  
  56.     "struct PS_INPUT {\n"
  57.     "  float2 texcoord : TEXCOORD0;\n"
  58.     "  float4 color : TEXCOORD1;\n"
  59.     "  float3 worldPos : TEXCOORD2;\n"
  60.     "  float4 viewPos : TEXCOORD3;\n"
  61.     "};\n"
  62.  
  63.     "#define MAX_LIGHTS 5\n"
  64.  
  65.     "float3 lightDiffuseColor[ MAX_LIGHTS ];\n"
  66.     "float3 lightPosition[ MAX_LIGHTS ];\n"
  67.     "float  lightRange[ MAX_LIGHTS ];\n"
  68.  
  69.     "int litNum = 0;\n"
  70.     "int withLight = 0;\n"
  71.  
  72.     "float4x4 invViewProj;\n"
  73.  
  74.     "float4 main(PS_INPUT input) : COLOR0\n"
  75.     "{\n"
  76.  
  77.     "  input.viewPos /= input.viewPos.w;\n"
  78.     "  float2 depthCoord = float2( input.viewPos.x  * 0.5 + 0.5, -input.viewPos.y * 0.5 + 0.5);\n"
  79.    
  80.     // diffuse color is product of texture diffuse color and color
  81.     "  float4 diffuse = tex2D( texsampler, input.texcoord ) * input.color;\n"
  82.  
  83.     // get depth from depth map
  84.     "  float depth = tex2D( depthSampler, depthCoord ).r;\n"
  85.     // restore position from depth
  86.     "  float4 screenPosition;\n"
  87.     "  screenPosition.x = depthCoord.x * 2.0f - 1.0f;\n"
  88.     "  screenPosition.y = -(depthCoord.y * 2.0f - 1.0f);\n"
  89.     "  screenPosition.z = depth;\n"
  90.     "  screenPosition.w = 1.0f;\n"
  91.  
  92.     "  float4 p = mul( screenPosition, invViewProj );\n"
  93.     "  p /= p.w;\n"
  94.  
  95.     "  float4 output = float4( 1, 1, 1, 1 );\n"
  96.    
  97.     // do simple lighting if it's needed
  98.     "  if( withLight )\n"
  99.     "  {\n"
  100.  
  101.     "    output = float4( 0, 0, 0, 0 );\n"
  102.  
  103.     "    for( int i = 0; i < litNum; i++ )\n"
  104.     "    {\n"
  105.     "      float3 lightDir = lightPosition[ i ] - input.worldPos;\n"
  106.     "      output += float4( (lightDiffuseColor[ i ] * ( lightRange[ i ] / dot(lightDir, lightDir )) ).xyz, 0 );\n"
  107.     "    }\n"
  108.  
  109.     "    output.w = 1.0;\n"
  110.  
  111.     "  }\n"
  112.  
  113.     "  output *= diffuse;"
  114.  
  115.     "  output.a *= saturate( 0.05 * distance( p.xyz, input.worldPos ) );\n"
  116.  
  117.     "  return output ;"
  118.     "};\n";
  119.  
  120.   pixelShader = new PixelShader( pixelSource );
  121.  
  122.   pColor = pixelShader->GetConstantTable()->GetConstantByName( 0, "lightDiffuseColor" );
  123.   pRange = pixelShader->GetConstantTable()->GetConstantByName( 0, "lightRange" );
  124.   pPosition = pixelShader->GetConstantTable()->GetConstantByName( 0, "lightPosition" );
  125.   pLightCount = pixelShader->GetConstantTable()->GetConstantByName( 0, "litNum" );
  126.   pWithLight = pixelShader->GetConstantTable()->GetConstantByName( 0, "withLight" );  
  127.   pInvViewProj = pixelShader->GetConstantTable()->GetConstantByName( 0, "invViewProj" );  
  128.  
  129.   D3DVERTEXELEMENT9 vdElem[ ] =
  130.   {
  131.     { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
  132.     { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
  133.     { 0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
  134.     D3DDECL_END()
  135.   };
  136.  
  137.   g_device->CreateVertexDeclaration( vdElem, &vd );
  138. }
  139.  
  140. ParticleSystemRenderer::~ParticleSystemRenderer()
  141. {
  142.   delete vertexShader;
  143.   delete pixelShader;
  144.  
  145.   vd->Release();
  146. }
  147.  
  148. void ParticleSystemRenderer::Render()
  149. {
  150.   IDirect3DStateBlock9 * state;
  151.   g_device->CreateStateBlock( D3DSBT_ALL, &state );
  152.  
  153.   vertexShader->Bind();
  154.   pixelShader->Bind();
  155.   g_device->SetVertexDeclaration( vd );
  156.  
  157.   g_device->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE,  D3DMCS_COLOR1 );
  158.  
  159.   g_device->SetRenderState ( D3DRS_ALPHATESTENABLE, FALSE );  
  160.  
  161.   g_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  162.   g_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
  163.   g_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );  
  164.  
  165.   g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
  166.   g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  167.   g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  168.   g_device->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD);
  169.  
  170.   g_device->SetRenderState(D3DRS_ZENABLE, TRUE );
  171.   g_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE );
  172.  
  173.   g_device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  174.  
  175.   vertexShader->GetConstantTable()->SetMatrix( g_device, vView, &g_camera->view );
  176.   vertexShader->GetConstantTable()->SetMatrix( g_device, vProj, &g_camera->projection );
  177.  
  178.   g_device->SetTexture( 1, g_deferredRenderer->depthMap );
  179.  
  180.   D3DXMATRIX viewProj;
  181.   D3DXMatrixMultiply( &viewProj, &g_camera->view, &g_camera->projection );
  182.  
  183.   D3DXMATRIX invViewProj;
  184.   D3DXMatrixInverse( &invViewProj, 0, &viewProj );
  185.  
  186.   pixelShader->GetConstantTable()->SetMatrix( g_device, pInvViewProj, &invViewProj );
  187.  
  188.   for( auto it = g_particleSystems.begin(); it != g_particleSystems.end(); ++it )
  189.   {
  190.     ParticleSystem * ps = *it;
  191.  
  192.     if( !ps->base->visible )
  193.       continue;
  194.  
  195.     if( !ps->enabled )
  196.       continue;
  197.  
  198.     g_device->SetTexture( 0, ps->tex->texture );
  199.  
  200.     UpdateParticleSystem( ps );
  201.  
  202.     g_device->SetStreamSource( 0, ps->vb, 0, sizeof( ParticleVertex ));
  203.  
  204.     if( ps->aliveParticles )
  205.     {
  206.       g_device->SetIndices( ps->ib );
  207.  
  208.       D3DXMATRIX world; g_device->GetTransform( D3DTS_WORLD, &world );
  209.  
  210.       vertexShader->GetConstantTable()->SetMatrix( g_device, vWorld, &world );
  211.  
  212.       if( ps->lightingEnabled )
  213.       {
  214.         vertexShader->GetConstantTable()->SetInt( g_device, pWithLight, 1 );
  215.  
  216.         int lightPerPass = 5;
  217.         int passCount = 1;//ceil( (float)g_lights.size() / (float)lightPerPass );
  218.  
  219.         int cnt = 0;
  220.  
  221.         vector< Light*> affectedLights;
  222.  
  223.         // draw mesh with each light
  224.         for( size_t j = 0; j < g_lights.size(); j++ )
  225.         {
  226.           Light * light = g_lights.at( j );    
  227.  
  228.           if( !NodeVisible( light->base ) )
  229.             continue;
  230.  
  231.           if( light->radius < 0.1 )
  232.             continue;
  233.  
  234.           affectedLights.push_back( light );
  235.         }
  236.  
  237.         for( int passNum = 0; passNum < passCount; passNum++ )
  238.         {
  239.           cnt = affectedLights.size() > (size_t)lightPerPass ? lightPerPass : affectedLights.size();
  240.  
  241.           vertexShader->GetConstantTable()->SetInt( g_device, pLightCount, cnt );      
  242.  
  243.           for( size_t j = 0; j < (size_t)cnt; j++ )
  244.           {
  245.             Light * lit = affectedLights.at( j );
  246.  
  247.             D3DXHANDLE nPos = pixelShader->GetConstantTable()->GetConstantElement( pPosition, j );
  248.             pixelShader->GetConstantTable()->SetFloatArray( g_device, nPos, lit->base->globalTransform.getOrigin().m_floats, 3 );
  249.  
  250.             pixelShader->GetConstantTable()->SetFloatArray( g_device, pixelShader->GetConstantTable()->GetConstantElement( pColor, j ), lit->color.elements, 3 );
  251.  
  252.             pixelShader->GetConstantTable()->SetFloat( g_device, pixelShader->GetConstantTable()->GetConstantElement( pRange, j ), lit->radius );
  253.           }
  254.  
  255.           g_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, ps->aliveParticles * 4, 0, ps->aliveParticles * 2 );    
  256.  
  257.           for( size_t j = 0; j < (size_t)cnt; j++ )
  258.           {
  259.             affectedLights.erase( affectedLights.begin() );
  260.           }
  261.         }
  262.       }
  263.       else
  264.       {
  265.         vertexShader->GetConstantTable()->SetInt( g_device, pWithLight, 0 );
  266.  
  267.         g_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, ps->aliveParticles * 4, 0, ps->aliveParticles * 2 );
  268.       }      
  269.     }
  270.   }
  271.  
  272.   state->Apply();
  273.   state->Release();
  274. }
Add Comment
Please, Sign In to add comment