3DShader之投影网格(Projected Grid)

来源:互联网 发布:中金在线网络 编辑:程序博客网 时间:2024/06/05 17:08

哎呀,这个月的最后一天了,赶快在12点之前再写一篇,不然我的持之以恒徽章又要不亮了.


其实这个程序早在20号左右就写出来了,由于水下效果不是很好,所以一直没敢show出来,最近一直在忙于用OGRE改造HYDRAX,哎,帧数太慢了,准备放弃治疗了.现在迫不得已,先贴出来吧,看下水上也不错.国际惯例上图先:



说个大概原理,详细的自己去看论文

http://fileadmin.cs.lth.se/graphics/theses/projects/projgrid/


为了实现无限海洋,我们只需要在摄像机前画一片海洋.具体方法是算出视椎体与平面的相交部分,最后在相交的部分转换到标准设备空间,在标准设备空间中算出x,y平面的包围矩阵,最后只渲染出包围矩阵这一部分的海洋即可.


贴下代码:

/*------------------------------------------------------------3D_Shader_ProjectedGrid.cpp -- achieve projected grid(c) Seamanj.2013/9/11------------------------------------------------------------*/#include "DXUT.h"#include "resource.h"// phase0 : use camera we created// phase1 : add camera// phase2 : add noise// phase3 : generate noise textures// phase4 : generate range matrix// phase5 : generate projective grid// phase6 : generate height map texture// phase7 : generate normal map texture// phase8 : render the grid// phase9 : set the grid parameter// phase10 : render refracted scene to texture// phase11 : render reflected scene to texture// phase12 : render sky box// phase13 : render the actual scene// phase14 : add refracted island// phase15 : add actual island// phase16 : render underwater scene#define phase0 1#define phase1 0#define phase2 1#define phase3 1#define phase4 1#define phase5 1#define phase6 1#define phase7 1#define phase8 1#define phase9 1#define phase10 1#define phase11 1#define phase12 1#define phase13 1#define phase14 1#define phase15 1#define phase16 1#if phase0#include "mycamera.h"#include "dxmouse.h"float mouseX=0, mouseY=0;float mspeed = 0.005;bool drag=false;boolkeys[256];// Array Used For The Keyboard RoutineMyCamera*g_pRenderingCamera = NULL,*g_pObservingCamera = NULL;//g_pObservingCamera过时的摄像机dxmouse *g_pMouse;#endif#if phase1#include "camera.h"MyCamera* g_pRenderingCamera = NULL;#endif#if phase2#include "noise.h"float g_fStrength = 0.9f;float g_fScale = 0.38f;software_noisemaker myNoise(0.607f, g_fStrength, g_fScale, 1.27f, 8);#endif#if phase3LPDIRECT3DTEXTURE9g_texPackedNoise[2];#endif#if phase4D3DXMATRIXA16 g_matRange;D3DXPLANE g_planeBase;D3DXPLANE g_planeUpper;D3DXPLANE g_planeLower;D3DXVECTOR3 g_vec3BasePlaneNormal(0, 1, 0), g_vec3BasePlaneOrigin(0, 0, 0);MyCamera* g_pProjectingCamera;float g_fElevation = 7.0f;bool g_bPlaneWithinFrustrum = false;#endif#if phase5struct SOFTWARESURFACEVERTEX{float x,y,z;float nx,ny,nz;float tu,tv;};#define D3DFVF_SOFTWARESURFACEVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)int gridsize_x = 128, gridsize_y = 256;int sizeX = gridsize_x + 1, sizeY = gridsize_y + 1;SOFTWARESURFACEVERTEX *g_pVertices;// Vertex BufferLPDIRECT3DVERTEXBUFFER9 g_pGridVB = NULL;// Index BufferLPDIRECT3DINDEXBUFFER9 g_pGridIB = NULL;D3DXVECTOR4 t_corners0,t_corners1,t_corners2,t_corners3;float g_fWaterColorR = 0.17f;float g_fWaterColorG = 0.27f;float g_fWaterColorB = 0.26f;#endif#if phase6LPDIRECT3DTEXTURE9g_texHeightMap;#define nmapsize_x512#define nmapsize_y1024#include "SDKmisc.h"//加载文件时会用到ID3DXEffect*g_pHeightMapEffect = NULL;D3DXHANDLEg_hScale = 0;D3DXHANDLEg_hNoiseTex0 = 0;D3DXHANDLEg_hNoiseTex1 = 0;LPDIRECT3DSURFACE9g_surDepthStencil = 0;#endif#if phase7LPDIRECT3DTEXTURE9  g_texNormalMap;ID3DXEffect*g_pNormalMapEffect = NULL;D3DXHANDLEg_hInvMapSizeX = 0;D3DXHANDLEg_hInvMapSizeY = 0;D3DXHANDLEg_hCorner00 = 0;D3DXHANDLEg_hCorner01 = 0;D3DXHANDLEg_hCorner10 = 0;D3DXHANDLEg_hCorner11 = 0;D3DXHANDLEg_hAmplitude = 0;D3DXHANDLEg_hHeightMap = 0;#endif#if phase8ID3DXEffect*g_pWaterGridEffect = NULL;D3DXHANDLEg_hViewProj = 0;D3DXHANDLEg_hView = 0;D3DXHANDLEg_hViewPos = 0;D3DXHANDLEg_hWaterColor = 0;D3DXHANDLEg_hLODbias = 0;D3DXHANDLEg_hSunShininess = 0;D3DXHANDLEg_hSunStrength = 0;D3DXHANDLEg_hSunVec = 0;D3DXHANDLEg_hReflRefrOffset = 0;D3DXHANDLEg_hDiffuseSkyRef = 0;D3DXHANDLEg_hEnvironmentMap = 0;D3DXHANDLEg_hFresnelMap = 0;D3DXHANDLEg_hRefractionMap = 0;D3DXHANDLEg_hReflectionMap = 0;D3DXHANDLEg_hHeightMapForWaterGridFX = 0;D3DXHANDLEg_hNormalMapForWaterGridFX = 0;#endif#if phase9PDIRECT3DCUBETEXTURE9  g_texEnvironmentMap;LPDIRECT3DTEXTURE9  g_texFresnelMap;float g_fSunPosAlpha = 1.38f;float g_fSunPosTheta = 1.09f;float g_fSunShininess = 84.0f;float g_fSunStrength = 12.0f;float g_fReflRefrOffset = 0.1;bool g_bDiffuseSkyRef = false;float g_fLODbias = 0.0f;D3DLIGHT9 sun;#endif#if phase10#define reflrefrdetail 512LPDIRECT3DTEXTURE9  g_texRefractionMap;#endif#if phase11LPDIRECT3DTEXTURE9  g_texReflectionMap;LPDIRECT3DSURFACE9g_surDepthStencilForRefrRefl = 0;LPDIRECT3DSURFACE9g_surOriginDepthStencil= NULL;#define PI3.1415926535898struct duck{float x,y,z;float y_vel;float angle;};duck duckie_pos;LPD3DXMESH duckie= NULL;LPD3DXBUFFER duck_Adjacency, duck_Materials, duck_EffectInstances;#endif#if phase12ID3DXEffect*g_pSkyBoxEffect = NULL;D3DXHANDLEg_hSkyViewProj = 0;D3DXHANDLEg_hSkyInvViewProj = 0;D3DXHANDLEg_hSkyInvView = 0;D3DXHANDLEg_hSkyViewPosition = 0;D3DXHANDLEg_hSkySunAlpha = 0;D3DXHANDLEg_hSkySunTheta = 0;D3DXHANDLEg_hSkySunShininess = 0;D3DXHANDLEg_hSkySunStrength = 0;D3DXHANDLEg_hSkyEnvironmentMap = 0;LPDIRECT3DVERTEXBUFFER9g_pSkyBoxVB;LPDIRECT3DINDEXBUFFER9g_pSkyBoxIB;#define skyboxdetail 16struct SURFACEVERTEX{D3DXVECTOR3position;float displacement;};#define D3DFVF_SURFACEVERTEX (D3DFVF_XYZ|D3DFVF_TEX1) //|D3DFVF_TEX1#endif#if phase14ID3DXEffect*g_pIslandEffect = NULL;LPDIRECT3DTEXTURE9g_texIsland = 0;D3DXHANDLEg_hIslandViewProj = 0;D3DXHANDLEg_hIslandView = 0;D3DXHANDLEg_hIslandViewPos = 0;D3DXHANDLEg_hIslandWaterColor = 0;D3DXHANDLEg_hIslandSunShininess = 0;D3DXHANDLEg_hIslandSunStrength = 0;D3DXHANDLEg_hIslandSunVec = 0;D3DXHANDLEg_hIslandTex = 0;LPD3DXMESH island= NULL;LPD3DXBUFFER island_Adjacency, island_Materials, island_EffectInstances;#endif#if phase16 ID3DXEffect*g_pUnderWaterEffect = NULL;D3DXHANDLEg_hUnderWaterViewProj = 0;D3DXHANDLEg_hUnderWaterViewPos = 0;D3DXHANDLEg_hUnderWaterWaterColor = 0;D3DXHANDLEg_hUnderWaterSunShininess = 0;D3DXHANDLEg_hUnderWaterSunStrength = 0;D3DXHANDLEg_hUnderWaterSunAlpha = 0;D3DXHANDLEg_hUnderWaterSunTheta = 0;D3DXHANDLEg_hUnderWaterEnvironmentMap = 0;D3DXHANDLEg_hUnderWaterFresnelMap = 0;D3DXHANDLEg_hUnderWaterNormalMap = 0;#endif//--------------------------------------------------------------------------------------// Rejects any D3D9 devices that aren't acceptable to the app by returning false//--------------------------------------------------------------------------------------bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,                                      bool bWindowed, void* pUserContext ){    // Typically want to skip back buffer formats that don't support alpha blending    IDirect3D9* pD3D = DXUTGetD3D9Object();    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,                                         AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,                                         D3DRTYPE_TEXTURE, BackBufferFormat ) ) )        return false;    return true;}//--------------------------------------------------------------------------------------// Before a device is created, modify the device settings as needed//--------------------------------------------------------------------------------------bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ){#if phase1pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;#endif    return true;}#if phase5D3DXVECTOR4 calc_worldpos(D3DXVECTOR2 uv){// this is hacky.. this does take care of the homogenous coordinates in a correct way, // but only when the plane lies at y=0D3DXVECTOR4origin(uv.x,uv.y,-1,1);D3DXVECTOR4direction(uv.x,uv.y,1,1);D3DXVec4Transform( &origin, &origin, &g_matRange );D3DXVec4Transform( &direction, &direction, &g_matRange );direction -= origin;    floatl = -origin.y / direction.y;// assumes the plane is y=0//与世界坐标系中y=0平面的四个交点D3DXVECTOR4 worldPos = origin + direction*l;    return worldPos;}#endif//--------------------------------------------------------------------------------------// Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)// and aren't tied to the back buffer size//--------------------------------------------------------------------------------------HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,                                     void* pUserContext ){#if phase3HRESULT hr;#endif#if phase0g_pRenderingCamera = new MyCamera(D3DXVECTOR3(-27,8,0),0.3,450,0,45,1.33,0.3,5000.0);g_pMouse = new dxmouse(DXUTGetHWND(), DXUTGetHINSTANCE());g_pMouse->Init();#endif#if phase1g_pRenderingCamera = new MyCamera();// Setup the camera's view parameters    D3DXVECTOR3 vecEye( -27.0f, 8.0f, 0.0f );  D3DXVECTOR3 vecAt ( 0.0f, 0.0f, 0.0f );  g_pRenderingCamera->SetViewParams( &vecEye, &vecAt );  g_pRenderingCamera->SetEnablePositionMovement( true );#endif#if phase2myNoise.init_noise();#endif#if phase5g_pVertices= new SOFTWARESURFACEVERTEX[sizeX * sizeY];for(int v=0; v<sizeY; v++){for(int u=0; u<sizeX; u++){g_pVertices[v*sizeX + u].nx =0.0f;g_pVertices[v*sizeX + u].ny =1.0f;g_pVertices[v*sizeX + u].nz =0.0f;g_pVertices[v*sizeX + u].tu = (float)u/(sizeX-1);g_pVertices[v*sizeX + u].tv = (float)v/(sizeY-1);}}#endif#if phase6WCHAR str[MAX_PATH];// Read the D3DX effect fileV_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"HeightMapGen.fx" ) );// Create the effect LPD3DXBUFFER pErrorBuff = NULL;V_RETURN( D3DXCreateEffectFromFile(pd3dDevice,// associated devicestr,// effect filenameNULL,// no preprocessor definitionsNULL,// no ID3DXInclude interfaceD3DXSHADER_DEBUG,// compile flagsNULL,// don't share parameters&g_pHeightMapEffect,// return effect&pErrorBuff// return error messages) );if( pErrorBuff )MessageBoxA(0, (char*)pErrorBuff->GetBufferPointer(), 0, 0);// get techD3DXHANDLE hTechnique;g_pHeightMapEffect->FindNextValidTechnique(NULL, &hTechnique);    g_pHeightMapEffect->SetTechnique(hTechnique);//get handleg_hScale = g_pHeightMapEffect->GetParameterByName(0, "g_fScale");g_hNoiseTex0 = g_pHeightMapEffect->GetParameterByName(0, "g_texNoise0");g_hNoiseTex1 = g_pHeightMapEffect->GetParameterByName(0, "g_texNoise1");#endif#if phase7// Read the D3DX effect fileV_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"NormalMapGen.fx" ) );// Create the effect pErrorBuff = NULL;V_RETURN( D3DXCreateEffectFromFile(pd3dDevice,// associated devicestr,// effect filenameNULL,// no preprocessor definitionsNULL,// no ID3DXInclude interfaceD3DXSHADER_DEBUG,// compile flagsNULL,// don't share parameters&g_pNormalMapEffect,// return effect&pErrorBuff// return error messages) );if( pErrorBuff )MessageBoxA(0, (char*)pErrorBuff->GetBufferPointer(), 0, 0);// get techg_pNormalMapEffect->FindNextValidTechnique(NULL, &hTechnique);    g_pNormalMapEffect->SetTechnique(hTechnique);//get handleg_hInvMapSizeX = g_pNormalMapEffect->GetParameterByName(0, "g_fInvMapSizeX");g_hInvMapSizeY = g_pNormalMapEffect->GetParameterByName(0, "g_fInvMapSizeY");g_hCorner00 = g_pNormalMapEffect->GetParameterByName(0, "corner00");g_hCorner01 = g_pNormalMapEffect->GetParameterByName(0, "corner01");g_hCorner10 = g_pNormalMapEffect->GetParameterByName(0, "corner10");g_hCorner11 = g_pNormalMapEffect->GetParameterByName(0, "corner11");g_hAmplitude = g_pNormalMapEffect->GetParameterByName(0, "g_fAmplitude");g_hHeightMap = g_pNormalMapEffect->GetParameterByName(0, "g_texHeightMap");#endif#if phase8// Read the D3DX effect fileV_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"WaterGrid.fx" ) );// Create the effect pErrorBuff = NULL;V_RETURN( D3DXCreateEffectFromFile(pd3dDevice,// associated devicestr,// effect filenameNULL,// no preprocessor definitionsNULL,// no ID3DXInclude interfaceD3DXSHADER_DEBUG,// compile flagsNULL,// don't share parameters&g_pWaterGridEffect,// return effect&pErrorBuff// return error messages) );if( pErrorBuff )MessageBoxA(0, (char*)pErrorBuff->GetBufferPointer(), 0, 0);// get techg_pWaterGridEffect->FindNextValidTechnique(NULL, &hTechnique);    g_pWaterGridEffect->SetTechnique(hTechnique);//get handleg_hViewProj = g_pWaterGridEffect->GetParameterByName(0, "g_mViewProj");g_hView = g_pWaterGridEffect->GetParameterByName(0, "g_mView");g_hViewPos = g_pWaterGridEffect->GetParameterByName(0, "g_f4ViewPos");g_hWaterColor = g_pWaterGridEffect->GetParameterByName(0, "g_f3WaterColor");g_hLODbias = g_pWaterGridEffect->GetParameterByName(0, "g_fLODbias");g_hSunShininess = g_pWaterGridEffect->GetParameterByName(0, "g_fSunShininess");g_hSunStrength = g_pWaterGridEffect->GetParameterByName(0, "g_fSunStrength");g_hSunVec = g_pWaterGridEffect->GetParameterByName(0, "g_f3SunVec");g_hReflRefrOffset = g_pWaterGridEffect->GetParameterByName(0, "g_fReflRefrOffset");g_hDiffuseSkyRef = g_pWaterGridEffect->GetParameterByName(0, "g_bDiffuseSkyRef");g_hEnvironmentMap = g_pWaterGridEffect->GetParameterByName(0, "g_texEnvironmentMap");g_hFresnelMap = g_pWaterGridEffect->GetParameterByName(0, "g_texFresnelMap");g_hRefractionMap = g_pWaterGridEffect->GetParameterByName(0, "g_texRefractionMap");g_hReflectionMap = g_pWaterGridEffect->GetParameterByName(0, "g_texReflectionMap");g_hHeightMapForWaterGridFX = g_pWaterGridEffect->GetParameterByName(0, "g_texHeightMap");g_hNormalMapForWaterGridFX = g_pWaterGridEffect->GetParameterByName(0, "g_texNormalMap");#endif#if phase9// read texturesD3DXCreateCubeTextureFromFile(pd3dDevice, L"skybox.dds", &g_texEnvironmentMap);D3DXCreateTextureFromFile(pd3dDevice, L"fresnel_water_linear.bmp", &g_texFresnelMap);#endif#if phase11pd3dDevice->GetDepthStencilSurface(&g_surOriginDepthStencil);DWORD n_materials;D3DXLoadMeshFromX( L"duckie.x", D3DXMESH_MANAGED, pd3dDevice, &duck_Adjacency, &duck_Materials, &duck_EffectInstances, &n_materials, &duckie );#endif#if phase12// Read the D3DX effect fileV_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"SkyBox.fx" ) );// Create the effect pErrorBuff = NULL;V_RETURN( D3DXCreateEffectFromFile(pd3dDevice,// associated devicestr,// effect filenameNULL,// no preprocessor definitionsNULL,// no ID3DXInclude interfaceD3DXSHADER_DEBUG,// compile flagsNULL,// don't share parameters&g_pSkyBoxEffect,// return effect&pErrorBuff// return error messages) );if( pErrorBuff )MessageBoxA(0, (char*)pErrorBuff->GetBufferPointer(), 0, 0);// get techg_pSkyBoxEffect->FindNextValidTechnique(NULL, &hTechnique);    g_pSkyBoxEffect->SetTechnique(hTechnique);//get handleg_hSkyViewProj = g_pSkyBoxEffect->GetParameterByName(0, "g_mViewProj");g_hSkyInvViewProj = g_pSkyBoxEffect->GetParameterByName(0, "g_mInvViewProj");g_hSkyInvView = g_pSkyBoxEffect->GetParameterByName(0, "g_mInvView");g_hSkyViewPosition = g_pSkyBoxEffect->GetParameterByName(0, "g_f4ViewPosition");g_hSkySunAlpha = g_pSkyBoxEffect->GetParameterByName(0, "g_fSunAlpha");g_hSkySunTheta = g_pSkyBoxEffect->GetParameterByName(0, "g_fSunTheta");g_hSkySunShininess = g_pSkyBoxEffect->GetParameterByName(0, "g_fSunShiness");g_hSkySunStrength = g_pSkyBoxEffect->GetParameterByName(0, "g_fSunStrength");g_hSkyEnvironmentMap = g_pSkyBoxEffect->GetParameterByName(0, "g_texEnvironmentMap");#endif#if phase14// Read the D3DX effect fileV_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"Island.fx" ) );// Create the effect pErrorBuff = NULL;V_RETURN( D3DXCreateEffectFromFile(pd3dDevice,// associated devicestr,// effect filenameNULL,// no preprocessor definitionsNULL,// no ID3DXInclude interfaceD3DXSHADER_DEBUG,// compile flagsNULL,// don't share parameters&g_pIslandEffect,// return effect&pErrorBuff// return error messages) );if( pErrorBuff )MessageBoxA(0, (char*)pErrorBuff->GetBufferPointer(), 0, 0);// get techg_pIslandEffect->FindNextValidTechnique(NULL, &hTechnique);    g_pIslandEffect->SetTechnique(hTechnique);//get handleg_hIslandViewProj = g_pIslandEffect->GetParameterByName(0, "g_mViewProj");g_hIslandView = g_pIslandEffect->GetParameterByName(0, "g_mView");g_hIslandViewPos = g_pIslandEffect->GetParameterByName(0, "g_f4ViewPos");g_hIslandWaterColor = g_pIslandEffect->GetParameterByName(0, "g_f3WaterColor");g_hIslandSunShininess = g_pIslandEffect->GetParameterByName(0, "g_fSunShininess");g_hIslandSunStrength = g_pIslandEffect->GetParameterByName(0, "g_fSunStrength");g_hIslandSunVec = g_pIslandEffect->GetParameterByName(0, "g_f3SunVec");g_hIslandTex = g_pIslandEffect->GetParameterByName(0, "g_texDiffuse");// read texturesD3DXCreateTextureFromFile(pd3dDevice, L"Island.png", &g_texIsland);// read meshD3DXLoadMeshFromX( L"Island.x", D3DXMESH_MANAGED, pd3dDevice, &island_Adjacency, &island_Materials, &island_EffectInstances, &n_materials, &island );#endif#if phase16// Read the D3DX effect fileV_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"UnderWater.fx" ) );// Create the effect pErrorBuff = NULL;V_RETURN( D3DXCreateEffectFromFile(pd3dDevice,// associated devicestr,// effect filenameNULL,// no preprocessor definitionsNULL,// no ID3DXInclude interfaceD3DXSHADER_DEBUG,// compile flagsNULL,// don't share parameters&g_pUnderWaterEffect,// return effect&pErrorBuff// return error messages) );if( pErrorBuff )MessageBoxA(0, (char*)pErrorBuff->GetBufferPointer(), 0, 0);// get techg_pUnderWaterEffect->FindNextValidTechnique(NULL, &hTechnique);    g_pUnderWaterEffect->SetTechnique(hTechnique);//get handleg_hUnderWaterViewProj = g_pUnderWaterEffect->GetParameterByName(0, "g_mViewProj");g_hUnderWaterViewPos = g_pUnderWaterEffect->GetParameterByName(0, "g_f4ViewPos");g_hUnderWaterWaterColor = g_pUnderWaterEffect->GetParameterByName(0, "g_f3WaterColor");g_hUnderWaterSunShininess = g_pUnderWaterEffect->GetParameterByName(0, "g_fSunShiness");g_hUnderWaterSunStrength = g_pUnderWaterEffect->GetParameterByName(0, "g_fSunStrength");g_hUnderWaterSunAlpha = g_pUnderWaterEffect->GetParameterByName(0, "g_fSunAlpha");g_hUnderWaterSunTheta = g_pUnderWaterEffect->GetParameterByName(0, "g_fSunTheta");g_hUnderWaterEnvironmentMap = g_pUnderWaterEffect->GetParameterByName(0, "g_texEnvironmentMap");g_hUnderWaterFresnelMap = g_pUnderWaterEffect->GetParameterByName(0, "g_texFresnelMap");g_hUnderWaterNormalMap = g_pUnderWaterEffect->GetParameterByName(0, "g_texNormalMap");#endif    return S_OK;}#if phase5static HRESULT initVertexIndexBuffer(IDirect3DDevice9* pd3dDevice){// create the vertexbuffer used in the softwaremode (it can be empty as it'll be memcpy-ed to)if (FAILED(pd3dDevice->CreateVertexBuffer(sizeX * sizeY * sizeof(SOFTWARESURFACEVERTEX),D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, D3DFVF_SOFTWARESURFACEVERTEX,D3DPOOL_DEFAULT,&g_pGridVB, NULL))) {return E_FAIL;}// Create and initialize index bufferif (FAILED(pd3dDevice->CreateIndexBuffer(sizeof(unsigned int) * 6 * gridsize_x * gridsize_y ,D3DUSAGE_WRITEONLY, D3DFMT_INDEX32,D3DPOOL_DEFAULT,&g_pGridIB, NULL))) {return E_FAIL;}unsigned int* pIndices;if (FAILED(g_pGridIB->Lock(0, 0, /* map entire buffer */(void**)&pIndices, 0))) {return E_FAIL;}int i = 0;for(int v=0; v<gridsize_y; v++){for(int u=0; u<gridsize_x; u++){// face 1 |/pIndices[i++]= v*sizeX + u;pIndices[i++]= v*sizeX + u + 1;pIndices[i++]= (v+1)*sizeX + u;// face 2 /|pIndices[i++]= (v+1)*sizeX + u;pIndices[i++]= v*sizeX + u + 1;pIndices[i++]= (v+1)*sizeX + u + 1;}}g_pGridIB->Unlock();#if phase12// create the skybox vertexbufferif (FAILED(pd3dDevice->CreateVertexBuffer(skyboxdetail * skyboxdetail * sizeof(SURFACEVERTEX),D3DUSAGE_WRITEONLY, D3DFVF_SURFACEVERTEX,D3DPOOL_DEFAULT,&g_pSkyBoxVB, NULL))) {return E_FAIL;}SURFACEVERTEX* pVertices;if( FAILED( g_pSkyBoxVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) )return E_FAIL;for(int v=0; v<skyboxdetail; v++){for(int u=0; u<skyboxdetail; u++){floatal = -2*3.14159265*((float)u/(skyboxdetail-1.0f)),th = 0.6*3.14159265*((float)v/(skyboxdetail-1.0f));pVertices[v*skyboxdetail+u].position.x = sin(th)*sin(al);pVertices[v*skyboxdetail+u].position.y = cos(th);pVertices[v*skyboxdetail+u].position.z = sin(th)*cos(al);pVertices[v*skyboxdetail+u].displacement = 0.0f;}}g_pSkyBoxVB->Unlock();// create / fill the skybox indexbufferif(FAILED( pd3dDevice->CreateIndexBuffer(sizeof(unsigned int) * 6 * (skyboxdetail-1)*(skyboxdetail-1),D3DUSAGE_WRITEONLY,D3DFMT_INDEX32,D3DPOOL_DEFAULT,&g_pSkyBoxIB,NULL))){return E_FAIL;}if( FAILED( g_pSkyBoxIB->Lock(0,0,(void**)&pIndices,0 ) ) )return E_FAIL;i = 0;for(int v=0; v<skyboxdetail-1; v++){for(int u=0; u<skyboxdetail-1; u++){// face 1 |/pIndices[i++]= v*skyboxdetail + u;pIndices[i++]= v*skyboxdetail + u + 1;pIndices[i++]= (v+1)*skyboxdetail + u;// face 2 /|pIndices[i++]= (v+1)*skyboxdetail + u;pIndices[i++]= v*skyboxdetail + u + 1;pIndices[i++]= (v+1)*skyboxdetail + u + 1;}}g_pSkyBoxIB->Unlock();#endifreturn S_OK;}#endif//--------------------------------------------------------------------------------------// Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT) // or that are tied to the back buffer size //--------------------------------------------------------------------------------------HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,                                    void* pUserContext ){#if phase3HRESULT hr;#endif#if phase1pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );  //关闭光照处理, 默认情况下启用光照处理   pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );  //Setup the camera's projection parameters   float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;    //g_pRenderingCamera->SetProjParams( D3DX_PI / 2, fAspectRatio, 0.1f, 5000.0f );  g_pRenderingCamera->SetProjParams( 45, fAspectRatio, 0.1f, 5000.0f );  #endif#if phase3// create two noise texturesV( D3DXCreateTexture( pd3dDevice, np_size, np_size, 0, D3DUSAGE_DYNAMIC, D3DFMT_L16, D3DPOOL_DEFAULT, &g_texPackedNoise[0] ));V( D3DXCreateTexture( pd3dDevice, np_size, np_size, 0, D3DUSAGE_DYNAMIC, D3DFMT_L16, D3DPOOL_DEFAULT, &g_texPackedNoise[1] ));#endif#if phase6// create height mapV( D3DXCreateTexture( pd3dDevice, nmapsize_x, nmapsize_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16, D3DPOOL_DEFAULT, &g_texHeightMap ));// create z/stencil bufferV( pd3dDevice->CreateDepthStencilSurface(nmapsize_x, nmapsize_y, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &g_surDepthStencil, NULL  ) );if( g_pHeightMapEffect )        V_RETURN( g_pHeightMapEffect->OnResetDevice() );#endif#if phase7// // create normal mapV( D3DXCreateTexture( pd3dDevice, nmapsize_x, nmapsize_y, 1, D3DUSAGE_AUTOGENMIPMAP|D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16, D3DPOOL_DEFAULT, &g_texNormalMap ));if( g_pNormalMapEffect )V_RETURN( g_pHeightMapEffect->OnResetDevice() );#endif#if phase8if( g_pWaterGridEffect )        V_RETURN( g_pWaterGridEffect->OnResetDevice() );#endif#if phase10// create refracted scene mapV( D3DXCreateTexture(pd3dDevice,reflrefrdetail, reflrefrdetail, 1, D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_texRefractionMap) );#endif#if phase11// create reflected scene mapV( D3DXCreateTexture(pd3dDevice,reflrefrdetail, reflrefrdetail, 1, D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_texReflectionMap) );// create z/stencil bufferV( pd3dDevice->CreateDepthStencilSurface(reflrefrdetail, reflrefrdetail, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &g_surDepthStencilForRefrRefl, NULL  ) );#endif#if phase12if( g_pSkyBoxEffect )        V_RETURN( g_pSkyBoxEffect->OnResetDevice() );#endif#if phase14if( g_pIslandEffect )V_RETURN( g_pIslandEffect->OnResetDevice() );#endif#if phase16if( g_pUnderWaterEffect )V_RETURN( g_pUnderWaterEffect->OnResetDevice() );#endif#if !phase5    return S_OK;#elsereturn initVertexIndexBuffer(pd3dDevice);#endif}//--------------------------------------------------------------------------------------// Handle updates to the scene.  This is called regardless of which D3D API is used//--------------------------------------------------------------------------------------void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ){#if phase3HRESULT hr;#endif#if phase0g_pMouse->Update();//// update mouse & kbdfloat movespeed;if( GetAsyncKeyState(VK_LCONTROL) != 0){mspeed = 0.05;movespeed = 5.0f;}else{mspeed = 0.005;movespeed = 0.3f;}if(keys['A'])g_pRenderingCamera->position -= movespeed*g_pRenderingCamera->right;if(keys['D'])g_pRenderingCamera->position += movespeed*g_pRenderingCamera->right;if(keys['W'])g_pRenderingCamera->position += movespeed*g_pRenderingCamera->forward;if(keys['S'])g_pRenderingCamera->position -= movespeed*g_pRenderingCamera->forward;g_pRenderingCamera->FrameMove( fElapsedTime );if(g_pMouse->mousedown(MOUSE_LEFT)){g_pRenderingCamera->roty -= 0.005 * g_pMouse->x;g_pRenderingCamera->rotx -= 0.005 * g_pMouse->y;g_pRenderingCamera->update();}#endif#if phase1g_pRenderingCamera->FrameMove( fElapsedTime );#endif#if phase0delete g_pObservingCamera;g_pObservingCamera = new MyCamera(g_pRenderingCamera);#endif// Setup the world, view, and projection matrices (this is used to render the frustum)D3DXMATRIXA16 matWorld,matProj;// obsolete with vertexshadersD3DXMatrixIdentity(&matWorld);DXUTGetD3D9Device()->SetTransform( D3DTS_WORLD, &matWorld );DXUTGetD3D9Device()->SetTransform( D3DTS_VIEW,  g_pObservingCamera->GetViewMatrix());//设置摄像机矩阵DXUTGetD3D9Device()->SetTransform( D3DTS_PROJECTION, g_pObservingCamera->GetProjMatrix());//设置投影矩阵//先渲染出几何体再计算#if phase5//render geometryif( g_bPlaneWithinFrustrum ){#if phase2myNoise.calc_noise();#endiffloat magnitude = n_dec_magn * g_fScale;float inv_magnitude_sq = 1.0f/(g_fScale * g_fScale);//计算Projector的视椎体与y = 0平面的四个交点t_corners0 = calc_worldpos(D3DXVECTOR2(0.0f,0.0f));  //  2      3t_corners1 = calc_worldpos(D3DXVECTOR2(+1.0f,0.0f));t_corners2 = calc_worldpos(D3DXVECTOR2(0.0f,+1.0f));t_corners3 = calc_worldpos(D3DXVECTOR2(+1.0f,+1.0f));//  0      1D3DXMATRIXA16 surface_to_world;floatdu = 1.0f/float(sizeX-1),dv = 1.0f/float(sizeY-1),u,v=0.0f;D3DXVECTOR4 result;int i=0;for(int iv=0; iv<sizeY; iv++){u = 0.0f;for(int iu=0; iu<sizeX; iu++){result.x = (1.0f-v)*( (1.0f-u)*t_corners0.x + u*t_corners1.x ) + v*( (1.0f-u)*t_corners2.x + u*t_corners3.x );result.z = (1.0f-v)*( (1.0f-u)*t_corners0.z + u*t_corners1.z ) + v*( (1.0f-u)*t_corners2.z + u*t_corners3.z );result.w = (1.0f-v)*( (1.0f-u)*t_corners0.w + u*t_corners1.w ) + v*( (1.0f-u)*t_corners2.w + u*t_corners3.w );float divide = 1.0f/result.w;result.x *= divide;result.z *= divide;g_pVertices[i].x = result.x;g_pVertices[i].z = result.z;g_pVertices[i].y = myNoise.get_height_dual(magnitude*result.x, magnitude*result.z );i++;u += du;}v += dv;}// smooth the heightdata//for(int n=0; n<3; n++)for(int v=1; v<(sizeY-1); v++){for(int u=1; u<(sizeX-1); u++){g_pVertices[v*sizeX + u].y =0.2f * (g_pVertices[v*sizeX + u].y +g_pVertices[v*sizeX + (u+1)].y + g_pVertices[v*sizeX + (u-1)].y + g_pVertices[(v+1)*sizeX + u].y + g_pVertices[(v-1)*sizeX + u].y);}}#if phase3// upload noise// write data to noise texturesD3DLOCKED_RECT lockedRect;unsigned short* imageData;int tempdata[np_size_sq];for (int t = 0; t < 2; ++t){int offset = np_size_sq * t;g_texPackedNoise[t]->LockRect(0, &lockedRect, NULL, D3DLOCK_DISCARD);imageData = (unsigned short*)lockedRect.pBits;for(int i = 0; i < np_size_sq; ++i)imageData[i] = 32768 + myNoise.p_noise[i + offset];g_texPackedNoise[t]->UnlockRect(0);int c = g_texPackedNoise[t]->GetLevelCount();V(g_texPackedNoise[t]->LockRect(1, &lockedRect, NULL, 0));imageData = (unsigned short*)lockedRect.pBits;int sz = np_size >> 1;for(int v=0; v<sz; v++){for(int u=0; u<sz; u++){tempdata[v*np_size + u] = (myNoise.p_noise[((v<<1))*np_size + (u<<1)+offset] +myNoise.p_noise[((v<<1))*np_size + (u<<1) + 1+offset] + myNoise.p_noise[((v<<1)+1)*np_size + (u<<1)+offset] + myNoise.p_noise[((v<<1)+1)*np_size + (u<<1) + 1+offset])>>2;imageData[v*sz+u] = 32768+tempdata[v*np_size + u];}}g_texPackedNoise[t]->UnlockRect(1);for(int j=2; j<c; j++)//mipmap{hr = g_texPackedNoise[t]->LockRect( j, &lockedRect, NULL, 0 );imageData = (unsigned short*)lockedRect.pBits;int pitch = (lockedRect.Pitch)>>1;sz = np_size>>j;for(int v=0; v<sz; v++){for(int u=0; u<sz; u++){tempdata[v*np_size + u] =(tempdata[((v<<1))*np_size + (u<<1)] + tempdata[((v<<1))*np_size + (u<<1) + 1] +tempdata[((v<<1)+1)*np_size + (u<<1)] + tempdata[((v<<1)+1)*np_size + (u<<1) + 1])>>2;imageData[v*pitch+u] = 32768+tempdata[v*np_size + u];}}g_texPackedNoise[t]->UnlockRect( j );}}D3DXSaveTextureToFile(L"MyPerlinNoiseTex1.dds", D3DXIFF_DDS,g_texPackedNoise[0],NULL);//这种生成的随机图片可以看得到D3DXSaveTextureToFile(L"MyPerlinNoiseTex2.dds", D3DXIFF_DDS,g_texPackedNoise[1],NULL);#endif//fill vertex bufferD3DVERTEXBUFFER_DESC pDesc;SOFTWARESURFACEVERTEX *vertices;V( g_pGridVB->GetDesc( &pDesc ) );if( FAILED(g_pGridVB->Lock( 0, 0, (void**) &vertices, D3DLOCK_DISCARD))){MessageBoxA(NULL, "Could not lock vertexbuffer", 0, MB_OK);}else{int size = pDesc.Size;memcpy(vertices, g_pVertices, size);g_pGridVB->Unlock();}}#endif#if phase4//获取range矩阵g_bPlaneWithinFrustrum = false;D3DXPlaneFromPointNormal( &g_planeBase, &g_vec3BasePlaneOrigin, &g_vec3BasePlaneNormal);D3DXPlaneFromPointNormal( &g_planeUpper, &(g_vec3BasePlaneOrigin +g_fStrength * g_vec3BasePlaneNormal),&g_vec3BasePlaneNormal); D3DXPlaneFromPointNormal( &g_planeLower, &(g_vec3BasePlaneOrigin - g_fStrength * g_vec3BasePlaneNormal),&g_vec3BasePlaneNormal); floatx_min,y_min,x_max,y_max;D3DXVECTOR3 frustum[8],proj_points[24];// frustum to check the camera againstint n_points=0;int cube[] = {0,1,0,2,2,3,1,3,0,4,2,6,3,7,1,5,4,6,4,5,5,7,6,7};// which frustum points are connected together?// transform frustum points to worldspace (should be done to the rendering_camera because it's the interesting one)//将标准设备坐标系中的点转到世界坐标系中,获取视椎体的8个点在世界坐标系中的坐标D3DXVec3TransformCoord(&frustum[0], &D3DXVECTOR3(-1,-1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[1], &D3DXVECTOR3(+1,-1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[2], &D3DXVECTOR3(-1,+1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[3], &D3DXVECTOR3(+1,+1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[4], &D3DXVECTOR3(-1,-1,+1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[5], &D3DXVECTOR3(+1,-1,+1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[6], &D3DXVECTOR3(-1,+1,+1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[7], &D3DXVECTOR3(+1,+1,+1), g_pRenderingCamera->GetInvViewProjMatrix());// check intersections with upper_bound and lower_boundfor(int i=0; i<12; i++){int src=cube[i*2], dst=cube[i*2+1];if ((g_planeUpper.a*frustum[src].x + g_planeUpper.b*frustum[src].y + g_planeUpper.c*frustum[src].z + g_planeUpper.d*1)*(g_planeUpper.a*frustum[dst].x + g_planeUpper.b*frustum[dst].y + g_planeUpper.c*frustum[dst].z + g_planeUpper.d*1)<0){D3DXPlaneIntersectLine( &proj_points[n_points++], &g_planeUpper, &frustum[src], &frustum[dst]);}if ((g_planeLower.a*frustum[src].x + g_planeLower.b*frustum[src].y + g_planeLower.c*frustum[src].z + g_planeLower.d*1)*(g_planeLower.a*frustum[dst].x + g_planeLower.b*frustum[dst].y + g_planeLower.c*frustum[dst].z + g_planeLower.d*1)<0){D3DXPlaneIntersectLine( &proj_points[n_points++], &g_planeLower, &frustum[src], &frustum[dst]);}}// check if any of the frustums vertices lie between the upper_bound and lower_bound planes{for(int i=0; i<8; i++){if ((g_planeUpper.a*frustum[i].x + g_planeUpper.b*frustum[i].y + g_planeUpper.c*frustum[i].z + g_planeUpper.d*1)*(g_planeLower.a*frustum[i].x + g_planeLower.b*frustum[i].y + g_planeLower.c*frustum[i].z + g_planeLower.d*1)<0){proj_points[n_points++] = frustum[i];}}}delete g_pProjectingCamera;g_pProjectingCamera = new MyCamera(*g_pRenderingCamera);// make sure the camera isn't too close to the planefloat fHeightInPlane = (g_planeLower.a * g_pProjectingCamera->GetEyePt()->x + g_planeLower.b * g_pProjectingCamera->GetEyePt()->y +     g_planeLower.c * g_pProjectingCamera->GetEyePt()->z);bool bKeepItSimple = false;bool bUnderWater = false;if (fHeightInPlane < 0.0f) bUnderWater = true;//小于最低平面,则是处于水下if(!bKeepItSimple)//简单的方式就是直接运用渲染摄像机的视椎体{}else{D3DXVECTOR3 aimpoint, aimpoint2;if (fHeightInPlane < (g_fStrength + g_fElevation)){if(bUnderWater)//把摄像机提高到距水平面p_fElevation + abs(height_in_plane)的高度*g_pProjectingCamera->GetEyePt() += D3DXVECTOR3(g_planeLower.a,g_planeLower.b,g_planeLower.c) *(g_fStrength + g_fElevation - 2 * fHeightInPlane);else//把摄像机提高到距水面平距水平面p_fElevation的高度*g_pProjectingCamera->GetEyePt() += D3DXVECTOR3(g_planeLower.a,g_planeLower.b,g_planeLower.c)*(g_fStrength + g_fElevation - fHeightInPlane);} // aim the projector at the point where the camera view-vector intersects the plane// if the camera is aimed away from the plane, mirror it's view-vector against the planeif( ((D3DXPlaneDotNormal(&g_planeBase, g_pRenderingCamera->GetWorldAhead()) < 0.0f) && (D3DXPlaneDotCoord(&g_planeBase, g_pRenderingCamera->GetWorldAhead()) >= 0.0f )) ||((D3DXPlaneDotNormal(&g_planeBase, g_pRenderingCamera->GetWorldAhead()) >= 0.0f) && (D3DXPlaneDotCoord(&g_planeBase, g_pRenderingCamera->GetWorldAhead()) < 0.0f ))){D3DXPlaneIntersectLine( &aimpoint, &g_planeBase, g_pRenderingCamera->GetEyePt(),&(*g_pRenderingCamera->GetEyePt() + *g_pRenderingCamera->GetWorldAhead()) );}else{D3DXVECTOR3 flipped;flipped = *g_pRenderingCamera->GetWorldAhead() - 2 * g_vec3BasePlaneNormal * D3DXVec3Dot(g_pRenderingCamera->GetWorldAhead(),&g_vec3BasePlaneNormal);D3DXPlaneIntersectLine( &aimpoint, &g_planeBase, g_pRenderingCamera->GetEyePt(),&(*g_pRenderingCamera->GetEyePt() + flipped) );}// force the point the camera is looking at in a plane, and have the projector look at it// works well against horizon, even when camera is looking upwards// doesn't work straight down/upfloat af = fabs(D3DXPlaneDotNormal(&g_planeBase, g_pRenderingCamera->GetWorldAhead()));//af = 1 - (1-af)*(1-af)*(1-af)*(1-af)*(1-af);//aimpoint2 = (rendering_camera->position + rendering_camera->zfar * rendering_camera->forward);aimpoint2 = (*g_pRenderingCamera->GetEyePt() + 10.0f * *g_pRenderingCamera->GetWorldAhead());aimpoint2 = aimpoint2 - g_vec3BasePlaneNormal * D3DXVec3Dot(&aimpoint2, &g_vec3BasePlaneNormal);// fade between aimpoint & aimpoint2 depending on view angleaimpoint = aimpoint*af + aimpoint2*(1.0f-af);//aimpoint = aimpoint2;*g_pProjectingCamera->GetWorldAhead() = aimpoint - *g_pProjectingCamera->GetEyePt();g_pProjectingCamera->FrameMove(0);}for(int i=0; i<n_points; i++){// project the point onto the surface planeproj_points[i] = proj_points[i] - g_vec3BasePlaneNormal * D3DXVec3Dot(&proj_points[i], &g_vec3BasePlaneNormal);}for(int i=0; i<n_points; i++){D3DXVec3TransformCoord( &proj_points[i], &proj_points[i], g_pProjectingCamera->GetViewMatrix()); D3DXVec3TransformCoord( &proj_points[i], &proj_points[i], g_pProjectingCamera->GetProjMatrix());}if (n_points > 0){x_min = proj_points[0].x;x_max = proj_points[0].x;y_min = proj_points[0].y;y_max = proj_points[0].y;for(int i=1; i<n_points; i++){if (proj_points[i].x > x_max) x_max = proj_points[i].x;if (proj_points[i].x < x_min) x_min = proj_points[i].x;if (proj_points[i].y > y_max) y_max = proj_points[i].y;if (proj_points[i].y < y_min) y_min = proj_points[i].y;}// build the packing matrix that spreads the grid across the "projection window"D3DXMATRIXA16 pack(x_max-x_min,0,0,x_min,0,y_max-y_min,0,y_min,0,0,1,0,0,0,0,1);D3DXMatrixTranspose(&pack,&pack);g_matRange = pack * *g_pProjectingCamera->GetInvViewProjMatrix();g_bPlaneWithinFrustrum = true;}#endif#if phase11// move the duckduckie_pos.angle += 0.001;if (duckie_pos.angle > (2*PI)) duckie_pos.angle -= 2*PI;duckie_pos.x = 20*cos(duckie_pos.angle);duckie_pos.z = -20*sin(duckie_pos.angle);float new_y = myNoise.get_height_at(duckie_pos.x,duckie_pos.z);duckie_pos.y_vel = new_y - duckie_pos.y;duckie_pos.y += 0.2*duckie_pos.y_vel;#endif}//--------------------------------------------------------------------------------------// Render the scene using the D3D9 device//--------------------------------------------------------------------------------------void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ){    HRESULT hr;//     // Clear the render target and the zbuffer //     V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) );    // Render the scene    if( SUCCEEDED( pd3dDevice->BeginScene() ) )    {#if phase5D3DXMATRIXA16 matWorld,matProj;// obsolete with vertexshadersD3DXMatrixIdentity(&matWorld);DXUTGetD3D9Device()->SetTransform( D3DTS_WORLD, &matWorld );DXUTGetD3D9Device()->SetTransform( D3DTS_VIEW,  g_pRenderingCamera->GetViewMatrix());//设置摄像机矩阵DXUTGetD3D9Device()->SetTransform( D3DTS_PROJECTION, g_pRenderingCamera->GetProjMatrix());//设置投影矩阵//获取Range矩阵#if phase4g_bPlaneWithinFrustrum = false;D3DXPlaneFromPointNormal( &g_planeBase, &g_vec3BasePlaneOrigin, &g_vec3BasePlaneNormal);D3DXPlaneFromPointNormal( &g_planeUpper, &(g_vec3BasePlaneOrigin +g_fStrength * g_vec3BasePlaneNormal),&g_vec3BasePlaneNormal); D3DXPlaneFromPointNormal( &g_planeLower, &(g_vec3BasePlaneOrigin - g_fStrength * g_vec3BasePlaneNormal),&g_vec3BasePlaneNormal); floatx_min,y_min,x_max,y_max;D3DXVECTOR3 frustum[8],proj_points[24];// frustum to check the camera againstint n_points=0;int cube[] = {0,1,0,2,2,3,1,3,0,4,2,6,3,7,1,5,4,6,4,5,5,7,6,7};// which frustum points are connected together?// transform frustum points to worldspace (should be done to the rendering_camera because it's the interesting one)//将标准设备坐标系中的点转到世界坐标系中,获取视椎体的8个点在世界坐标系中的坐标D3DXVec3TransformCoord(&frustum[0], &D3DXVECTOR3(-1,-1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[1], &D3DXVECTOR3(+1,-1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[2], &D3DXVECTOR3(-1,+1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[3], &D3DXVECTOR3(+1,+1,-1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[4], &D3DXVECTOR3(-1,-1,+1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[5], &D3DXVECTOR3(+1,-1,+1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[6], &D3DXVECTOR3(-1,+1,+1), g_pRenderingCamera->GetInvViewProjMatrix());D3DXVec3TransformCoord(&frustum[7], &D3DXVECTOR3(+1,+1,+1), g_pRenderingCamera->GetInvViewProjMatrix());// check intersections with upper_bound and lower_boundfor(int i=0; i<12; i++){int src=cube[i*2], dst=cube[i*2+1];if ((g_planeUpper.a*frustum[src].x + g_planeUpper.b*frustum[src].y + g_planeUpper.c*frustum[src].z + g_planeUpper.d*1)*(g_planeUpper.a*frustum[dst].x + g_planeUpper.b*frustum[dst].y + g_planeUpper.c*frustum[dst].z + g_planeUpper.d*1)<0){D3DXPlaneIntersectLine( &proj_points[n_points++], &g_planeUpper, &frustum[src], &frustum[dst]);}if ((g_planeLower.a*frustum[src].x + g_planeLower.b*frustum[src].y + g_planeLower.c*frustum[src].z + g_planeLower.d*1)*(g_planeLower.a*frustum[dst].x + g_planeLower.b*frustum[dst].y + g_planeLower.c*frustum[dst].z + g_planeLower.d*1)<0){D3DXPlaneIntersectLine( &proj_points[n_points++], &g_planeLower, &frustum[src], &frustum[dst]);}}// check if any of the frustums vertices lie between the upper_bound and lower_bound planes{for(int i=0; i<8; i++){if ((g_planeUpper.a*frustum[i].x + g_planeUpper.b*frustum[i].y + g_planeUpper.c*frustum[i].z + g_planeUpper.d*1)*(g_planeLower.a*frustum[i].x + g_planeLower.b*frustum[i].y + g_planeLower.c*frustum[i].z + g_planeLower.d*1)<0){proj_points[n_points++] = frustum[i];}}}delete g_pProjectingCamera;g_pProjectingCamera = new MyCamera(*g_pRenderingCamera);// make sure the camera isn't too close to the planefloat fHeightInPlane = (g_planeLower.a * g_pProjectingCamera->GetEyePt()->x + g_planeLower.b * g_pProjectingCamera->GetEyePt()->y +     g_planeLower.c * g_pProjectingCamera->GetEyePt()->z);bool bKeepItSimple = false;bool bUnderWater = false;if (fHeightInPlane < 0.0f) bUnderWater = true;//小于最低平面,则是处于水下if(bKeepItSimple)//简单的方式就是直接运用渲染摄像机的视椎体{}else{D3DXVECTOR3 aimpoint, aimpoint2;if (fHeightInPlane < (g_fStrength + g_fElevation)){if(bUnderWater)//把摄像机提高到距水平面p_fElevation + abs(height_in_plane)的高度*g_pProjectingCamera->GetEyePt() += D3DXVECTOR3(g_planeLower.a,g_planeLower.b,g_planeLower.c) *(g_fStrength + g_fElevation - 2 * fHeightInPlane);else//把摄像机提高到距水面平距水平面p_fElevation的高度*g_pProjectingCamera->GetEyePt() += D3DXVECTOR3(g_planeLower.a,g_planeLower.b,g_planeLower.c)*(g_fStrength + g_fElevation - fHeightInPlane);} // aim the projector at the point where the camera view-vector intersects the plane// if the camera is aimed away from the plane, mirror it's view-vector against the planeif( ((D3DXPlaneDotNormal(&g_planeBase, g_pRenderingCamera->GetWorldAhead()) < 0.0f) && (D3DXPlaneDotCoord(&g_planeBase, g_pRenderingCamera->GetEyePt()) >= 0.0f )) ||((D3DXPlaneDotNormal(&g_planeBase, g_pRenderingCamera->GetWorldAhead()) >= 0.0f) && (D3DXPlaneDotCoord(&g_planeBase, g_pRenderingCamera->GetEyePt()) < 0.0f ))){D3DXPlaneIntersectLine( &aimpoint, &g_planeBase, g_pRenderingCamera->GetEyePt(),&(*g_pRenderingCamera->GetEyePt() + *g_pRenderingCamera->GetWorldAhead()) );}else{D3DXVECTOR3 flipped;flipped = *g_pRenderingCamera->GetWorldAhead() - 2 * g_vec3BasePlaneNormal * D3DXVec3Dot(g_pRenderingCamera->GetWorldAhead(),&g_vec3BasePlaneNormal);D3DXPlaneIntersectLine( &aimpoint, &g_planeBase, g_pRenderingCamera->GetEyePt(),&(*g_pRenderingCamera->GetEyePt() + flipped) );}// force the point the camera is looking at in a plane, and have the projector look at it// works well against horizon, even when camera is looking upwards// doesn't work straight down/upfloat af = fabs(D3DXPlaneDotNormal(&g_planeBase, g_pRenderingCamera->GetWorldAhead()));//af = 1 - (1-af)*(1-af)*(1-af)*(1-af)*(1-af);//aimpoint2 = (rendering_camera->position + rendering_camera->zfar * rendering_camera->forward);aimpoint2 = (*g_pRenderingCamera->GetEyePt() + 10.0f * *g_pRenderingCamera->GetWorldAhead());aimpoint2 = aimpoint2 - g_vec3BasePlaneNormal * D3DXVec3Dot(&aimpoint2, &g_vec3BasePlaneNormal);// fade between aimpoint & aimpoint2 depending on view angleaimpoint = aimpoint*af + aimpoint2*(1.0f-af);//aimpoint = aimpoint2;*g_pProjectingCamera->GetWorldAhead() = aimpoint - *g_pProjectingCamera->GetEyePt();g_pProjectingCamera->update_lookat();}for(int i=0; i<n_points; i++){// project the point onto the surface planeproj_points[i] = proj_points[i] - g_vec3BasePlaneNormal * D3DXVec3Dot(&proj_points[i], &g_vec3BasePlaneNormal);}for(int i=0; i<n_points; i++){D3DXVec3TransformCoord( &proj_points[i], &proj_points[i], g_pProjectingCamera->GetViewMatrix()); D3DXVec3TransformCoord( &proj_points[i], &proj_points[i], g_pProjectingCamera->GetProjMatrix());}if (n_points > 0){x_min = proj_points[0].x;x_max = proj_points[0].x;y_min = proj_points[0].y;y_max = proj_points[0].y;for(int i=1; i<n_points; i++){if (proj_points[i].x > x_max) x_max = proj_points[i].x;if (proj_points[i].x < x_min) x_min = proj_points[i].x;if (proj_points[i].y > y_max) y_max = proj_points[i].y;if (proj_points[i].y < y_min) y_min = proj_points[i].y;}// build the packing matrix that spreads the grid across the "projection window"D3DXMATRIXA16 pack(x_max-x_min,0,0,x_min,0,y_max-y_min,0,y_min,0,0,1,0,0,0,0,1);D3DXMatrixTranspose(&pack,&pack);g_matRange = pack * *g_pProjectingCamera->GetInvViewProjMatrix();g_bPlaneWithinFrustrum = true;}#endif#if phase6LPDIRECT3DSURFACE9 target, bb, old_depthstencil;#endif//水的折射部分#if phase10{V( pd3dDevice->GetRenderTarget(0, &bb) );V( g_texRefractionMap->GetSurfaceLevel(0, &target) );V( pd3dDevice->SetRenderTarget(0, target) );V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB((int)(255 * g_fWaterColorR), (int)(255*g_fWaterColorG), (int)(255*g_fWaterColorB)), 1.0f, 0 ));D3DXMATRIXA16 store, scale;// squach the scenepd3dDevice->GetTransform(D3DTS_WORLD, &store);D3DXMatrixScaling( &scale, 1, 0.75, 1 );pd3dDevice->MultiplyTransform(D3DTS_WORLD, &scale );pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW  );// add a clip-plane as wellfloat plane[4];plane[0] = 0;plane[1] = -1;plane[2] = 0;plane[3] = 1.7*g_fStrength;// a slight offset to avoid seamspd3dDevice->SetClipPlane(0,plane);///////////////////////////////////////////////////////////sun.Direction.x = -cos(g_fSunPosTheta) *sin(g_fSunPosAlpha);sun.Direction.y = -sin(g_fSunPosTheta);sun.Direction.z = -cos(g_fSunPosTheta)*cos(g_fSunPosAlpha);sun.Diffuse.r = 1.0f;sun.Diffuse.g = 1.0f;sun.Diffuse.b = 1.0f;sun.Diffuse.a = 1.0f;sun.Ambient.a = 1.0f;sun.Ambient.r = 0.2f;sun.Ambient.g = 0.3f;sun.Ambient.b = 0.3f;sun.Specular.r = 1.0f;sun.Specular.g = 1.0f;sun.Specular.b = 1.0f;sun.Specular.a = 1.0f;sun.Attenuation0 = 1.0f;sun.Type = D3DLIGHT_DIRECTIONAL;pd3dDevice->SetLight(0, &sun);#if phase14LPDIRECT3DVERTEXBUFFER9 vb;LPDIRECT3DINDEXBUFFER9 ib;island->GetVertexBuffer(&vb);island->GetIndexBuffer(&ib);pd3dDevice->SetStreamSource(0, vb, 0, island->GetNumBytesPerVertex());pd3dDevice->SetIndices(ib);pd3dDevice->SetFVF( island->GetFVF() );g_pIslandEffect->Begin(NULL,NULL);g_pIslandEffect->BeginPass(0);g_pIslandEffect->SetMatrix(g_hIslandViewProj, g_pObservingCamera->GetViewProjMatrix());g_pIslandEffect->SetMatrix(g_hIslandView, g_pObservingCamera->GetViewMatrix());g_pIslandEffect->SetVector(g_hIslandSunVec,&D3DXVECTOR4(cos(g_fSunPosTheta)*sin(g_fSunPosAlpha), sin(g_fSunPosTheta), cos(g_fSunPosTheta)*cos(g_fSunPosAlpha),0));g_pIslandEffect->SetFloat(g_hIslandSunShininess, g_fSunShininess);g_pIslandEffect->SetFloat(g_hIslandSunStrength, g_fSunStrength);g_pIslandEffect->SetVector(g_hIslandWaterColor, &D3DXVECTOR4(g_fWaterColorR, g_fWaterColorG, g_fWaterColorB, 1));g_pIslandEffect->SetVector(g_hIslandViewPos, &D3DXVECTOR4(g_pObservingCamera->GetEyePt()->x,g_pObservingCamera->GetEyePt()->y, g_pObservingCamera->GetEyePt()->z,1));g_pIslandEffect->SetTexture(g_hIslandTex, g_texIsland);pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, island->GetNumVertices(), 0, island->GetNumFaces() );g_pIslandEffect->EndPass();g_pIslandEffect->End();SAFE_RELEASE(vb);SAFE_RELEASE(ib);#endif// restore stuffpd3dDevice->SetRenderState( D3DRS_LIGHTING, false);pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW  );////////////////////////////////////////////////////////////// restorepd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0);pd3dDevice->SetTransform(D3DTS_WORLD, &store);pd3dDevice->SetRenderTarget(0, bb);SAFE_RELEASE(target);SAFE_RELEASE(bb);}#endif//水的反射部分#if phase11 {pd3dDevice->GetRenderTarget(0, &bb );g_texReflectionMap->GetSurfaceLevel( 0,&target );pd3dDevice->SetRenderTarget(0, target);pd3dDevice->SetDepthStencilSurface( g_surDepthStencilForRefrRefl );// alpha & z must be clearedpd3dDevice->Clear( 0, NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0, 1.0f, 0 );D3DXMATRIXA16 store, scale;// mirror the scenepd3dDevice->GetTransform(D3DTS_WORLD,&store);D3DXMatrixScaling( &scale, 1, -1, 1 );pd3dDevice->MultiplyTransform(D3DTS_WORLD, &scale );pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW  );// add a clip-plane as wellfloat plane[4];plane[0] = 0;plane[1] = -1;plane[2] = 0;plane[3] = 0;pd3dDevice->SetClipPlane(0,plane);pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 1);/////////////////////////////sun.Direction.x = -cos(g_fSunPosTheta) *sin(g_fSunPosAlpha);sun.Direction.y = sin(g_fSunPosTheta);sun.Direction.z = -cos(g_fSunPosTheta)*cos(g_fSunPosAlpha);sun.Diffuse.r = 1.0f;sun.Diffuse.g = 1.0f;sun.Diffuse.b = 1.0f;sun.Diffuse.a = 1.0f;sun.Ambient.a = 1.0f;sun.Ambient.r = 0.2f;sun.Ambient.g = 0.3f;sun.Ambient.b = 0.3f;sun.Specular.r = 1.0f;sun.Specular.g = 1.0f;sun.Specular.b = 1.0f;sun.Specular.a = 1.0f;sun.Attenuation0 = 1.0f;sun.Type = D3DLIGHT_DIRECTIONAL;pd3dDevice->SetLight(0, &sun);pd3dDevice->LightEnable( 0, true);///////// draw duck{D3DXMATRIXA16 store, offset, yrot,scale;pd3dDevice->GetTransform(D3DTS_WORLD,&store);float duckX = -15, duckZ = -5;D3DXMatrixTranslation( &offset, duckie_pos.x, -duckie_pos.y + myNoise.get_height_at(duckie_pos.x,duckie_pos.z), duckie_pos.z);pd3dDevice->MultiplyTransform(D3DTS_WORLD, &offset );D3DXMatrixRotationY( &yrot, duckie_pos.angle);pd3dDevice->MultiplyTransform(D3DTS_WORLD, &yrot );D3DXMatrixScaling( &scale, 3, 3, 3 );pd3dDevice->MultiplyTransform(D3DTS_WORLD, &scale );//g_pd3dDevice->SetMaterial((D3DMATERIAL9*)duck_Materials->GetBufferPointer());pd3dDevice->SetRenderState( D3DRS_LIGHTING, true);pd3dDevice->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 );pd3dDevice->SetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR1 );pd3dDevice->SetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1 );float plane[4];pd3dDevice->GetClipPlane(0,plane);plane[3] = myNoise.get_height_at(duckX, duckZ) + 0.1;pd3dDevice->SetClipPlane(0,plane);duckie->DrawSubset(0);pd3dDevice->SetTransform(D3DTS_WORLD, &store);}////////// restore stuffpd3dDevice->SetRenderState( D3DRS_LIGHTING, false);pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW  );///////////////////////// restorepd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 0);pd3dDevice->SetTransform(D3DTS_WORLD, &store);pd3dDevice->SetRenderTarget(0, bb);pd3dDevice->SetDepthStencilSurface( g_surOriginDepthStencil );SAFE_RELEASE(target);SAFE_RELEASE(bb);}#endifpd3dDevice->Clear( 0, NULL,D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, D3DCOLOR_XRGB((int)(255 * g_fWaterColorR),(int)(255 * g_fWaterColorG),(int)(255 * g_fWaterColorB)), 1.0f, 0 );// set rendering statespd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE,true);pd3dDevice->SetRenderState(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,false);//天空盒#if phase12pd3dDevice->SetStreamSource( 0, g_pSkyBoxVB, 0, sizeof(SURFACEVERTEX) );pd3dDevice->SetFVF( D3DFVF_SURFACEVERTEX);pd3dDevice->SetIndices(g_pSkyBoxIB);g_pSkyBoxEffect->Begin(NULL,NULL);g_pSkyBoxEffect->BeginPass(0);// build the 'fake' viweproj with the distance vector set to 0,0,0D3DXMATRIXA16 fvproj(*g_pObservingCamera->GetViewMatrix());fvproj._41 = 0;fvproj._42 = 0;fvproj._43 = 0;fvproj = fvproj * *g_pObservingCamera->GetProjMatrix();g_pSkyBoxEffect->SetMatrix(g_hSkyViewProj,&fvproj);//g_pSkyBoxEffect->SetMatrix(g_hSkyViewProj, g_pRenderingCamera->GetViewProjMatrix());g_pSkyBoxEffect->SetMatrix(g_hSkyInvViewProj,g_pObservingCamera->GetInvViewProjMatrix());g_pSkyBoxEffect->SetMatrix(g_hSkyInvView,g_pObservingCamera->GetInvViewMatrix());g_pSkyBoxEffect->SetFloat(g_hSkySunAlpha, g_fSunPosAlpha);g_pSkyBoxEffect->SetFloat(g_hSkySunTheta, g_fSunPosTheta);g_pSkyBoxEffect->SetFloat(g_hSkySunShininess, g_fSunShininess);g_pSkyBoxEffect->SetFloat(g_hSkySunStrength, g_fSunStrength);g_pSkyBoxEffect->SetVector(g_hSkyViewPosition, &D3DXVECTOR4(g_pObservingCamera->GetEyePt()->x,g_pObservingCamera->GetEyePt()->y, g_pObservingCamera->GetEyePt()->z,1));g_pSkyBoxEffect->SetTexture(g_hSkyEnvironmentMap, g_texEnvironmentMap);pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0, skyboxdetail*skyboxdetail, 0, 2*(skyboxdetail-1)*(skyboxdetail-1) );g_pSkyBoxEffect->EndPass();g_pSkyBoxEffect->End();#endifif( g_bPlaneWithinFrustrum ){//渲染水下#if phase16// underwater passpd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW  );pd3dDevice->SetStreamSource( 0, g_pGridVB, 0, sizeof(SOFTWARESURFACEVERTEX) );pd3dDevice->SetFVF( D3DFVF_SOFTWARESURFACEVERTEX);pd3dDevice->SetIndices(g_pGridIB);g_pUnderWaterEffect->Begin(NULL,NULL);g_pUnderWaterEffect->BeginPass(0);g_pUnderWaterEffect->SetMatrix(g_hUnderWaterViewProj, g_pObservingCamera->GetViewProjMatrix());g_pUnderWaterEffect->SetFloat(g_hUnderWaterSunAlpha, g_fSunPosAlpha);g_pUnderWaterEffect->SetFloat(g_hUnderWaterSunTheta, g_fSunPosTheta);g_pUnderWaterEffect->SetFloat(g_hUnderWaterSunShininess, g_fSunShininess);g_pUnderWaterEffect->SetFloat(g_hUnderWaterSunStrength, g_fSunStrength);g_pUnderWaterEffect->SetVector(g_hUnderWaterWaterColor, &D3DXVECTOR4(g_fWaterColorR, g_fWaterColorG, g_fWaterColorB, 1));g_pUnderWaterEffect->SetVector(g_hUnderWaterViewPos, &D3DXVECTOR4(g_pObservingCamera->GetEyePt()->x,g_pObservingCamera->GetEyePt()->y, g_pObservingCamera->GetEyePt()->z,1));g_pUnderWaterEffect->SetTexture(g_hUnderWaterEnvironmentMap,g_texEnvironmentMap);g_pUnderWaterEffect->SetTexture(g_hUnderWaterFresnelMap,g_texFresnelMap);g_pUnderWaterEffect->SetTexture(g_hUnderWaterNormalMap,g_texNormalMap);V( pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, sizeX*sizeY, 0, 2*(sizeX-1)*(sizeY-1) ) );g_pUnderWaterEffect->EndPass();g_pUnderWaterEffect->End();#endifpd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE  );pd3dDevice->SetStreamSource( 0, g_pGridVB, 0, sizeof(SOFTWARESURFACEVERTEX) );pd3dDevice->SetFVF( D3DFVF_SOFTWARESURFACEVERTEX);pd3dDevice->SetIndices(g_pGridIB);#if phase6// write data to height map//写高度图纹理V( pd3dDevice->GetRenderTarget(0, &bb) );V( g_texHeightMap->GetSurfaceLevel(0, &target) );V( pd3dDevice->GetDepthStencilSurface(&old_depthstencil) );V( pd3dDevice->SetFVF( D3DFVF_SOFTWARESURFACEVERTEX ) );V( g_pHeightMapEffect->Begin(NULL, NULL) );V( g_pHeightMapEffect->BeginPass(0) );g_pHeightMapEffect->SetFloat(g_hScale, g_fScale);g_pHeightMapEffect->SetTexture(g_hNoiseTex0, g_texPackedNoise[0]);g_pHeightMapEffect->SetTexture(g_hNoiseTex1, g_texPackedNoise[1]);V( pd3dDevice->SetRenderTarget(0, target) );V( pd3dDevice->SetDepthStencilSurface(g_surDepthStencil) );V( pd3dDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ));V( pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, sizeX*sizeY, 0, 2*(sizeX-1)*(sizeY-1) ));V( g_pHeightMapEffect->EndPass() );V( g_pHeightMapEffect->End());//D3DXSaveTextureToFile(L"HeightMap.dds", D3DXIFF_DDS,g_texHeightMap,NULL);//写法向量纹理#if phase7SAFE_RELEASE(target);V( g_texNormalMap->GetSurfaceLevel(0, &target) );V( pd3dDevice->SetRenderTarget(0, target) );V( g_pNormalMapEffect->Begin(NULL, NULL) );V( g_pNormalMapEffect->BeginPass(0) );g_pNormalMapEffect->SetFloat(g_hInvMapSizeX, 1.0f / nmapsize_x);g_pNormalMapEffect->SetFloat(g_hInvMapSizeY, 1.0f / nmapsize_y);g_pNormalMapEffect->SetFloatArray(g_hCorner00, (const FLOAT *)&t_corners0, 4);g_pNormalMapEffect->SetFloatArray(g_hCorner01, (const FLOAT *)&t_corners1, 4);g_pNormalMapEffect->SetFloatArray(g_hCorner10, (const FLOAT *)&t_corners2, 4);g_pNormalMapEffect->SetFloatArray(g_hCorner11, (const FLOAT *)&t_corners3, 4);g_pNormalMapEffect->SetFloat(g_hAmplitude, g_fStrength);g_pNormalMapEffect->SetTexture(g_hHeightMap, g_texHeightMap);V( pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, sizeX*sizeY, 0, 2*(sizeX-1)*(sizeY-1) ) );V( g_pNormalMapEffect->EndPass() );V( g_pNormalMapEffect->End() );//D3DXSaveTextureToFile(L"NormalMap.dds", D3DXIFF_DDS,g_texNormalMap,NULL);#endif// restore the devicepd3dDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );pd3dDevice->SetRenderTarget( 0, bb );pd3dDevice->SetDepthStencilSurface( old_depthstencil );/////////////////////////////////////SAFE_RELEASE(target);SAFE_RELEASE(bb);SAFE_RELEASE(old_depthstencil);#endif#if phase8pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );V( g_pWaterGridEffect->Begin(NULL, NULL) );V( g_pWaterGridEffect->BeginPass(0) );g_pWaterGridEffect->SetMatrix(g_hViewProj, g_pObservingCamera->GetViewProjMatrix());g_pWaterGridEffect->SetMatrix(g_hView, g_pObservingCamera->GetViewMatrix());g_pWaterGridEffect->SetVector(g_hViewPos, &D3DXVECTOR4(g_pObservingCamera->GetEyePt()->x,g_pObservingCamera->GetEyePt()->y, g_pObservingCamera->GetEyePt()->z,1));#if phase9g_pWaterGridEffect->SetVector(g_hSunVec,&D3DXVECTOR4(cos(g_fSunPosTheta)*sin(g_fSunPosAlpha), sin(g_fSunPosTheta), cos(g_fSunPosTheta)*cos(g_fSunPosAlpha),0));g_pWaterGridEffect->SetFloat(g_hSunShininess, g_fSunShininess);g_pWaterGridEffect->SetFloat(g_hSunStrength, g_fSunStrength);g_pWaterGridEffect->SetFloat(g_hReflRefrOffset, g_fReflRefrOffset);g_pWaterGridEffect->SetBool(g_hDiffuseSkyRef, g_bDiffuseSkyRef);g_pWaterGridEffect->SetVector(g_hWaterColor, &D3DXVECTOR4(g_fWaterColorR, g_fWaterColorG, g_fWaterColorB, 1));g_pWaterGridEffect->SetFloat(g_hLODbias, g_fLODbias);g_pWaterGridEffect->SetTexture(g_hEnvironmentMap, g_texEnvironmentMap);g_pWaterGridEffect->SetTexture(g_hHeightMapForWaterGridFX, g_texHeightMap);g_pWaterGridEffect->SetTexture(g_hNormalMapForWaterGridFX, g_texNormalMap);g_pWaterGridEffect->SetTexture(g_hFresnelMap, g_texFresnelMap);#endif#if phase10g_pWaterGridEffect->SetTexture(g_hRefractionMap, g_texRefractionMap);#endif#if phase11g_pWaterGridEffect->SetTexture(g_hReflectionMap, g_texReflectionMap);#endifV( pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, sizeX*sizeY, 0, 2*(sizeX-1)*(sizeY-1) ) );V( g_pWaterGridEffect->EndPass() );V( g_pWaterGridEffect->End() );#endif#if phase13pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW  );pd3dDevice->SetDepthStencilSurface(g_surOriginDepthStencil);/////////////////////////////sun.Direction.x = -cos(g_fSunPosTheta) *sin(g_fSunPosAlpha);sun.Direction.y = sin(g_fSunPosTheta);sun.Direction.z = -cos(g_fSunPosTheta)*cos(g_fSunPosAlpha);sun.Diffuse.r = 1.0f;sun.Diffuse.g = 1.0f;sun.Diffuse.b = 1.0f;sun.Diffuse.a = 1.0f;sun.Ambient.a = 1.0f;sun.Ambient.r = 0.2f;sun.Ambient.g = 0.3f;sun.Ambient.b = 0.3f;sun.Specular.r = 1.0f;sun.Specular.g = 1.0f;sun.Specular.b = 1.0f;sun.Specular.a = 1.0f;sun.Attenuation0 = 1.0f;sun.Type = D3DLIGHT_DIRECTIONAL;pd3dDevice->SetLight(0, &sun);pd3dDevice->LightEnable( 0, true);///////// draw duck{D3DXMATRIXA16 store, offset, yrot,scale;pd3dDevice->GetTransform(D3DTS_WORLD,&store);float duckX = -15, duckZ = -5;// D3DXMatrixTranslation( &offset, duckie_pos.x, -duckie_pos.y + // myNoise.get_height_at(duckie_pos.x,duckie_pos.z), duckie_pos.z);D3DXMatrixTranslation( &offset, duckie_pos.x, duckie_pos.y, duckie_pos.z);pd3dDevice->MultiplyTransform(D3DTS_WORLD, &offset );D3DXMatrixRotationY( &yrot, duckie_pos.angle);pd3dDevice->MultiplyTransform(D3DTS_WORLD, &yrot );D3DXMatrixScaling( &scale, 3, 3, 3 );pd3dDevice->MultiplyTransform(D3DTS_WORLD, &scale );//g_pd3dDevice->SetMaterial((D3DMATERIAL9*)duck_Materials->GetBufferPointer());pd3dDevice->SetRenderState( D3DRS_LIGHTING, true);pd3dDevice->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 );pd3dDevice->SetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR1 );pd3dDevice->SetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1 );float plane[4];pd3dDevice->GetClipPlane(0,plane);plane[3] = myNoise.get_height_at(duckX, duckZ) + 0.1;pd3dDevice->SetClipPlane(0,plane);duckie->DrawSubset(0);pd3dDevice->SetTransform(D3DTS_WORLD, &store);}////////#if phase15{sun.Direction.y = -sin(g_fSunPosTheta);pd3dDevice->SetLight(0, &sun);pd3dDevice->SetRenderState( D3DRS_LIGHTING, true);pd3dDevice->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL );pd3dDevice->SetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL );pd3dDevice->SetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL );pd3dDevice->SetTexture(0, g_texIsland);float plane[4];pd3dDevice->GetClipPlane(0,plane);plane[3] = 0;pd3dDevice->SetClipPlane(0,plane);for(int i=0; i<7; i++){LPD3DXMATERIAL mat = (LPD3DXMATERIAL) island_Materials->GetBufferPointer();pd3dDevice->SetMaterial(&(mat->MatD3D));island->DrawSubset(i);}}#endif// restore stuffpd3dDevice->SetRenderState( D3DRS_LIGHTING, false);pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW  );///////////////////////#endif}#endif        V( pd3dDevice->EndScene() );    }}//--------------------------------------------------------------------------------------// Handle messages to the application //--------------------------------------------------------------------------------------LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,                          bool* pbNoFurtherProcessing, void* pUserContext ){#if phase0switch( uMsg ){case WM_KEYDOWN:{keys[wParam] = true;break;}case WM_KEYUP:{keys[wParam] = false;break;}}#endif#if phase1if( g_pRenderingCamera)g_pRenderingCamera->HandleMessages( hWnd, uMsg, wParam, lParam );#endif    return 0;}//--------------------------------------------------------------------------------------// Release D3D9 resources created in the OnD3D9ResetDevice callback //--------------------------------------------------------------------------------------void CALLBACK OnD3D9LostDevice( void* pUserContext ){#if phase3SAFE_RELEASE(g_texPackedNoise[0]);SAFE_RELEASE(g_texPackedNoise[1]);#endif#if phase5SAFE_RELEASE(g_pGridVB);SAFE_RELEASE(g_pGridIB);#endif#if phase6if( g_pHeightMapEffect )        g_pHeightMapEffect->OnLostDevice();SAFE_RELEASE(g_texHeightMap);SAFE_RELEASE(g_surDepthStencil);#endif#if phase7if( g_pNormalMapEffect )g_pNormalMapEffect->OnLostDevice();SAFE_RELEASE(g_texNormalMap);#endif#if phase8if( g_pWaterGridEffect )g_pWaterGridEffect->OnLostDevice();#endif#if phase10SAFE_RELEASE(g_texRefractionMap);#endif#if phase11SAFE_RELEASE(g_texReflectionMap);SAFE_RELEASE(g_surDepthStencilForRefrRefl);#endif#if phase12SAFE_RELEASE(g_pSkyBoxVB);SAFE_RELEASE(g_pSkyBoxIB);#endif#if phase14if( g_pIslandEffect )g_pIslandEffect->OnLostDevice();#endif#if phase16if( g_pUnderWaterEffect)g_pUnderWaterEffect->OnLostDevice();#endif}//--------------------------------------------------------------------------------------// Release D3D9 resources created in the OnD3D9CreateDevice callback //--------------------------------------------------------------------------------------void CALLBACK OnD3D9DestroyDevice( void* pUserContext ){#if phase1delete g_pRenderingCamera;#endif#if phase5delete [] g_pVertices;#endif#if phase6SAFE_RELEASE(g_pHeightMapEffect);#endif#if phase7SAFE_RELEASE(g_pNormalMapEffect);#endif#if phase8SAFE_RELEASE(g_pWaterGridEffect);#endif#if phase9SAFE_RELEASE(g_texEnvironmentMap);SAFE_RELEASE(g_texFresnelMap);#endif#if phase11SAFE_RELEASE(duckie);SAFE_RELEASE(duck_Adjacency);SAFE_RELEASE(duck_Materials);SAFE_RELEASE(duck_EffectInstances);SAFE_RELEASE(g_surOriginDepthStencil);#endif#if phase12SAFE_RELEASE(g_pSkyBoxEffect);#endif#if phase14SAFE_RELEASE(g_pIslandEffect);SAFE_RELEASE(g_texIsland);SAFE_RELEASE(island);SAFE_RELEASE(island_Adjacency);SAFE_RELEASE(island_Materials);SAFE_RELEASE(island_EffectInstances);#endif#if phase16SAFE_RELEASE(g_pUnderWaterEffect);#endif}//--------------------------------------------------------------------------------------// Initialize everything and go into a render loop//--------------------------------------------------------------------------------------INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int ){    // Enable run-time memory check for debug builds.#if defined(DEBUG) | defined(_DEBUG)    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );#endif    // Set the callback functions    DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );    DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );    DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );    DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );    DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );    DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );    DXUTSetCallbackMsgProc( MsgProc );    DXUTSetCallbackFrameMove( OnFrameMove );    // TODO: Perform any application-level initialization here    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application    DXUTInit( true, true ); // Parse the command line and show msgboxes    DXUTSetHotkeyHandling( true, true, true );  // handle the default hotkeys    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen    DXUTCreateWindow( L"3D_Shader_ProjectedGrid" );    DXUTCreateDevice( true, 1024, 768 );    // Start the render loop    DXUTMainLoop();    // TODO: Perform any application-level cleanup here    return DXUTGetExitCode();}



源代码请点此


原创粉丝点击