layout: restructure into src/ tests/ android/ scripts/ tools/
- extension/src/{port,platform,codepage} -> src/; native_render -> src/host
(+ dxt, shaders/); libgr2 -> src/gr2; extension/third_party -> third_party
- extension/tests -> tests/port, libgr2/tests -> tests/gr2
- android-native -> android (build.sh, push-client.sh moved in)
- script -> scripts; tools/40250 -> tools/server; oracle -> tools/granny-oracle;
perf tools -> tools/perf
- all build trees under build/ (native, release, android, port-gate)
- xrender:: CMake aliases -> mt::; port-map ledger impl paths rewritten
No code changes. ctest 15/15, port_gate macos+android PASS, port_map check 0 errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
70710477cf
commit
a46093104c
@@ -0,0 +1,120 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// SpeedTreeRT runtime configuration #defines
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
|
||||
#pragma once
|
||||
|
||||
const int c_nNumWindMatrices = 4;
|
||||
const int c_nNumInstancesPerModel = 10;
|
||||
const float c_fForestSize = 200.0f;
|
||||
const float c_fSpacingTolerance = 30.0f;
|
||||
const int c_nMaxPlacementIterations = 500;
|
||||
const int c_nDefaultAlphaTestValue = 84;
|
||||
const float c_fNearLodFactor = 2.0f;
|
||||
const float c_fFarLodFactor = 9.0f;
|
||||
const float c_fBenchmarkPeriod = 1.0f;
|
||||
|
||||
// vertex shader constant locations
|
||||
const int c_nVertexShader_LeafLightingAdjustment = 70;
|
||||
const int c_nVertexShader_Light = 71;
|
||||
const int c_nVertexShader_Material = 74;
|
||||
const int c_nVertexShader_TreePos = 52;
|
||||
const int c_nVertexShader_CompoundMatrix = 0;
|
||||
const int c_nVertexShader_WindMatrices = 54;
|
||||
const int c_nVertexShader_LeafTables = 4;
|
||||
const int c_nVertexShader_Fog = 85;
|
||||
|
||||
// lighting
|
||||
const float c_afLightPosition[4] = { -0.707f, 0.0f, 0.707f, 0.0f };
|
||||
const float c_afLightAmbient[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
const float c_afLightDiffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
const float c_afLightSpecular[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
const float c_afLightGlobalAmbient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
|
||||
// setup lighting (enable ONE of the two below)
|
||||
#define WRAPPER_USE_STATIC_LIGHTING
|
||||
//#define WRAPPER_USE_DYNAMIC_LIGHTING
|
||||
|
||||
#if defined WRAPPER_USE_STATIC_LIGHTING && defined WRAPPER_USE_DYNAMIC_LIGHTING
|
||||
#error Please define exactly one lighting mode
|
||||
#endif
|
||||
|
||||
// setup wind (enable ONE of the three below)
|
||||
//#define WRAPPER_USE_GPU_WIND
|
||||
//#define WRAPPER_USE_CPU_WIND
|
||||
#define WRAPPER_USE_NO_WIND
|
||||
|
||||
#if defined WRAPPER_USE_GPU_WIND && defined WRAPPER_USE_CPU_WIND
|
||||
#error Please define exactly one lighting mode
|
||||
#elif defined WRAPPER_USE_GPU_WIND && defined WRAPPER_USE_NO_WIND
|
||||
#error Please define exactly one lighting mode
|
||||
#elif defined WRAPPER_USE_CPU_WIND && defined WRAPPER_USE_NO_WIND
|
||||
#error Please define exactly one lighting mode
|
||||
#endif
|
||||
|
||||
// leaf placement algorithm (enable ONE of the two below)
|
||||
//#define WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||
#define WRAPPER_USE_CPU_LEAF_PLACEMENT
|
||||
|
||||
#if defined WRAPPER_USE_GPU_LEAF_PLACEMENT && defined WRAPPER_USE_CPU_LEAF_PLACEMENT
|
||||
#error Please define exactly one leaf placement algorithm
|
||||
#endif
|
||||
|
||||
// texture coordinates (enable this define for DirectX-based engines)
|
||||
#define WRAPPER_FLIP_T_TEXCOORD
|
||||
|
||||
// up vector
|
||||
//#define WRAPPER_UP_POS_Y
|
||||
#define WRAPPER_UP_POS_Z
|
||||
|
||||
#if defined WRAPPER_UP_POS_Y && defined WRAPPER_UP_POS_Z
|
||||
#error Please define exactly one up vector
|
||||
#endif
|
||||
|
||||
// loading from STF or clones/instances? (enable ONE of the two below)
|
||||
//#define WRAPPER_FOREST_FROM_STF
|
||||
#define WRAPPER_FOREST_FROM_INSTANCES
|
||||
|
||||
#if defined WRAPPER_FOREST_FROM_STF && defined WRAPPER_FOREST_FROM_INSTANCES
|
||||
#error Please define exactly one loading mechanism
|
||||
#endif
|
||||
|
||||
// billboard modes
|
||||
#define WRAPPER_BILLBOARD_MODE
|
||||
//#define WRAPPER_RENDER_HORIZONTAL_BILLBOARD
|
||||
|
||||
// render self-shadows
|
||||
#define WRAPPER_RENDER_SELF_SHADOWS
|
||||
|
||||
// use fog
|
||||
#define WRAPPER_USE_FOG
|
||||
|
||||
// derived constants
|
||||
#ifdef WRAPPER_USE_GPU_WIND
|
||||
#define BRANCHES_USE_SHADERS
|
||||
#define FRONDS_USE_SHADERS
|
||||
#define LEAVES_USE_SHADERS
|
||||
#endif
|
||||
|
||||
#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||
#define LEAVES_USE_SHADERS
|
||||
#endif
|
||||
@@ -0,0 +1,316 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest Class
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Include Files
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <vector>
|
||||
#include "../EterBase/Filename.h"
|
||||
#include "../EterBase/MappedFile.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "SpeedTreeForest.h"
|
||||
#include "SpeedTreeConfig.h"
|
||||
#include <cfloat>
|
||||
|
||||
using namespace std;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest constructor
|
||||
|
||||
CSpeedTreeForest::CSpeedTreeForest() : m_fWindStrength(0.0f)
|
||||
{
|
||||
CSpeedTreeRT::SetNumWindMatrices(c_nNumWindMatrices);
|
||||
|
||||
m_afForestExtents[0] = m_afForestExtents[1] = m_afForestExtents[2] = FLT_MAX;
|
||||
m_afForestExtents[3] = m_afForestExtents[4] = m_afForestExtents[5] = -FLT_MAX;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest destructor
|
||||
|
||||
CSpeedTreeForest::~CSpeedTreeForest()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CSpeedTreeForest::Clear()
|
||||
{
|
||||
TTreeMap::iterator itor = m_pMainTreeMap.begin();
|
||||
UINT uiCount;
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
delete ppInstances[i];
|
||||
|
||||
delete pMainTree;
|
||||
}
|
||||
|
||||
m_pMainTreeMap.clear();
|
||||
}
|
||||
|
||||
CSpeedTreeWrapper * CSpeedTreeForest::GetMainTree(DWORD dwCRC)
|
||||
{
|
||||
TTreeMap::iterator itor = m_pMainTreeMap.find(dwCRC);
|
||||
|
||||
if (itor == m_pMainTreeMap.end())
|
||||
return NULL;
|
||||
|
||||
return itor->second;
|
||||
}
|
||||
|
||||
BOOL CSpeedTreeForest::GetMainTree(DWORD dwCRC, CSpeedTreeWrapper ** ppMainTree, const char * c_pszFileName)
|
||||
{
|
||||
TTreeMap::iterator itor = m_pMainTreeMap.find(dwCRC);
|
||||
|
||||
CSpeedTreeWrapper * pTree;
|
||||
|
||||
if (itor != m_pMainTreeMap.end())
|
||||
pTree = itor->second;
|
||||
else
|
||||
{
|
||||
CMappedFile file;
|
||||
LPCVOID c_pvData;
|
||||
|
||||
// NOTE : 파일이 없을때는 return FALSE 아닌가요? - [levites]
|
||||
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
|
||||
return FALSE;
|
||||
|
||||
pTree = new CSpeedTreeWrapper;
|
||||
|
||||
if (!pTree->LoadTree(c_pszFileName, (const BYTE *) c_pvData, file.Size()))
|
||||
{
|
||||
delete pTree;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_pMainTreeMap.insert(std::map<DWORD, CSpeedTreeWrapper *>::value_type(dwCRC, pTree));
|
||||
|
||||
file.Destroy();
|
||||
}
|
||||
|
||||
*ppMainTree = pTree;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CSpeedTreeWrapper* CSpeedTreeForest::CreateInstance(float x, float y, float z, DWORD dwTreeCRC, const char * c_szTreeName)
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree;
|
||||
if (!GetMainTree(dwTreeCRC, &pMainTree, c_szTreeName))
|
||||
return NULL;
|
||||
|
||||
CSpeedTreeWrapper* pTreeInst = pMainTree->MakeInstance();
|
||||
pTreeInst->SetPosition(x, y, z);
|
||||
pTreeInst->RegisterBoundingSphere();
|
||||
return pTreeInst;
|
||||
}
|
||||
|
||||
void CSpeedTreeForest::DeleteInstance(CSpeedTreeWrapper * pInstance)
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
CSpeedTreeWrapper * pParentTree = pInstance->InstanceOf();
|
||||
|
||||
if (!pParentTree)
|
||||
return;
|
||||
|
||||
pParentTree->DeleteInstance(pInstance);
|
||||
}
|
||||
|
||||
void CSpeedTreeForest::UpdateSystem(float fCurrentTime)
|
||||
{
|
||||
// 업데이트 할 때 한번
|
||||
static float fLastTime = fCurrentTime;
|
||||
float fElapsedTime = fCurrentTime - fLastTime;
|
||||
CSpeedTreeRT::SetTime(fElapsedTime);
|
||||
|
||||
m_fAccumTime += fElapsedTime;
|
||||
SetupWindMatrices(m_fAccumTime);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest::AdjustExtents
|
||||
void CSpeedTreeForest::AdjustExtents(float x, float y, float z)
|
||||
{
|
||||
// min
|
||||
m_afForestExtents[0] = __min(m_afForestExtents[0], x);
|
||||
m_afForestExtents[1] = __min(m_afForestExtents[1], y);
|
||||
m_afForestExtents[2] = __min(m_afForestExtents[2], z);
|
||||
|
||||
// max
|
||||
m_afForestExtents[3] = __max(m_afForestExtents[3], x);
|
||||
m_afForestExtents[4] = __max(m_afForestExtents[4], y);
|
||||
m_afForestExtents[5] = __max(m_afForestExtents[5], z);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest::SetWindStrength
|
||||
void CSpeedTreeForest::SetWindStrength(float fStrength)
|
||||
{
|
||||
if (m_fWindStrength == fStrength)
|
||||
return;
|
||||
|
||||
m_fWindStrength = fStrength;
|
||||
|
||||
TTreeMap::iterator itor = m_pMainTreeMap.begin();
|
||||
UINT uiCount;
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
ppInstances[i]->GetSpeedTree()->SetWindStrength(m_fWindStrength);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest::SetupWindMatrices
|
||||
void CSpeedTreeForest::SetupWindMatrices(float fTimeInSecs)
|
||||
{
|
||||
// matrix computational data
|
||||
static float afMatrixTimes[c_nNumWindMatrices] = { 0.0f };
|
||||
static float afFrequencies[c_nNumWindMatrices][2] =
|
||||
{
|
||||
{ 0.15f, 0.17f },
|
||||
{ 0.25f, 0.15f },
|
||||
{ 0.19f, 0.05f },
|
||||
{ 0.15f, 0.22f }
|
||||
};
|
||||
|
||||
// compute time since last call
|
||||
static float fTimeOfLastCall = 0.0f;
|
||||
float fTimeSinceLastCall = fTimeInSecs - fTimeOfLastCall;
|
||||
fTimeOfLastCall = fTimeInSecs;
|
||||
|
||||
// wind strength
|
||||
static float fOldStrength = m_fWindStrength;
|
||||
|
||||
// increment matrix times
|
||||
for (int i = 0; i < c_nNumWindMatrices; ++i)
|
||||
afMatrixTimes[i] += fTimeSinceLastCall;
|
||||
|
||||
// compute maximum branch throw
|
||||
float fBaseAngle = m_fWindStrength * 35.0f;
|
||||
|
||||
// build rotation matrices
|
||||
for (int j = 0; j < c_nNumWindMatrices; ++j)
|
||||
{
|
||||
// adjust time to prevent "jumping"
|
||||
if (m_fWindStrength != 0.0f)
|
||||
afMatrixTimes[j] = (afMatrixTimes[j] * fOldStrength) / m_fWindStrength;
|
||||
|
||||
// compute percentages for each axis
|
||||
float fBaseFreq = m_fWindStrength * 20.0f;
|
||||
float fXPercent = sinf(fBaseFreq * afFrequencies[j % c_nNumWindMatrices][0] * afMatrixTimes[j]);
|
||||
float fYPercent = cosf(fBaseFreq * afFrequencies[j % c_nNumWindMatrices][1] * afMatrixTimes[j]);
|
||||
|
||||
// build compound rotation matrix (rotate on 'x' then on 'y')
|
||||
const float c_fDeg2Rad = 57.2957795f;
|
||||
float fSinX = sinf(fBaseAngle * fXPercent / c_fDeg2Rad);
|
||||
float fSinY = sinf(fBaseAngle * fYPercent / c_fDeg2Rad);
|
||||
float fCosX = cosf(fBaseAngle * fXPercent / c_fDeg2Rad);
|
||||
float fCosY = cosf(fBaseAngle * fYPercent / c_fDeg2Rad);
|
||||
|
||||
float afMatrix[16] = { 0.0f };
|
||||
afMatrix[0] = fCosY;
|
||||
afMatrix[2] = -fSinY;
|
||||
afMatrix[4] = fSinX * fSinY;
|
||||
afMatrix[5] = fCosX;
|
||||
afMatrix[6] = fSinX * fCosY;
|
||||
afMatrix[8] = fSinY * fCosX;
|
||||
afMatrix[9] = -fSinX;
|
||||
afMatrix[10] = fCosX * fCosY;
|
||||
afMatrix[15] = 1.0f;
|
||||
|
||||
#ifdef WRAPPER_USE_CPU_WIND
|
||||
CSpeedTreeRT::SetWindMatrix(j, afMatrix);
|
||||
#endif
|
||||
|
||||
#ifdef WRAPPER_USE_GPU_WIND
|
||||
// graphics API specific
|
||||
UploadWindMatrix(c_nVertexShader_WindMatrices + j * 4, afMatrix);
|
||||
#endif
|
||||
}
|
||||
|
||||
// track wind strength
|
||||
fOldStrength = m_fWindStrength;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest::SetLodLimits
|
||||
/*
|
||||
void CSpeedTreeForest::SetLodLimits(void)
|
||||
{
|
||||
// find tallest tree
|
||||
float fTallest = -1.0f;
|
||||
|
||||
TTreeMap::iterator itor = m_pMainTreeMap.begin();
|
||||
UINT uiCount;
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
float fHeight;
|
||||
fHeight = pMainTree->GetBoundingBox()[5] - pMainTree->GetBoundingBox()[0];
|
||||
fTallest = __max(fHeight, fTallest);
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
{
|
||||
fHeight = ppInstances[i]->GetBoundingBox()[5] - ppInstances[i]->GetBoundingBox()[0];
|
||||
fTallest = __max(fHeight, fTallest);
|
||||
}
|
||||
}
|
||||
|
||||
itor = m_pMainTreeMap.begin();
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
pMainTree->GetSpeedTree()->SetLodLimits(fTallest * c_fNearLodFactor, fTallest * c_fFarLodFactor);
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
ppInstances[i]->GetSpeedTree()->SetLodLimits(fTallest * c_fNearLodFactor, fTallest * c_fFarLodFactor);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void CSpeedTreeForest::SetLight(const float * afDirection, const float * afAmbient, const float * afDiffuse)
|
||||
{
|
||||
m_afLighting[0] = afDirection[0];
|
||||
m_afLighting[1] = afDirection[1];
|
||||
m_afLighting[2] = afDirection[2];
|
||||
m_afLighting[3] = 1.0f;
|
||||
|
||||
m_afLighting[4] = afAmbient[0];
|
||||
m_afLighting[5] = afAmbient[1];
|
||||
m_afLighting[6] = afAmbient[2];
|
||||
m_afLighting[7] = afAmbient[3];
|
||||
|
||||
m_afLighting[8] = afDiffuse[0];
|
||||
m_afLighting[9] = afDiffuse[1];
|
||||
m_afLighting[10] = afDiffuse[2];
|
||||
m_afLighting[11] = afDiffuse[3];
|
||||
}
|
||||
|
||||
void CSpeedTreeForest::SetFog(float fFogNear, float fFogFar)
|
||||
{
|
||||
const float c_fFogLinearScale = (1.0f / (fFogFar - fFogNear));
|
||||
|
||||
m_afFog[0] = fFogNear;
|
||||
m_afFog[1] = fFogFar;
|
||||
m_afFog[2] = c_fFogLinearScale;
|
||||
m_afFog[3] = 0.0f;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForest Class
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// This class is provided to illustrate one way to incorporate
|
||||
// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT
|
||||
// calls that must be made on a per tree basis are done by this class.
|
||||
// Calls that apply to all trees (i.e. static SpeedTreeRT functions)
|
||||
// are made in the functions in main.cpp.
|
||||
//
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Include Files
|
||||
#include <SpeedTreeRT.h>
|
||||
#include "SpeedTreeWrapper.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Render bit vector
|
||||
|
||||
#define Forest_RenderBranches (1 << 0)
|
||||
#define Forest_RenderLeaves (1 << 1)
|
||||
#define Forest_RenderFronds (1 << 2)
|
||||
#define Forest_RenderBillboards (1 << 3)
|
||||
#define Forest_RenderAll ((1 << 4) - 1)
|
||||
#define Forest_RenderToShadow (1 << 5)
|
||||
#define Forest_RenderToMiniMap (1 << 6)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// class CSpeedTreeForest declaration
|
||||
|
||||
class CSpeedTreeForest
|
||||
{
|
||||
public:
|
||||
typedef std::map<DWORD, CSpeedTreeWrapper *> TTreeMap;
|
||||
|
||||
public:
|
||||
CSpeedTreeForest();
|
||||
virtual ~CSpeedTreeForest();
|
||||
|
||||
void ClearMainTree();
|
||||
|
||||
|
||||
BOOL GetMainTree(DWORD dwCRC, CSpeedTreeWrapper ** ppMainTree, const char * c_pszFileName);
|
||||
CSpeedTreeWrapper * GetMainTree(DWORD dwCRC);
|
||||
void DeleteMainTree(DWORD dwCRC);
|
||||
|
||||
CSpeedTreeWrapper * CreateInstance(float x, float y, float z, DWORD dwTreeCRC, const char * c_pszTreeName);
|
||||
void DeleteInstance(CSpeedTreeWrapper * pTree);
|
||||
|
||||
//void SetLodLimits(void);
|
||||
|
||||
void UpdateSystem(float fCurrentTime);
|
||||
|
||||
void Clear();
|
||||
|
||||
void SetLight(const float * afDirection, const float * afAmbient, const float * afDiffuse);
|
||||
void SetFog(float fFogNear, float fFogFar);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const float * GetExtents(void) const { return m_afForestExtents; }
|
||||
|
||||
// wind management
|
||||
float GetWindStrength(void) const { return m_fWindStrength; }
|
||||
void SetWindStrength(float fStrength);
|
||||
void SetupWindMatrices(float fTimeInSecs);
|
||||
|
||||
// overridden by specific graphics API
|
||||
virtual void UploadWindMatrix(unsigned int uiLocation, const float* pMatrix) const = 0;
|
||||
virtual void Render(unsigned long ulRenderBitVector) = 0;
|
||||
|
||||
protected:
|
||||
TTreeMap m_pMainTreeMap;
|
||||
|
||||
float m_afLighting[12];
|
||||
float m_afFog[4];
|
||||
|
||||
private:
|
||||
void AdjustExtents(float x, float y, float z);
|
||||
|
||||
float m_afForestExtents[6]; // [0] = min x, [1] = min y..., [3] = max x, [4] = max y...
|
||||
float m_fWindStrength; // 0.0 = no wind, 1.0 = full strength
|
||||
|
||||
float m_fAccumTime;
|
||||
};
|
||||
@@ -0,0 +1,344 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForestDirectX8 Class
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// This class is provided to illustrate one way to incorporate
|
||||
// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT
|
||||
// calls that must be made on a per tree basis are done by this class.
|
||||
// Calls that apply to all trees (i.e. static SpeedTreeRT functions)
|
||||
// are made in the functions in main.cpp.
|
||||
//
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <d3d8.h>
|
||||
#include <d3d8types.h>
|
||||
#include <d3dx8.h>
|
||||
|
||||
#include "../EterBase/Timer.h"
|
||||
#include "../EterLib/StateManager.h"
|
||||
#include "../EterLib/Camera.h"
|
||||
|
||||
#include "SpeedTreeForestDirectX8.h"
|
||||
#include "SpeedTreeConfig.h"
|
||||
#include "VertexShaders.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForestDirectX8::CSpeedTreeForestDirectX8
|
||||
|
||||
CSpeedTreeForestDirectX8::CSpeedTreeForestDirectX8() : m_dwBranchVertexShader(0), m_dwLeafVertexShader(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForestDirectX8::~CSpeedTreeForestDirectX8
|
||||
|
||||
CSpeedTreeForestDirectX8::~CSpeedTreeForestDirectX8()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForestDirectX8::InitVertexShaders
|
||||
bool CSpeedTreeForestDirectX8::InitVertexShaders(void)
|
||||
{
|
||||
NANOBEGIN
|
||||
// load the vertex shaders
|
||||
if (!m_dwBranchVertexShader)
|
||||
m_dwBranchVertexShader = LoadBranchShader(m_pDx);
|
||||
|
||||
if (!m_dwLeafVertexShader)
|
||||
m_dwLeafVertexShader = LoadLeafShader(m_pDx);
|
||||
|
||||
if (m_dwBranchVertexShader && m_dwLeafVertexShader)
|
||||
{
|
||||
CSpeedTreeWrapper::SetVertexShaders(m_dwBranchVertexShader, m_dwLeafVertexShader);
|
||||
return true;
|
||||
}
|
||||
|
||||
NANOEND
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSpeedTreeForestDirectX8::SetRenderingDevice(LPDIRECT3DDEVICE8 lpDevice)
|
||||
{
|
||||
m_pDx = lpDevice;
|
||||
|
||||
if (!InitVertexShaders())
|
||||
return false;
|
||||
|
||||
const float c_afLightPosition[4] = { -0.707f, -0.300f, 0.707f, 0.0f };
|
||||
const float c_afLightAmbient[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
const float c_afLightDiffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
const float c_afLightSpecular[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
float afLight1[] =
|
||||
{
|
||||
c_afLightPosition[0], c_afLightPosition[1], c_afLightPosition[2], // pos
|
||||
c_afLightDiffuse[0], c_afLightDiffuse[1], c_afLightDiffuse[2], // diffuse
|
||||
c_afLightAmbient[0], c_afLightAmbient[1], c_afLightAmbient[2], // ambient
|
||||
c_afLightSpecular[0], c_afLightSpecular[1], c_afLightSpecular[2], // specular
|
||||
c_afLightPosition[3], // directional flag
|
||||
1.0f, 0.0f, 0.0f // attenuation (constant, linear, quadratic)
|
||||
};
|
||||
|
||||
CSpeedTreeRT::SetNumWindMatrices(c_nNumWindMatrices);
|
||||
|
||||
CSpeedTreeRT::SetLightAttributes(0, afLight1);
|
||||
CSpeedTreeRT::SetLightState(0, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForestDirectX8::UploadWindMatrix
|
||||
|
||||
void CSpeedTreeForestDirectX8::UploadWindMatrix(UINT uiLocation, const float* pMatrix) const
|
||||
{
|
||||
STATEMANAGER.SetVertexShaderConstant(uiLocation, pMatrix, 4);
|
||||
}
|
||||
|
||||
void CSpeedTreeForestDirectX8::UpdateCompundMatrix(const D3DXVECTOR3 & c_rEyeVec, const D3DXMATRIX & c_rmatView, const D3DXMATRIX & c_rmatProj)
|
||||
{
|
||||
// setup composite matrix for shader
|
||||
D3DXMATRIX matBlend;
|
||||
D3DXMatrixIdentity(&matBlend);
|
||||
|
||||
D3DXMATRIX matBlendShader;
|
||||
D3DXMatrixMultiply(&matBlendShader, &c_rmatView, &c_rmatProj);
|
||||
|
||||
float afDirection[3];
|
||||
afDirection[0] = matBlendShader.m[0][2];
|
||||
afDirection[1] = matBlendShader.m[1][2];
|
||||
afDirection[2] = matBlendShader.m[2][2];
|
||||
CSpeedTreeRT::SetCamera(c_rEyeVec, afDirection);
|
||||
|
||||
D3DXMatrixTranspose(&matBlendShader, &matBlendShader);
|
||||
STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_CompoundMatrix, &matBlendShader, 4);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForestDirectX8::Render
|
||||
|
||||
void CSpeedTreeForestDirectX8::Render(unsigned long ulRenderBitVector)
|
||||
{
|
||||
UpdateSystem(CTimer::Instance().GetCurrentSecond());
|
||||
|
||||
if (m_pMainTreeMap.empty())
|
||||
return;
|
||||
|
||||
if (!(ulRenderBitVector & Forest_RenderToShadow) && !(ulRenderBitVector & Forest_RenderToMiniMap))
|
||||
UpdateCompundMatrix(CCameraManager::Instance().GetCurrentCamera()->GetEye(), ms_matView, ms_matProj);
|
||||
|
||||
DWORD dwLightState = STATEMANAGER.GetRenderState(D3DRS_LIGHTING);
|
||||
DWORD dwColorVertexState = STATEMANAGER.GetRenderState(D3DRS_COLORVERTEX);
|
||||
DWORD dwFogVertexMode = STATEMANAGER.GetRenderState(D3DRS_FOGVERTEXMODE);
|
||||
|
||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
||||
#else
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, TRUE);
|
||||
#endif
|
||||
|
||||
TTreeMap::iterator itor;
|
||||
UINT uiCount;
|
||||
|
||||
itor = m_pMainTreeMap.begin();
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
{
|
||||
ppInstances[i]->Advance();
|
||||
}
|
||||
}
|
||||
|
||||
STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Light, m_afLighting, 3);
|
||||
STATEMANAGER.SetVertexShaderConstant(c_nVertexShader_Fog, m_afFog, 1);
|
||||
|
||||
if (ulRenderBitVector & Forest_RenderToShadow)
|
||||
{
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
}
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_CW);
|
||||
|
||||
// set up fog if it is enabled
|
||||
if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE))
|
||||
{
|
||||
#ifdef WRAPPER_USE_GPU_WIND
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); // GPU needs to work on all cards
|
||||
#endif
|
||||
}
|
||||
|
||||
// choose fixed function pipeline or custom shader for fronds and branches
|
||||
STATEMANAGER.SetVertexShader(m_dwBranchVertexShader);
|
||||
|
||||
// render branches
|
||||
if (ulRenderBitVector & Forest_RenderBranches)
|
||||
{
|
||||
itor = m_pMainTreeMap.begin();
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
pMainTree->SetupBranchForTreeType();
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
if (ppInstances[i]->isShow())
|
||||
ppInstances[i]->RenderBranches();
|
||||
}
|
||||
}
|
||||
|
||||
// set render states
|
||||
STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
// render fronds
|
||||
if (ulRenderBitVector & Forest_RenderFronds)
|
||||
{
|
||||
itor = m_pMainTreeMap.begin();
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
pMainTree->SetupFrondForTreeType();
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
if (ppInstances[i]->isShow())
|
||||
ppInstances[i]->RenderFronds();
|
||||
}
|
||||
}
|
||||
|
||||
// render leaves
|
||||
if (ulRenderBitVector & Forest_RenderLeaves)
|
||||
{
|
||||
STATEMANAGER.SetVertexShader(m_dwLeafVertexShader);
|
||||
|
||||
if (STATEMANAGER.GetRenderState(D3DRS_FOGENABLE))
|
||||
{
|
||||
#if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000);
|
||||
}
|
||||
|
||||
itor = m_pMainTreeMap.begin();
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
pMainTree->SetupLeafForTreeType();
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
if (ppInstances[i]->isShow())
|
||||
ppInstances[i]->RenderLeaves();
|
||||
}
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
(itor++)->second->EndLeafForTreeType();
|
||||
|
||||
if (ulRenderBitVector & Forest_RenderToShadow || ulRenderBitVector & Forest_RenderToMiniMap)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
|
||||
}
|
||||
}
|
||||
|
||||
// render billboards
|
||||
#ifndef WRAPPER_NO_BILLBOARD_MODE
|
||||
if (ulRenderBitVector & Forest_RenderBillboards)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, FALSE);
|
||||
|
||||
itor = m_pMainTreeMap.begin();
|
||||
|
||||
while (itor != m_pMainTreeMap.end())
|
||||
{
|
||||
CSpeedTreeWrapper * pMainTree = (itor++)->second;
|
||||
CSpeedTreeWrapper ** ppInstances = pMainTree->GetInstances(uiCount);
|
||||
|
||||
pMainTree->SetupBranchForTreeType();
|
||||
|
||||
for (UINT i = 0; i < uiCount; ++i)
|
||||
if (ppInstances[i]->isShow())
|
||||
ppInstances[i]->RenderBillboards();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLightState);
|
||||
STATEMANAGER.SetRenderState(D3DRS_COLORVERTEX, dwColorVertexState);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, dwFogVertexMode);
|
||||
|
||||
// 셀프섀도우로 쓰는 TextureStage 1의 COLOROP와 ALPHAOP를 꺼줘야 다음 렌더링 할 놈들이
|
||||
// 제대로 나온다. (안그러면 검게 나올 가능성이..)
|
||||
if (!(ulRenderBitVector & Forest_RenderToShadow))
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeForestOpenGL Class
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// This class is provided to illustrate one way to incorporate
|
||||
// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT
|
||||
// calls that must be made on a per tree basis are done by this class.
|
||||
// Calls that apply to all trees (i.e. static SpeedTreeRT functions)
|
||||
// are made in the functions in main.cpp.
|
||||
//
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Include Files
|
||||
|
||||
//#include <map>
|
||||
#define SPEEDTREE_DATA_FORMAT_DIRECTX
|
||||
|
||||
#include "SpeedTreeForest.h"
|
||||
#include "SpeedTreeMaterial.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// class CSpeedTreeForestDirectX8 declaration
|
||||
class CSpeedTreeForestDirectX8 : public CSpeedTreeForest, public CGraphicBase, public CSingleton<CSpeedTreeForestDirectX8>
|
||||
{
|
||||
public:
|
||||
CSpeedTreeForestDirectX8();
|
||||
virtual ~CSpeedTreeForestDirectX8();
|
||||
|
||||
void UploadWindMatrix(unsigned int uiLocation, const float* pMatrix) const;
|
||||
void UpdateCompundMatrix(const D3DXVECTOR3 & c_rEyeVec, const D3DXMATRIX & c_rmatView, const D3DXMATRIX & c_rmatProj);
|
||||
|
||||
void Render(unsigned long ulRenderBitVector = Forest_RenderAll);
|
||||
bool SetRenderingDevice(LPDIRECT3DDEVICE8 pDevice);
|
||||
|
||||
private:
|
||||
bool InitVertexShaders();
|
||||
|
||||
private:
|
||||
LPDIRECT3DDEVICE8 m_pDx; // the rendering context
|
||||
|
||||
DWORD m_dwBranchVertexShader; // branch/frond vertex shaders
|
||||
DWORD m_dwLeafVertexShader; // leaf vertex shader
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// CSpeedTreeMaterial Class
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// This class is provided to illustrate one way to incorporate
|
||||
// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT
|
||||
// calls that must be made on a per tree basis are done by this class.
|
||||
// Calls that apply to all trees (i.e. static SpeedTreeRT functions)
|
||||
// are made in the functions in main.cpp.
|
||||
//
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Include Files
|
||||
|
||||
#include <d3d8.h>
|
||||
#include <d3d8types.h>
|
||||
#include <d3dx8.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// class CSpeedTreeMaterial declaration/definiton
|
||||
|
||||
class CSpeedTreeMaterial
|
||||
{
|
||||
public:
|
||||
CSpeedTreeMaterial()
|
||||
{
|
||||
m_cMaterial.Ambient.r = m_cMaterial.Diffuse.r = m_cMaterial.Specular.r = m_cMaterial.Emissive.r = 1.0f;
|
||||
m_cMaterial.Ambient.g = m_cMaterial.Diffuse.g = m_cMaterial.Specular.g = m_cMaterial.Emissive.g = 1.0f;
|
||||
m_cMaterial.Ambient.b = m_cMaterial.Diffuse.b = m_cMaterial.Specular.b = m_cMaterial.Emissive.b = 1.0f;
|
||||
m_cMaterial.Ambient.a = m_cMaterial.Diffuse.a = m_cMaterial.Specular.a = m_cMaterial.Emissive.a = 1.0f;
|
||||
m_cMaterial.Power = 5.0f;
|
||||
}
|
||||
|
||||
void Set(const float * pMaterialArray)
|
||||
{
|
||||
memcpy(&m_cMaterial.Diffuse, pMaterialArray, 3 * sizeof(float));
|
||||
m_cMaterial.Diffuse.a = 1.0f;
|
||||
|
||||
memcpy(&m_cMaterial.Ambient, pMaterialArray + 3, 3 * sizeof(float));
|
||||
m_cMaterial.Ambient.a = 1.0f;
|
||||
|
||||
memcpy(&m_cMaterial.Specular, pMaterialArray + 6, 3 * sizeof(float));
|
||||
m_cMaterial.Specular.a = 1.0f;
|
||||
|
||||
memcpy(&m_cMaterial.Emissive, pMaterialArray + 9, 3 * sizeof(float));
|
||||
m_cMaterial.Emissive.a = 1.0f;
|
||||
|
||||
m_cMaterial.Power = pMaterialArray[12];
|
||||
}
|
||||
|
||||
D3DMATERIAL8 * Get()
|
||||
{
|
||||
return &m_cMaterial;
|
||||
}
|
||||
|
||||
private:
|
||||
D3DMATERIAL8 m_cMaterial; // the material object
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,203 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// SpeedTreeRTExample Class
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// This class is provided to illustrate one way to incorporate
|
||||
// SpeedTreeRT into an OpenGL application. All of the SpeedTreeRT
|
||||
// calls that must be made on a per tree basis are done by this class.
|
||||
// Calls that apply to all trees (i.e. static SpeedTreeRT functions)
|
||||
// are made in the functions in main.cpp.
|
||||
//
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#pragma warning (disable : 4786)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Include files
|
||||
|
||||
#include "SpeedTreeMaterial.h"
|
||||
#include <SpeedTreeRT.h>
|
||||
|
||||
#include <d3d8.h>
|
||||
#include <d3d8types.h>
|
||||
#include <d3dx8.h>
|
||||
#include <vector>
|
||||
|
||||
#include "../EterLib/GrpObjectInstance.h"
|
||||
#include "../EterLib/GrpImageInstance.h"
|
||||
|
||||
#ifndef SAFE_DELETE
|
||||
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
|
||||
#endif
|
||||
|
||||
#ifndef SAFE_DELETE_ARRAY
|
||||
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = NULL; } }
|
||||
#endif
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } }
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// class CSpeedTreeWrapper declaration
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4100)
|
||||
|
||||
class CSpeedTreeWrapper : public CGraphicObjectInstance
|
||||
{
|
||||
enum
|
||||
{
|
||||
ID = TREE_OBJECT
|
||||
};
|
||||
int GetType() const { return ID; }
|
||||
|
||||
// Collision Data
|
||||
protected:
|
||||
virtual void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector);
|
||||
virtual void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance) {}
|
||||
virtual bool OnGetObjectHeight(float fX, float fY, float * pfHeight) { return false; }
|
||||
// Bounding Sphere
|
||||
public:
|
||||
virtual bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius);
|
||||
|
||||
public:
|
||||
static bool ms_bSelfShadowOn;
|
||||
|
||||
public:
|
||||
// methods from CGraphicObjectInstance
|
||||
virtual void SetPosition(float x, float y, float z);
|
||||
virtual void CalculateBBox();
|
||||
|
||||
virtual void OnRender(); // Render 시에 메소드, 그러나 프리뷰나 특수한 경우에만 직접 Render 콜을 부르며
|
||||
// 그 이외에는 RenderBranches, RenderFronds 등의 메소드를 CSpeedTreeForest에서 호출한다.
|
||||
virtual void OnBlendRender() {}
|
||||
virtual void OnRenderToShadowMap() {}
|
||||
virtual void OnRenderShadow() {}
|
||||
virtual void OnRenderPCBlocker();
|
||||
|
||||
public:
|
||||
CSpeedTreeWrapper();
|
||||
virtual ~CSpeedTreeWrapper();
|
||||
|
||||
const float * GetPosition();
|
||||
static void SetVertexShaders(DWORD dwBranchVertexShader, DWORD dwLeafVertexShader);
|
||||
|
||||
// geometry
|
||||
bool LoadTree(const char * pszSptFile, const BYTE * c_pbBlock = NULL, unsigned int uiBlockSize = 0, unsigned int nSeed = 1, float fSize = -1.0f, float fSizeVariance = -1.0f);
|
||||
const float * GetBoundingBox(void) const { return m_afBoundingBox; }
|
||||
void GetTreeSize(float & r_fSize, float & r_fVariance);
|
||||
UINT GetCollisionObjectCount();
|
||||
void GetCollisionObject(unsigned int nIndex, CSpeedTreeRT::ECollisionObjectType& eType, float* pPosition, float* pDimensions);
|
||||
|
||||
// rendering
|
||||
void SetupBranchForTreeType(void) const;
|
||||
void SetupFrondForTreeType(void) const;
|
||||
void SetupLeafForTreeType(void) const;
|
||||
void EndLeafForTreeType(void);
|
||||
|
||||
#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||
void UploadLeafTables(unsigned int uiLocation) const;
|
||||
#endif
|
||||
|
||||
void RenderBranches(void) const;
|
||||
void RenderFronds(void) const;
|
||||
void RenderLeaves(void) const;
|
||||
void RenderBillboards(void) const;
|
||||
|
||||
// instancing
|
||||
CSpeedTreeWrapper ** GetInstances(unsigned int& nCount);
|
||||
CSpeedTreeWrapper * InstanceOf(void) const { return m_pInstanceOf; }
|
||||
CSpeedTreeWrapper * MakeInstance();
|
||||
void DeleteInstance(CSpeedTreeWrapper * pInstance);
|
||||
CSpeedTreeRT * GetSpeedTree(void) const { return m_pSpeedTree; }
|
||||
|
||||
// lighting
|
||||
const CSpeedTreeMaterial & GetBranchMaterial(void) const { return m_cBranchMaterial; }
|
||||
const CSpeedTreeMaterial & GetFrondMaterial(void) const { return m_cFrondMaterial; }
|
||||
const CSpeedTreeMaterial & GetLeafMaterial(void) const { return m_cLeafMaterial; }
|
||||
float GetLeafLightingAdjustment(void) const { return m_pSpeedTree->GetLeafLightingAdjustment( ); }
|
||||
|
||||
// wind
|
||||
void SetWindStrength(float fStrength) { m_pSpeedTree->SetWindStrength(fStrength); }
|
||||
void Advance(void);
|
||||
|
||||
// utility
|
||||
LPDIRECT3DTEXTURE8 GetBranchTexture(void) const;
|
||||
void CleanUpMemory(void);
|
||||
|
||||
private:
|
||||
void SetupBuffers(void);
|
||||
void SetupBranchBuffers(void);
|
||||
void SetupFrondBuffers(void);
|
||||
void SetupLeafBuffers(void);
|
||||
void PositionTree(void) const;
|
||||
static bool LoadTexture(const char* pFilename, CGraphicImageInstance & rImage);
|
||||
void SetShaderConstants(const float* pMaterial) const;
|
||||
|
||||
|
||||
private:
|
||||
// SpeedTreeRT data
|
||||
CSpeedTreeRT* m_pSpeedTree; // the SpeedTree object
|
||||
CSpeedTreeRT::STextures* m_pTextureInfo; // texture info cache
|
||||
bool m_bIsInstance; // is this an instance?
|
||||
std::vector<CSpeedTreeWrapper*> m_vInstances; // what is an instance of us
|
||||
CSpeedTreeWrapper* m_pInstanceOf; // which tree is this an instance of
|
||||
|
||||
// geometry cache
|
||||
CSpeedTreeRT::SGeometry* m_pGeometryCache; // cache for pulling geometry from SpeedTree avoids lots of reallocation
|
||||
|
||||
// branch buffers
|
||||
LPDIRECT3DVERTEXBUFFER8 m_pBranchVertexBuffer; // branch vertex buffer
|
||||
unsigned int m_unBranchVertexCount; // number of vertices in branches
|
||||
LPDIRECT3DINDEXBUFFER8 m_pBranchIndexBuffer; // branch index buffer
|
||||
unsigned short* m_pBranchIndexCounts; // number of indexes per branch LOD level
|
||||
|
||||
// frond buffers
|
||||
LPDIRECT3DVERTEXBUFFER8 m_pFrondVertexBuffer; // frond vertex buffer
|
||||
unsigned int m_unFrondVertexCount; // number of vertices in frond
|
||||
LPDIRECT3DINDEXBUFFER8 m_pFrondIndexBuffer; // frond index buffer
|
||||
unsigned short* m_pFrondIndexCounts; // number of indexes per frond LOD level
|
||||
|
||||
// leaf buffers
|
||||
unsigned short m_usNumLeafLods; // the number of leaf LODs
|
||||
LPDIRECT3DVERTEXBUFFER8* m_pLeafVertexBuffer; // leaf vertex buffer
|
||||
bool* m_pLeavesUpdatedByCpu; // stores which LOD's have been updated already per frame
|
||||
|
||||
// tree properties
|
||||
float m_afPos[3]; // tree position
|
||||
float m_afBoundingBox[6]; // tree bounding box
|
||||
|
||||
// materials
|
||||
CSpeedTreeMaterial m_cBranchMaterial; // branch material
|
||||
CSpeedTreeMaterial m_cLeafMaterial; // leaf material
|
||||
CSpeedTreeMaterial m_cFrondMaterial; // frond material
|
||||
|
||||
// branch texture
|
||||
CGraphicImageInstance m_BranchImageInstance;
|
||||
CGraphicImageInstance m_ShadowImageInstance; // shadow texture object (used if shadows are enabled)
|
||||
CGraphicImageInstance m_CompositeImageInstance;
|
||||
|
||||
static DWORD ms_dwBranchVertexShader;
|
||||
static DWORD ms_dwLeafVertexShader;
|
||||
};
|
||||
|
||||
#pragma warning(pop)
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <assert.h>
|
||||
//#include <crtdbg.h>
|
||||
|
||||
//#include "Forest.h"
|
||||
#include "SpeedTreeForestDirectX8.h"
|
||||
|
||||
// Armadillo nanomite protection
|
||||
#ifndef NANOBEGIN
|
||||
#ifdef __BORLANDC__
|
||||
#define NANOBEGIN __emit__ (0xEB,0x03,0xD6,0xD7,0x01)
|
||||
#define NANOEND __emit__ (0xEB,0x03,0xD6,0xD7,0x00)
|
||||
#else
|
||||
#define NANOBEGIN __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x01
|
||||
#define NANOEND __asm _emit 0xEB __asm _emit 0x03 __asm _emit 0xD6 __asm _emit 0xD7 __asm _emit 0x00
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,332 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// SpeedTreeRT DirectX Example
|
||||
//
|
||||
// (c) 2003 IDV, Inc.
|
||||
//
|
||||
// This example demonstrates how to render trees using SpeedTreeRT
|
||||
// and DirectX. Techniques illustrated include ".spt" file parsing,
|
||||
// static lighting, dynamic lighting, LOD implementation, cloning,
|
||||
// instancing, and dynamic wind effects.
|
||||
//
|
||||
//
|
||||
// *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION ***
|
||||
//
|
||||
// This software is supplied under the terms of a license agreement or
|
||||
// nondisclosure agreement with Interactive Data Visualization and may
|
||||
// not be copied or disclosed except in accordance with the terms of
|
||||
// that agreement.
|
||||
//
|
||||
// Copyright (c) 2001-2003 IDV, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// IDV, Inc.
|
||||
// 1233 Washington St. Suite 610
|
||||
// Columbia, SC 29201
|
||||
// Voice: (803) 799-1699
|
||||
// Fax: (803) 931-0320
|
||||
// Web: http://www.idvinc.com
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
|
||||
#pragma once
|
||||
#include "SpeedTreeConfig.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Branch & Frond Vertex Formats
|
||||
|
||||
static DWORD D3DFVF_SPEEDTREE_BRANCH_VERTEX =
|
||||
D3DFVF_XYZ | // always have the position
|
||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING // precomputed colors or geometric normals
|
||||
D3DFVF_NORMAL |
|
||||
#else
|
||||
D3DFVF_DIFFUSE |
|
||||
#endif
|
||||
#ifdef WRAPPER_RENDER_SELF_SHADOWS
|
||||
D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) // shadow texture coordinates
|
||||
#else
|
||||
D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0) // always have first texture layer coords
|
||||
#endif
|
||||
#ifdef WRAPPER_USE_GPU_WIND
|
||||
| D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE2(2) // GPU Only - wind weight and index passed in second texture layer
|
||||
#endif
|
||||
;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// FVF Branch Vertex Structure
|
||||
|
||||
struct SFVFBranchVertex
|
||||
{
|
||||
D3DXVECTOR3 m_vPosition; // Always Used
|
||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING
|
||||
D3DXVECTOR3 m_vNormal; // Dynamic Lighting Only
|
||||
#else
|
||||
DWORD m_dwDiffuseColor; // Static Lighting Only
|
||||
#endif
|
||||
FLOAT m_fTexCoords[2]; // Always Used
|
||||
#ifdef WRAPPER_RENDER_SELF_SHADOWS
|
||||
FLOAT m_fShadowCoords[2]; // Texture coordinates for the shadows
|
||||
#endif
|
||||
#ifdef WRAPPER_USE_GPU_WIND
|
||||
FLOAT m_fWindIndex; // GPU Only
|
||||
FLOAT m_fWindWeight;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Branch/Frond Vertex Program
|
||||
|
||||
static const char g_achSimpleVertexProgram[] =
|
||||
{
|
||||
"vs.1.1\n" // identity shader version
|
||||
|
||||
"mov oT0.xy, v7\n" // always pass texcoord0 through
|
||||
|
||||
#ifdef WRAPPER_RENDER_SELF_SHADOWS
|
||||
"mov oT1.xy, v8\n" // pass shadow texcoords through if enabled
|
||||
#endif
|
||||
|
||||
// retrieve and convert wind matrix index
|
||||
"mov a0.x, v9.x\n"
|
||||
|
||||
// perform wind interpolation
|
||||
"m4x4 r1, v0, c[54+a0.x]\n" // compute full wind effect
|
||||
"sub r2, r1, v0\n" // compute difference between full wind and none
|
||||
"mov r3.x, v9.y\n" // mad can't access two v's at once, use r3.x as tmp
|
||||
"mad r1, r2, r3.x, v0\n" // perform interpolation
|
||||
|
||||
"add r2, c[52], r1\n" // translate to tree's position
|
||||
"m4x4 oPos, r2, c[0]\n" // project to screen
|
||||
|
||||
#ifdef WRAPPER_USE_FOG
|
||||
"dp4 r1, r2, c[2]\n" // find distance to vertex
|
||||
"sub r2.x, c[85].y, r1.z\n" // linear fogging
|
||||
"mul oFog, r2.x, c[85].z\n" // write to fog register
|
||||
#endif
|
||||
|
||||
#ifdef WRAPPER_USE_STATIC_LIGHTING
|
||||
"mov oD0, v5\n" // pass color through
|
||||
#else
|
||||
"mov r1, c[74]\n" // can only use one const register per instruction
|
||||
"mul r5, c[73], r1\n" // diffuse values
|
||||
|
||||
"mov r1, c[75]\n" // can only use one const register per instruction
|
||||
"mul r4, c[72], r1\n" // ambient values
|
||||
|
||||
"dp3 r2, v3, c[71]\n" // dot light direction with normal
|
||||
// "max r2.x, r2.x, c[70].x\n" // limit it
|
||||
"mad oD0, r2.x, r5, r4\n" // compute the final color
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// LoadBranchShader
|
||||
|
||||
static DWORD LoadBranchShader(LPDIRECT3DDEVICE8 pDx)
|
||||
{
|
||||
#ifndef WRAPPER_USE_GPU_WIND
|
||||
return D3DFVF_SPEEDTREE_BRANCH_VERTEX;
|
||||
#endif
|
||||
|
||||
// branch shader declaration
|
||||
DWORD pBranchShaderDecl[] =
|
||||
{
|
||||
D3DVSD_STREAM(0),
|
||||
D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
|
||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING
|
||||
D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
|
||||
#else
|
||||
D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
|
||||
#endif
|
||||
D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
|
||||
#ifdef WRAPPER_RENDER_SELF_SHADOWS
|
||||
D3DVSD_REG(D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2),
|
||||
#endif
|
||||
#ifdef WRAPPER_USE_GPU_WIND
|
||||
D3DVSD_REG(D3DVSDE_TEXCOORD2, D3DVSDT_FLOAT2),
|
||||
#endif
|
||||
D3DVSD_END( )
|
||||
};
|
||||
|
||||
// assemble shader
|
||||
DWORD dwShader;
|
||||
LPD3DXBUFFER pCode, pError;
|
||||
|
||||
if (D3DXAssembleShader(g_achSimpleVertexProgram, sizeof(g_achSimpleVertexProgram) - 1, 0, NULL, &pCode, &pError) == D3D_OK)
|
||||
{
|
||||
if (pDx->CreateVertexShader(pBranchShaderDecl, (DWORD*) pCode->GetBufferPointer( ), &dwShader, 0) != D3D_OK)
|
||||
{
|
||||
char szError[1024];
|
||||
sprintf(szError, "Failed to create branch vertex shader.");
|
||||
MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char szError[1024];
|
||||
sprintf(szError, "Failed to assemble branch vertex shader.\nThe error reported is [ %s ].\n", pError->GetBufferPointer( ));
|
||||
MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
|
||||
}
|
||||
|
||||
if (pCode)
|
||||
pCode->Release();
|
||||
|
||||
return dwShader;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Leaf Vertex Formats
|
||||
|
||||
static DWORD D3DFVF_SPEEDTREE_LEAF_VERTEX =
|
||||
D3DFVF_XYZ | // always have the position
|
||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING // precomputed colors or geometric normals
|
||||
D3DFVF_NORMAL |
|
||||
#else
|
||||
D3DFVF_DIFFUSE |
|
||||
#endif
|
||||
D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0) // always have first texture layer coords
|
||||
#if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||
| D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2) // GPU Only - wind weight and index passed in second texture layer
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// FVF Leaf Vertex Structure
|
||||
|
||||
struct SFVFLeafVertex
|
||||
{
|
||||
D3DXVECTOR3 m_vPosition; // Always Used
|
||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING
|
||||
D3DXVECTOR3 m_vNormal; // Dynamic Lighting Only
|
||||
#else
|
||||
DWORD m_dwDiffuseColor; // Static Lighting Only
|
||||
#endif
|
||||
FLOAT m_fTexCoords[2]; // Always Used
|
||||
#if defined WRAPPER_USE_GPU_WIND || defined WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||
FLOAT m_fWindIndex; // Only used when GPU is involved
|
||||
FLOAT m_fWindWeight;
|
||||
FLOAT m_fLeafPlacementIndex;
|
||||
FLOAT m_fLeafScalarValue;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Leaf Vertex Program
|
||||
|
||||
static const char g_achLeafVertexProgram[] =
|
||||
{
|
||||
"vs.1.1\n" // identity shader version
|
||||
|
||||
"mov oT0.xy, v7\n" // always pass texcoord0 through
|
||||
|
||||
#ifdef WRAPPER_USE_GPU_WIND
|
||||
// retrieve and convert wind matrix index
|
||||
"mov a0.x, v9.x\n"
|
||||
|
||||
// perform wind interpolation
|
||||
"m4x4 r1, v0, c[54+a0.x]\n" // compute full wind effect
|
||||
"sub r2, r1, v0\n" // compute difference between full wind and none
|
||||
"mov r3.x, v9.y\n" // mad can't access two v's at once, use r3.x as tmp
|
||||
"mad r0, r2, r3.x, v0\n" // perform interpolation
|
||||
#else
|
||||
"mov r0, v0\n" // wind already handled, pass the vertex through
|
||||
#endif
|
||||
|
||||
#ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT
|
||||
"mov a0.x, v9.z\n" // place the leaves
|
||||
"mul r1, c[a0.x], v9.w\n"
|
||||
"add r0, r1, r0\n"
|
||||
#endif
|
||||
|
||||
"add r0, c[52], r0\n" // translate to tree's position
|
||||
"m4x4 oPos, r0, c[0]\n" // project to screen
|
||||
|
||||
#ifdef WRAPPER_USE_FOG
|
||||
"dp4 r1, r0, c[2]\n" // find distance to vertex
|
||||
"sub r2.x, c[85].y, r1.z\n" //
|
||||
"mul oFog, r2.x, c[85].z\n"
|
||||
#endif
|
||||
|
||||
#ifdef WRAPPER_USE_STATIC_LIGHTING
|
||||
"mov oD0, v5\n" // pass color through
|
||||
#else
|
||||
"mov r1, c[74]\n" // can only use one const register per instruction
|
||||
"mul r5, c[73], r1\n" // diffuse values
|
||||
|
||||
"mov r1, c[75]\n" // can only use one const register per instruction
|
||||
"mul r4, c[72], r1\n" // ambient values
|
||||
|
||||
"dp3 r2.x, v3, c[71]\n" // dot light direction with normal
|
||||
"max r2.x, r2.x, c[70].x\n" // limit it
|
||||
"mad oD0, r2.x, r5, r4\n" // compute the final color
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// LoadLeafShader
|
||||
|
||||
static DWORD LoadLeafShader(LPDIRECT3DDEVICE8 pDx)
|
||||
{
|
||||
DWORD dwShader = D3DFVF_SPEEDTREE_LEAF_VERTEX;
|
||||
|
||||
#if defined WRAPPER_USE_GPU_LEAF_PLACEMENT || defined WRAPPER_USE_GPU_WIND
|
||||
|
||||
// leaf shader declaration
|
||||
DWORD pLeafShaderDecl[ ] =
|
||||
{
|
||||
D3DVSD_STREAM(0),
|
||||
D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
|
||||
#ifdef WRAPPER_USE_DYNAMIC_LIGHTING
|
||||
D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3),
|
||||
#else
|
||||
D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
|
||||
#endif
|
||||
D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
|
||||
D3DVSD_REG(D3DVSDE_TEXCOORD2, D3DVSDT_FLOAT4),
|
||||
D3DVSD_END( )
|
||||
};
|
||||
|
||||
// assemble shader
|
||||
LPD3DXBUFFER pCode, pError;
|
||||
|
||||
if (D3DXAssembleShader(g_achLeafVertexProgram, sizeof(g_achLeafVertexProgram) - 1, 0, NULL, &pCode, &pError) == D3D_OK)
|
||||
{
|
||||
if (pDx->CreateVertexShader(pLeafShaderDecl, (DWORD*) pCode->GetBufferPointer( ), &dwShader, 0) != D3D_OK)
|
||||
{
|
||||
Tracef("Failed to create leaf vertex shader.");
|
||||
/*
|
||||
char szError[1024];
|
||||
sprintf(szError, "Failed to create leaf vertex shader.");
|
||||
MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracef("Failed to assemble leaf vertex shader. The error reported is [ %s ].\n", pError->GetBufferPointer( ));
|
||||
/*
|
||||
char szError[1024];
|
||||
sprintf(szError, "Failed to assemble leaf vertex shader. The error reported is [ %s ].\n", pError->GetBufferPointer( ));
|
||||
MessageBox(NULL, szError, "Vertex Shader Error", MB_ICONSTOP);
|
||||
*/
|
||||
}
|
||||
|
||||
if (pCode)
|
||||
pCode->Release( );
|
||||
|
||||
#else
|
||||
|
||||
dwShader = D3DFVF_SPEEDTREE_LEAF_VERTEX;
|
||||
|
||||
#endif
|
||||
|
||||
return dwShader;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user