#include "stdafx.h" #include "SViewPort.h" #include "k3dcamera.h" #include "KPrimitive.h" #include "TerrainPrimitive.h" #include "KRenderDeviceDX.h" #include "KRenderObject.h" //#include "SEnvPrimitive.h" #include "SSpeedTreeVertexShaders.h" #include #include "GameDefine.h" #include "KResourceManager.h" //#include "KPrimitiveSpeedGrass.h" #include "KSeqSpeedGrass.h" #include //#include /// 2010.11.10 - prodongi #include "SItemDB.h" #include "SGameLobbyDefine.h" #ifdef CLOUD_LUA #include "SGameCloud.h" #endif #ifdef _DEBUG_DPCOUNT bool __output_dp = false; enum { __TYPE_ITEM = 0, __TYPE_VIEWPORT, }; struct __RENDER_ITEM_INFO { std::string Name; int Type; int DP; int Face; LONGLONG Time; }; std::vector<__RENDER_ITEM_INFO> __vtRenderItem; float __getCountPerMesc() { LARGE_INTEGER counter; QueryPerformanceFrequency( &counter); return static_cast( counter.LowPart )/ 1000.f; } void __outputResult(LPCSTR name, int DP, int face, LONGLONG time, DWORD Ratio) { const static float COUNT_PER_MESC = __getCountPerMesc(); static char buf[1024]; std::string ouput_str = name; size_t tabCount = 10 - ouput_str.size() / 4; ouput_str.append(tabCount, '\t'); std::string tabAlignDP = "\t\t"; if(DP > 99) tabAlignDP ="\t"; std::string tabAlignFace = "\t\t"; if(face > 1000) tabAlignFace ="\t"; _oprint("%s - DP: %d, %sFace: %d, %sAverage Face: %.2f, \tTime: %.2fms, \tPercent: %d%%\n",ouput_str.c_str(),DP, tabAlignDP.c_str(), face, tabAlignFace.c_str(), static_cast(face) / DP, static_cast(time) / COUNT_PER_MESC , Ratio); } void __startOneFrame() { __vtRenderItem.clear(); __output_dp = 0 != HIBYTE(GetAsyncKeyState(VK_RSHIFT)); } void __endOneFrame() { if(false == __output_dp) return; _oprint("*************************************************Start One Frame*************************************************\n"); DWORD totalTime =0; int totalDP = 0; int totalFace = 0; for(size_t i = 0; i < __vtRenderItem.size(); ++i) { if(__TYPE_ITEM == __vtRenderItem.at(i).Type ) { totalTime += __vtRenderItem.at(i).Time; totalDP += __vtRenderItem.at(i).DP; totalFace += __vtRenderItem.at(i).Face; } } bool bRenderViewport = false; for(size_t i = 0; i < __vtRenderItem.size(); ++i) { const __RENDER_ITEM_INFO& info = __vtRenderItem.at(i); if(__TYPE_VIEWPORT == info.Type ) { // 예전에 찍던게 있으면 if(bRenderViewport) { _oprint("-------------------------------------------------------------------------------------------------------------------\n"); } bRenderViewport = true; _oprint("-------------------------------------------------------------------------------------------------------------------\n"); _oprint("Start printing DP for %s\n",info.Name.c_str()); continue; } __outputResult(info.Name.c_str(), info.DP, info.Face, info.Time, static_cast(info.Time)/ totalTime * 100.f ); } const static float COUNT_PER_MESC = __getCountPerMesc(); _oprint("-------------------------------------------------------------------------------------------------------------------\n"); _oprint("Total DP: %d, Total Face: %d, Total Time: %.2fms\n", totalDP, totalFace, static_cast(totalTime) / COUNT_PER_MESC ); _oprint("*************************************************End One Frame*************************************************\n"); } void __startRenderToViewport(LPCSTR viewportName) { if(false == __output_dp) return; __RENDER_ITEM_INFO item; item.Type = __TYPE_VIEWPORT; item.Name = viewportName; __vtRenderItem.push_back(item); } void __addRenderItem(LPCSTR name,int DP, int face, LARGE_INTEGER counter1, LARGE_INTEGER counter2) { if(false == __output_dp || DP == 0) return; __RENDER_ITEM_INFO item; item.DP = DP; item.Name = name; item.Face = face; item.Time = counter2.QuadPart - counter1.QuadPart; item.Type = __TYPE_ITEM; __vtRenderItem.push_back(item); } #endif SViewPort::SViewPort( DWORD attr, bool bClearColorBuffer, bool bClearDepthBuffer) : KViewportObject( attr, bClearColorBuffer, bClearDepthBuffer ) { ClearRegisteredList(); int n = 0xffffffff; m_nRenderFlag.CopyFrom( &n ); K3DMatrixIdentity( m_matProjection ); K3DMatrixIdentity( m_matView ); K3DMatrixIdentity( m_matInvView ); //#ifndef NDEBUG // m_bDebugMode = false; //#endif //m_bLocalCoord = true; m_bRenderSelfShadow = false; // true 로 바꾸지 말 것 (워터뷰포트에도 적용되는 불상사가 일어남) by blackfish m_bRenderBumpMap = false; // true 로 바꾸지 말 것 (워터뷰포트에도 적용되는 불상사가 일어남) by blackfish m_nUseSpecular = 0; // true 로 바꾸지 말 것 (워터뷰포트에도 적용되는 불상사가 일어남) by blackfish m_fSelfShadowAmbientFactor = 1.f; } SViewPort::~SViewPort() { } void SViewPort::SetRenderFlag( int nFlag ) { if( m_nRenderFlag.IsOn(nFlag) ) m_nRenderFlag.Off(nFlag); else m_nRenderFlag.On(nFlag); } void SViewPort::Initilaize( K3DRenderDevice *dev, const KViewportStruct &viewarea, float nearClip, float farClip ) { KViewportObject::Initilaize( dev, viewarea, nearClip, farClip ); } void SViewPort::ClearRegisteredList() { KViewportObject::ClearRegisteredList(); } void SViewPort::Register( K3DPrimitive *pr, DWORD flag ) { //if( !m_bUseSpecular && pr->IsSpecular() ) //스페큘러 지원 안하는 클라이언트는 강제로 끈다. // pr->SetSpecular( m_bUseSpecular ); //if( m_bUseSpecular && pr->IsSpecular() ) // pr->SetSpecular( true ); //else // pr->SetSpecular( false ); //if( pr->IsSpecular() ) // pr->SetSpecular( true ); //else // pr->SetSpecular( false ); // 어차피 Shader에서 Point Light 지원을 현재 안하고 있기 때문에 사용하나 마나 (attenuation 설정때문에 걸리지도 않는다) int usablelit = 0; if( pr->IsPosition() && m_pLightList.size() ) { //사용할 Light Index 구하기 float distance = 9999999; for(int i = 1 ; i < m_pLightList.size(); ++i) { const K3DLight *lit = m_pLightList[i]; K3DVector * pos = (K3DVector *)&pr->GetTransform()->_41; float tdist = K3DVectorLength((lit->position - *pos)); if(tdist < lit->range && tdist < distance && 1.f/(1+tdist*lit->attenuation1) > 0.05f) { distance = tdist; usablelit = i; } } } pr->SetLightIndex( usablelit ); // 투명 오브젝트의 경우는 포그에서 항상 제외 switch ( LOWORD(flag) ) { /*case KRenderObject::RENDEREFX_NONE: { } break; case KRenderObject::RENDEREFX_NOFOG: { } break; case KRenderObject::RENDEREFX_NOLIGHT: { } break;*/ case KRenderObject::RENDEREFX_SKY: { pr->SetSpecular(false); m_prListSky.push_back( pr ); } break; case KRenderObject::RENDEREFX_CLOUD: { pr->SetSpecular(false); m_prListCloud.push_back( pr ); } break; // { [sonador] case KRenderObject::RENDEREFX_LIGHTNING: { pr->SetSpecular( false ); m_prListLightning.push_back( pr ); } break; // } case KRenderObject::RENDEREFX_LENSFLARE: { pr->SetSpecular(false); m_prListLensFlare.push_back( pr ); } break; // { [sonador][2007.03.19] case KRenderObject::RENDEREFX_WEATHER: { pr->SetSpecular( false ); m_prListWeather.push_back( pr ); } break; // } case KRenderObject::RENDEREFX_TERRAIN: { pr->SetSpecular(false); m_prListTerrain.push_back( pr ); } break; case KRenderObject::RENDEREFX_SHADOW_TERRAIN: { //스페큘러도 꺼지면, 그림자는 찍지 않는다. //if( m_bUseSpecular == false ) return; m_prListTerrainShadow.push_back( pr ); } break; /*case KRenderObject::RENDEREFX_BUILDING: case KRenderObject::RENDEREFX_BUILDING_HAS_STOOL: { } break; case KRenderObject::RENDEREFX_PROP: case KRenderObject::RENDEREFX_PROP_HAS_STOOL : { } break; case KRenderObject::RENDEREFX_PROP_NOMIP: { } break;*/ case KRenderObject::RENDEREFX_SPEEDTREE_BRANCH : { pr->SetSpecular(true); m_prListBranch.push_back( pr ); } break; case KRenderObject::RENDEREFX_SPEEDTREE_FROND : { pr->SetSpecular(false); m_prListFrond.push_back( pr ); } break; case KRenderObject::RENDEREFX_SPEEDTREE_LEAF : { pr->SetSpecular(false); //잎 사귀는 반투명 안 한다. 안 이쁨. m_prListLeaf.push_back( pr ); } break; case KRenderObject::RENDEREFX_SPEEDTREE_BILLBOARD : { pr->SetSpecular(false); //잎 사귀는 반투명 안 한다. 안 이쁨. m_prListTreeBillboard.push_back( pr ); } break; case KRenderObject::RENDEREFX_SPEEDGRASS : { pr->SetSpecular(false); m_prListSpeedGrass.push_back( pr ); } break; //case KRenderObject::RENDEREFX_PATHEFFECT: // { // pr->SetSpecular(false); // m_prListPathEffect.push_back(pr); // } // break; case KRenderObject::RENDEREFX_QUAD: { pr->SetSpecular(false); m_prListQuad.push_back(pr); } break; case KRenderObject::RENDEREFX_LINE: { pr->SetSpecular(false); m_prListLine.push_back(pr); } break; case KRenderObject::RENDEREFX_POLYLINE: { pr->SetSpecular(false); m_prListPolyLine.push_back(pr); } break; case KRenderObject::RENDEREFX_WATER: { // { sonador 7.0.14 카메라 위치에 따른 물효과 컬링 문제 수정 bool valid = false; if ( pr->IsTransparent() == false ) { RENDER_MESHEX container; float depth = pr->GetMagicNumber() + usablelit; valid = AllocNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth, 0, true ); if( valid ) m_prMesh.push_back( container ); } else { const K3DVector& pos = pr->GetCenterPosition(); float depth = K3DVectorLength( pos - GetCameraTargetPos() ); // sonador 1.6.2 프랍 렌더링시 정렬 문제 해결 RENDER_MESHEX container; valid = AllocNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth, 0, true ); if( valid ) { m_prTransMesh.push_back( container ); if( pr->GetBlendMode() == K3DMaterial::MBM_ALPHABLENDTWOPASS ) { valid = AllocNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth, 1, true ); if( valid ) m_prTransMesh.push_back( container ); } } } // } } break; /*case KRenderObject::RENDEREFX_SHADOW: { } break;*/ case KRenderObject::RENDEREFX_AFTER_SPRITE: { bool valid = false; if ( pr->IsTransparent() == false ) { float depth = pr->GetMagicNumber() + usablelit; RENDER_MESHEX container; valid = AllocAfterSpriteNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth ); if( valid ) m_prAfterSpriteMesh.push_back( container ); } else { const K3DVector& pos = pr->GetCenterPosition(); float depth = K3DVectorLength( pos - GetCameraTargetPos() ); // sonador 1.6.2 프랍 렌더링시 정렬 문제 해결 RENDER_MESHEX container; valid = AllocAfterSpriteNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth ); if( valid ) m_prAfterSpriteTransMesh.push_back( container ); if( pr->GetBlendMode() == K3DMaterial::MBM_ALPHABLENDTWOPASS ) { valid = AllocAfterSpriteNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth, 1 ); if( valid ) m_prAfterSpriteTransMesh.push_back( container ); } } } break; case KRenderObject::RENDEREFX_SELECT: { RENDER_MESHEX container; float depth = pr->GetMagicNumber() + usablelit; bool valid = AllocNewMeshEX( container, pr, LOWORD( flag ), usablelit, false, false, pr->GetVSMode(), false, false ); if( valid ) m_prSelectMesh.push_back( container ); } break; default: { bool valid = false; if ( pr->IsTransparent() == false ) { RENDER_MESHEX container; float depth = pr->GetMagicNumber() + usablelit; valid = AllocNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth ); if( valid ) m_prMesh.push_back( container ); } else { const K3DVector& pos = pr->GetCenterPosition(); float depth = K3DVectorLength( pos - GetCameraTargetPos() ); // sonador 1.6.2 프랍 렌더링시 정렬 문제 해결 RENDER_MESHEX container; valid = AllocNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth ); if( valid ) { m_prTransMesh.push_back( container ); if( pr->GetBlendMode() == K3DMaterial::MBM_ALPHABLENDTWOPASS ) { valid = AllocNewMeshEX( container, pr, LOWORD( flag ), usablelit, pr->IsBump(), pr->IsSpecular(), pr->GetVSMode(), pr->IsUseLightMap(), depth, 1 ); if( valid ) m_prTransMesh.push_back( container ); } } } } break; } } void SViewPort::Render( K3DRenderTarget *pRT, DWORD flag, bool bClearRegister ) { // m_useRenderTarget = true; if( flag == SHADOW_DEFAULT ) { KViewportStruct backview = m_viewport; m_dev->BeginScene(); m_dev->SetRenderTarget( pRT ); m_viewport.X = m_viewport.Y = 0; m_viewport.Width = pRT->GetWidth(); m_viewport.Height = pRT->GetHeight(); this->Render( bClearRegister, false ); m_dev->SetRenderTarget( NULL ); m_dev->EndScene(); m_viewport = backview; } // m_useRenderTarget = false; } void SViewPort::RenderSky() { ////////////////////////////////////////////////////////////////////////// //하늘 if ( m_prListSky.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_SKY) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Sky"); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_NOLIGHT_VTXCOLOR ); // sonador 4.2.1 스카이 박스 포그 오류 수정 m_dev->SetFogMode( K3DRenderDevice::FOGM_HEIGHT, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); float TopColor[4] = { m_SkyColorStart.r, m_SkyColorStart.g, m_SkyColorStart.b, m_SkyColorStart.a }; float MidColor[4] = { m_SkyColorMid.r , m_SkyColorMid.g , m_SkyColorMid.b , m_SkyColorMid.a }; float BottomColor[4] = { m_SkyColorEnd.r , m_SkyColorEnd.g , m_SkyColorEnd.b , m_SkyColorEnd.a }; m_dev->SetVertexShaderConstant( CONSTANT_SKYCOLORBALANCE_TOP , TopColor , 4 ); m_dev->SetVertexShaderConstant( CONSTANT_SKYCOLORBALANCE_MID , MidColor , 4 ); m_dev->SetVertexShaderConstant( CONSTANT_SKYCOLORBALANCE_BOTTOM, BottomColor, 4 ); float fMaxHeight = (m_vTarPos.z + m_fSkyMaxHeight); float fMinHeight = (m_vTarPos.z - m_fSkyMinHeight); float fMidHeight = fMaxHeight * m_fSKyMidPercent; m_dev->SetVertexShaderConstant( CONSTANT_SKYMAX_HEIGHT, &fMaxHeight, 1 ); m_dev->SetVertexShaderConstant( CONSTANT_SKYMID_HEIGHT, &fMidHeight, 1 ); m_dev->SetVertexShaderConstant( CONSTANT_SKYMIN_HEIGHT, &fMinHeight, 1 ); m_dev->SetVertexShader(VTXDECLARATION_OBJECTMESH, TECHNIQUE_SKYBOX); KCustomVector::iterator it = m_prListSky.begin(); for ( ; it != m_prListSky.end() ; ++it ) { (*it)->Render( this, m_dev ); } // restore fog mode m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); END_DPCOUNT(); } } } void SViewPort::RenderCloud() { ////////////////////////////////////////////////////////////////////////// //구름 if ( m_prListCloud.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_CLOUD) ) { #ifdef CLOUD_LUA // m_dev->SetVertexShaderDefault(); m_dev->ResetPrevDeclarationTechnique(); #else m_dev->ResetPrevDeclarationTechnique(); #endif START_DPCOUNT("Cloud"); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_ALWAYS ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_CLOUD ); // { [sonador] //m_dev->SetVertexShader(VTXDECLARATION_OBJECTMESH, TECHNIQUE_CLOUDSPREAD); m_dev->SetVertexShader(VTXDECLARATION_CLOUD, TECHNIQUE_CLOUDSPREAD); // } K3DVector4 uvani(0, 0, 0, 1); m_dev->SetVertexShaderConstant(CONSTANT_UVANIMATION, (float *)&uvani, 4); if( m_bLocalCoord ) { BackUpViewCamera(); K3DVector vCampos, vCamtargetpos; vCampos = m_ViewCamera.GetCamPos(); vCamtargetpos = m_ViewCamera.GetTargetPos(); vCamtargetpos = vCamtargetpos - vCampos; m_ViewCamera.SetCamPos( 0.f, 0.f, 0.f ); m_ViewCamera.SetTargetPos( vCamtargetpos.x, vCamtargetpos.y, vCamtargetpos.z ); SetCamera( &m_ViewCamera ); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); // [sonador][1.1.4]구름 효과 오류 수정 float campos[4] = { 0.f, 0.f, 0.f, 0.f }; m_dev->SetVertexShaderConstant(CONSTANT_CLOUDSPREADCENTER, campos, 4); KCustomVector::iterator it = m_prListCloud.begin(); for ( ; it != m_prListCloud.end() ; ++it ) { #ifdef CLOUD_LUA #else K3DMatrix matTrans = *(*it)->GetTransform(); K3DVector vOripos = K3DVector( matTrans._41, matTrans._42, matTrans._43 ); vOripos = vOripos - vCampos; // [sonador][1.1.4]구름 효과 오류 수정 K3DMatrixTranslation( matTrans, 0.f, 0.f, 0.f ); m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matTrans ); #endif (*it)->Render( this, m_dev ); } RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); } else { float campos[4] = { m_ViewCamera.GetTargetPos().x, m_ViewCamera.GetTargetPos().y, m_ViewCamera.GetTargetPos().z, 0.f }; m_dev->SetVertexShaderConstant(CONSTANT_CLOUDSPREADCENTER, campos, 4); KCustomVector::iterator it = m_prListCloud.begin(); for ( ; it != m_prListCloud.end() ; ++it ) { K3DMatrix matTrans = *(*it)->GetTransform(); m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matTrans ); (*it)->Render( this, m_dev ); } } END_DPCOUNT(); } } } // { [sonador][2007.04.12] 번개 효과 렌더링 void SViewPort::RenderLightning() { if( m_prListLightning.size() > 0 ) { START_DPCOUNT("Lightning"); m_dev->SetVertexShaderDefault(); m_dev->ResetPrevDeclarationTechnique(); // set render state m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetRenderState( K3DRenderDevice::RS_WEATHER ); // call render method KCustomVector::iterator it, itEnd = m_prListLightning.end(); for( it = m_prListLightning.begin(); it != itEnd; ++it ) { K3DPrimitive* pPrim = *it; if( pPrim ) { pPrim->Render( this, m_dev ); } } END_DPCOUNT(); } } // } // { [sonador][2007.03.19] 비 효과 랜더링 void SViewPort::RenderWeather() { if( m_prListWeather.size() > 0 ) { START_DPCOUNT("Weather"); m_dev->SetVertexShaderDefault(); m_dev->ResetPrevDeclarationTechnique(); // set render state m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetRenderState( K3DRenderDevice::RS_WEATHER ); m_dev->SetVertexShader( VTXDECLARATION_WEATHER, TECHNIQUE_WEATHER ); // call render method KCustomVector::iterator it, itEnd = m_prListWeather.end(); for( it = m_prListWeather.begin(); it != itEnd; ++it ) { (*it)->Render( this, m_dev ); } END_DPCOUNT(); } } // } /// 2010.11.10 - prodongi //#ifdef _DEV //extern bool g_bDebugMode; //#endif void SViewPort::RenderTerrain( bool bCheckOcclusionCull ) { if( !m_nRenderFlag.IsOn(RENDER_TERRAIN) || m_prListTerrain.size() <= 0 ) return; m_dev->ResetPrevDeclarationTechnique(); int nAllCount = m_prListTerrain.size(); int nDrawCount = 0; START_DPCOUNT("Terrain"); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; //K3DVector4 vec4; 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); //vec4.x = vecCam.x; //vec4.y = vecCam.y; //vec4.z = vecCam.z; //vec4.w = 0.0f; //m_dev->SetVertexShaderConstant(CONSTANT_LOCALCOORD_OFFSET, (float*) &vec4, 4); m_dev->SetLocalCoordOffset( vecCam ); } else { //vec4.x = 0.0f; vec4.y = 0.0f; vec4.z = 0.0f; vec4.w = 0.0f; //m_dev->SetVertexShaderConstant(CONSTANT_LOCALCOORD_OFFSET, (float*) &vec4, 4); 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); } KCustomVector::iterator it = m_prListTerrain.begin(); CTerrainPrimitive* pTerrainPrimitive = static_cast(*it); pTerrainPrimitive->PreRenderPrimitiveGroup(m_dev, this ); for ( ; it != m_prListTerrain.end() ; ++it ) { if( bCheckOcclusionCull && (*it)->IsOcclusioCulled() ) continue; ++nDrawCount; 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 ); } } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } //pTerrainPrimitive->PostRenderPrimitiveGroup(m_dev, this ); /// 2010.11.10 - prodongi //#ifdef _DEV if (g_UserInfo.isMonkeyTail()) { extern bool g_bDebugMode; if( bCheckOcclusionCull && g_bDebugMode && 0 != HIBYTE(GetAsyncKeyState(VK_SHIFT)) && 0 != HIBYTE(GetAsyncKeyState(VK_DOWN)) ) _oprint( "OcclusionCulling : All[%d] Drawed[%d]\n", nAllCount, nDrawCount ); } //#endif END_DPCOUNT(); } void SViewPort::RenderTerrainShadow(SRenderTargetContainer *cont1, SRenderTargetContainer *cont2) { if( m_prListTerrainShadow.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_TERRAIN_SHADOW) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Terrain Shadow"); m_dev->SetRenderState( K3DRenderDevice::RS_SHADOW_MESH ); 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 ); m_dev->SetVertexShaderLight( GetLight() ); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; //K3DVector4 vec4; 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); //vec4.x = vecCam.x; //vec4.y = vecCam.y; //vec4.z = vecCam.z; //vec4.w = 0.0f; //m_dev->SetVertexShaderConstant(CONSTANT_LOCALCOORD_OFFSET, (float*) &vec4, 4); m_dev->SetLocalCoordOffset( vecCam ); } else { //vec4.x = 0.0f; vec4.y = 0.0f; vec4.z = 0.0f; vec4.w = 0.0f; //m_dev->SetVertexShaderConstant(CONSTANT_LOCALCOORD_OFFSET, (float*) &vec4, 4); vecCam.x = 0.0f; vecCam.y = 0.0f; vecCam.z = 0.0f; m_dev->SetLocalCoordOffset( vecCam ); } KCustomVector::iterator it = m_prListTerrainShadow.begin(); for ( ; it != m_prListTerrainShadow.end() ; ++it ) { m_dev->SetTexture( 0, cont1 ? cont1->GetRenderTarget(0, (*it)) : NULL ); m_dev->SetTexture( 1, cont2 ? cont2->GetRenderTarget(0, (*it)) : NULL ); m_dev->SetTexture( 3, NULL ); 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 ); } } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); END_DPCOUNT(); } } } namespace { enum { _STATE_INVALID = 0, _STATE_NORMAL_OBJECT, _STATE_NORMAL_SKINMESH, _STATE_LIGHTMAP, _STATE_SPECULAR, _STATE_BUMP, }; inline int getStateByOption( bool bUseBump, bool bUseSpecular, bool bSkinMesh, bool bUseLightmap ) { if(bUseBump) return _STATE_BUMP; else if( bUseSpecular ) return _STATE_SPECULAR; else if(bUseLightmap) return _STATE_LIGHTMAP; else if( bSkinMesh ) return _STATE_NORMAL_SKINMESH; else return _STATE_NORMAL_OBJECT; } enum PRALPHALIST_FLAG { DEFAULT_AHLPHA_BUMP_MAP = 1 << 1, DEFAULT_AHLPHA_BUMP_MAP_SELFSHADOW = 1 << 2, DEFAULT_AHLPHA_BUMP_MAP_NOT_SELFSHADOW = 1 << 3, DEFAULT_AHLPHA_SPECULAR_MAP = 1 << 4, DEFAULT_AHLPHA_LIGHT_MAP = 1 << 5, DEFAULT_AHLPHA_DEFAULT_MAP = 1 << 6, DEFAULT_AHLPHA_DEFAULT_MAP_VSMODE = 1 << 7, DEFAULT_AHLPHA_DEFAULT_MAP_NOT_VSMODE = 1 << 8, ALPHABLENDTWOPASS_BUMP_MAP = 1 << 9, ALPHABLENDTWOPASS_BUMP_MAP_SELFSHADOW = 1 << 10, ALPHABLENDTWOPASS_BUMP_MAP_NOT_SELFSHADOW = 1 << 11, ALPHABLENDTWOPASS_SPECULAR_MAP = 1 << 12, ALPHABLENDTWOPASS_LIGHT_MAP = 1 << 13, ALPHABLENDTWOPASS_DEFAULT_MAP = 1 << 14, ALPHABLENDTWOPASS_DEFAULT_MAP_VSMODE = 1 << 15, ALPHABLENDTWOPASS_DEFAULT_MAP_NOT_VSMODE = 1 << 16, ADDITIVE_SPECULAR_MAP = 1 << 17, ADDITIVE_LIGHT_MAP = 1 << 18, ADDITIVE_DEFAULT_MAP = 1 << 19, }; } void SViewPort::RenderPrList(vec_rendermesh& renderlist, SRenderTargetContainer *cont1, SRenderTargetContainer *cont2) { if(renderlist.size() <= 0) return; std::sort( renderlist.begin(), renderlist.end(), MeshLess() ); if( m_nRenderFlag.IsOn(RENDER_PRIMITIVE) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Normal Primitive"); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; //K3DVector4 vec4; 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 ); } // 현재는 이런 코드로 땜빵하지만, State별로 Sort 하는게 필요할듯.. DWORD oldState = _STATE_INVALID; int oldLightIndex = -1; const K3DLight* pLight = GetLight(); if(pLight != NULL) { KColor color = (pLight->ambient) / 2.f; m_dev->SetTextureFactor(color.color); } // 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_dev->VizQueryIssueBegin() && it->primitive->SupportsBoundOcclusion() ) { K3DMatrix world_mat; K3DMatrixIdentity( world_mat ); if(m_bLocalCoord) { world_mat = *it->primitive->GetRootMat(); K3DMatrixGetPosVector(vecTrans, world_mat ); vecTrans -= vecCam; world_mat.SetPosVector(vecTrans); } m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &world_mat ); it->primitive->RenderBoundOcclusion( this, m_dev ); if( m_dev->VizQueryIssueEnd() == false ) { oldState = _STATE_INVALID; oldLightIndex = -1; m_dev->ResetPrevDeclarationTechnique(); continue; } }*/ #ifdef _SPECULAR_EDITING_ DWORD newState = getStateByOption( pRenderMesh->bUseBump, pRenderMesh->bUseSpecular, pRenderMesh->primitive->GetVSMode(), pRenderMesh->bUseLightmap ); #else DWORD newState = getStateByOption( pRenderMesh->bUseBump && m_bRenderBumpMap, ( pRenderMesh->bUseSpecular || ( pRenderMesh->bUseBump && !m_bRenderBumpMap ) ) && m_nUseSpecular, pRenderMesh->primitive->GetVSMode(), pRenderMesh->bUseLightmap ); #endif // if(newState != oldState) { oldState = newState; switch(newState) { case _STATE_NORMAL_OBJECT: m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); m_dev->SetRenderState( K3DRenderDevice::RS_OBJECTSHADOW_SPECULAR2X ); m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH); break; case _STATE_NORMAL_SKINMESH: m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); break; case _STATE_LIGHTMAP: m_dev->SetRenderState( K3DRenderDevice::RS_OBJECTSHADOW_LIGHTMAP); m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH_LIGHTMAP); break; case _STATE_SPECULAR: m_dev->SetRenderState( K3DRenderDevice::RS_MESH_SPECULAR ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_SPECULAR); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); break; case _STATE_BUMP: m_dev->SetRenderState( K3DRenderDevice::RS_MESH_SPECULAR ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); if(m_bRenderSelfShadow) { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_BUMP_SPECULAR_SELFSHADOW ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SELFSHADOW_AMBIENT_FACTOR, (float*) &m_fSelfShadowAmbientFactor, 1); } else { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_BUMP_SPECULAR ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } break; } } // 이건 매번 해줘야 하므로..(ATI 때문에-_-) switch(newState) { case _STATE_NORMAL_OBJECT: m_dev->SetTexture( 1, cont1 ? cont1->GetRenderTarget(0, pRenderMesh->primitive) : NULL ); m_dev->SetTexture( 2, cont2 ? cont2->GetRenderTarget(0, pRenderMesh->primitive) : NULL ); break; case _STATE_NORMAL_SKINMESH: break; case _STATE_LIGHTMAP: m_dev->SetTexture( 2, cont1 ? cont1->GetRenderTarget(0, pRenderMesh->primitive) : NULL ); m_dev->SetTexture( 3, cont2 ? cont2->GetRenderTarget(0, pRenderMesh->primitive) : NULL ); break; case _STATE_SPECULAR: m_dev->SetTexture( 3, cont1 ? cont1->GetRenderTarget(1, pRenderMesh->primitive) : NULL ); break; case _STATE_BUMP: if(m_bRenderSelfShadow) m_dev->SetTexture( 3, cont1 ? cont1->GetRenderTarget(1, pRenderMesh->primitive) : NULL ); break; } //MTE if( pRenderMesh->primitive->GetEnableMTE() ) { if( pRenderMesh->primitive->IsSpecular() ) m_dev->SetRenderState( K3DRenderDevice::RS_MTE ); else m_dev->SetRenderState( K3DRenderDevice::RS_MTE_S1 ); } if(oldLightIndex != pRenderMesh->nLitIndex) { oldLightIndex = pRenderMesh->nLitIndex; m_dev->SetVertexShaderLight(GetLight(oldLightIndex) ) ; } 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 SViewPort::RenderPrAlphaList( vec_rendermesh& renderlist, SRenderTargetContainer *cont1, SRenderTargetContainer *cont2) { if(renderlist.size() <= 0) return; std::sort( renderlist.begin(), renderlist.end(), TransMeshLess() ); if( !m_nRenderFlag.IsOn(RENDER_PRIMITIVE_ALPHA) ) return; START_DPCOUNT("Primitive Alpha"); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->ResetPrevDeclarationTechnique(); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat = NULL; 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 ); } KCustomVector< const RENDER_MESHEX* > m_TopTransMesh; KCustomVector< const RENDER_MESHEX* > m_MidTransMesh; KCustomVector< const RENDER_MESHEX* > m_BotTransMesh; vec_rendermesh::iterator iter = renderlist.begin(); for( ; iter != renderlist.end() ; ) { const RENDER_MESHEX *mesh = iter; if( mesh->primitive->GetBlendMode() == K3DMaterial::MBM_LQ_WATER || mesh->primitive->GetBlendMode() == K3DMaterial::MBM_HQ_WATER ) { m_MidTransMesh.push_back( mesh ); } else { //물 높이가 존재 한다면 if( m_bExistenceWaterHeight ) { const K3DVector &pos = mesh->primitive->GetCenterPosition(); if( m_fWaterHeight < pos.z ) m_TopTransMesh.push_back( mesh ); else m_BotTransMesh.push_back( mesh ); } else m_TopTransMesh.push_back( mesh ); } ++iter; } const K3DLight* pLight = GetLight(); if(pLight != NULL) { KColor color = (pLight->ambient) / 2.f; m_dev->SetTextureFactor(color.color); } SetOldBlendMode( K3DMaterial::MBM_MAX, true ); if( m_bInsideWater ) { RenderPrAlphaList( cont1, cont2, m_TopTransMesh, vecCam, false ); RenderPrAlphaList( cont1, cont2, m_MidTransMesh, vecCam, false ); RenderPrAlphaList( cont1, cont2, m_BotTransMesh, vecCam, false ); RenderPrAlphaList( cont1, cont2, m_TopTransMesh, vecCam, true ); RenderPrAlphaList( cont1, cont2, m_MidTransMesh, vecCam, true ); RenderPrAlphaList( cont1, cont2, m_BotTransMesh, vecCam, true ); } else { RenderPrAlphaList( cont1, cont2, m_BotTransMesh, vecCam, false ); RenderPrAlphaList( cont1, cont2, m_MidTransMesh, vecCam, false ); RenderPrAlphaList( cont1, cont2, m_TopTransMesh, vecCam, false ); RenderPrAlphaList( cont1, cont2, m_BotTransMesh, vecCam, true ); RenderPrAlphaList( cont1, cont2, m_MidTransMesh, vecCam, true ); RenderPrAlphaList( cont1, cont2, m_TopTransMesh, vecCam, true ); } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } m_TopTransMesh.clear(); m_MidTransMesh.clear(); m_BotTransMesh.clear(); END_DPCOUNT(); } void SViewPort::RenderPrAlphaList(SRenderTargetContainer *cont1, SRenderTargetContainer *cont2, KCustomVector< const RENDER_MESHEX* > & vMesh, K3DVector & vecCam, bool bEnableAdditive ) { DWORD old_cull_mode; int nBlendMode = K3DMaterial::MBM_MAX; for( int it = 0; it < vMesh.size(); it++ ) { K3DVector vecTrans; K3DMatrix* pRootMat; const RENDER_MESHEX *mesh = vMesh[it]; const RENDER_MESHEX *render_mesh; /* if( m_dev->VizQueryIssueBegin() && mesh->primitive->SupportsBoundOcclusion() ) { K3DMatrix world_mat; K3DMatrixIdentity( world_mat ); if(m_bLocalCoord) { world_mat = *mesh->primitive->GetRootMat(); K3DMatrixGetPosVector(vecTrans, world_mat ); vecTrans -= vecCam; world_mat.SetPosVector(vecTrans); } m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &world_mat ); mesh->primitive->RenderBoundOcclusion( this, m_dev ); if( m_dev->VizQueryIssueEnd() == false ) { m_dev->ResetPrevDeclarationTechnique(); continue; } }*/ SetOldBlendMode( nBlendMode ); //이전 BlendMode 저장 nBlendMode = mesh->primitive->GetBlendMode(); if( bEnableAdditive ) { if( nBlendMode != K3DMaterial::MBM_ADDITIVE && nBlendMode != K3DMaterial::MBM_ADDTIVE_BILLBOARD && nBlendMode != K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_ADD && nBlendMode != K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND_ADD ) { SetOldBlendFlag(); continue; } } else { if( nBlendMode == K3DMaterial::MBM_ADDITIVE || nBlendMode == K3DMaterial::MBM_ADDTIVE_BILLBOARD || nBlendMode == K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_ADD || nBlendMode == K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND_ADD ) { SetOldBlendFlag(); continue; } } if( nBlendMode == K3DMaterial::MBM_DEFAULT || nBlendMode == K3DMaterial::MBM_ALPHABLEND ) { if( m_nOldBlendMode != K3DMaterial::MBM_DEFAULT && m_nOldBlendMode != K3DMaterial::MBM_ALPHABLEND ) { if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } if( m_nOldBlendMode != nBlendMode ) { if( nBlendMode == K3DMaterial::MBM_DEFAULT ) m_dev->SetDepthBufferWriteEnable( true ); else m_dev->SetDepthBufferWriteEnable( false ); } if( mesh->bUseBump && m_bRenderBumpMap ) { if( ( m_nOldBlend_Flag & DEFAULT_AHLPHA_BUMP_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MESH_SPECULAR ); m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } if( m_bRenderSelfShadow ) { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_BUMP_SPECULAR_SELFSHADOW ); if( ( m_nOldBlend_Flag & DEFAULT_AHLPHA_BUMP_MAP_SELFSHADOW ) == false ) { m_dev->SetVertexShaderConstant(CONSTANT_SELFSHADOW_AMBIENT_FACTOR, (float*) &m_fSelfShadowAmbientFactor, 1); } m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, cont1 ? cont1->GetRenderTarget(1, mesh->primitive) : NULL ); SetOldBlendFlag( DEFAULT_AHLPHA_BUMP_MAP | DEFAULT_AHLPHA_BUMP_MAP_SELFSHADOW ); } else { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_BUMP_SPECULAR ); m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, NULL ); SetOldBlendFlag( DEFAULT_AHLPHA_BUMP_MAP | DEFAULT_AHLPHA_BUMP_MAP_NOT_SELFSHADOW ); } } else if( ( mesh->bUseSpecular || ( mesh->bUseBump && !m_bRenderBumpMap ) ) && m_nUseSpecular ) { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_SPECULAR); if( ( m_nOldBlend_Flag & DEFAULT_AHLPHA_SPECULAR_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MESH_SPECULAR ); m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); // m_dev->SetRenderState( K3DRenderDevice::RS_ALPHATEST ); //gmbpigsun( 20130117 ) m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, cont1 ? cont1->GetRenderTarget(1, mesh->primitive) : NULL ); SetOldBlendFlag( DEFAULT_AHLPHA_SPECULAR_MAP ); } else if(mesh->bUseLightmap) { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH_LIGHTMAP); if( ( m_nOldBlend_Flag & DEFAULT_AHLPHA_LIGHT_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_OBJECTSHADOW_LIGHTMAP); m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); } m_dev->SetTexture( 2, cont1 ? cont1->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 3, cont2 ? cont2->GetRenderTarget(0, mesh->primitive) : NULL ); SetOldBlendFlag( DEFAULT_AHLPHA_LIGHT_MAP ); } else { if( ( m_nOldBlend_Flag & DEFAULT_AHLPHA_DEFAULT_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); } if(mesh->primitive->GetVSMode()) { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH); if( ( m_nOldBlend_Flag & DEFAULT_AHLPHA_DEFAULT_MAP_VSMODE ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } SetOldBlendFlag( DEFAULT_AHLPHA_DEFAULT_MAP | DEFAULT_AHLPHA_DEFAULT_MAP_VSMODE ); } else { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH); if( ( m_nOldBlend_Flag & DEFAULT_AHLPHA_DEFAULT_MAP_NOT_VSMODE ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); m_dev->SetRenderState( K3DRenderDevice::RS_OBJECTSHADOW_SPECULAR2X ); } m_dev->SetTexture( 1, cont1 ? cont1->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 2, cont2 ? cont2->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 3, NULL ); SetOldBlendFlag( DEFAULT_AHLPHA_DEFAULT_MAP | DEFAULT_AHLPHA_DEFAULT_MAP_NOT_VSMODE ); } } } else if( nBlendMode == K3DMaterial::MBM_ALPHABLEND_NOALPHAUVANI ) { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_NOUVANIIN2NDTEX ); if( m_nOldBlendMode != nBlendMode ) { if( m_fogMode != K3DRenderDevice::FOGM_NONE ) m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH_NOALPHAUVANI ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } SetOldBlendFlag(); } else if( nBlendMode == K3DMaterial::MBM_ALPHABLEND_NOCOLORUVANI ) { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_NOUVANIIN2NDTEX ); if( m_nOldBlendMode != nBlendMode ) { if( m_fogMode != K3DRenderDevice::FOGM_NONE ) m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH_NOCOLORUVANI ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } SetOldBlendFlag(); } else if( nBlendMode == K3DMaterial::MBM_ALPHABLENDTWOPASS ) { if( m_nOldBlendMode != nBlendMode ) { if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } } if( mesh->bUseBump && m_bRenderBumpMap ) { if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_BUMP_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MESH_SPECULAR ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); //m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); } if( m_bRenderSelfShadow ) { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_BUMP_SPECULAR_SELFSHADOW ); if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_BUMP_MAP_SELFSHADOW ) == false ) { m_dev->SetVertexShaderConstant(CONSTANT_SELFSHADOW_AMBIENT_FACTOR, (float*) &m_fSelfShadowAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, cont1 ? cont1->GetRenderTarget(1, mesh->primitive) : NULL ); SetOldBlendFlag( ALPHABLENDTWOPASS_BUMP_MAP | ALPHABLENDTWOPASS_BUMP_MAP_SELFSHADOW ); } else { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_BUMP_SPECULAR ); if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_BUMP_MAP_NOT_SELFSHADOW ) == false ) { m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, NULL ); SetOldBlendFlag( ALPHABLENDTWOPASS_BUMP_MAP | ALPHABLENDTWOPASS_BUMP_MAP_NOT_SELFSHADOW ); } } else if( ( mesh->bUseSpecular || ( mesh->bUseBump && !m_bRenderBumpMap ) ) && m_nUseSpecular ) { //헤어 m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_SPECULAR); if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_SPECULAR_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MESH_SPECULAR ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); //m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, cont1 ? cont1->GetRenderTarget(1, mesh->primitive) : NULL ); SetOldBlendFlag( ALPHABLENDTWOPASS_SPECULAR_MAP ); } else if(mesh->bUseLightmap) { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH_LIGHTMAP); if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_LIGHT_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_OBJECTSHADOW_LIGHTMAP); //m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); } m_dev->SetTexture( 2, cont1 ? cont1->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 3, cont2 ? cont2->GetRenderTarget(0, mesh->primitive) : NULL ); SetOldBlendFlag( ALPHABLENDTWOPASS_LIGHT_MAP ); } else { if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_DEFAULT_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); //m_dev->SetRenderState( K3DRenderDevice::RS_TRANSPARENT_MESH ); } if(mesh->primitive->GetVSMode()) { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH); if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_DEFAULT_MAP_VSMODE ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } SetOldBlendFlag( ALPHABLENDTWOPASS_DEFAULT_MAP | ALPHABLENDTWOPASS_DEFAULT_MAP_VSMODE ); } else { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH); if( ( m_nOldBlend_Flag & ALPHABLENDTWOPASS_DEFAULT_MAP_NOT_VSMODE ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); m_dev->SetRenderState( K3DRenderDevice::RS_OBJECTSHADOW_SPECULAR2X ); } m_dev->SetTexture( 1, cont1 ? cont1->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 2, cont2 ? cont2->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 3, NULL ); SetOldBlendFlag( ALPHABLENDTWOPASS_DEFAULT_MAP | ALPHABLENDTWOPASS_DEFAULT_MAP_NOT_VSMODE ); } } //이건 그냥 매번해주자 if( mesh->nPass == 0 ) { m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetRenderState( K3DRenderDevice::RS_ALPHABLEND_1STPASS ); } else { m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_ALPHABLEND_2NDPASS ); } } else if( nBlendMode == K3DMaterial::MBM_ADDITIVE) { if( m_nOldBlendMode != nBlendMode ) { m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); } if(mesh->bUseSpecular) { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_SPECULAR); if( ( m_nOldBlend_Flag & ADDITIVE_SPECULAR_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, NULL ); SetOldBlendFlag( ADDITIVE_SPECULAR_MAP ); } else if(mesh->bUseLightmap) { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH_LIGHTMAP); if( ( m_nOldBlend_Flag & ADDITIVE_LIGHT_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_OBJECTSHADOW_LIGHTMAP); m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH_WITHOUT_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); } m_dev->SetTexture( 2, cont1 ? cont1->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 3, cont2 ? cont2->GetRenderTarget(0, mesh->primitive) : NULL ); SetOldBlendFlag( ADDITIVE_LIGHT_MAP ); } else { m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH); if( ( m_nOldBlend_Flag & ADDITIVE_DEFAULT_MAP ) == false ) { m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } m_dev->SetTexture( 1, cont1 ? cont1->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 2, cont2 ? cont2->GetRenderTarget(0, mesh->primitive) : NULL ); m_dev->SetTexture( 3, NULL ); SetOldBlendFlag( ADDITIVE_DEFAULT_MAP ); } } else if( nBlendMode == K3DMaterial::MBM_ADDITIVE_NOALPHAUVANI ) { SetOldBlendFlag(); m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_NOUVANIIN2NDTEX ); if( m_nOldBlendMode != nBlendMode ) { m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH_NOALPHAUVANI ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } } else if( nBlendMode == K3DMaterial::MBM_ADDITIVE_NOCOLORUVANI ) { m_dev->SetVertexShader( VTXDECLARATION_SKINMESH, TECHNIQUE_SKINMESH_NOUVANIIN2NDTEX ); if( m_nOldBlendMode != nBlendMode ) { m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_MESH_NOCOLORUVANI ); m_dev->SetRenderState( K3DRenderDevice::RS_DISABLE_UVTRANSFORM ); m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); m_dev->SetVertexShaderConstant(CONSTANT_AMBIENT_FACTOR, &m_fSkinAmbientFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_DIFFUSE_FACTOR, &m_fSkinDiffuseFactor, 1); m_dev->SetVertexShaderConstant(CONSTANT_SPECULAR_FACTOR, &m_fSkinSpecularFactor, 1); } SetOldBlendFlag(); } else if( nBlendMode == K3DMaterial::MBM_BILLBOARD) { SetOldBlendFlag(); if( m_nOldBlendMode != nBlendMode ) { m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetRenderState( K3DRenderDevice::RS_BILLBOARD ); } m_dev->SetTransformIdentity( K3DRenderDevice::TS_WORLD ); } else if( nBlendMode == K3DMaterial::MBM_ADDTIVE_BILLBOARD) { SetOldBlendFlag(); if( m_nOldBlendMode != nBlendMode ) { m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_PARTICLE ); } m_dev->SetTransformIdentity( K3DRenderDevice::TS_WORLD ); } else if( nBlendMode == K3DMaterial::MBM_SELECT_FX) { SetOldBlendFlag(); render_mesh = mesh; if( m_nOldBlendMode != nBlendMode ) { m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_SELECT_TARGET_FX); m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetRenderState( K3DRenderDevice::RS_SELECT_EFFECT ); K3DVector4 uvani(0.f, 0.f, 0, 1.f ); m_dev->SetVertexShaderConstant(CONSTANT_UVANIMATION, (float *)&uvani, 4); } pRootMat = render_mesh->primitive->GetRootMat(); K3DMatrixGetPosVector(vecTrans, *pRootMat); vecTrans -= vecCam; K3DMatrix matWorld; K3DMatrixTranslation( matWorld, vecTrans.x, vecTrans.y, vecTrans.z ); m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matWorld ); render_mesh->primitive->Render( this, m_dev ); //m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); //continue; goto SET_NULLTEXTURE; } else if( nBlendMode == K3DMaterial::MBM_LQ_WATER) { SetOldBlendFlag(); render_mesh = mesh; //if( !m_bLocalCoord ) continue; if( !m_bLocalCoord ) goto SET_NULLTEXTURE; old_cull_mode = m_dev->GetCullMode(); m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); //IDirect3DDevice9* pD3dDevice = ((K3DRenderDeviceDX*) m_dev)->GetD3DDevice(); //pD3dDevice->SetRenderState( D3DRS_FOGENABLE, TRUE ); if( m_nOldBlendMode != nBlendMode ) { if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); m_dev->SetRenderState( K3DRenderDevice::RS_LQWATER ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetVertexShader(VTXDECLARATION_WATER, TECHNIQUE_WATER_SPECULAR); m_dev->SetVertexShaderLight( GetLight() ); } K3DMatrix mat; K3DMatrixIdentity(mat); m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &mat ); K3DMatrix matWorld = *mesh->primitive->GetTransform();; K3DVector vOripos = K3DVector( matWorld._41, matWorld._42, matWorld._43 ); vOripos = vOripos - vecCam; K3DMatrixTranslation( matWorld, vOripos.x, vOripos.y, vOripos.z ); m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matWorld ); render_mesh->primitive->Render( this, m_dev ); //m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); m_dev->SetCullMode( old_cull_mode ); //continue; goto SET_NULLTEXTURE; } else if( nBlendMode == K3DMaterial::MBM_HQ_WATER ) { SetOldBlendFlag(); //if( !DrawWater() ) continue; if( !DrawWater() ) goto SET_NULLTEXTURE; m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetVertexShader( VTXDECLARATION_WATER, TECHNIQUE_HQWATER ); //m_dev->SetVertexShaderDefault(); IDirect3DDevice9* pD3dDevice = ((K3DRenderDeviceDX*) m_dev)->GetD3DDevice(); pD3dDevice->SetRenderState( D3DRS_FOGENABLE, TRUE ); //K3DMatrix matWorld, matView, matProj; //matWorld = *m_dev->GetTransform( K3DRenderDevice::TS_WORLD ); //matView = *m_dev->GetTransform( K3DRenderDevice::TS_VIEW ); //matProj = *m_dev->GetTransform( K3DRenderDevice::TS_PROJECTION ); //K3DMatrix matIdent; //K3DMatrixIdentity( matIdent ); //m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matIdent ); //m_dev->SetTransform( K3DRenderDevice::TS_VIEW, &matIdent ); //m_dev->SetTransform( K3DRenderDevice::TS_PROJECTION, &matIdent ); //m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matWorld ); //m_dev->SetTransform( K3DRenderDevice::TS_VIEW, &matView ); //m_dev->SetTransform( K3DRenderDevice::TS_PROJECTION, &matProj ); pRootMat = mesh->primitive->GetRootMat(); K3DMatrixGetPosVector(vecTrans, *pRootMat); vecTrans -= vecCam; pRootMat->SetPosVector(vecTrans); render_mesh = mesh; render_mesh->primitive->Render( this, m_dev ); vecTrans += vecCam; pRootMat->SetPosVector(vecTrans); //m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matWorld ); //m_dev->SetTransform( K3DRenderDevice::TS_VIEW, &matView ); //m_dev->SetTransform( K3DRenderDevice::TS_PROJECTION, &matProj ); //반사맵 렌더 후 디폴트로 설정 m_dev->SetRenderState( K3DRenderDevice::RS_DEFAULT ); //위에 디폴트땜시 다시 설정해 줘야 한다 m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetCullMode(K3DRenderDevice::KCM_CCW); //continue; goto SET_NULLTEXTURE; } else if( nBlendMode == K3DMaterial::MBM_CIRCLE_FX) { SetOldBlendFlag(); if( m_nOldBlendMode != nBlendMode ) { m_dev->SetRenderState( K3DRenderDevice::RS_LOWSHADOW); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetVertexShader(VTXDECLARATION_SKINMESH, TECHNIQUE_OBJECTMESH); m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } render_mesh = mesh; } #ifdef _DEBUG else if( nBlendMode == K3DMaterial::MBM_ENVMAP) { SetOldBlendFlag(); render_mesh = mesh; m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); if( !DrawWater() ) goto SET_NULLTEXTURE; m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetVertexShader(VTXDECLARATION_ENVMAP, TECHNIQUE_ENVMAP); m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); pRootMat = render_mesh->primitive->GetRootMat(); K3DMatrixGetPosVector(vecTrans, *pRootMat); vecTrans -= vecCam; K3DMatrix matWorld; K3DMatrixTranslation( matWorld, vecTrans.x, vecTrans.y, vecTrans.z ); m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &matWorld ); render_mesh->primitive->Render( this, m_dev ); vecTrans += vecCam; pRootMat->SetPosVector(vecTrans); m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); continue; } #endif else if ( (nBlendMode == K3DMaterial::MBM_ALPHATEX ) || (nBlendMode == K3DMaterial::MBM_ALPHATEX_EDGEENHANCE) || (nBlendMode == K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND) || (nBlendMode == K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_ADD) || (nBlendMode == K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND_ADD)) { // Colored-textured and alpha blended, with fog SetOldBlendFlag(); if( m_nOldBlendMode != nBlendMode ) { // TEMPORARY : disable fog for alpha-... m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); m_dev->SetDepthBufferWriteEnable( false ); // Disable depth buffer modification switch ( nBlendMode ) { case K3DMaterial::MBM_ALPHATEX_EDGEENHANCE: m_dev->SetRenderState(K3DRenderDevice::RS_ALPHATEX); m_dev->SetVertexShader(VTXDECLARATION_ALPHATEX, TECHNIQUE_ALPHATEX_EDGEENHANCE); break; case K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND: m_dev->SetRenderState(K3DRenderDevice::RS_ALPHATEX); m_dev->SetVertexShader(VTXDECLARATION_ALPHATEX, TECHNIQUE_ALPHATEX_EDGEENHANCE_BLEND); break; case K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_ADD: m_dev->SetRenderState(K3DRenderDevice::RS_ALPHATEX_ADD); m_dev->SetVertexShader(VTXDECLARATION_ALPHATEX, TECHNIQUE_ALPHATEX_EDGEENHANCE); break; case K3DMaterial::MBM_ALPHATEX_EDGEENHANCE_BLEND_ADD: m_dev->SetRenderState(K3DRenderDevice::RS_ALPHATEX_ADD); m_dev->SetVertexShader(VTXDECLARATION_ALPHATEX, TECHNIQUE_ALPHATEX_EDGEENHANCE_BLEND); break; case K3DMaterial::MBM_ALPHATEX: default: m_dev->SetRenderState(K3DRenderDevice::RS_ALPHATEX); m_dev->SetVertexShader(VTXDECLARATION_ALPHATEX, TECHNIQUE_ALPHATEX); } } m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, NULL ); m_dev->SetTexture( 4, NULL ); } //MTE if( mesh->primitive->GetEnableMTE() ) { if( mesh->primitive->IsSpecular() ) m_dev->SetRenderState( K3DRenderDevice::RS_MTE ); else m_dev->SetRenderState( K3DRenderDevice::RS_MTE_S1 ); } render_mesh = mesh; // KMeshPrimitive에서 매번해주는걸 뺐기 때문에. m_dev->SetVertexShaderLight(GetLight(render_mesh->nLitIndex ) ); if(m_bLocalCoord) { pRootMat = (render_mesh->primitive)->GetRootMat(); K3DMatrixGetPosVector(vecTrans, *pRootMat); vecTrans -= vecCam; pRootMat->SetPosVector(vecTrans); render_mesh->primitive->Render( this, m_dev ); vecTrans += vecCam; pRootMat->SetPosVector(vecTrans); } else { render_mesh->primitive->Render( this, m_dev ); } SET_NULLTEXTURE: m_dev->SetTexture( 0, NULL ); m_dev->SetTexture( 1, NULL ); m_dev->SetTexture( 2, NULL ); m_dev->SetTexture( 3, NULL ); } } void SViewPort::SetOldBlendMode( int nBlendMode, bool bReset ) { if( bReset ) { m_nOldBlendMode = K3DMaterial::MBM_MAX; m_nOldBlend_Flag = 0; } else { if( ( m_nOldBlendMode == K3DMaterial::MBM_ALPHABLEND || m_nOldBlendMode == K3DMaterial::MBM_DEFAULT ) && ( nBlendMode == K3DMaterial::MBM_ALPHABLEND || nBlendMode == K3DMaterial::MBM_DEFAULT ) ) { } else if( m_nOldBlendMode != K3DMaterial::MBM_MAX && m_nOldBlendMode != nBlendMode ) { SetOldBlendFlag( 0 ); } m_nOldBlendMode = nBlendMode; } } void SViewPort::SetOldBlendFlag( int nFlag ) { m_nOldBlend_Flag = nFlag; } void SViewPort::RenderPrAdditiveList(SRenderTargetContainer *cont1, SRenderTargetContainer *cont2) { } void SViewPort::RenderBranch(bool renderTransparentOrOpaque) // true : render opqaue only, false : render transparent only { if( m_prListBranch.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_SPEED_TREE) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Branch"); if (renderTransparentOrOpaque) { // Transparent polygon m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_ALPHABLEND ); } else { // Opaque polygon m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_NONALPHABLEND ); } // m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); ((K3DRenderDeviceDX*)m_dev)->SetVertexShaderBranch(); //K3DMatrix TrBlendShaderMatrix; //K3DMatrixTranspose( &TrBlendShaderMatrix, &m_matBlendShader ); //m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; K3DVector4 vec4; float fFogOfsZ = 0.0f; 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); K3DMatrix BlendShaderMatrix, TrBlendShaderMatrix; K3DMatrixMultiply(BlendShaderMatrix, m_matView, m_matProjection); K3DMatrixTranspose( TrBlendShaderMatrix, BlendShaderMatrix ); m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); fFogOfsZ = vecCam.z; } #ifdef WRAPPER_USE_FOG D3DXVECTOR4 vecConstant1(m_fogFactor1, m_fogFactor2, (1.0f / (m_fogFactor2 - m_fogFactor1)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog1, (float*)&vecConstant1, 1 ); D3DXVECTOR4 vecConstant2(m_fogFactor3 - fFogOfsZ, m_fogFactor4 - fFogOfsZ, (1.0f / (m_fogFactor4 - m_fogFactor3)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog2, (float*)&vecConstant2, 1 ); #endif KCustomVector::iterator it = m_prListBranch.begin(); for ( ; it != m_prListBranch.end() ; ++it ) { // 투명모드인가 아닌가 if ((*it)->IsTransparent()!=renderTransparentOrOpaque) continue; { const K3DLight* pLight = GetLight((*it)->GetLightIndex()); K3DVector litdir; if(pLight->type == K3DLight::LT_POINT) { K3DVector *pos = (K3DVector*)&(*it)->GetTransform()->_41; //litdir = GetLight(0)->position - *pos; litdir = pLight->position - *pos; } else if(pLight->type == K3DLight::LT_DIRECTIONAL) { //litdir = GetLight(0)->direction; litdir = pLight->direction * -1.0f; } else { assert(0 && "포인트, 디렉셔널 타입 외의 광원은 지원하지 않음."); } //K3DVector litdir = GetLight(1)->position - *pos; // 임시코드 Normalize(litdir); // setup shader constants for light const float afLighting[] = { litdir.x, litdir.y, litdir.z, 1.0f, // [71] normalized light direction //1.0f, 0.0f, 0.0f, 1.0f, // 임시 코드 //GetLight(0)->ambient.r, GetLight(0)->ambient.g, GetLight(0)->ambient.b, GetLight(0)->ambient.a, // [72] light ambient color pLight->ambient.r, pLight->ambient.g, pLight->ambient.b, pLight->ambient.a, // [72] light ambient color //GetLight(0)->diffuse.r, GetLight(0)->diffuse.g, GetLight(0)->diffuse.b, GetLight(0)->diffuse.a // [73] light diffuse color pLight->diffuse.r, pLight->diffuse.g, pLight->diffuse.b, pLight->diffuse.a // [73] light diffuse color }; m_dev->SetVertexShaderConstant( c_nVertexShader_Light, afLighting, 3 ); } 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 ); } } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } END_DPCOUNT(); } } } void SViewPort::RenderFrond(bool renderTransparentOrOpaque) { if( m_prListFrond.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_SPEED_TREE) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Frond"); if (renderTransparentOrOpaque) { // Transparent polygon m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_ALPHABLEND ); } else { // Opaque polygon m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_NONALPHABLEND ); } // m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); //K3DMatrix TrBlendShaderMatrix; //K3DMatrixTranspose( &TrBlendShaderMatrix, &m_matBlendShader ); //m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); // 이 중복 코드좀 없앴으면 하는 소망이있음 -_- K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; K3DVector4 vec4; float fFogOfsZ = 0.0f; 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); K3DMatrix BlendShaderMatrix, TrBlendShaderMatrix; K3DMatrixMultiply(BlendShaderMatrix, m_matView, m_matProjection); K3DMatrixTranspose( TrBlendShaderMatrix, BlendShaderMatrix ); m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); fFogOfsZ = vecCam.z; } #ifdef WRAPPER_USE_FOG D3DXVECTOR4 vecConstant1(m_fogFactor1, m_fogFactor2, (1.0f / (m_fogFactor2 - m_fogFactor1)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog1, (float*)&vecConstant1, 1 ); D3DXVECTOR4 vecConstant2(m_fogFactor3 - fFogOfsZ, m_fogFactor4 - fFogOfsZ, (1.0f / (m_fogFactor4 - m_fogFactor3)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog2, (float*)&vecConstant2, 1 ); #endif KCustomVector::iterator it = m_prListFrond.begin(); for ( ; it != m_prListFrond.end() ; ++it ) { // 투명모드인가 아닌가 if ((*it)->IsTransparent()!=renderTransparentOrOpaque) continue; 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 ); } } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } END_DPCOUNT(); } } } void SViewPort::RenderLeaf(bool renderTransparentOrOpaque) { if( m_prListLeaf.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_SPEED_TREE) ) { m_dev->ResetPrevDeclarationTechnique(); // m_dev->SetMipBias( 0.f ); START_DPCOUNT("Leaf"); if (renderTransparentOrOpaque) { // Transparent polygon m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_ALPHABLEND ); } else { // Opaque polygon m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_NONALPHABLEND ); } // m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); //m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); ((K3DRenderDeviceDX*)m_dev)->SetVertexShaderLeaf(); //K3DMatrix TrBlendShaderMatrix; //K3DMatrixTranspose( &TrBlendShaderMatrix, &m_matBlendShader ); //m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; K3DVector4 vec4; float fFogOfsZ = 0.0f; 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); K3DMatrix BlendShaderMatrix, TrBlendShaderMatrix; K3DMatrixMultiply(BlendShaderMatrix, m_matView, m_matProjection); K3DMatrixTranspose( TrBlendShaderMatrix, BlendShaderMatrix ); m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); fFogOfsZ = vecCam.z; } #ifdef WRAPPER_USE_FOG D3DXVECTOR4 vecConstant1(m_fogFactor1, m_fogFactor2, (1.0f / (m_fogFactor2 - m_fogFactor1)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog1, (float*)&vecConstant1, 1 ); D3DXVECTOR4 vecConstant2(m_fogFactor3 - fFogOfsZ, m_fogFactor4 - fFogOfsZ, (1.0f / (m_fogFactor4 - m_fogFactor3)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog2, (float*)&vecConstant2, 1 ); #endif KCustomVector::iterator it = m_prListLeaf.begin(); for ( ; it != m_prListLeaf.end() ; ++it ) { // 투명모드인가 아닌가 if ((*it)->IsTransparent()!=renderTransparentOrOpaque) continue; { const K3DLight* pLight = GetLight((*it)->GetLightIndex()); K3DVector litdir; if(pLight->type == K3DLight::LT_POINT) { K3DVector *pos = (K3DVector*)&(*it)->GetTransform()->_41; //litdir = GetLight(0)->position - *pos; litdir = pLight->position - *pos; } else if(pLight->type == K3DLight::LT_DIRECTIONAL) { //litdir = GetLight(0)->direction; litdir = pLight->direction * -1.0f; } else { assert(0 && "포인트, 디렉셔널 타입 외의 광원은 지원하지 않음."); } //K3DVector litdir = GetLight(1)->position - *pos; // 임시코드 Normalize(litdir); // setup shader constants for light const float afLighting[] = { litdir.x, litdir.y, litdir.z, 1.0f, // [71] normalized light direction //1.0f, 0.0f, 0.0f, 1.0f, // 임시 코드 //GetLight(0)->ambient.r, GetLight(0)->ambient.g, GetLight(0)->ambient.b, GetLight(0)->ambient.a, // [72] light ambient color pLight->ambient.r, pLight->ambient.g, pLight->ambient.b, pLight->ambient.a, // [72] light ambient color //GetLight(0)->diffuse.r, GetLight(0)->diffuse.g, GetLight(0)->diffuse.b, GetLight(0)->diffuse.a // [73] light diffuse color pLight->diffuse.r, pLight->diffuse.g, pLight->diffuse.b, pLight->diffuse.a // [73] light diffuse color }; m_dev->SetVertexShaderConstant( c_nVertexShader_Light, afLighting, 3 ); } 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 ); } } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } END_DPCOUNT(); } } } // sonador #2.1.7.1 스피드 트리 퍼포먼스 증가 void SViewPort::RenderTreeBillboard() { #ifdef WRAPPER_BILLBOARD_MODE if( m_prListTreeBillboard.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_SPEED_TREE) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Tree Billboard"); //if (renderTransparentOrOpaque) { // // Transparent polygon // m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_ALPHABLEND ); //} else { // Opaque polygon m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_TREE_NONALPHABLEND ); //} //m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); //m_dev->SetRenderState( K3DRenderDevice::RS_MODULATE2X ); //m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); ((K3DRenderDeviceDX*)m_dev)->SetVertexShaderSpeedTreeBillboard(); //K3DMatrix TrBlendShaderMatrix; //K3DMatrixTranspose( &TrBlendShaderMatrix, &m_matBlendShader ); //m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); K3DCamera camTemp; K3DVector vecCam; K3DVector vecTar; K3DMatrix* pRootMat; K3DVector vecTrans; K3DVector4 vec4; float fFogOfsZ = 0.0f; 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); K3DMatrix BlendShaderMatrix, TrBlendShaderMatrix; K3DMatrixMultiply(BlendShaderMatrix, m_matView, m_matProjection); K3DMatrixTranspose( TrBlendShaderMatrix, BlendShaderMatrix ); m_dev->SetVertexShaderConstant( c_nVertexShader_CompoundMatrix, &TrBlendShaderMatrix, 4 ); fFogOfsZ = vecCam.z; } #ifdef WRAPPER_USE_FOG D3DXVECTOR4 vecConstant1(m_fogFactor1, m_fogFactor2, (1.0f / (m_fogFactor2 - m_fogFactor1)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog1, (float*)&vecConstant1, 1 ); D3DXVECTOR4 vecConstant2(m_fogFactor3 - fFogOfsZ, m_fogFactor4 - fFogOfsZ, (1.0f / (m_fogFactor4 - m_fogFactor3)), 0.0f); m_dev->SetVertexShaderConstant( c_nVertexShader_Fog2, (float*)&vecConstant2, 1 ); #endif KCustomVector::iterator it = m_prListTreeBillboard.begin(); for ( ; it != m_prListTreeBillboard.end() ; ++it ) { // 투명모드인가 아닌가 //if ((*it)->IsTransparent()!=renderTransparentOrOpaque) continue; { const K3DLight* pLight = GetLight((*it)->GetLightIndex()); K3DVector litdir; if(pLight->type == K3DLight::LT_POINT) { K3DVector *pos = (K3DVector*)&(*it)->GetTransform()->_41; //litdir = GetLight(0)->position - *pos; litdir = pLight->position - *pos; } else if(pLight->type == K3DLight::LT_DIRECTIONAL) { //litdir = GetLight(0)->direction; litdir = pLight->direction * -1.0f; } else { assert(0 && "포인트, 디렉셔널 타입 외의 광원은 지원하지 않음."); } //K3DVector litdir = GetLight(1)->position - *pos; // 임시코드 Normalize(litdir); // setup shader constants for light const float afLighting[] = { litdir.x, litdir.y, litdir.z, 1.0f, // [71] normalized light direction //1.0f, 0.0f, 0.0f, 1.0f, // 임시 코드 //GetLight(0)->ambient.r, GetLight(0)->ambient.g, GetLight(0)->ambient.b, GetLight(0)->ambient.a, // [72] light ambient color pLight->ambient.r, pLight->ambient.g, pLight->ambient.b, pLight->ambient.a, // [72] light ambient color //GetLight(0)->diffuse.r, GetLight(0)->diffuse.g, GetLight(0)->diffuse.b, GetLight(0)->diffuse.a // [73] light diffuse color pLight->diffuse.r, pLight->diffuse.g, pLight->diffuse.b, pLight->diffuse.a // [73] light diffuse color }; m_dev->SetVertexShaderConstant( c_nVertexShader_Light, afLighting, 3 ); } 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 ); } } if( m_bLocalCoord ) { RestoreBackUpViewCamera(); m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); } END_DPCOUNT(); //m_dev->SetTransform(K3DRenderDevice::TS_VIEW, &m_matView); //m_dev->SetTransform(K3DRenderDevice::TS_PROJECTION, &m_matProjection); } } #endif } void SViewPort::RenderSpeedGrass() { if( m_prListSpeedGrass.size() > 0 ) { if( m_nRenderFlag.IsOn( RENDER_SPEED_GRASS ) ) { m_dev->ResetPrevDeclarationTechnique(); START_DPCOUNT("Grass"); m_dev->SetRenderState( K3DRenderDevice::RS_SPEED_GRASS ); m_dev->SetDepthBufferWriteEnable( true ); ( ( K3DRenderDeviceDX* ) m_dev )->SetVertexShaderGrass(); SetSpeedGrassShaderConstants(); KCustomVector< K3DPrimitive* >::iterator it = m_prListSpeedGrass.begin(); for ( ; it != m_prListSpeedGrass.end() ; it++ ) { // set light infos const K3DLight* pLight = GetLight( ( *it )->GetLightIndex() ); K3DVector litdir; if( pLight->type == K3DLight::LT_POINT ) { K3DVector *pos = ( K3DVector* ) &( *it )->GetTransform()->_41; litdir = pLight->position - *pos; } else if(pLight->type == K3DLight::LT_DIRECTIONAL) { litdir = pLight->direction * -1.0f; } else { assert(0 && "포인트, 디렉셔널 타입 외의 광원은 지원하지 않음."); } Normalize(litdir); const float afLighting[] = { litdir.x, litdir.y, litdir.z, 1.0f, // [21] normalized light direction pLight->ambient.r, pLight->ambient.g, pLight->ambient.b, pLight->ambient.a, // [22] light ambient color pLight->diffuse.r, pLight->diffuse.g, pLight->diffuse.b, pLight->diffuse.a // [23] light diffuse color }; m_dev->SetVertexShaderConstant( c_nShaderLightInfos, afLighting, 3 ); ( *it )->Render( this, m_dev ); } END_DPCOUNT(); } } } void SViewPort::RenderQuadPrimitive() { if( m_prListQuad.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_QUAD) ) { m_dev->ResetPrevDeclarationTechnique(); m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); m_dev->SetVertexShaderDefault(); m_dev->EnableLightEffect(false); IDirect3DDevice9* pD3dDevice = ((K3DRenderDeviceDX*) m_dev)->GetD3DDevice(); pD3dDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE); pD3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE ); m_dev->SetTransformIdentity(K3DRenderDevice::TS_WORLD); KCustomVector::iterator it = m_prListQuad.begin(); for (; it != m_prListQuad.end() ; ++it ) { (*it)->Render( this, m_dev ); } } } } void SViewPort::RenderLinePrimitive() { if( m_prListLine.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_QUAD) ) { m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); m_dev->SetVertexShaderDefault(); m_dev->EnableLightEffect(false); IDirect3DDevice9* pD3dDevice = ((K3DRenderDeviceDX*) m_dev)->GetD3DDevice(); pD3dDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE); pD3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE ); m_dev->SetTransformIdentity(K3DRenderDevice::TS_WORLD); KCustomVector::iterator it = m_prListLine.begin(); for (; it != m_prListLine.end() ; ++it ) { (*it)->Render( this, m_dev ); } } } } void SViewPort::RenderPolyLinePrimitive() { if(m_prListPolyLine.size() > 0) { if(m_nRenderFlag.IsOn(RENDER_POLYLINE)) { m_dev->SetRenderState(K3DRenderDevice::RS_DEFAULT); m_dev->SetVertexShaderDefault(); m_dev->EnableLightEffect(false); IDirect3DDevice9* pD3dDevice = ((K3DRenderDeviceDX*) m_dev)->GetD3DDevice(); pD3dDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE); pD3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE ); m_dev->SetTransformIdentity(K3DRenderDevice::TS_WORLD); KCustomVector::iterator it = m_prListPolyLine.begin(); for (; it != m_prListPolyLine.end() ; ++it ) { (*it)->Render(this, m_dev); } } } } void SViewPort::RenderBliiboardList() { } void SViewPort::RenderAdditiveBliiboard() { } void SViewPort::RenderLensflare() { if ( m_prListLensFlare.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_LENSFLARE) ) { START_DPCOUNT("Lens Flare"); m_dev->SetRenderState( K3DRenderDevice::RS_LENSFLARE ); m_dev->SetDepthBufferWriteEnable( false ); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_ALWAYS ); KCustomVector::iterator it = m_prListLensFlare.begin(); for ( ; it != m_prListLensFlare.end() ; ++it ) { (*it)->Render( this, m_dev ); } END_DPCOUNT(); } } } void SViewPort::RenderHighQualityWater() { } void SViewPort::RenderSprite() { if ( m_prSpriteList.size() > 0 || m_prAdditiveSpriteList.size() > 0 || m_prFrontSpriteList.size() > 0 || m_prFrontAdditiveSpriteList.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_SPRITE) ) { START_DPCOUNT("Sprite"); m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_ALWAYS ); m_dev->SetDepthBufferWriteEnable( false ); K3DMatrix backupWorldMat = *m_dev->GetTransform( K3DRenderDevice::TS_WORLD ); m_dev->SetTransformIdentity( K3DRenderDevice::TS_WORLD ); if ( m_prSpriteList.size() > 0 ) { m_dev->SetRenderState( K3DRenderDevice::RS_SPRITE ); //m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); drawSprite( &m_prSpriteList.front(), m_prSpriteList.size() ); } if ( m_prAdditiveSpriteList.size() > 0 ) { m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_PARTICLE ); //m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); drawSprite( &m_prAdditiveSpriteList.front(), m_prAdditiveSpriteList.size() ); } if ( m_prFrontSpriteList.size() > 0 ) { m_dev->SetRenderState( K3DRenderDevice::RS_SPRITE ); //m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); drawSprite( &m_prFrontSpriteList.front(), m_prFrontSpriteList.size() ); } if ( m_prFrontAdditiveSpriteList.size() > 0 ) { m_dev->SetRenderState( K3DRenderDevice::RS_ADDITIVE_PARTICLE ); //m_dev->SetRenderState( K3DRenderDevice::RS_NO_MIPMAP ); drawSprite( &m_prFrontAdditiveSpriteList.front(), m_prFrontAdditiveSpriteList.size() ); } END_DPCOUNT(); m_dev->SetTransform( K3DRenderDevice::TS_WORLD, &backupWorldMat ); } } } void SViewPort::RenderWirePrimitive() { if ( m_wprList.size() > 0 ) { if( m_nRenderFlag.IsOn(RENDER_WPRLIST) ) { m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); m_dev->SetDepthBufferWriteEnable( true ); m_dev->SetRenderState( K3DRenderDevice::RS_NOLIGHT_VTXCOLOR ); for( std::list::iterator it = m_wprList.begin(); it != m_wprList.end(); it++ ) (*it)->Render( this, m_dev ); } } } void SViewPort::BeginRender() { /// 2010.11.10 - prodongi //#ifdef _DEV // extern bool g_bDebugMode; //#endif { m_dev->SetViewport( m_viewport ); if ( m_bClearDepthBuf || m_bClearColorBuf ) { int option = 0; option |= m_bClearColorBuf ? K3DRenderDevice::FILL_COLOR : 0; option |= m_bClearDepthBuf ? K3DRenderDevice::FILL_DEPTH : 0; m_dev->SetFillColor( m_colFill ); m_dev->Fill(option); } updateLight(); //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 ); //#ifndef NDEBUG /// 2010.11.10 - prodongi //#ifdef _DEV if (g_UserInfo.isMonkeyTail()) { extern bool g_bDebugMode; if( g_bDebugMode && GetKeyState( 20 ) ) m_dev->SetFillMode(K3DRenderDevice::FM_WIREFRAME); else m_dev->SetFillMode(K3DRenderDevice::FM_SOLID); } //#else else { m_dev->SetFillMode(K3DRenderDevice::FM_SOLID); } //#endif //#endif } m_dev->SetVertexShaderConstant(CONSTANT_CAMERAPOSITION, (const float*)&GetCameraPos(), 3); if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } if(m_pLightList.size() > 0) { //K3DVector lightdir = GetCameraTargetPos() - GetLight(0)->position; //lightdir = lightdir - 0.2f*K3DVector(lightdir.x, lightdir.y, 0); K3DVector lightdir = GetLight(0)->direction; Normalize(lightdir); m_dev->SetVertexShaderConstant(CONSTANT_LIGHTDIRECTION, (const float *)&lightdir, 3); } } void SViewPort::EndRender(bool bClearRegister) { if(bClearRegister) ClearRegisteredList(); } void SViewPort::Render( bool bClearRegister, bool bSetRenderTarget /*= true*/ ) { BeginRender(); RenderSky(); RenderCloud(); ////////////////////////////////////////////////////////////////////////// //지형 // camera의 위치 설정 RenderTerrain( false ); RenderTerrainShadow(NULL, NULL); /*RenderBuilding(NULL, NULL); RenderAlphaBuilding(NULL, NULL); */ /* Moved to bottom, to enable transparent tree RenderBranch(); RenderFrond(); RenderLeaf(); RenderTreeBillboard(); */ //RenderPathEffect(); RenderQuadPrimitive(); RenderLinePrimitive(); RenderPolyLinePrimitive(); /*RenderProp(NULL, NULL); RenderAlphaProp(NULL, NULL); */ //m_dev->SetDepthBufferWriteEnable( true ); //m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); // if ( m_dev ) // Setting Light attribute for VS // m_dev->SetVertexShaderGlobal( m_nLightIndex ); /*RenderPrNoLightList(); */ if ( m_fogMode != K3DRenderDevice::FOGM_NONE ) { m_dev->SetFogMode( m_fogMode, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); } //m_dev->SetDepthBufferCompareMode( K3DRenderDevice::DCM_LESSEQUAL ); //m_dev->SetDepthBufferWriteEnable( true ); /*RenderPrList( m_prMesh ); RenderPrListSpecularList(); RenderPrVSList(); RenderPrVSListSpecularList(); */ RenderPrList(m_prMesh, 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(); */ // Render tree (opaque parts) // NOTE : THIS ROUTINES ARE NOT EXECUTED : See SGameViewPort.cpp for active code. RenderBranch(false); RenderFrond(false); RenderLeaf(false); RenderTreeBillboard(); // Render transparent tree parts RenderBranch(true); RenderFrond(true); RenderLeaf(true); // Note : Billboard has no transparent rendering routine RenderPrAlphaList(m_prTransMesh, NULL, NULL); // fog off m_dev->SetFogMode( K3DRenderDevice::FOGM_NONE, m_fogColor, m_fogFactor1, m_fogFactor2, m_fogFactor3, m_fogFactor4 ); //RenderPrAdditiveList(NULL, NULL); //RenderBliiboardList(); /*RenderPrNoFogAlphaList(); RenderAdditiveBuilding(NULL, NULL); RenderAdditiveProp(NULL, NULL); */ //RenderAdditiveBliiboard(); m_dev->SetCullMode( K3DRenderDevice::KCM_NONE ); // No culling RenderSpeedGrass(); if( NULL != m_pChildViewportObj ) m_pChildViewportObj->Render( bClearRegister ); m_dev->SetCullMode(K3DRenderDevice::KCM_NONE); RenderLensflare(); ////////////////////////////////////////////////////////////////////////// /// 인터페이스 RenderSprite(); m_dev->SetCullMode(K3DRenderDevice::KCM_CCW); RenderWirePrimitive(); EndRender(bClearRegister); } //void SViewPort::SetRenderBumpMapMode( bool bRender ) //{ // m_bRenderBumpMap = bRender; //} // //bool SViewPort::GetRenderBumpMapMode() //{ // return m_bRenderBumpMap; //} void SViewPort::SetSelfShadowAmbientFactor( float fFactor ) { m_fSelfShadowAmbientFactor = fFactor; } void SViewPort::SetSpeedGrassShaderConstants() { K3DMatrix TrBlendShaderMatrix; K3DMatrixTranspose( TrBlendShaderMatrix, m_matBlendShader ); m_dev->SetVertexShaderConstant( c_nShaderCompositeMatrix, &TrBlendShaderMatrix, 4 ); //#ifdef WRAPPER_USE_FOG // D3DXVECTOR4 vecConstant1(m_fogFactor1, m_fogFactor2, (1.0f / (m_fogFactor2 - m_fogFactor1)), 0.0f); // m_dev->SetVertexShaderConstant( c_nVertexShader_Fog1, (float*)&vecConstant1, 1 ); // D3DXVECTOR4 vecConstant2(m_fogFactor3, m_fogFactor4, (1.0f / (m_fogFactor4 - m_fogFactor3)), 0.0f); // m_dev->SetVertexShaderConstant( c_nVertexShader_Fog2, (float*)&vecConstant2, 1 ); //#endif // pass in unitized billboarded grass quad const float* pUnitBB = CSpeedGrassRT::GetUnitBillboard( ); const float c_fGrassWidth = 2.0f; for (int i = 0; i < 4; ++i) { float afVector[4] = { c_fGrassWidth * pUnitBB[i * 3 + 0], c_fGrassWidth * pUnitBB[i * 3 + 1], pUnitBB[i * 3 + 2], 0.0f }; m_dev->SetVertexShaderConstant(c_nShaderUnitGrassBillboard + i, afVector, 1); } // setup LOD information float afVector[4] = { 0.0f }; CSpeedGrassRT::GetLodParams(afVector[0], afVector[1]); m_dev->SetVertexShaderConstant(c_nShaderLodParams, afVector, 1); // setup camera information const float* pCameraPos = CSpeedGrassRT::GetCameraPos(); m_dev->SetVertexShaderConstant(c_nShaderCameraPos, pCameraPos, 1); // set global wind direction m_dev->SetVertexShaderConstant(c_nShaderWindDirection, CSpeedGrassRT::GetWindDirection(), 1); // set time values float afTimeValues[4] = { KSeqSpeedGrass::GetAccumTime() * c_fShaderTimeScale, c_fShaderWindPeriod, 0.0f, 0.0f }; m_dev->SetVertexShaderConstant(c_nShaderTimeValues, afTimeValues, 1); }