// デフォルトコンストラクタ Light::Light() { // ライトの設定 ZeroMemory(&light, sizeof(D3DLIGHT9)); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 1.0f; light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; light.Ambient.r = 1.0f; light.Ambient.g = 1.0f; light.Ambient.b = 1.0f; light.Specular.r = 1.0f; light.Specular.g = 1.0f; light.Specular.b = 1.0f; D3DXVECTOR3 lightAngle; lightAngle = D3DXVECTOR3(1.0f, -1.0f, 1.0f); D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &lightAngle); d3dDevice->SetLight(0, &light); d3dDevice->LightEnable(0, true); d3dDevice->SetRenderState(D3DRS_LIGHTING, true); d3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00111111); d3dDevice->SetRenderState(D3DRS_SPECULARENABLE, true); // 霧の発生 d3dDevice->SetRenderState(D3DRS_FOGENABLE, true); d3dDevice->SetRenderState(D3DRS_FOGCOLOR, 0xff000033); d3dDevice->SetRenderState(D3DRS_FOGSTART, FtoDW(100.0f)); d3dDevice->SetRenderState(D3DRS_FOGEND, FtoDW(315.0f)); d3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); }
HRESULT KG3DEnvEffFog::Apply() { if (!m_bEnableBlending) { m_DescStruct.ToKey(&m_curKey); } else { ///<DW_Frame> KG3DDWGC_Key_Fog BeforeKey; m_DescStruct.ToKey(&BeforeKey); m_curKey.CalculateInterp(BeforeKey, m_SubKey, m_fBlendPercent); } //外部请求全权控制Fog,内部就不做事 KG_PROCESS_SUCCESS(m_bIsUnderFullControl); g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, m_DescStruct.m_bFogEnable); FLOAT fFogEndUse = CalFogEnd(m_curKey.m_fFogEndValue, m_fDistancePercent); g_pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, m_curKey.m_FogColor); g_pd3dDevice->SetRenderState(D3DRS_FOGSTART, FtoDW(m_curKey.m_fFogStartValue)); g_pd3dDevice->SetRenderState(D3DRS_FOGEND, FtoDW(fFogEndUse)); g_pd3dDevice->SetRenderState(D3DRS_FOGDENSITY, FtoDW(m_DescStruct.m_fFogDensity)); if (m_DescStruct.m_bUsingTableFog) { g_pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); g_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, m_DescStruct.m_nFogMode); ///W_FOG是自动的 } else { g_pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); g_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, m_DescStruct.m_nFogMode); g_pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, m_DescStruct.m_bRangeBasedFog); } Exit1: return S_OK; }
void CKind::EnablePointSprites( int level) { // turn off lighting m_dev->SetRenderState( D3DRS_LIGHTING, false); m_dev->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); //m_dev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); //m_dev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); //Set up the render states for using point sprites... m_dev->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE ); // Turn on point sprites m_dev->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE ); // Allow sprites to be scaled with distance this->SetPSSize( level); m_dev->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(1.2f) ); // Float value that specifies the minimum size of point primitives. Point primitives are clamped to this size during rendering. m_dev->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(1.0f) ); // Default 1.0 m_dev->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.0f) ); // Default 0.0 m_dev->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(1.0f) ); // Default 0.0 }
// virtual function // this is pretty much a default implementation for rendering void ParticleSystem::render() { // Enable point sprites, and set the size of the point. renderTarget_ -> SetRenderState(D3DRS_POINTSPRITEENABLE, true); renderTarget_ -> SetRenderState(D3DRS_POINTSCALEENABLE, true); // Disable z buffer while rendering the particles. Makes rendering quicker and // stops any visual (alpha) 'artefacts' on screen while rendering. renderTarget_ -> SetRenderState(D3DRS_ZENABLE, false); // Scale the points according to distance... renderTarget_ -> SetRenderState(D3DRS_POINTSIZE, FtoDW(maxParticleSize_)); renderTarget_ -> SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(0.00f)); renderTarget_ -> SetRenderState(D3DRS_POINTSCALE_A, FtoDW(0.00f)); renderTarget_ -> SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.00f)); renderTarget_ -> SetRenderState(D3DRS_POINTSCALE_C, FtoDW(1.00f)); // Now select the texture for the points... // Use texture colour and alpha components. renderTarget_ -> SetTexture(0, particleTexture_); renderTarget_ -> SetRenderState(D3DRS_ALPHABLENDENABLE, true); renderTarget_ -> SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); renderTarget_ -> SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); renderTarget_ -> SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); renderTarget_ -> SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); renderTarget_ -> SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); renderTarget_ -> SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); // Render the contents of the vertex buffer. renderTarget_ -> SetStreamSource(0, points_, 0, sizeof(POINTVERTEX)); renderTarget_ -> SetFVF(D3DFVF_POINTVERTEX); renderTarget_ -> DrawPrimitive(D3DPT_POINTLIST, 0, particlesAlive_); // Reset the render states. renderTarget_ -> SetRenderState(D3DRS_POINTSPRITEENABLE, false); renderTarget_ -> SetRenderState(D3DRS_POINTSCALEENABLE, false); renderTarget_ -> SetRenderState(D3DRS_ALPHABLENDENABLE, false); renderTarget_ -> SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); renderTarget_ -> SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); }
void r1_dx9_class::set_fogging_mode(w32 fogcolor, i4_float startvalue, i4_float endvalue) { //doesn't work yet. Perhaps only sensefull on dx8. //currently just shows the entire scene in fogcolor. m_dwFogColor=fogcolor; m_fFogStartValue=startvalue; m_fFogEndValue=endvalue; if (fogcolor==0x0) { d3d_device->SetRenderState(D3DRS_FOGENABLE,FALSE); return; } D3DMATRIX matrix1; //let's keep that one just in case. ZeroMemory(&matrix1,sizeof(matrix1)); matrix1._11=1.0f; //ok... widht is..what is the near/far plane? matrix1._22=1.0f; //the near plane is 0.0(0?)1 and the far plane is 100 matrix1._33=1.0f; //the width is 2*g1_render.center_x, the height 2*g1_render.center_y matrix1._43=4.0f; //should be a + number....from my tests matrix1._34=1.0f; //but msdn says this is positive, //43 might be negative... in the mcfog i send you negative doesn't work //ok, what do you suggest? +1? I've tried this, too. //i used a 4*_33 value so in this case 4 but firts try witthout a table... //compile now //the 11 and 22 are aspect ratio modifiers...so 1 1 is ok.... //but i sugest we try on the smaller exampole()fog test( it takes less time to see the modifications //ok, if it behaves as golg does... d3d_device->SetTransform(D3DTS_PROJECTION,&matrix1); d3d_device->SetRenderState( D3DRS_FOGENABLE, TRUE ); d3d_device->SetRenderState( D3DRS_FOGCOLOR, m_dwFogColor ); d3d_device->SetRenderState( D3DRS_FOGVERTEXMODE, m_dwFogMode ); d3d_device->SetRenderState( D3DRS_RANGEFOGENABLE, FALSE); //d3d_device->SetRenderState( D3DRS_FOGTABLEMODE, m_dwFogMode ); d3d_device->SetRenderState( D3DRS_FOGSTART, FtoDW(m_fFogStartValue) ); d3d_device->SetRenderState( D3DRS_FOGEND, FtoDW(m_fFogEndValue) ); d3d_device->SetRenderState( D3DRS_FOGDENSITY, FtoDW(m_fFogDensity) ); }
void Render(float timeDelta) { if (!g_bActive) { Sleep(50) ; } SetupMatrix() ; // Clear the back-buffer to a RED color g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); // Begin the scene if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { // Render state g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); g_pd3dDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE) ; g_pd3dDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE) ; g_pd3dDevice->SetRenderState( D3DRS_POINTSIZE, FtoDW(0.2f) ); // Set texture g_pd3dDevice->SetTexture(0, g_pTexture) ; // Draw points g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(POINTVERTEX)); g_pd3dDevice->SetFVF(D3DFVF_POINTVERTEX) ; g_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, NUM_VERTEX) ; // Restore state g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); // End the scene g_pd3dDevice->EndScene(); } // Present the back-buffer contents to the display g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); }
HRESULT CSnowDropper::Render () { m_D3DRender ->SetVertexShader ( GTH_SNOW_FORMAT ); m_D3DRender ->SetStreamSource ( 0, m_VB.GetD3DVertexBuffer (), sizeof (SNOWVERTEX) ); m_D3DRender ->SetTexture ( 0, g_texMng.GetD3DTexture( m_snowShaderRef ) ); LPDIRECT3DDEVICE8 pd3dDevice = g_d3dDevice.GetD3DDevice(); pd3dDevice ->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); pd3dDevice ->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); pd3dDevice ->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); pd3dDevice ->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); pd3dDevice ->SetRenderState ( D3DRS_ZWRITEENABLE, FALSE ); pd3dDevice ->SetRenderState ( D3DRS_ALPHABLENDENABLE, TRUE ); pd3dDevice ->SetRenderState ( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); pd3dDevice ->SetRenderState ( D3DRS_DESTBLEND, D3DBLEND_DESTALPHA ); pd3dDevice ->SetRenderState ( D3DRS_POINTSIZE, FtoDW(5.0f) ); pd3dDevice ->SetRenderState ( D3DRS_POINTSPRITEENABLE, true ); pd3dDevice ->SetRenderState ( D3DRS_POINTSCALEENABLE, true ); pd3dDevice ->SetRenderState ( D3DRS_POINTSIZE_MIN, FtoDW(0.0f) ); pd3dDevice ->SetRenderState ( D3DRS_POINTSIZE_MAX, FtoDW(500.0f) ); pd3dDevice ->SetRenderState ( D3DRS_POINTSCALE_A, FtoDW(0.00f) ); pd3dDevice ->SetRenderState ( D3DRS_POINTSCALE_B, FtoDW(0.00f) ); pd3dDevice ->SetRenderState ( D3DRS_POINTSCALE_C, FtoDW(1.00f) ); pd3dDevice ->SetTransform ( D3DTS_WORLD, &m_matWorld ); pd3dDevice ->DrawPrimitive ( D3DPT_POINTLIST, m_VB.GetBase (), m_drawCount ); pd3dDevice ->SetRenderState ( D3DRS_POINTSPRITEENABLE, false ); pd3dDevice ->SetRenderState ( D3DRS_POINTSCALEENABLE, false ); return S_OK; }
void ifs_render(float t) { if(ifs_loaded!=(int)(ifs_number)) ifs_load((int)ifs_number); // if(ifs_loaded!=(int)(angles[254])) ifs_load((int)angles[254]); g_pd3dDevice->BeginScene(); // g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0xff000000, 1.0f, 0L ); ifs_clear(); g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); g_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS); // render_bg(g_pd3dDevice, bg); D3DXMATRIX matWorld; D3DXMatrixIdentity( &matWorld ); // D3DXMatrixScaling(&matWorld, ifs_z,ifs_z,ifs_z); g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); // Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction. D3DXMATRIX matView; D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 0.0f,-3.0f+ifs_z), &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) ); g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered). D3DXMATRIX matProj; //D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); D3DXMatrixPerspectiveFovLH( &matProj, 1, 4.f/3.f, 0.1f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); g_pd3dDevice->SetTexture(3, m_pParticleTexture ); int alpha=(int)(255*fade); m_pd3dDevice->SetRenderState( D3DRS_TEXTUREFACTOR, 0x01010101*(alpha)); m_pd3dDevice->SetTextureStageState( 3, D3DTSS_TEXCOORDINDEX, 0); m_pd3dDevice->SetTextureStageState( 3, D3DTSS_COLOROP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 3, D3DTSS_COLORARG2, D3DTA_CURRENT); m_pd3dDevice->SetTextureStageState( 3, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 3, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 3, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); m_pd3dDevice->SetTextureStageState( 3, D3DTSS_ALPHAARG1, D3DTA_CURRENT ); // Set the render states for using point sprites g_pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE); g_pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE ); g_pd3dDevice->SetRenderState( D3DRS_POINTSIZE, FtoDW(8.0f) ); g_pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.01f) ); g_pd3dDevice->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(0.00f) ); g_pd3dDevice->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.00f) ); g_pd3dDevice->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(1.00f) ); // Set up the vertex buffer to be rendered // pd3dDevice->SetStreamSource( 0, ifs_vb, 0, sizeof(POINTVERTEX) ); g_pd3dDevice->SetVertexShader( D3DFVF_XYZ | D3DFVF_DIFFUSE ); /* g_pd3dDevice->SetRenderState (D3DRS_POINTSCALEENABLE, FALSE); // All textures must be turned off. g_pd3dDevice->SetTexture (0, NULL); g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); // The point size render state must be set to any value between 0.0-1.0 g_pd3dDevice->SetRenderState(D3DRS_POINTSIZE, 1.0); */ g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); // Turn off culling g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); // Turn off D3D lighting g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); // printf("%4.2f\n", t); g_anim.time = fmodf(t, g_anim.getEndTime()); g_anim.renderFlame(); g_pd3dDevice->SetTexture(3, NULL); g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); g_pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE); g_pd3dDevice->EndScene(); // g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); }
/************************************************************************ * desc: Buffers and render states that need to be * reset/recreated after a device rest ************************************************************************/ void CXDevice::ResetXDevice() { HRESULT hresult; postProcBufIndex = 0; // Grab the surface of the display buffer if( FAILED( hresult = spDXDevice->GetRenderTarget( 0, &spDisplaySurface ) ) ) DisplayError( hresult ); // Create the shadow map buffer if( CSettings::Instance().GetCreateShadowMapBuffer() ) { CSize<int> size = CSettings::Instance().GetShadowMapBufferSize(); if( FAILED( hresult = spDXDevice->CreateTexture( size.w, size.h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &spShadowMapBufferTexture, NULL ) ) ) { DisplayError( hresult ); } // Grab the surface of the shadow map buffer if( FAILED( hresult = spShadowMapBufferTexture->GetSurfaceLevel( 0, &spShadowMapBufferSurface ) ) ) DisplayError( hresult ); } // Create post-process buffer if( CSettings::Instance().GetCreatePostProcBuf() ) { for( size_t i = 0; i < CSettings::Instance().GetPostProcBufCount(); ++i ) { CComPtr<IDirect3DTexture9> spPostProcessBufferTexture; CComPtr<IDirect3DSurface9> spPostProcessBufferSurface; // Get the info about this post process buffer const CSettings::CPostProcBuff & postProcInfo = CSettings::Instance().GetPostProcBufInfo(static_cast<int>(i)); if( FAILED( hresult = spDXDevice->CreateTexture( (UINT)(GetBufferWidth() * postProcInfo.scale), (UINT)(GetBufferHeight() * postProcInfo.scale), 1, D3DUSAGE_RENDERTARGET, dxpp.BackBufferFormat, D3DPOOL_DEFAULT, &spPostProcessBufferTexture, NULL ) ) ) { DisplayError( hresult ); } // Grab the surface of the post process buffer if( FAILED( hresult = spPostProcessBufferTexture->GetSurfaceLevel( 0, &spPostProcessBufferSurface ) ) ) DisplayError( hresult ); // Add the texture and surface to our vectors pPostProcTextVec.push_back( spPostProcessBufferTexture ); pPostProcSurfaceVec.push_back( spPostProcessBufferSurface ); } } // Create the post process vertex buffer CreatePostProcessVertexBuffer(); // Turn on the zbuffer if( CSettings::Instance().GetCreateDepthStencilBuffer() ) { spDXDevice->SetRenderState( D3DRS_ZWRITEENABLE, true ); spDXDevice->SetRenderState( D3DRS_ZENABLE, CSettings::Instance().GetEnableDepthBuffer() ); } // Disable lighting - not needed because shader lighting is used spDXDevice->SetRenderState( D3DRS_LIGHTING, false ); // Turn on/off point sprites spDXDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, false ); // Allow sprites to be scaled with distance spDXDevice->SetRenderState( D3DRS_POINTSCALEENABLE, true ); // Float value that specifies the minimum size of point primitives. Point primitives are clamped to this size during rendering. spDXDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.0) ); // Not needed unless you want to specify a size smaller then video card max //spDXDevice->SetRenderState( D3DRS_POINTSIZE_MAX, FtoDW(32.0) ); spDXDevice->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(0.0) ); spDXDevice->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.0) ); spDXDevice->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(1.0) ); ////////////////////////////////////////////////// // Set the alpha blend states but they are not // used until the alpha rendering state is enable ////////////////////////////////////////////////// // Turn on alpha blending spDXDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true ); // source blend factor spDXDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); // D3DBLEND_SRCALPHA D3DBLEND_ONE // destination blend factor spDXDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); // D3DBLEND_INVSRCALPHA D3DBLEND_ONE // alpha from texture spDXDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); spDXDevice->SetRenderState( D3DRS_ALPHATESTENABLE, true ); spDXDevice->SetRenderState( D3DRS_ALPHAREF, 0x01 ); spDXDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); // Enable culling spDXDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); } // ResetXDevice
//----------------------------------------------------------------------------- // Name: Render() // Desc: Renders the particle system using pointsprites loaded in a vertex // buffer. // // Note: D3DLOCK_DISCARD: // // The application overwrites, with a write-only operation, the entire // index buffer. This enables Direct3D to return a pointer to a new // memory area so that the dynamic memory access (DMA) and rendering // from the old area do not stall. // // D3DLOCK_NOOVERWRITE: // // Indicates that no vertices that were referred to in drawing calls // since the start of the frame or the last lock without this flag will // be modified during the lock. This can enable optimizations when the // application is appending data only to the vertex buffer. //----------------------------------------------------------------------------- HRESULT CParticleSystem::Render( LPDIRECT3DDEVICE9 pd3dDevice ) { HRESULT hr; // // Set the render states for using point sprites.. // pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE ); // Turn on point sprites pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE ); // Allow sprites to be scaled with distance pd3dDevice->SetRenderState( D3DRS_POINTSIZE, FtoDW(m_fSize) ); // Float value that specifies the size to use for point size computation in cases where point size is not specified for each vertex. pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(1.0f) ); // Float value that specifies the minimum size of point primitives. Point primitives are clamped to this size during rendering. pd3dDevice->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(0.0f) ); // Default 1.0 pd3dDevice->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.0f) ); // Default 0.0 pd3dDevice->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(1.0f) ); // Default 0.0 Particle *pParticle = m_pActiveList; PointVertex *pVertices; DWORD dwNumParticlesToRender = 0; // Lock the vertex buffer. We fill the vertex buffer in small // chunks, using D3DLOCK_NOOVERWRITE. When we are done filling // each chunk, we call DrawPrim, and lock the next chunk. When // we run out of space in the vertex buffer, we start over at // the beginning, using D3DLOCK_DISCARD. // Move the offset forward so we can fill the next chunk of the vertex buffer m_dwVBOffset += m_dwFlush; // If we're about to overflow the buffer, reset the offset counter back to 0 if( m_dwVBOffset >= m_dwDiscard ) m_dwVBOffset = 0; if( FAILED( hr = m_pVB->Lock( m_dwVBOffset * sizeof(PointVertex), // Offset to lock m_dwFlush * sizeof(PointVertex), // Size to lock (void**) &pVertices, m_dwVBOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD))) { return hr; } // Render each particle while( pParticle ) { D3DXVECTOR3 vPos(pParticle->m_vCurPos); D3DXVECTOR3 vVel(pParticle->m_vCurVel); pVertices->posit = vPos; pVertices->color = m_clrColor; pVertices++; if( ++dwNumParticlesToRender == m_dwFlush ) { // Done filling this chunk of the vertex buffer. Lets unlock and // draw this portion so we can begin filling the next chunk. m_pVB->Unlock(); pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(PointVertex) ); pd3dDevice->SetFVF( PointVertex::FVF_Flags ); if( FAILED(hr = pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwVBOffset, dwNumParticlesToRender))) { return hr; } // Lock the next chunk of the vertex buffer. If we are at the // end of the vertex buffer, DISCARD the vertex buffer and start // at the beginning. Otherwise, specify NOOVERWRITE, so we can // continue filling the VB while the previous chunk is drawing. m_dwVBOffset += m_dwFlush; // If we're about to overflow the buffer, reset the offset counter back to 0 if( m_dwVBOffset >= m_dwDiscard ) m_dwVBOffset = 0; if( FAILED( hr = m_pVB->Lock( m_dwVBOffset * sizeof(PointVertex), // Offset to lock m_dwFlush * sizeof(PointVertex), // Size to lock (void**) &pVertices, m_dwVBOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD))) { return hr; } dwNumParticlesToRender = 0; } pParticle = pParticle->m_pNext; } // Unlock the vertex buffer m_pVB->Unlock(); // Render any remaining particles if( dwNumParticlesToRender ) { pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(PointVertex) ); pd3dDevice->SetFVF( PointVertex::FVF_Flags ); if(FAILED(hr = pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwVBOffset, dwNumParticlesToRender ))) return hr; } // // Reset render states... // pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE ); pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE ); return S_OK; }
//----------------------------------------------------------------------------- // Name: Render() // Desc: Renders the particle system using either pointsprites (if supported) // or using 4 vertices per particle //----------------------------------------------------------------------------- HRESULT CParticles::Render( LPDIRECT3DDEVICE9 pd3dDevice ) { if( m_bActive == FALSE ) return S_OK; if( m_pParticleTexture == NULL ) return S_OK; if( m_dwParticles <= 0 ) return S_OK; D3DXMATRIX mWorld; D3DXMatrixIdentity( &mWorld ); pd3dDevice->SetTransform( D3DTS_WORLD, &mWorld ); // Set World Transform // Draw particles pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT ); pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); // pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT ); // pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE ); pd3dDevice->SetTexture(0, m_pParticleTexture ); HRESULT hr; // Set the render states for using point sprites pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE ); pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE ); pd3dDevice->SetRenderState( D3DRS_POINTSIZE, FtoDW(m_fSize) ); pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(1.00f) ); pd3dDevice->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(0.00f) ); pd3dDevice->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.00f) ); pd3dDevice->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(1.00f) ); // Set up the vertex buffer to be rendered pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(POINTVERTEX) ); pd3dDevice->SetVertexShader( NULL ); pd3dDevice->SetVertexDeclaration( NULL ); pd3dDevice->SetFVF( POINTVERTEX::FVF ); PARTICLE* pParticle = m_pParticles; POINTVERTEX* pVertices; DWORD dwNumParticlesToRender = 0; // Lock the vertex buffer. We fill the vertex buffer in small // chunks, using D3DLOCK_NOOVERWRITE. When we are done filling // each chunk, we call DrawPrim, and lock the next chunk. When // we run out of space in the vertex buffer, we start over at // the beginning, using D3DLOCK_DISCARD. m_dwBase += m_dwFlush; if(m_dwBase >= m_dwDiscard) m_dwBase = 0; if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX), (void**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return hr; } D3DXCOLOR clrDiffuse; D3DXVECTOR3 vPos; D3DXVECTOR3 vVel; // 파티클 리스트를 따라 파티클을 렌더링한다. while( pParticle ) { vPos = pParticle->m_vPos; vVel = pParticle->m_vVel; /* // 파티클의 잔상을 보여주기 위한 부분. FLOAT fLengthSq = D3DXVec3LengthSq(&vVel); UINT dwSteps; if( fLengthSq < 1.0f ) dwSteps = 2; else if( fLengthSq < 4.00f ) dwSteps = 3; else if( fLengthSq < 9.00f ) dwSteps = 4; else if( fLengthSq < 12.25f ) dwSteps = 5; else if( fLengthSq < 16.00f ) dwSteps = 6; else if( fLengthSq < 20.25f ) dwSteps = 7; else dwSteps = 8; vVel *= -0.04f / (FLOAT)dwSteps; */ D3DXColorLerp( &clrDiffuse, &pParticle->m_clrFade, &pParticle->m_clrDiffuse, pParticle->m_fFade ); DWORD dwDiffuse = (DWORD) clrDiffuse; // Render each particle a bunch of times to get a blurring effect // dwSteps = 1; // for( DWORD i = 0; i < dwSteps; i++ ) { pVertices->v = vPos; pVertices->color = dwDiffuse; pVertices++; if( ++dwNumParticlesToRender == m_dwFlush ) { // Done filling this chunk of the vertex buffer. Lets unlock and // draw this portion so we can begin filling the next chunk. m_pVB->Unlock(); if(FAILED(hr = pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender))) return hr; // Lock the next chunk of the vertex buffer. If we are at the // end of the vertex buffer, DISCARD the vertex buffer and start // at the beginning. Otherwise, specify NOOVERWRITE, so we can // continue filling the VB while the previous chunk is drawing. m_dwBase += m_dwFlush; if(m_dwBase >= m_dwDiscard) m_dwBase = 0; if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX), (void**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) ) { return hr; } dwNumParticlesToRender = 0; } // vPos += vVel; // 잔상처리를 위한 부분. } // for dwSteps pParticle = pParticle->m_pNext; } // particle list // Unlock the vertex buffer m_pVB->Unlock(); // Render any remaining particles if( dwNumParticlesToRender ) // 위에서 512개씩 출력해주고 남은 파티클을 여기서 마저 다 그려줌. { if(FAILED(hr = pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender ))) return hr; } // Reset render states pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE ); pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE ); pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); // pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); return S_OK; }
PROTECTED RETCODE fxGas2Func(hPARFX thisPARFX, DWORD message, LPARAM dumbParam, WPARAM otherParam) { switch(message) { case PARFXM_CREATE: { float center[eMaxPt]; hOBJ obj = OBJQuery(&thisPARFX->objKey); fxGas2_init *init = (fxGas2_init *)dumbParam; if(!init) return RETCODE_FAILURE; //set up the main particle if(MemAlloc(&thisPARFX->data, sizeof(fxGas2), M_ZERO) != RETCODE_SUCCESS) { ASSERT_MSG(0, "Unable to allocate gas data", "fxGas2Func"); return RETCODE_FAILURE; } fxGas2 *data = (fxGas2 *)thisPARFX->data; data->gasTxt = init->gasTxt; TextureAddRef(data->gasTxt); data->size = init->size; data->maxParticle = init->maxParticle; //translate the bounds if obj is specified if(obj) OBJGetLoc(obj, center); else memcpy(center, init->center, sizeof(float)*eMaxPt); //allocate the particle gases if(MemAlloc((void**)&data->bunchOgas, sizeof(fxGas2_par)*data->maxParticle, M_ZERO) != RETCODE_SUCCESS) { ASSERT_MSG(0, "Unable to allocate gas particles", "fxGas2Func"); return RETCODE_FAILURE; } //create vertex buffer //_GFXCheckError(HRESULT hr, bool displayMsg, const char *header) if(_GFXCheckError(g_p3DDevice->CreateVertexBuffer(sizeof(fxGas_vtx)*data->maxParticle, D3DUSAGE_POINTS, FXGASVTXFLAG, D3DPOOL_MANAGED, &data->gasVtx), true, "fxGas2Func")) return RETCODE_FAILURE; //initialize each gas particle for(int i = 0; i < data->maxParticle; i++) _fxGas2InitParticle(init, center, &data->bunchOgas[i]); } break; case PARFXM_UPDATE: { fxGas2 *data = (fxGas2 *)thisPARFX->data; fxGas_vtx *pGasVtx; if(FAILED(data->gasVtx->Lock(0,0, (BYTE**)&pGasVtx, 0))) { ASSERT_MSG(0, "Unable to lock gas particle vtx", "fxGas2Func"); return RETCODE_FAILURE; } data->numAlive=0; for(int i = 0; i < data->maxParticle; i++) { if(_fxGas2UpdateParticle(&data->bunchOgas[i], data->size)) { memcpy(&pGasVtx[i], &data->bunchOgas[i].curVtx, sizeof(fxGas_vtx)); data->numAlive++; } } data->gasVtx->Unlock(); if(data->numAlive==0) return RETCODE_BREAK; } break; case PARFXM_DISPLAY: { //push world stack and set this object's world mtx g_pWrldStack->Push(); g_pWrldStack->LoadIdentity(); //do transformations g_p3DDevice->SetTransform(D3DTS_WORLD, g_pWrldStack->GetTop()); DWORD srcBlend, destBlend; fxGas2 *data = (fxGas2 *)thisPARFX->data; //disable light if(!TESTFLAGS(g_FLAGS, GFX_LIGHTDISABLE)) g_p3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE); TextureSet(data->gasTxt, 0); g_p3DDevice->GetRenderState( D3DRS_SRCBLEND, &srcBlend ); g_p3DDevice->GetRenderState( D3DRS_DESTBLEND, &destBlend ); g_p3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_p3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); g_p3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE ); g_p3DDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE ); g_p3DDevice->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE ); g_p3DDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.08f) ); g_p3DDevice->SetRenderState( D3DRS_POINTSIZE_MAX, FtoDW(1000.0f) ); g_p3DDevice->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(0.00f) ); g_p3DDevice->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.00f) ); g_p3DDevice->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(1.00f) ); g_p3DDevice->SetStreamSource( 0, data->gasVtx, sizeof(fxGas_vtx) ); g_p3DDevice->SetVertexShader( FXGASVTXFLAG ); if(FAILED(g_p3DDevice->DrawPrimitive( D3DPT_POINTLIST, 0, data->numAlive))) { ASSERT_MSG(0, "Failed to draw particles", "fxGasFunc"); return RETCODE_FAILURE; } g_p3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); g_p3DDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE ); g_p3DDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE ); g_p3DDevice->SetRenderState( D3DRS_SRCBLEND, srcBlend ); g_p3DDevice->SetRenderState( D3DRS_DESTBLEND, destBlend ); //enable light again, if flag is set if(!TESTFLAGS(g_FLAGS, GFX_LIGHTDISABLE)) g_p3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE); TextureSet(0, 0); //take this junk out! g_pWrldStack->Pop(); } break; case PARFXM_DESTROY: { fxGas2 *data = (fxGas2 *)thisPARFX->data; if(data) { if(data->bunchOgas) MemFree((void**)&data->bunchOgas); TextureDestroy(&data->gasTxt); if(data->gasVtx) data->gasVtx->Release(); } } break; } return RETCODE_SUCCESS; }
void CKind::SetPSSize( int level) { m_dev->SetRenderState( D3DRS_POINTSIZE, FtoDW(m_LSystem->GetPSSizes( )[ level]) ); // Float value that specifies the size to use for point size computation in cases where point size is not specified for each vertex. }