#include "stdafx.h" #include "SGameViewPort.h" #include "SShadowViewPort.h" #include "SWaterViewPort.h" #include "KPrimitive.h" #include "KRenderDeviceDX.h" #include "SSpeedTreeVertexShaders.h" #include //#include "GameDefine.h" #include "KResourceManager.h" #include #include #include "SGameLowQualityWater.h" #include #include "KPrimitiveSpeedTree.h" #include "TerrainPrimitive.h" /// 2010.11.10 - prodongi #include "SItemDB.h" #include "SGameLobbyDefine.h" //#define HDRTEXTURE_WIDTH 1024 // 실제 Backbuffer의 크기로 잡는다. //#define HDRBLURTEXTURE_WIDTH 512 // 실제 Backbuffer 보다 클수록 고사양 고품질 SGameViewPort::SGameViewPort( bool bClearColorBuffer, bool bClearDepthBuffer) : SViewPort( VIEWPORT_GAME, bClearColorBuffer, bClearDepthBuffer ) { m_pShadowViewPort = NULL; m_pWaterViewPort = NULL; //m_nTypeHDR = HDR_TYPE_NONE; //m_dwHDR_Factor = 0xBBBBBBBB; //m_nVarFilter01 = 215; //m_nVarFilter02 = 10; //m_bUseHDR = false; //기본은 안 쓴다. m_bRenderShadow = false; m_nUseSpecular = true; m_bRenderBumpMap = true; m_fWaterBumpSpeed = 0.2f; m_fWaterBumpSize = 0.04f; m_fBlurRadius = 0.01f; // 반지름 m_nHdrQuality = 0; m_fHdrBlurMixRatio = 0.3f; m_fHdrExposure = 1.3f; m_fHdrGamma = 1.1f; m_vbSelect = NULL; m_rtSelect = NULL; m_rtSelectOutLine = NULL; m_enableSelectOutLine = false; } SGameViewPort::~SGameViewPort() { } void SGameViewPort::SetViewArea( const KRect &viewarea ) { KViewportObject::SetViewArea( viewarea ); if( !m_spHdrVb || !m_spHdrVb->IsValidVtx() ) return; float fWidth, fHeight; fWidth = (float)viewarea.GetWidth(); fHeight = (float)viewarea.GetWidth(); K3DVERTEX_LENS *pTempBuf = NULL; int size = 4; //Size 사용 안함. m_spHdrVb->Lock( ( void** ) &pTempBuf, size ); assert(pTempBuf && "m_spHdrVb->Lock( ( void** ) &pTempBuf, size );"); pTempBuf[0].p = D3DXVECTOR3( 0, 0, 0.5f ); pTempBuf[0].rhw = 1.f; pTempBuf[0].tu = 0.f; pTempBuf[0].tv = 0.f; pTempBuf[1].p = D3DXVECTOR3( fWidth, 0, 0.5f ); pTempBuf[1].rhw = 1.f; pTempBuf[1].tu = 1.f; pTempBuf[1].tv = 0.f; pTempBuf[2].p = D3DXVECTOR3( 0, fHeight, 0.5f ); pTempBuf[2].rhw = 1.f; pTempBuf[2].tu = 0.f; pTempBuf[2].tv = 1.f; pTempBuf[3].p = D3DXVECTOR3( fWidth, fHeight, 0.5f ); pTempBuf[3].rhw = 1.f; pTempBuf[3].tu = 1.f; pTempBuf[3].tv = 1.f; pTempBuf[0].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[1].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[2].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[3].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 m_spHdrVb->Unlock(); } void SGameViewPort::Initilaize( K3DRenderDevice *dev, const KViewportStruct &viewarea, float nearClip, float farClip ) { SViewPort::Initilaize( dev, viewarea, nearClip, farClip ); m_spHdrVb = NULL; m_nShadowStride = 0; m_spHdrVb = m_dev->CreateVertexBuffer( VERTEX_LENS, 4 ); if( m_spHdrVb && m_spHdrVb->IsValidVtx() ) { m_nShadowStride = K3DVertexBuffer::CalcVertexStride( VERTEX_LENS ); float fWidth, fHeight; fWidth = (float)viewarea.Width; fHeight = (float)viewarea.Width; K3DVERTEX_LENS *pTempBuf = NULL; int size = 4; //Size 사용 안함. m_spHdrVb->Lock( (void**) &pTempBuf, size ); assert(pTempBuf && "m_spHdrVb->Lock( (void**)&pTempBuf, size );"); pTempBuf[0].p = D3DXVECTOR3( 0, 0, 0.5f ); pTempBuf[0].rhw = 1.f; pTempBuf[0].tu = 0.f; pTempBuf[0].tv = 0.f; pTempBuf[1].p = D3DXVECTOR3( fWidth, 0, 0.5f ); pTempBuf[1].rhw = 1.f; pTempBuf[1].tu = 1.f; pTempBuf[1].tv = 0.f; pTempBuf[2].p = D3DXVECTOR3( 0, fHeight, 0.5f ); pTempBuf[2].rhw = 1.f; pTempBuf[2].tu = 0.f; pTempBuf[2].tv = 1.f; pTempBuf[3].p = D3DXVECTOR3( fWidth, fHeight, 0.5f ); pTempBuf[3].rhw = 1.f; pTempBuf[3].tu = 1.f; pTempBuf[3].tv = 1.f; pTempBuf[0].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[1].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[2].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[3].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 m_spHdrVb->Unlock(); } //ENV().Bind( "engine.hdr_type", &m_nTypeHDR ); ENV().Bind( "engine.hdr_quality", &m_nHdrQuality ); } // 이전 HDR 코드에서 쓰던 거 //void SGameViewPort::SetViewArea( const KRect &viewarea ) //{ // KViewportObject::SetViewArea( viewarea ); // // if( !m_spShadowVB ) return; // // float fWidth, fHeight; // fWidth = (float)viewarea.GetWidth(); // fHeight = (float)viewarea.GetWidth(); // // K3DVERTEX_LENS *pTempBuf = NULL; // int size = 4; //Size 사용 안함. // m_spShadowVB->Lock( (void**)&pTempBuf, size ); // assert(pTempBuf && "m_spShadowVB->Lock( (void**)&pTempBuf, size );"); // // pTempBuf[0].p = D3DXVECTOR3( 0, 0, 0.5f ); pTempBuf[0].rhw = 1.f; // pTempBuf[0].tu = 0.f; pTempBuf[0].tv = 0.f; // pTempBuf[1].p = D3DXVECTOR3( fWidth, 0, 0.5f ); pTempBuf[1].rhw = 1.f; // pTempBuf[1].tu = 1.f; pTempBuf[1].tv = 0.f; // pTempBuf[2].p = D3DXVECTOR3( 0, fHeight, 0.5f ); pTempBuf[2].rhw = 1.f; // pTempBuf[2].tu = 0.f; pTempBuf[2].tv = 1.f; // pTempBuf[3].p = D3DXVECTOR3( fWidth, fHeight, 0.5f ); pTempBuf[3].rhw = 1.f; // pTempBuf[3].tu = 1.f; pTempBuf[3].tv = 1.f; // pTempBuf[0].color = D3DCOLOR_RGBA(255,255,255,255); //농도 // pTempBuf[1].color = D3DCOLOR_RGBA(255,255,255,255); //농도 // pTempBuf[2].color = D3DCOLOR_RGBA(255,255,255,255); //농도 // pTempBuf[3].color = D3DCOLOR_RGBA(255,255,255,255); //농도 // // m_spShadowVB->Unlock(); //} // //void SGameViewPort::Initilaize( K3DRenderDevice *dev, const KViewportStruct &viewarea, float nearClip, float farClip ) //{ // SViewPort::Initilaize( dev, viewarea, nearClip, farClip ); // m_spShadowVB = NULL; // m_nShadowStride = 0; // ////#ifndef NDEBUG // m_spShadowVB = m_dev->CreateVertexBuffer( VERTEX_LENS, 4 ); // m_nShadowStride = K3DVertexBuffer::CalcVertexStride( VERTEX_LENS ); // // // float fWidth, fHeight; // fWidth = (float)viewarea.Width; // fHeight = (float)viewarea.Width; // // K3DVERTEX_LENS *pTempBuf = NULL; // int size = 4; //Size 사용 안함. // m_spShadowVB->Lock( (void**)&pTempBuf, size ); // assert(pTempBuf && "m_spShadowVB->Lock( (void**)&pTempBuf, size );"); // // pTempBuf[0].p = D3DXVECTOR3( 0, 0, 0.5f ); pTempBuf[0].rhw = 1.f; // pTempBuf[0].tu = 0.f; pTempBuf[0].tv = 0.f; // pTempBuf[1].p = D3DXVECTOR3( fWidth, 0, 0.5f ); pTempBuf[1].rhw = 1.f; // pTempBuf[1].tu = 1.f; pTempBuf[1].tv = 0.f; // pTempBuf[2].p = D3DXVECTOR3( 0, fHeight, 0.5f ); pTempBuf[2].rhw = 1.f; // pTempBuf[2].tu = 0.f; pTempBuf[2].tv = 1.f; // pTempBuf[3].p = D3DXVECTOR3( fWidth, fHeight, 0.5f ); pTempBuf[3].rhw = 1.f; // pTempBuf[3].tu = 1.f; pTempBuf[3].tv = 1.f; // pTempBuf[0].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // pTempBuf[1].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // pTempBuf[2].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // pTempBuf[3].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // // m_spShadowVB->Unlock(); // // ////////////////////////////////////////////////////////////////////////// // fWidth = HDRBLURTEXTURE_WIDTH; // fHeight = HDRBLURTEXTURE_WIDTH; // m_spHDR_VB = m_dev->CreateVertexBuffer( VERTEX_LENS, 4 ); // // pTempBuf = NULL; // m_spHDR_VB->Lock( (void**)&pTempBuf, size ); // assert(pTempBuf && "m_spHDR_VB->Lock( (void**)&pTempBuf, size );"); // // pTempBuf[0].p = D3DXVECTOR3( 0, 0, 0.5f ); pTempBuf[0].rhw = 1.f; // pTempBuf[0].tu = 0.f; pTempBuf[0].tv = 0.f; // pTempBuf[1].p = D3DXVECTOR3( fWidth, 0, 0.5f ); pTempBuf[1].rhw = 1.f; // pTempBuf[1].tu = 1.f; pTempBuf[1].tv = 0.f; // pTempBuf[2].p = D3DXVECTOR3( 0, fHeight, 0.5f ); pTempBuf[2].rhw = 1.f; // pTempBuf[2].tu = 0.f; pTempBuf[2].tv = 1.f; // pTempBuf[3].p = D3DXVECTOR3( fWidth, fHeight, 0.5f ); pTempBuf[3].rhw = 1.f; // pTempBuf[3].tu = 1.f; pTempBuf[3].tv = 1.f; // pTempBuf[0].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // pTempBuf[1].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // pTempBuf[2].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // pTempBuf[3].color = D3DCOLOR_RGBA( 255, 255, 255, 255 ); // 농도 // // m_spHDR_VB->Unlock(); // // ENV().Bind( "engine.hdr_type", &m_nTypeHDR ); ////#endif //} void SGameViewPort::Initilaize( const SGameViewPort* pViewport ) { Initilaize( pViewport->m_dev, pViewport->m_viewport, pViewport->m_fNearClip, pViewport->m_fFarClip ); } void SGameViewPort::ClearRegisteredList() { SViewPort::ClearRegisteredList(); } void SGameViewPort::AllViewPortClear() { if( m_pWaterViewPort ) m_pWaterViewPort->ClearRegisteredList(); if( m_pShadowViewPort ) m_pShadowViewPort->ClearRegisteredList(); } void SGameViewPort::Register( K3DPrimitive *pr, DWORD flag ) { // flag 참조하여 필요없는 것은 패스 시킨다. SViewPort::Register(pr, flag); } float g_vBlurVtx[] = { 0.0f , 0.0f , 0.0f, 0.0f, 1.0f, 2048.0f, 0.0f , 0.0f, 1.0f, 1.0f, 2048.0f, 2048.0f, 0.0f, 1.0f, 0.0f, 2048.0f, 2048.0f, 0.0f, 1.0f, 0.0f, 0.0f , 2048.0f, 0.0f, 0.0f, 0.0f, 0.0f , 0.0f , 0.0f, 0.0f, 1.0f, }; //float fullscreenvtx[] = { // 0 , 0, 0, 0, 1, 0, 1, 0, 1, // 2048, 0, 0, 1, 1, 1, 1, 1, 1, // 2048, 2048, 0, 1, 0, 1, 0, 1, 0, // 2048, 2048, 0, 1, 0, 1, 0, 1, 0, // 0 , 2048, 0, 0, 0, 0, 0, 0, 0, // 0 , 0, 0, 0, 1, 0, 1, 0, 1, //}; // //const float c_fOri_cross = 0.00197f; //const float c_fOri_blur = 0.00097f; // //float hdrblurvtx[] = //{ // 0 , 0, 0, 0-0, 1+0, 0-0, 1+0, 0-0, 1+0, 0-0, 1+0, // 2048, 0, 0, 1-0, 1+0, 1-0, 1+0, 1-0, 1+0, 1-0, 1+0, // 2048, 2048, 0, 1-0, 0+0, 1-0, 0+0, 1-0, 0+0, 1-0, 0+0, // 2048, 2048, 0, 1-0, 0+0, 1-0, 0+0, 1-0, 0+0, 1-0, 0+0, // 0 , 2048, 0, 0-0, 0+0, 0-0, 0+0, 0-0, 0+0, 0-0, 0+0, // 0 , 0, 0, 0-0, 1+0, 0-0, 1+0, 0-0, 1+0, 0-0, 1+0, //}; // ////Cross Filter 에서 사용 //float blur_screen_coord1[2*16] = //{ // 0, 0, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, // c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, // // c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, // c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, c_fOri_cross, //}; //float blur_screen_coord2[2*16] = //{ // -0, 0, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, // -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, // // -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, // -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, //}; //float blur_screen_coord3[2*16] = //{ // 0, -0, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, // c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, // // c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, // c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, c_fOri_cross, -c_fOri_cross, //}; //float blur_screen_coord4[2*16] = //{ // -0, -0, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, // -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, // // -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, // -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, -c_fOri_cross, //}; //float blur_screen_color1[4*16] = //{ // 16/32.f, 16/32.f, 16/32.f, 16/32.f, // 15/32.f, 15/32.f, 15/32.f, 15/32.f, // 14/32.f, 14/32.f, 14/32.f, 14/32.f, // 13/32.f, 13/32.f, 13/32.f, 13/32.f, // 12/32.f, 12/32.f, 12/32.f, 12/32.f, // 11/32.f, 11/32.f, 11/32.f, 11/32.f, // 10/32.f, 10/32.f, 10/32.f, 10/32.f, // 9/32.f, 9/32.f, 9/32.f, 9/32.f, // 8/32.f, 8/32.f, 8/32.f, 8/32.f, // 7/32.f, 7/32.f, 7/32.f, 7/32.f, // 6/32.f, 6/32.f, 6/32.f, 6/32.f, // 5/32.f, 5/32.f, 5/32.f, 5/32.f, // 4/32.f, 4/32.f, 4/32.f, 4/32.f, // 3/32.f, 3/32.f, 3/32.f, 3/32.f, // 2/32.f, 2/32.f, 2/32.f, 2/32.f, // 1/32.f, 1/32.f, 1/32.f, 1/32.f, //}; // ////Blur Filter 에서 사용 //float blur_screen_coord5[2*16] = //{ // -c_fOri_blur , -c_fOri_blur , -c_fOri_blur , -c_fOri_blur , -c_fOri_blur , -c_fOri_blur , -c_fOri_blur , -c_fOri_blur, // // 4*c_fOri_blur-c_fOri_blur , 5*c_fOri_blur , -c_fOri_blur , c_fOri_blur , -c_fOri_blur , c_fOri_blur , -c_fOri_blur , c_fOri_blur, // // 5*c_fOri_blur , c_fOri_blur-c_fOri_blur*4 , c_fOri_blur , c_fOri_blur , c_fOri_blur , c_fOri_blur , c_fOri_blur , c_fOri_blur, // // c_fOri_blur-c_fOri_blur*4 , -4*c_fOri_blur-c_fOri_blur , c_fOri_blur , -c_fOri_blur , c_fOri_blur , -c_fOri_blur , c_fOri_blur , -c_fOri_blur, //}; // //float blur_screen_color2[4*16] = //{ // 16/20.f, 16/20.f, 16/20.f, 16/20.f, // 12/20.f, 12/20.f, 12/20.f, 12/20.f, // 8/20.f, 8/20.f, 8/20.f, 8/20.f, // 4/20.f, 4/20.f, 4/20.f, 4/20.f, // // 16/20.f, 16/20.f, 16/20.f, 16/20.f, // 12/20.f, 12/20.f, 12/20.f, 12/20.f, // 8/20.f, 8/20.f, 8/20.f, 8/20.f, // 4/20.f, 4/20.f, 4/20.f, 4/20.f, // // 16/20.f, 16/20.f, 16/20.f, 16/20.f, // 12/20.f, 12/20.f, 12/20.f, 12/20.f, // 8/20.f, 8/20.f, 8/20.f, 8/20.f, // 4/20.f, 4/20.f, 4/20.f, 4/20.f, // // 16/20.f, 16/20.f, 16/20.f, 16/20.f, // 12/20.f, 12/20.f, 12/20.f, 12/20.f, // 8/20.f, 8/20.f, 8/20.f, 8/20.f, // 4/20.f, 4/20.f, 4/20.f, 4/20.f, //}; //물그림용 임시 namespace namespace { struct tmp_WATER_D3DVERTEX { D3DXVECTOR3 V; D3DCOLOR color; D3DXVECTOR2 T; D3DXVECTOR2 T2; }; void DrawWaterEx(LPDIRECT3DDEVICE9 m_pD3DDevice, const D3DXMATRIX &viewproj, D3DXVECTOR3 *cube, float m_fWaterHeight, DWORD color, LPDIRECT3DTEXTURE9 tex, LPDIRECT3DTEXTURE9 bumptex, float speed) { HRESULT hr = m_pD3DDevice->TestCooperativeLevel(); if( hr != S_OK ) { return; } D3DXVECTOR3 pos[4]; //D3DXVECTOR3 *cube = GetFrustumCube(); float val; val = (m_fWaterHeight - cube[0].z)/(cube[3].z - cube[0].z); pos[0] = val*cube[3] + (1 - val)*cube[0]; val = (m_fWaterHeight - cube[1].z)/(cube[2].z - cube[1].z); pos[1] = val*cube[2] + (1 - val)*cube[1]; val = (m_fWaterHeight - cube[5].z)/(cube[6].z - cube[5].z); pos[3] = val*cube[6] + (1 - val)*cube[5]; val = (m_fWaterHeight - cube[4].z)/(cube[7].z - cube[4].z); pos[2] = val*cube[7] + (1 - val)*cube[4]; m_pD3DDevice->SetTexture(0, bumptex); m_pD3DDevice->SetTextureStageState(0, D3DTSS_RESULTARG, D3DTA_CURRENT); m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP ); m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); m_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); m_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); m_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); //m_pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); m_pD3DDevice->SetTexture(1, tex); m_pD3DDevice->SetTextureStageState(1, D3DTSS_RESULTARG, D3DTA_CURRENT); m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); m_pD3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); m_pD3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); m_pD3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); m_pD3DDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); //m_pD3DDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); m_pD3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pD3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_pD3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pD3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_pD3DDevice->SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pD3DDevice->SetTextureStageState(4, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_pD3DDevice->SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pD3DDevice->SetTextureStageState(5, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, false); m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false); m_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); m_pD3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, false); m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, true); FLOAT r = 0.04f; D3DXMATRIX matBumpMat; float fTime = GetSafeTickCount()*speed/1000.f; matBumpMat._11 = r * cosf( fTime * 9.0f ); matBumpMat._12 = -r * sinf( fTime * 9.0f ); matBumpMat._21 = r * sinf( fTime * 9.0f ); matBumpMat._22 = r * cosf( fTime * 9.0f ); m_pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT00, F2DW( matBumpMat._11 ) ); m_pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT01, F2DW( matBumpMat._12 ) ); m_pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT10, F2DW( matBumpMat._21 ) ); m_pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT11, F2DW( matBumpMat._22 ) ); D3DXMATRIX mat; D3DXMatrixIdentity(&mat); m_pD3DDevice->SetTransform(D3DTS_WORLD, &mat); m_pD3DDevice->SetTransform(D3DTS_VIEW, &mat); m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &mat); tmp_WATER_D3DVERTEX cppos[4]; // front cppos[0].color = color; cppos[1].color = color; cppos[2].color = color; cppos[3].color = color; cppos[0].T.x = 1; cppos[0].T.y = 0; cppos[1].T.x = 1; cppos[1].T.y = 1; cppos[2].T.x = 0; cppos[2].T.y = 1; cppos[3].T.x = 0; cppos[3].T.y = 0; cppos[0].T2.x = 1; cppos[0].T2.y = 1; cppos[1].T2.x = 0; cppos[1].T2.y = 1; cppos[2].T2.x = 0; cppos[2].T2.y = 0; cppos[3].T2.x = 1; cppos[3].T2.y = 0; D3DXVec3TransformCoord(&cppos[0].V, &pos[0], &viewproj); D3DXVec3TransformCoord(&cppos[1].V, &pos[1], &viewproj); D3DXVec3TransformCoord(&cppos[2].V, &pos[2], &viewproj); D3DXVec3TransformCoord(&cppos[3].V, &pos[3], &viewproj); //cppos[0].V = pos[0]; //cppos[1].V = pos[1]; //cppos[2].V = pos[2]; //cppos[3].V = pos[3]; m_pD3DDevice->SetVertexShader(NULL); m_pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2); m_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, cppos, sizeof(tmp_WATER_D3DVERTEX)); m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); } }; bool SGameViewPort::DrawWater() { bool bCheck = (m_bUseWater && m_bRenderWater && m_pWaterViewPort && m_pWaterViewPort->GetWaterQuality() > 0); if( !bCheck ) return false; LPDIRECT3DDEVICE9 pD3DDevice = ((K3DRenderDeviceDX*)m_dev)->GetD3DDevice(); HRESULT hr = pD3DDevice->TestCooperativeLevel(); if( hr != S_OK ) { return false; } LPDIRECT3DTEXTURE9 tex = ((K3DRenderTargetDX*)m_pWaterViewPort->GetWaterReflection())->GetD3DTexture(); LPDIRECT3DTEXTURE9 bumptex = ((K3DTextureDX*)m_pWaterViewPort->GetWaterBump())->GetD3DTexture(); pD3DDevice->SetTexture(0, bumptex); pD3DDevice->SetTextureStageState(0, D3DTSS_RESULTARG, D3DTA_CURRENT); pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP ); pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); //pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); //pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); pD3DDevice->SetTexture(1, tex); pD3DDevice->SetTextureStageState(1, D3DTSS_RESULTARG, D3DTA_CURRENT); pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); //pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE ); pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); pD3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); pD3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); pD3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); pD3DDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); //pD3DDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); //// 텍스쳐 설정은 SWater::Render() 에서 하고 있3 ////pD3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_ADD ); //pD3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_ADDSMOOTH ); ////pD3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); //pD3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_CURRENT ); //pD3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE); //pD3DDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_ADD ); ////pD3DDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); //pD3DDevice->SetTextureStageState( 2, D3DTSS_ALPHAARG1, D3DTA_CURRENT ); //pD3DDevice->SetTextureStageState( 2, D3DTSS_ALPHAARG2, D3DTA_TEXTURE ); //pD3DDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); //pD3DDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); //pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); //pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); //pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); //pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); //pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(4, D3DTSS_COLOROP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(4, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(5, D3DTSS_COLOROP, D3DTOP_DISABLE); pD3DDevice->SetTextureStageState(5, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pD3DDevice->SetRenderState(D3DRS_LIGHTING, false); pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false); pD3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); pD3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, false); pD3DDevice->SetRenderState(D3DRS_ZENABLE, true); //FLOAT r = 0.04f; D3DXMATRIX matBumpMat; //float fTime = GetSafeTickCount()*speed/1000.f; float fTime = GetSafeTickCount() * m_fWaterBumpSpeed / 1000.f; //matBumpMat._11 = r * cosf( fTime * 9.0f ); //matBumpMat._12 = -r * sinf( fTime * 9.0f ); //matBumpMat._21 = r * sinf( fTime * 9.0f ); //matBumpMat._22 = r * cosf( fTime * 9.0f ); matBumpMat._11 = m_fWaterBumpSize * cosf( fTime * 9.0f ); matBumpMat._12 = -m_fWaterBumpSize * sinf( fTime * 9.0f ); matBumpMat._21 = m_fWaterBumpSize * sinf( fTime * 9.0f ); matBumpMat._22 = m_fWaterBumpSize * cosf( fTime * 9.0f ); pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT00, F2DW( matBumpMat._11 ) ); pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT01, F2DW( matBumpMat._12 ) ); pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT10, F2DW( matBumpMat._21 ) ); pD3DDevice->SetTextureStageState( 0, D3DTSS_BUMPENVMAT11, F2DW( matBumpMat._22 ) ); return true; /* D3DXMATRIX matWorld, matView, matProj; pD3DDevice->GetTransform(D3DTS_WORLD, &matWorld); pD3DDevice->GetTransform(D3DTS_VIEW, &matView); pD3DDevice->GetTransform(D3DTS_PROJECTION, &matProj); D3DXMATRIX matIdent; D3DXMatrixIdentity(&matIdent); pD3DDevice->SetTransform(D3DTS_WORLD, &matIdent); pD3DDevice->SetTransform(D3DTS_VIEW, &matIdent); pD3DDevice->SetTransform(D3DTS_PROJECTION, &matIdent); RenderHighQualityWater(); pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); pD3DDevice->SetTransform(D3DTS_VIEW, &matView); pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); //반사맵 렌더 후 디폴트로 설정 m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); //위에 디폴트땜시 다시 설정해 줘야 한다 m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetCullMode(K3DRenderDevice::KCM_CCW);*/ } void SGameViewPort::SetWaterBumpSpeed( float fSpeed ) { m_fWaterBumpSpeed = fSpeed; } void SGameViewPort::SetWaterBumpSize( float fSize ) { m_fWaterBumpSize = fSize; } void SGameViewPort::SetHQWaterHeight (float fHeight ) { if(m_bUseWater && m_pWaterViewPort && m_pWaterViewPort->GetWaterQuality() > 0) m_pWaterViewPort->SetHQWaterHeight(fHeight); } void SGameViewPort::SetCamera( const K3DCamera *cam ) { SViewPort::SetCamera(cam); if(m_pShadowViewPort) m_pShadowViewPort->SetShadowBottomHeight(cam->GetTargetPos().z); //테스트중 // if( m_pWaterViewPort ) // m_pWaterViewPort->SetWaterHeight( cam->GetTargetPos().z-3.f ); CSpeedGrassRT::SetPerspective( m_fVertexAspect, m_ViewCamera.GetFOV() ); } /// 2010.11.10 - prodongi //#ifdef _DEV //extern bool g_bDebugMode; //#endif void SGameViewPort::Render( K3DRenderTarget *pRT, DWORD flag /*= 0*/, bool bClearRegister /*= true*/ ) { SViewPort::Render( pRT, flag, bClearRegister ); } void SGameViewPort::Render( bool bClearRegister, bool bSetRenderTarget ) { START_RENDER_VIEWPORT("Game Viweport"); m_bLocalCoord = true; if( m_pShadowViewPort ) { m_bRenderShadow = m_pShadowViewPort->IsShadowValid(); m_bRenderSelfShadow = m_pShadowViewPort->GetShadowBufferQuality() > 0 ? true : false; } BeginRender(); m_dev->SetCullMode( K3DRenderDevice::KCM_CCW ); renderSelectRT(); renderSelectOutLineRT(); //if( m_bUseHDR && m_nTypeHDR != HDR_TYPE_NONE ) if (m_rtSourceScene) { if (m_enableSelectOutLine || m_nHdrQuality > 0) StartRTSourceScene(); } /* if (m_enableSelectOutLine && m_rtSourceScene) StartRTSourceScene(); */ //Pre if( NULL != m_pChildViewportObj ) { m_pChildViewportObj->Render( bClearRegister, bSetRenderTarget ); //복구 //m_dev->SetMipBias( m_fMipBias ); m_dev->SetSceneAmbientLight( m_colSceneAmbient ); m_dev->SetTransform( K3DRenderDevice::TS_PROJECTION, &m_matProjection ); m_dev->SetTransform( K3DRenderDevice::TS_VIEW, &m_matView ); } //if(GetKeyState(VK_F1)) { RenderSky(); m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); RenderCloud(); if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } m_dev->SetCullMode( K3DRenderDevice::KCM_CCW ); { RenderTerrain( true ); } if( m_pShadowViewPort ) { float scale = 1/m_pShadowViewPort->SHADOW_RATIO; m_dev->SetVertexShaderConstant(CONSTANT_TERRAIN1STTEXTURESCALE, &scale, 1); // 그림자의 uv가 시작되는 위치 if(m_pShadowViewPort) { float center[4]; center[0] = m_pShadowViewPort->GetShadowBase().x; center[1] = m_pShadowViewPort->GetShadowBase().y; center[2] = m_pShadowViewPort->GetShadowBase().z; center[3] = 0; m_dev->SetVertexShaderConstant(CONSTANT_TERRAINTEXTURECENTER, center, 4); } // 높이에의해 uv가 영향받는 수치(light의 방향과 같지만 z값이 1로 고정) //K3DVector prpos(0, 0, 0);// = pr->GetPosition(); //K3DVector litdir = (prpos - GetLight(0/**/)->position); //Normalize(litdir); //float val = (1/litdir.z); //float vecshadowProjectionByHeight[4] = { litdir.x*val, litdir.y*val, litdir.z*val, 0 }; //m_dev->SetVertexShaderConstant(CONSTANT_TERRAINTEXTUREIBH, vecshadowProjectionByHeight, 4); } { RenderTerrainShadow(m_bRenderShadow ? m_pShadowViewPort : NULL , NULL ); } // m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); /*RenderBuilding(m_pShadowViewPort, m_pDuskViewPort); RenderAlphaBuilding(m_pShadowViewPort, m_pDuskViewPort); */ m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetCullMode(K3DRenderDevice::KCM_CW); //RenderPathEffect(); { RenderQuadPrimitive(); RenderLinePrimitive(); RenderPolyLinePrimitive(); m_dev->SetVertexShaderDefault(); m_dev->SetCullMode( K3DRenderDevice::KCM_CCW ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); /*RenderProp(m_pShadowViewPort, m_pDuskViewPort); RenderAlphaProp(m_pShadowViewPort, m_pDuskViewPort); RenderPrNoLightList(); */ if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } /*RenderPrList(); RenderPrListSpecularList(); RenderPrVSList(); RenderPrVSListSpecularList(); */ RenderPrList( m_prMesh, m_bRenderShadow ? m_pShadowViewPort : NULL , NULL ); // fog off m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, 0, 0, 0, 0, 0 ); /*RenderPrNoFogList(); */ if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } /*RenderPrAlphaList(); RenderPrVSAlphaList(); RenderPrVSAlphaSpecularList(); */ } //m_bUseWater 고사양 물 옵션 체크 확인용 //m_bRenderWater 고사양 물 렌더 여부 //m_pWaterViewPort 워터 뷰포트 확인용 //m_pWaterViewPort->GetWaterQuality() 고사양 물 퀄리티 체크 // if(m_bUseWater && m_bRenderWater && m_pWaterViewPort && m_pWaterViewPort->GetWaterQuality() > 0) // { // 물그리기 // K3DMatrix mat = m_matView*m_matProjection; // DrawWaterEx(((K3DRenderDeviceDX*)m_dev)->GetD3DDevice(), *(D3DXMATRIX *)&mat, (D3DXVECTOR3*)m_pFrustum, // m_pWaterViewPort->GetWaterHeight(), 0x9977AADD, // ((K3DRenderTargetDX*)m_pWaterViewPort->GetWaterReflection())->GetD3DTexture(), // ((K3DTextureDX*)m_pWaterViewPort->GetWaterBump())->GetD3DTexture(), 0.2f); //DrawWater(( (K3DRenderDeviceDX*)m_dev)->GetD3DDevice(), // ((K3DRenderTargetDX*)m_pWaterViewPort->GetWaterReflection())->GetD3DTexture(), // ((K3DTextureDX*)m_pWaterViewPort->GetWaterBump())->GetD3DTexture(), 0.2f ); // DrawWater(( (K3DRenderDeviceDX*)m_dev)->GetD3DDevice(), // ((K3DRenderTargetDX*)m_pWaterViewPort->GetWaterReflection())->GetD3DTexture(), // ((K3DTextureDX*)m_pWaterViewPort->GetWaterBump())->GetD3DTexture() ); // } //반사맵 렌더 후 디폴트로 설정 // m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); //위에 디폴트땜시 다시 설정해 줘야 한다 // m_dev->SetDepthBufferWriteEnable( false ); // m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); // m_dev->SetCullMode(K3DRenderDevice::KCM_CCW); { m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); float campos[3]; m_ViewCamera.GetCamPos( campos[0], campos[1], campos[2] ); CSpeedGrassRT::SetCamera( campos, ( const float* ) &m_matView); m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); // No culling RenderSpeedGrass(); if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } // // Render Tree (opaque parts) // { SSpeedTreePrimitive::setTransparentRenderMode(false); // Set to non-transparent polygon rendering mode m_dev->SetCullMode( K3DRenderDevice::KCM_CW ); // Clockwise culling for SpeedTree RenderBranch(); m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); // No culling RenderFrond(); RenderLeaf(); RenderTreeBillboard(); m_dev->SetCullMode( K3DRenderDevice::KCM_CCW ); // Counterclockwise culling : default for Rappelz // // Render alpha-blended polygons // RenderPrAlphaList( m_prTransMesh, m_bRenderShadow ? m_pShadowViewPort : NULL , NULL ); //투명 지원 할 때만, 그림. if( IsSpeedTreeTransparent() ) { // // Render tree (transparent parts) // SSpeedTreePrimitive::setTransparentRenderMode(true); // Set to non-transparent polygon rendering mode m_dev->SetCullMode( K3DRenderDevice::KCM_CW ); // Clockwise culling for SpeedTree RenderBranch(true); m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); // No culling RenderFrond(true); RenderLeaf(true); // Note : Billboards have no transparent part. } m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); // { [sonador][2007.03.19] render weather RenderWeather(); // } // { [sonador][2007.04.12] RenderLightning(); // } // RenderPrAdditiveList(NULL, NULL); m_dev->SetCullMode(K3DRenderDevice::KCM_NONE); RenderBliiboardList(); m_dev->SetCullMode(K3DRenderDevice::KCM_CCW); /*RenderPrNoFogAlphaList(); RenderAdditiveBuilding(m_pShadowViewPort, m_pDuskViewPort); RenderAdditiveProp(m_pShadowViewPort, m_pDuskViewPort); */ //이놈은 무조건 최하위 RenderAdditiveBliiboard(); } } //Post //if( NULL != m_pChildViewportObj ) // m_pChildViewportObj->Render( bClearRegister ); //if( m_bUseHDR && m_nTypeHDR != HDR_TYPE_NONE ) if( m_nHdrQuality > 0 ) { ProcessHdr(); EndHdr(); } else if (m_enableSelectOutLine) { renderSelectOutLineBlend(); } m_dev->SetCullMode(K3DRenderDevice::KCM_NONE); RenderLensflare(); //} RenderSprite(); RenderWirePrimitive(); m_dev->SetCullMode(K3DRenderDevice::KCM_CCW); if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } //UI 찍은 후 다시 위에 찍는 것 추가 RenderPrList( m_prAfterSpriteMesh, m_bRenderShadow ? m_pShadowViewPort : NULL , NULL ); RenderPrAlphaList( m_prAfterSpriteTransMesh, m_bRenderShadow ? m_pShadowViewPort : NULL , NULL ); //if( 0 != HIBYTE(GetAsyncKeyState(VK_RSHIFT)) ) //{ // _oprint( "ViewPort Game - DP Count : %d\n", m_dev->GetDPCount() ); //} /// 2010.11.10 - prodongi //#ifdef _DEV if (g_UserInfo.isMonkeyTail()) { extern bool g_bDebugMode; if( g_bDebugMode && 0 != HIBYTE(GetAsyncKeyState(VK_LEFT)) ) { int nTotal = 0; int nSkyCount = m_prListSky.size(); nTotal += nSkyCount; int nCLoudCount = m_prListCloud.size(); nTotal += nCLoudCount; int nLensCount = m_prListLensFlare.size(); nTotal += nLensCount; int nLightCount = m_pLightList.size(); //nTotal += nLightCount; int nFrontSpriteCount = m_prFrontSpriteList.size(); nTotal += nFrontSpriteCount; int nFrontAdditiveSpriteCount = m_prFrontAdditiveSpriteList.size(); nTotal += nFrontAdditiveSpriteCount; int nSpriteCount = m_prSpriteList.size(); nTotal += nSpriteCount; int nAdditiveSpriteCount = m_prAdditiveSpriteList.size(); nTotal += nAdditiveSpriteCount; int nTileCount = m_prTileList.size(); nTotal += nTileCount; int nTerrainCount = m_prListTerrain.size(); nTotal += nTerrainCount; int nTerrainShadowCount = m_prListTerrainShadow.size(); nTotal += nTerrainShadowCount; int nBranchCount = m_prListBranch.size(); nTotal += nBranchCount; int nFrondCount = m_prListFrond.size(); nTotal += nFrondCount; int nLeafCount = m_prListLeaf.size(); nTotal += nLeafCount; int nTreeBillboardCount = m_prListTreeBillboard.size(); nTotal += nTreeBillboardCount; int nSpeedGrassCount = m_prListSpeedGrass.size(); nTotal += nSpeedGrassCount; int nQuadCount = m_prListQuad.size(); nTotal += nQuadCount; int nLineCount = m_prListLine.size(); nTotal += nLineCount; int nPolyLineCount = m_prListPolyLine.size(); nTotal += nPolyLineCount; int nMeshCount = m_prMesh.size(); nTotal += nMeshCount; int nTransMeshCount = m_prTransMesh.size(); nTotal += nTransMeshCount; int nBliiboardCount = m_prBliiboardList.size(); nTotal += nBliiboardCount; int nAdditiveBliiboardCount = m_prAdditiveBliiboardList.size(); nTotal += nAdditiveBliiboardCount; int nWireCount = m_wprList.size(); nTotal += nWireCount; if( nSkyCount ) _oprint( "SKY [%d] " , nSkyCount ); if( nCLoudCount ) _oprint( "CLOUD [%d] " , nCLoudCount ); if( nLensCount ) _oprint( "LENS [%d] " , nLensCount ); if( nFrontSpriteCount ) _oprint( "FSPRITE [%d] ", nFrontSpriteCount ); if( nFrontAdditiveSpriteCount ) _oprint( "FASPRITE [%d] ", nFrontAdditiveSpriteCount ); if( nSpriteCount ) _oprint( "SPRITE [%d] ", nSpriteCount ); if( nAdditiveSpriteCount ) _oprint( "ASPRITE [%d] ", nAdditiveSpriteCount ); if( nTileCount ) _oprint( "TITLE [%d] ", nTileCount ); if( nTerrainCount ) _oprint( "TERRAIN [%d] ", nTerrainCount ); if( nTerrainShadowCount ) _oprint( "TERRAINSHADOW [%d] ", nTerrainShadowCount ); if( nBranchCount ) _oprint( "BRANCH [%d] " , nBranchCount ); if( nFrondCount ) _oprint( "FROND [%d] " , nFrondCount ); if( nLeafCount ) _oprint( "LEAF [%d] " , nLeafCount ); if( nTreeBillboardCount ) _oprint( "TREEBILL [%d] " , nTreeBillboardCount ); if( nSpeedGrassCount ) _oprint( "SPEEDGRASS [%d] " , nSpeedGrassCount ); if( nQuadCount ) _oprint( "QUAD [%d] " , nQuadCount ); if( nLineCount ) _oprint( "LINE [%d] " , nLineCount ); if( nPolyLineCount ) _oprint( "POLYLINE [%d] " , nPolyLineCount ); if( nMeshCount ) _oprint( "MESH [%d] " , nMeshCount ); if( nTransMeshCount ) _oprint( "TRANS_MESH [%d] " , nTransMeshCount ); if( nBliiboardCount ) _oprint( "BLIIBOARD [%d]", nBliiboardCount ); if( nAdditiveBliiboardCount ) _oprint( "ADDITIVEBLIIBOARD [%d]", nAdditiveBliiboardCount ); if( nWireCount ) _oprint( "WIRE [%d]", nWireCount ); _oprint( "Total : %d\n", nTotal ); } } //#endif EndRender( bClearRegister ); if( bSetRenderTarget ) m_dev->SetRenderTarget(NULL); } bool SGameViewPort::InitHdr() { CreateBlurSampler(); return CreateHdrBuffers(); } // 1D 필터 void SGameViewPort::CreateBlurSampler() { float fIncU = m_fBlurRadius / ( float ) HDR_NUMSAMPLES; float fIncV = fIncU * 1.33333333333f; //float fIncParam = 1.0f / ( float ) HDR_NUMSAMPLES; // 가중치 파라미터 float fIncParam = 0.6f / ( float ) HDR_NUMSAMPLES; // 가중치 파라미터 float fStdDev = 0.35f; float fResult = 1.0f / ( fStdDev * sqrt( 2.0f * K3D_PI ) ); // 가중치 결과값 float fAccum = 0.0f; m_BlurSamplerX[ 0 ] = K3DPoint( 0.0f, 0.0f ); m_BlurSamplerY[ 0 ] = K3DPoint( 0.0f, 0.0f ); m_fBlurWeight[ 0 ] = fResult; fAccum += fResult; for( int i = 1; i <= HDR_NUMSAMPLES; i++ ) { //fResult = exp( log( fIncParam * ( float ) i ) * 2.0f ) * -1.0f + 1.0f; fResult = exp( -0.5f * pow( fIncParam * ( float ) i / fStdDev, 2 ) ) / ( fStdDev * sqrt( 2.0f * K3D_PI ) ); // + 방향 m_BlurSamplerX[ i * 2 - 1 ] = K3DPoint( fIncU * ( float ) i, 0.0f ); m_BlurSamplerY[ i * 2 - 1 ] = K3DPoint( 0.0f, fIncV * ( float ) i ); m_fBlurWeight[ i * 2 - 1 ] = fResult; fAccum += fResult; // - 방향 m_BlurSamplerX[ i * 2 ] = K3DPoint( -fIncU * ( float ) i, 0.0f ); m_BlurSamplerY[ i * 2 ] = K3DPoint( 0.0f, -fIncV * ( float ) i ); m_fBlurWeight[ i * 2 ] = fResult; fAccum += fResult; } // 노말라이즈 for( int i = 0; i < HDR_NUMSAMPLES * 2 + 1; i++ ) { m_fBlurWeight[ i ] /= fAccum; } } //// 2D 필터 //void SGameViewPort::CreateBlurSampler() //{ // float fIncU = m_fBlurRadius / ( float ) ( HDR_SAMPLESPAN / 2 ); // float fIncV = fIncU * 1.33333333333f; // //float fIncParam = 1.0f / ( float ) ( HDR_SAMPLESPAN / 2 ); // 가중치 파라미터 // float fIncParam = 0.6f / ( float ) ( HDR_SAMPLESPAN / 2 ); // 가중치 파라미터 // float fStdDev = 0.35f; // float fResult = 0.0f; // 가중치 결과값 // float fAccum = 0.0f; // // float fDist = 0.0f; // int nIndex = 0; // int numJ = 1; // int sign = 1; // int nCenterI = HDR_SAMPLESPAN / 2 + 1; // int nCenterJ = 1; // float nDistU, nDistV, fDistUV; // // for( int i = 1; i <= HDR_SAMPLESPAN; i++ ) // { // nCenterJ = numJ / 2 + 1; // // for( int j = 1; j <= numJ; j++ ) // { // nDistU = j - nCenterJ; // nDistV = i - nCenterI; // fDistUV = sqrt( ( float ) nDistU * ( float ) nDistU + ( float ) nDistV * ( float ) nDistV ); // // fResult = exp( -0.5f * pow( fIncParam * fDistUV / fStdDev, 2 ) ) / ( fStdDev * sqrt( 2.0f * K3D_PI ) ); // // m_BlurSampler[ nIndex ] = K3DPoint( fIncU * ( float ) nDistU, fIncV * ( float ) nDistV ); // m_fBlurWeight[ nIndex ] = fResult; // fAccum += fResult; // nIndex++; // } // // if( numJ == HDR_SAMPLESPAN ) sign = -1; // numJ += sign * 2; // } // // // 노말라이즈 // for( int i = 0; i < nIndex; i++ ) // { // m_fBlurWeight[ i ] /= fAccum; // } //} void SGameViewPort::CreateOcclusionBuffers() { m_spOcclusionBuffer = m_dev->CreateRenderTarget( 512, 512, 1, m_dev->GetCurrentDisplayModeFormat(), K3DRenderTarget::DEPTH_ENABLE, true ); } bool SGameViewPort::CreateHdrBuffers() { if( m_nHdrQuality < 0 ) m_nHdrQuality = 0; if( m_nHdrQuality > 1 ) m_nHdrQuality = 1; int nHdrQuality = m_nHdrQuality; switch( nHdrQuality ) { case 1: m_spHdrBlurX = m_dev->CreateRenderTarget( 512, 512, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_DISABLE ); m_spHdrBlurY = m_dev->CreateRenderTarget( 512, 512, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_DISABLE ); //m_spHdrBlur = m_dev->CreateRenderTarget( 512, 512, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_DISABLE ); if( m_spHdrBlurX && m_spHdrBlurY ) break; //if( m_spHdrSource && m_spHdrBlur ) //break; else { nHdrQuality = 0; m_nHdrQuality = 0; //모두 실패 되었으므로, HDR Off } case 0: m_spHdrBlurX = NULL; m_spHdrBlurY = NULL; //m_spHdrBlur = NULL; } if( m_nHdrQuality && ( !m_spHdrBlurX || !m_spHdrBlurY ) ) return false; //if( m_nHdrQuality && ( !m_spHdrSource || !m_spHdrBlur ) ) return false; return true; } void SGameViewPort::StartRTSourceScene() { //HDR 뷰포트 설정 m_backview = m_viewport; m_dev->SetRenderTarget( m_rtSourceScene ); int option = 0; option |= K3DRenderDevice::FILL_COLOR; option |= K3DRenderDevice::FILL_DEPTH; m_dev->SetFillColor( 0 ); m_dev->Fill(option); //뷰포트 설정 m_viewport.X = 0; m_viewport.Y = 0; float fRatio = m_dev->GetScreenVertexAspect(); m_viewport.Width = m_rtSourceScene->GetWidth(); m_viewport.Height = (DWORD)(m_rtSourceScene->GetWidth() / fRatio); m_viewport.MinZ = 0; m_viewport.MaxZ = 1; m_dev->SetViewport( m_viewport ); } void SGameViewPort::OcclusionCulling() { return; if( !m_dev->IsTestOcclusionCulling() ) return; HRESULT hr = m_dev->TestCooperativeLevel(); if( hr != S_OK ) { return; } if( m_prListTerrain.size() <= 0 ) return; if( m_spOcclusionBuffer == NULL || !m_spOcclusionBuffer->IsValid() ) return; m_backview = m_viewport; m_dev->BeginScene(); m_viewport.X = 0; m_viewport.Y = 0; m_viewport.Width = m_spOcclusionBuffer->GetWidth(); m_viewport.Height = m_spOcclusionBuffer->GetHeight(); m_viewport.MinZ = 0; m_viewport.MaxZ = 1; m_dev->SetViewport( m_viewport ); // 가로 본능 m_dev->SetRenderTarget( m_spOcclusionBuffer ); int option = 0; option |= K3DRenderDevice::FILL_COLOR; option |= K3DRenderDevice::FILL_DEPTH; m_dev->SetFillColor( KColor(200,200,200,255) ); m_dev->Fill(option); CTerrainPrimitive::SetCheckOcclusionCulling( true ); ////지형 프리미티브 랜더링 //RenderTerrain( false ); /// 2010.11.10 - prodongi //#ifdef _DEV if (g_UserInfo.isMonkeyTail()) { extern bool g_bDebugMode; if( g_bDebugMode && 0 != HIBYTE(GetAsyncKeyState(VK_HOME)) ) m_spOcclusionBuffer->SaveToFile( "OcclusionBuffer_start.dds" ); } //#endif //랜더 DWORD dwFillMode = m_dev->GetFillMode(); DWORD dwCullMode = m_dev->GetCullMode(); m_dev->SetFillMode( K3DRenderDevice::FM_SOLID ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); LPDIRECT3DDEVICE9 pD3DDevice = ((K3DRenderDeviceDX*)m_dev)->GetD3DDevice(); pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, 0 ); for( short i = 0; i < 8; ++i ) { m_dev->SetTexture( i, NULL ); } m_dev->SetVertexShader(VTXDECLARATION_TERRAIN, TECHNIQUE_TERRAIN); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; if(m_bLocalCoord) { BackUpViewCamera(); camTemp = m_ViewCamera; vecCam = camTemp.GetCamPos(); vecTar = camTemp.GetTargetPos(); vecTar -= vecCam; camTemp.SetCamPos(0.0f, 0.0f, 0.0f); camTemp.SetTargetPos(vecTar.x, vecTar.y, vecTar.z); SetCamera(&camTemp); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); m_dev->SetLocalCoordOffset( vecCam ); } else { vecCam.x = 0.0f; vecCam.y = 0.0f; vecCam.z = 0.0f; m_dev->SetLocalCoordOffset( vecCam ); } const K3DLight* pLight = GetLight(); if(pLight != NULL) { KColor color = (pLight->ambient) / 2.f; m_dev->SetTextureFactor(color.color); } std::sort( (CTerrainPrimitiveFor4Stage**)m_prListTerrain.begin(), (CTerrainPrimitiveFor4Stage**)m_prListTerrain.end(), TerrainLess() ); KCustomVector::iterator it = m_prListTerrain.begin(); CTerrainPrimitive* pTerrainPrimitive = static_cast(*it); pTerrainPrimitive->PreRenderPrimitiveGroup(m_dev, this ); int nAllCount = m_prListTerrain.size(); int nCullCount = 0; //Query LPDIRECT3DQUERY9 d3dQuery = (LPDIRECT3DQUERY9)m_dev->GetQuerry(); DWORD pixelsVisible = 0; for ( ; it != m_prListTerrain.end() ; ++it ) { d3dQuery->Issue( D3DISSUE_BEGIN ); if(m_bLocalCoord) { pRootMat = (*it)->GetRootMat(); K3DMatrixGetPosVector(vecTrans, *pRootMat); vecTrans -= vecCam; pRootMat->SetPosVector(vecTrans); (*it)->Render( this, m_dev ); vecTrans += vecCam; pRootMat->SetPosVector(vecTrans); } else { (*it)->Render( this, m_dev ); } d3dQuery->Issue( D3DISSUE_END ); // Loop until the data becomes available pixelsVisible = 0; while (d3dQuery->GetData((void *) &pixelsVisible, sizeof(DWORD), D3DGETDATA_FLUSH) == S_FALSE); if( pixelsVisible == 0 ) { (*it)->SetOcclusioCull( true ); ++nCullCount; } else (*it)->SetOcclusioCull( false ); } /// 2010.11.10 - prodongi //#ifdef _DEV if (g_UserInfo.isMonkeyTail()) { extern bool g_bDebugMode; if( g_bDebugMode && 0 != HIBYTE(GetAsyncKeyState(VK_END)) ) m_spOcclusionBuffer->SaveToFile( "OcclusionBuffer_end.dds" ); } //#endif if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } m_dev->SetRenderTarget( NULL ); m_dev->EndScene(); m_dev->SetFillMode( dwFillMode ); pD3DDevice->SetRenderState( D3DRS_COLORWRITEENABLE, 0x0000000F ); //복구 m_viewport = m_backview; m_dev->SetViewport( m_viewport ); CTerrainPrimitive::SetCheckOcclusionCulling( false ); /// 2010.11.10 - prodongi //#ifdef _DEV if (g_UserInfo.isMonkeyTail()) { extern bool g_bDebugMode; if( g_bDebugMode && 0 != HIBYTE(GetAsyncKeyState(VK_SHIFT)) && 0 != HIBYTE(GetAsyncKeyState(VK_UP)) ) _oprint( "OcclusionCulling : All[%d] Culled[%d]\n", nAllCount, nCullCount ); } //#endif } void SGameViewPort::ProcessHdr() { START_DPCOUNT("HDR Blur"); m_dev->SetDepthBufferCompareMode(K3DRenderDeviceDX::DCM_ALWAYS); m_dev->SetDepthBufferWriteEnable(false); m_dev->SetCullMode(K3DRenderDeviceDX::KCM_NONE); m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); K3DMatrix mat; K3DMatrixIdentity(mat); m_dev->SetTransform( K3DRenderDevice::TS_TEXTURE0, &mat ); m_viewport = m_backview; m_viewport.X = m_viewport.Y = 0; m_viewport.Width = m_spHdrBlurX->GetWidth(); m_viewport.Height = m_spHdrBlurX->GetHeight(); //m_viewport.Width = m_spHdrBlur->GetWidth(); //m_viewport.Height = m_spHdrBlur->GetHeight(); m_dev->SetViewport( m_viewport ); // 가로 본능 m_dev->SetRenderTarget( m_spHdrBlurX ); //// 2d 본능 //m_dev->SetRenderTarget( m_spHdrBlur ); int option = 0; option |= K3DRenderDevice::FILL_COLOR; m_dev->SetFillColor( 0 ); m_dev->Fill(option); K3DMatrix view, proj; K3DMatrixOrthoOffCenterLH( proj, 0, 2048, 0, 2048, -100.f, 8000.f ); K3DMatrixIdentity(view); m_dev->SetTransform(K3DRenderDevice::TS_PROJECTION, &proj); m_dev->SetTransform(K3DRenderDevice::TS_VIEW , &view); m_dev->SetTransform(K3DRenderDevice::TS_WORLD , &view); m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH ); m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetCullMode(K3DRenderDeviceDX::KCM_NONE); m_dev->EnableLightEffect(false); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); m_dev->SetTexture( 0, m_rtSourceScene); m_dev->SetVertexShader( 0, TECHNIQUE_BLURSCREEN ); m_dev->SetRenderState( K3DRenderDevice::RS_HDR ); m_dev->SetVertexShaderConstant( CONSTANT_BLUR_SAMPLEWEIGHT, m_fBlurWeight, HDR_NUMSAMPLES * 2 + 1 ); //m_dev->SetVertexShaderConstant( CONSTANT_BLUR_SAMPLEWEIGHT, m_fBlurWeight, HDR_NUMSAMPLES ); m_dev->SetVertexShaderConstant( CONSTANT_BLUR_SAMPLEOFFSET, ( float* ) m_BlurSamplerX, ( HDR_NUMSAMPLES * 2 + 1) * 2 ); //m_dev->SetVertexShaderConstant( CONSTANT_BLUR_SAMPLEOFFSET, ( float* ) m_BlurSampler, HDR_NUMSAMPLES * 2 ); m_dev->DrawPrimitiveUP_VS( D3DFVF_XYZ | D3DFVF_TEX1, g_vBlurVtx, 2, sizeof( float ) * 5 ); // 세로 본능 m_dev->SetRenderTarget( m_spHdrBlurY ); m_dev->SetTexture( 0, m_spHdrBlurX ); m_dev->SetVertexShaderConstant( CONSTANT_BLUR_SAMPLEOFFSET, ( float* ) m_BlurSamplerY, ( HDR_NUMSAMPLES * 2 + 1) * 2 ); m_dev->DrawPrimitiveUP_VS( D3DFVF_XYZ | D3DFVF_TEX1, g_vBlurVtx, 2, sizeof( float ) * 5 ); // 톤 맵핑 + 최종 렌더링 m_dev->SetRenderTarget( NULL ); m_viewport = m_backview; m_dev->SetViewport( m_viewport ); //static bool bSaveToDds = false; //if( bSaveToDds ) //{ // std::string strFile1 = "C:\\Down\\1.dds"; // m_spHdrSource->SaveToFile( strFile1 ); // std::string strFile2 = "C:\\Down\\2.dds"; // m_spHdrBlurY->SaveToFile( strFile2 ); // bSaveToDds = false; //} m_dev->SetTexture( 0, m_rtSourceScene ); m_dev->SetTexture( 1, m_spHdrBlurY ); if (m_enableSelectOutLine) m_dev->SetTexture( 2, m_rtSelectOutLine); //m_dev->SetTexture( 1, m_spHdrBlur ); m_dev->SetVertexShader( 0, TECHNIQUE_TONEMAPPING ); m_dev->SetVertexShaderConstant( CONSTANT_HDR_BLURMIXRATIO, &m_fHdrBlurMixRatio, 1 ); m_dev->SetVertexShaderConstant( CONSTANT_HDR_EXPOSURE, &m_fHdrExposure, 1 ); m_dev->SetVertexShaderConstant( CONSTANT_HDR_GAMMA, &m_fHdrGamma, 1 ); m_dev->DrawTriangleStripVB_VS( m_spHdrVb, 4 ); END_DPCOUNT(); } void SGameViewPort::EndHdr() { m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetCullMode( K3DRenderDeviceDX::KCM_CCW ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetDepthBufferCompareMode( K3DRenderDeviceDX::DCM_LESSEQUAL ); } void SGameViewPort::SetBlurRadius( float fRadius ) { m_fBlurRadius = fRadius; CreateBlurSampler(); } void SGameViewPort::SetHdrQuality( int nQuality ) { m_nHdrQuality = nQuality; CreateHdrBuffers(); } void SGameViewPort::SetHdrBlurMixRatio( float fRatio ) { m_fHdrBlurMixRatio = fRatio; } void SGameViewPort::SetHdrExposure( float fExposure ) { m_fHdrExposure = fExposure; } void SGameViewPort::SetHdrGamma( float fGamma ) { m_fHdrGamma = fGamma; } void SGameViewPort::createPostEffectData(bool enableSelectOutLine) { m_enableSelectOutLine = enableSelectOutLine; createSourceSceneRTData(); createSelectRTData(); } void SGameViewPort::createSourceSceneRTData() { if (m_rtSourceScene) return ; if( m_dev->GetScreenSize().width > 1024 ) m_rtSourceScene = m_dev->CreateRenderTarget( 2048, 2048, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_ENABLE ); if( m_dev->GetScreenSize().width <= 1024 || m_rtSourceScene == NULL ) m_rtSourceScene = m_dev->CreateRenderTarget( 1024, 1024, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_ENABLE ); } void SGameViewPort::createSelectRTData() { setSelectColor(K3DVector(1.0f, 0.0f, 0.0f)); createSelectRT(); float fRatio = m_dev->GetScreenVertexAspect(); createSelectRTVB(0.0f, 0.0f, (DWORD)m_rtSelect->GetWidth(), (DWORD)(m_rtSelect->GetWidth() / fRatio)); /// 수치는 직접 보면서 적용된 수치이다.(가로 1024 기준) //float selectTexInvSize = 0.00035f; float selectTexInvSize = 0.00040f; /// 해상도에 따라서 size가 변해야 된다 float r = (float)m_dev->GetScreenSize().width/1024.0f; selectTexInvSize *= r; m_dev->SetVertexShaderConstant(CONSTANT_SELECT_TEX_INV_SIZE, &selectTexInvSize, 1); } void SGameViewPort::createSelectRT() { int rtSize = 1024; /// 가로 해상도가 1024를 넘어 갔을 때, 커버 할 수 있는 최대 가로 해상도가 2048이라서 이렇게 한것 같다. if( m_dev->GetScreenSize().width > 1024 ) rtSize = 2048; if (!m_rtSelect) m_rtSelect = m_dev->CreateRenderTarget(rtSize, rtSize, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_DISABLE); if (!m_rtSelectOutLine) m_rtSelectOutLine = m_dev->CreateRenderTarget(rtSize, rtSize, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_DISABLE ); } void SGameViewPort::createSelectRTVB(float x, float y, float w, float h) { if (!m_vbSelect) { m_vbSelect = m_dev->CreateVertexBuffer( VERTEX_LENS, 4 ); } K3DVERTEX_LENS *pTempBuf = NULL; int size = 4; //Size 사용 안함. m_vbSelect->Lock( (void**) &pTempBuf, size ); pTempBuf[0].p = D3DXVECTOR3( x, y, 0.5f ); pTempBuf[0].rhw = 1.f; pTempBuf[0].tu = 0.f; pTempBuf[0].tv = 0.f; pTempBuf[1].p = D3DXVECTOR3( x+w, y, 0.5f ); pTempBuf[1].rhw = 1.f; pTempBuf[1].tu = 1.f; pTempBuf[1].tv = 0.f; pTempBuf[2].p = D3DXVECTOR3( x, y+h, 0.5f ); pTempBuf[2].rhw = 1.f; pTempBuf[2].tu = 0.f; pTempBuf[2].tv = 1.f; pTempBuf[3].p = D3DXVECTOR3( x+w, y+h, 0.5f ); pTempBuf[3].rhw = 1.f; pTempBuf[3].tu = 1.f; pTempBuf[3].tv = 1.f; pTempBuf[0].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[1].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[2].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 pTempBuf[3].color = D3DCOLOR_RGBA( 255, 255, 255, 255); //농도 m_vbSelect->Unlock(); } void SGameViewPort::renderSelectRT() { if (!m_enableSelectOutLine) return ; //뷰포트 설정 float fRatio = m_dev->GetScreenVertexAspect(); setViewPort(0, 0, m_rtSelect->GetWidth(), (DWORD)(m_rtSelect->GetWidth() / fRatio)); m_dev->SetRenderTarget(m_rtSelect); int option = 0; option |= K3DRenderDevice::FILL_COLOR; m_dev->SetFillColor( 0 ); m_dev->Fill(option); renderPrSelectList(m_prSelectMesh); m_dev->SetRenderTarget( NULL ); m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetCullMode( K3DRenderDeviceDX::KCM_CCW ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetDepthBufferCompareMode( K3DRenderDeviceDX::DCM_LESSEQUAL ); m_dev->SetViewport(m_viewport); } void SGameViewPort::renderSelectOutLineRT() { if (!m_enableSelectOutLine) return ; float fRatio = m_dev->GetScreenVertexAspect(); setViewPort(0, 0, m_rtSelectOutLine->GetWidth(), (DWORD)(m_rtSelectOutLine->GetWidth() / fRatio)); m_dev->SetRenderTarget(m_rtSelectOutLine); int option = 0; option |= K3DRenderDevice::FILL_COLOR; m_dev->SetFillColor( 0 ); m_dev->Fill(option); m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetRenderState( K3DRenderDevice::RS_HDR ); m_dev->SetCullMode(K3DRenderDevice::KCM_NONE); m_dev->SetVertexShader(0, TECHNIQUE_OUTLINE); m_dev->SetVertexShaderConstant(CONSTANT_SELECT_COLOR, m_selectColor, 3); m_dev->SetTexture(0, m_rtSelect); m_dev->SetTexture(1, NULL); m_dev->SetTexture(2, NULL); m_dev->SetTexture(3, NULL); m_dev->DrawTriangleStripVB_VS(m_vbSelect, 4); m_dev->SetRenderTarget(NULL); m_dev->SetViewport(m_viewport); } void SGameViewPort::renderSelectOutLineBlend() { m_dev->SetRenderTarget(NULL); m_dev->SetDepthBufferCompareMode(K3DRenderDeviceDX::DCM_ALWAYS); m_dev->SetDepthBufferWriteEnable(false); m_dev->SetCullMode(K3DRenderDeviceDX::KCM_NONE); m_viewport = m_backview; m_dev->SetViewport( m_viewport ); m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetVertexShader(0, TECHNIQUE_OUTLINE_BLEND); m_dev->SetTexture(0, m_rtSourceScene); m_dev->SetTexture(1, m_rtSelectOutLine); m_dev->SetTexture(2, NULL); m_dev->SetTexture(3, NULL); m_dev->DrawTriangleStripVB_VS( m_spHdrVb, 4 ); } void SGameViewPort::renderPrSelectList(vec_rendermesh& renderlist) { if(renderlist.size() <= 0) return; m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); //m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH); m_dev->SetRenderState( K3DRenderDevice::RS_SELECT_OUTLINE_MESH); m_dev->EnableLightEffect(false); m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_NO_TEX); if( m_nRenderFlag.IsOn(RENDER_PRIMITIVE) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Normal Primitive"); K3DVector vecCam; K3DMatrix* pRootMat; K3DVector vecTrans; if(m_bLocalCoord) { K3DCamera camTemp; K3DVector vecTar; BackUpViewCamera(); camTemp = m_ViewCamera; vecCam = camTemp.GetCamPos(); vecTar = camTemp.GetTargetPos(); vecTar -= vecCam; camTemp.SetCamPos(0.0f, 0.0f, 0.0f); camTemp.SetTargetPos(vecTar.x, vecTar.y, vecTar.z); SetCamera(&camTemp); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); m_dev->SetLocalCoordOffset( vecCam ); } else { vecCam.x = 0.0f; vecCam.y = 0.0f; vecCam.z = 0.0f; m_dev->SetLocalCoordOffset( vecCam ); } // sonador 1.6.2 프랍 렌더링시 정렬 문제 해결 int primCount = 0; vec_rendermesh::iterator it; for ( it = renderlist.begin(); it != renderlist.end() && primCount < MESH_POOL_COUNT; ++it, ++primCount ) { RENDER_MESHEX* pRenderMesh = it; if(m_bLocalCoord) { pRootMat = pRenderMesh->primitive->GetRootMat(); K3DMatrixGetPosVector(vecTrans, *pRootMat); vecTrans -= vecCam; pRootMat->SetPosVector(vecTrans); pRenderMesh->primitive->Render( this, m_dev ); vecTrans += vecCam; pRootMat->SetPosVector(vecTrans); } else { pRenderMesh->primitive->Render( this, m_dev ); } m_dev->SetTexture( 0, NULL ); m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, NULL ); } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } END_DPCOUNT(); } } void SGameViewPort::setViewPort(DWORD x, DWORD y, DWORD w, DWORD h, float minz, float maxz) { KViewportStruct viewport; viewport.X = x; viewport.Y = y; viewport.Width = w; viewport.Height = h; viewport.MinZ = minz; viewport.MaxZ = maxz; m_dev->SetViewport(viewport); } void SGameViewPort::setSelectColor(K3DVector const& color) { m_selectColor[0] = color.x; m_selectColor[1] = color.y; m_selectColor[2] = color.z; } // 이전 버전의 HDR, 일단 주석 처리 //bool SGameViewPort::InitHdr() //{ // m_spHDRSource = m_dev->CreateRenderTarget( HDRTEXTURE_WIDTH , HDRTEXTURE_WIDTH , 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_ENABLE ); // m_spHDRBlurSource = m_dev->CreateRenderTarget( HDRBLURTEXTURE_WIDTH, HDRBLURTEXTURE_WIDTH, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_DISABLE ); // m_spHDRBlurTarget = m_dev->CreateRenderTarget( HDRBLURTEXTURE_WIDTH, HDRBLURTEXTURE_WIDTH, 0, K3DFMT_X8R8G8B8, K3DRenderTarget::DEPTH_DISABLE ); // // if( !m_spHDRSource || !m_spHDRBlurSource || !m_spHDRBlurTarget ) return false; // // return true; //} // //void SGameViewPort::StartHdr() //{ // //HDR 뷰포트 설정 // m_backview = m_viewport; // // m_dev->BeginScene(); // m_dev->SetRenderTarget( m_spHDRSource ); // int option = 0; // option |= K3DRenderDevice::FILL_COLOR; // option |= K3DRenderDevice::FILL_DEPTH; // m_dev->SetFillColor( 0 ); // m_dev->Fill(option); // // //뷰포트 설정 // m_viewport.X = 0; // m_viewport.Y = 0; // m_viewport.Width = 1024; // m_viewport.Height = 768; // m_viewport.MinZ = 0; // m_viewport.MaxZ = 1; // m_dev->SetViewport( m_viewport ); //} // //void SGameViewPort::ProcessHdr() //{ // START_DPCOUNT("HDR Blur"); // // m_dev->SetDepthBufferCompareMode(K3DRenderDeviceDX::DCM_ALWAYS); // m_dev->SetDepthBufferWriteEnable(false); // m_dev->SetCullMode(K3DRenderDeviceDX::KCM_NONE); // m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); // K3DMatrix mat; // K3DMatrixIdentity(mat); // m_dev->SetTransform( K3DRenderDevice::TS_TEXTURE0, &mat ); // // //HDR을 여기 까지 먹여야 할 듯 하다. // m_dev->SetRenderTarget( NULL ); // // m_dev->EndScene(); // m_viewport = m_backview; // // //D3DXSaveTextureToFile("c:\\hdr1.bmp", D3DXIFF_BMP, ((K3DRenderTargetDX*)m_spHDRSource)->GetD3DTexture(), NULL); // // //HDR 소스 만들기 // //============================================================================= // //HDR one Pass // m_dev->SetRenderTarget( m_spHDRBlurSource ); // // //뷰포트 크기 변경 // m_viewport.X = m_viewport.Y = 0; // m_viewport.Width = m_spHDRBlurSource->GetWidth(); // m_viewport.Height = m_spHDRBlurSource->GetHeight(); // m_dev->SetViewport( m_viewport ); // // int option = 0; // option |= K3DRenderDevice::FILL_COLOR; // option |= K3DRenderDevice::FILL_DEPTH; // m_dev->SetFillColor( 0 ); // m_dev->Fill(option); // // K3DMatrix view, proj; // K3DMatrixOrthoOffCenterLH( &proj, 0, 2048, 0, 2048, -100.f, 8000.f ); // K3DMatrixIdentity(view); // // // m_dev->BeginScene(); // m_dev->SetTransform(K3DRenderDevice::TS_PROJECTION, &proj); // m_dev->SetTransform(K3DRenderDevice::TS_VIEW , &view); // m_dev->SetTransform(K3DRenderDevice::TS_WORLD , &view); // // m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH ); // m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); // m_dev->SetCullMode(K3DRenderDeviceDX::KCM_NONE); // m_dev->EnableLightEffect(false); // m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); // m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); // // //원본 복사 // m_dev->SetTexture( 0, m_spHDRSource ); // m_dev->DrawTriangleStripVB( m_spHDR_VB, 4 ); // m_dev->SetRenderTarget( NULL ); // // // m_dev->EndScene(); // // viewport setting // //D3DXSaveTextureToFile("c:\\hdr2.bmp", D3DXIFF_BMP, ((K3DRenderTargetDX*)m_spHDRBlurSource)->GetD3DTexture(), NULL); // // ////============================================================================= // //HDR two Pass // //블러링~ // m_dev->SetRenderTarget( m_spHDRBlurTarget ); // // option = 0; // option |= K3DRenderDevice::FILL_COLOR; // m_dev->Fill(option); // // // m_dev->BeginScene(); // m_dev->SetCullMode(K3DRenderDeviceDX::KCM_NONE); // m_dev->EnableLightEffect(false); // m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); // m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); // m_dev->SetVertexShaderDefault(); // // if( m_nTypeHDR & HDR_TYPE_CROSS ) // { // m_dev->SetVertexShader(0, TECHNIQUE_GLOWWHITESCREEN); // m_dev->SetRenderState( K3DRenderDevice::RS_HDR_BLUR01_1 ); // // float color_distort[4] = { 1, (float)m_nVarFilter01/255, 0, 1 };//- 커야됨 // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_COLORDISTORT, color_distort, 4); // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_SAMPLEWEIGHT, blur_screen_color1, 4*15); // // m_dev->SetTexture(0, m_spHDRBlurSource); // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_SAMPLEOFFSET, blur_screen_coord1, 2*15); // m_dev->DrawPrimitiveUP_VS(D3DFVF_XYZ | D3DFVF_TEX1, hdrblurvtx, 2*1, sizeof(float)*11); // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_SAMPLEOFFSET, blur_screen_coord2, 2*15); // m_dev->DrawPrimitiveUP_VS(D3DFVF_XYZ | D3DFVF_TEX1, hdrblurvtx, 2*1, sizeof(float)*11); // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_SAMPLEOFFSET, blur_screen_coord3, 2*15); // m_dev->DrawPrimitiveUP_VS(D3DFVF_XYZ | D3DFVF_TEX1, hdrblurvtx, 2*1, sizeof(float)*11); // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_SAMPLEOFFSET, blur_screen_coord4, 2*15); // m_dev->DrawPrimitiveUP_VS(D3DFVF_XYZ | D3DFVF_TEX1, hdrblurvtx, 2*1, sizeof(float)*11); // } // if( m_nTypeHDR & HDR_TYPE_BLUR ) // { // m_dev->SetVertexShader(0, TECHNIQUE_GLOWSCREEN); // m_dev->SetRenderState( K3DRenderDevice::RS_HDR_BLUR01_2 ); // // float color_distort[4] = { (float)m_nVarFilter02/255, 0, 1, 0 }; //* 작아야 됨 // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_COLORDISTORT, color_distort, 4); // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_SAMPLEWEIGHT, blur_screen_color2, 4*15); // // m_dev->SetTexture(0, m_spHDRBlurSource); // m_dev->SetVertexShaderConstant(CONSTANT_GLOW_SAMPLEOFFSET, blur_screen_coord5, 2*15); // m_dev->DrawPrimitiveUP_VS(D3DFVF_XYZ | D3DFVF_TEX1, hdrblurvtx, 2*1, sizeof(float)*11); // } // // m_dev->SetRenderTarget( NULL ); // // m_dev->EndScene(); // //////============================================================================= // // //D3DXSaveTextureToFile("c:\\hdr3.bmp", D3DXIFF_BMP, ((K3DRenderTargetDX*)m_spHDRBlurTarget)->GetD3DTexture(), NULL); // // //뷰포트 크기 변경 - 원래대로 // m_viewport = m_backview; // m_dev->SetViewport( m_viewport ); // // // m_dev->BeginScene(); // m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH ); // m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); // m_dev->SetCullMode(K3DRenderDeviceDX::KCM_NONE); // m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); // m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); // // ////원래 그림 그리기 // m_dev->SetTexture( 0, m_spHDRSource ); // m_dev->DrawTriangleStripVB( m_spShadowVB, 4 ); // // if( m_nTypeHDR & HDR_TYPE_BLUR ) // { // //약간 어둡게 하기 // m_dev->SetRenderState( K3DRenderDevice::RS_HDR_BLUR02 ); // m_dev->SetTextureFactor(m_dwHDR_Factor); // m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); // m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); // // m_dev->SetTexture(0, NULL); // m_dev->SetTexture(1, NULL); // m_dev->SetTexture(2, NULL); // m_dev->SetTexture(3, NULL); // m_dev->SetVertexShaderDefault(); // m_dev->DrawPrimitiveUP(D3DFVF_XYZ | D3DFVF_TEX3, fullscreenvtx, 2, sizeof(float)*9); // } // // //블러 텍스쳐 씌우기 // m_dev->SetRenderState( K3DRenderDevice::RS_HDR_END ); // m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); // m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); // // m_dev->SetTransform(K3DRenderDevice::TS_PROJECTION, &proj); // m_dev->SetTransform(K3DRenderDevice::TS_VIEW , &view); // m_dev->SetTransform(K3DRenderDevice::TS_WORLD , &view); // // m_dev->SetTexture(0, m_spHDRBlurTarget); // m_dev->SetTexture(1, NULL); // m_dev->SetTexture(2, NULL); // m_dev->SetTexture(3, NULL); // m_dev->SetVertexShaderDefault(); // m_dev->DrawTriangleStripVB( m_spShadowVB, 4 ); // // END_DPCOUNT(); //} // //void SGameViewPort::EndHdr() //{ // m_dev->SetCullMode(K3DRenderDeviceDX::KCM_CCW); // m_dev->SetDepthBufferWriteEnable(true); // m_dev->SetDepthBufferCompareMode(K3DRenderDeviceDX::DCM_LESSEQUAL); //}