Sea.cpp
上传用户:henghua
上传日期:2007-11-14
资源大小:7655k
文件大小:19k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. #include "Sea.h"
  2. #include <stdio.h>
  3. #include "tools.h"
  4. // 初始化部分
  5. CSea::CSea( const LPDIRECT3DDEVICE9 dev, CCamera *cam, CConfiguration *cfg, CMeshObj **ppmesh, int num_mesh, CBoatWave *pW)
  6. {
  7. position = SEAPOSITION;
  8. normal = SEANORMAL;
  9. sizeX = SEASIZEX+1;
  10. sizeY = SEASIZEY+1;
  11. config = cfg;
  12. device = dev;
  13. pCamera = cam;
  14. ppMeshObj = ppmesh;
  15. num_meshobj = num_mesh;
  16. pWave = pW;
  17. D3DXPlaneFromPointNormal( &plane, &position, &normal );
  18. D3DXPlaneFromPointNormal( &upPlane, &(position + 15.0f * normal), &normal);
  19. D3DXPlaneFromPointNormal( &downPlane, &(position - 15.0f * normal), &normal);
  20. pNoiseGenerator = new CNoiseGenerator(sizeX, sizeY, config, device);
  21. InitializeBuffers();
  22. InitializeTextures();
  23. LoadEffect();
  24. }
  25. bool CSea::InitializeBuffers(){
  26. if( FAILED( device->CreateVertexBuffer( sizeX*sizeY*sizeof(SEAVERTEX), D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, 
  27. D3DFVF_SEAVERTEX, D3DPOOL_DEFAULT, &seaVertices, NULL ) ) )
  28. return false;
  29. if( FAILED( device->CreateIndexBuffer( sizeof(unsigned int)*6*(sizeX-1)*(sizeY-1), D3DUSAGE_WRITEONLY,
  30. D3DFMT_INDEX32, D3DPOOL_DEFAULT, &seaIndices,NULL)))
  31. return false;
  32. unsigned int *pIB;
  33. if( FAILED( seaIndices->Lock(0,0,(void**)&pIB,0 ) ) )
  34. return false;
  35. int i = 0, v, u;
  36. for(v=0; v<sizeY-1; v++){
  37. for(u=0; u<sizeX-1; u++){
  38. pIB[i++] = v*sizeX + u;
  39. pIB[i++] = v*sizeX + u + 1;
  40. pIB[i++] = (v+1)*sizeX + u;
  41. pIB[i++] = (v+1)*sizeX + u;
  42. pIB[i++] = v*sizeX + u + 1;
  43. pIB[i++] = (v+1)*sizeX + u + 1;
  44. }
  45. }
  46. seaIndices->Unlock();
  47. return true;
  48. }
  49. bool CSea::InitializeTextures()
  50. {
  51. if( FAILED( D3DXCreateTextureFromFile( device, "textures/fresnel_water_linear.bmp", &FresnelMap ) ) )
  52. {
  53. MessageBox(NULL, "Could not find fresnelmap", "Textures.exe", MB_OK);
  54. return false;
  55. }
  56. device->CreateTexture(512, 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &SeaReflaMap,NULL);
  57. device->CreateTexture(512, 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &SeaRefraMap,NULL);
  58. device->CreateDepthStencilSurface(512, 512, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, true, &new_depthstencil, NULL );
  59. return true;
  60. }
  61. void CSea::LoadEffect(){
  62. char *errortext;
  63. LPD3DXBUFFER errors;
  64. D3DXHANDLE hTechnique;
  65. D3DXCreateEffectFromFile(device, "fx\SeaShader.fx", 
  66. NULL, NULL, 0, NULL, &SeaEffect, &errors );
  67. if (errors != NULL){
  68. errortext = (char*) errors->GetBufferPointer();
  69. MessageBox(NULL, errortext, "OceanFlame", MB_OK);
  70. }
  71. SeaEffect->FindNextValidTechnique(NULL, &hTechnique);    
  72. SeaEffect->SetTechnique(hTechnique);
  73. }
  74. bool CSea::Update()
  75. {
  76. SetupMatrices(pCamera);
  77. seaBeSeen = CalculateExtension();
  78. if (seaBeSeen){
  79. pNoiseGenerator->UpdateNoise(&extension, pWave);
  80. D3DVERTEXBUFFER_DESC pDesc;
  81. SEAVERTEX *pV;
  82. HRESULT hr = seaVertices->GetDesc( &pDesc );
  83. if( FAILED(seaVertices->Lock( 0, 0, (void**) &pV, D3DLOCK_DISCARD)))
  84. {
  85. MessageBox(NULL, "Could not lock vertexbuffer", "Textures.exe", MB_OK);
  86. }
  87. else
  88. {
  89. int size = pDesc.Size;
  90. memcpy(pV, pNoiseGenerator->noiseVertices, size);
  91. seaVertices->Unlock();
  92. }
  93. }
  94. return true;
  95. }
  96. // 利用投影网格技术计算投射矩阵
  97. bool CSea::CalculateExtension()
  98. {
  99. D3DXVECTOR3 frustum[8];
  100. D3DXVECTOR3 projectedPoints[24];
  101. 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};
  102. // 先求出视景体八个角的世界坐标
  103. D3DXVec3TransformCoord(&frustum[0], &D3DXVECTOR3(-1,-1,-1), &(pCamera->invviewproj));
  104. D3DXVec3TransformCoord(&frustum[1], &D3DXVECTOR3(+1,-1,-1), &(pCamera->invviewproj));
  105. D3DXVec3TransformCoord(&frustum[2], &D3DXVECTOR3(-1,+1,-1), &(pCamera->invviewproj));
  106. D3DXVec3TransformCoord(&frustum[3], &D3DXVECTOR3(+1,+1,-1), &(pCamera->invviewproj));
  107. D3DXVec3TransformCoord(&frustum[4], &D3DXVECTOR3(-1,-1,+1), &(pCamera->invviewproj));
  108. D3DXVec3TransformCoord(&frustum[5], &D3DXVECTOR3(+1,-1,+1), &(pCamera->invviewproj));
  109. D3DXVec3TransformCoord(&frustum[6], &D3DXVECTOR3(-1,+1,+1), &(pCamera->invviewproj));
  110. D3DXVec3TransformCoord(&frustum[7], &D3DXVECTOR3(+1,+1,+1), &(pCamera->invviewproj));
  111. // 计算视景体与海水起伏控制高度两个上下界面的交点并保存
  112. int i, numPoints=0;
  113. int head, tail;
  114. for(i=0; i<12; i++)
  115. {
  116. head=cube[i*2], tail=cube[i*2+1];
  117. if ((upPlane.a*frustum[head].x + upPlane.b*frustum[head].y + upPlane.c*frustum[head].z + upPlane.d*1)
  118. /(upPlane.a*frustum[tail].x + upPlane.b*frustum[tail].y + upPlane.c*frustum[tail].z + upPlane.d*1)<0)
  119. D3DXPlaneIntersectLine( &projectedPoints[numPoints++], &upPlane, &frustum[head], &frustum[tail]);
  120. if ((downPlane.a*frustum[head].x + downPlane.b*frustum[head].y + downPlane.c*frustum[head].z + downPlane.d*1)
  121. /(downPlane.a*frustum[tail].x + downPlane.b*frustum[tail].y + downPlane.c*frustum[tail].z + downPlane.d*1)<0)
  122. D3DXPlaneIntersectLine( &projectedPoints[numPoints++], &downPlane, &frustum[head], &frustum[tail]);
  123. }
  124. // 看视景体八个角点有无在两个界面之间
  125. for(i=0; i<8; i++)
  126. if ((upPlane.a*frustum[i].x + upPlane.b*frustum[i].y + upPlane.c*frustum[i].z + upPlane.d*1)
  127. /(downPlane.a*frustum[i].x + downPlane.b*frustum[i].y + downPlane.c*frustum[i].z + downPlane.d*1)<0)
  128. projectedPoints[numPoints++] = frustum[i];
  129. // 创建一个投射视角,用来构造投射矩阵
  130. CCamera *projectedCamera = new CCamera(pCamera);
  131. D3DXVECTOR3 lookAt1, lookAt2;
  132. projectedCamera->position += D3DXVECTOR3(downPlane.a,downPlane.b,downPlane.c)*10.0f;
  133. // 控制投射矩阵向前方向
  134. if(D3DXPlaneDotNormal(&plane, &(pCamera->forward)) < 0.0f)
  135. {
  136. D3DXPlaneIntersectLine( &lookAt1, &plane, &(pCamera->position), &(pCamera->position + pCamera->forward) );
  137. }
  138. else
  139. {
  140. D3DXVECTOR3 turnOver;
  141. turnOver = pCamera->forward - 2*normal*D3DXVec3Dot(&(pCamera->forward),&normal);
  142. D3DXPlaneIntersectLine( &lookAt1, &plane, &(pCamera->position), &(pCamera->position + turnOver) );
  143. }
  144. lookAt2 = pCamera->position + 10.0f * pCamera->forward;
  145. lookAt2 = lookAt2 - normal*D3DXVec3Dot(&lookAt2,&normal);
  146. float adjust= fabs(D3DXPlaneDotNormal(&plane, &(pCamera->forward)));
  147. lookAt1 = lookAt1*adjust + lookAt2*(1.0f-adjust);
  148. projectedCamera->forward = lookAt1-projectedCamera->position;
  149. projectedCamera->UpdateLookAt();
  150. // 求包围所有点的最大矩形包围
  151. for(i=0; i<numPoints; i++)
  152. {
  153. D3DXVec3TransformCoord( &projectedPoints[i], &projectedPoints[i], &(projectedCamera->viewproj));  
  154. }
  155. float xmin, xmax, ymin, ymax;
  156. if(numPoints > 0)
  157. {
  158. xmin = projectedPoints[0].x, xmax = projectedPoints[0].x;
  159. ymin = projectedPoints[0].y, ymax = projectedPoints[0].y;
  160. for(i=1; i<numPoints; i++)
  161. {
  162. if (projectedPoints[i].x > xmax) xmax = projectedPoints[i].x;
  163. if (projectedPoints[i].x < xmin) xmin = projectedPoints[i].x;
  164. if (projectedPoints[i].y > ymax) ymax = projectedPoints[i].y;
  165. if (projectedPoints[i].y < ymin) ymin = projectedPoints[i].y;
  166. }
  167. D3DXMATRIXA16 matrix(xmax-xmin, 0, 0, xmin,
  168.  0, ymax-ymin, 0, ymin,
  169.  0, 0, 1, 0,
  170.  0, 0, 0, 1);
  171. D3DXMatrixTranspose(&matrix,&matrix);
  172. // 生成投射矩阵
  173. extension = matrix*projectedCamera->invviewproj;
  174. if(projectedCamera != NULL)
  175. delete projectedCamera;
  176. return true;
  177. }
  178. if(projectedCamera != NULL)
  179. delete projectedCamera;
  180. return false;
  181. }
  182. bool CSea::Render(){
  183. D3DXMATRIXA16 temp;
  184. D3DXMatrixIdentity(&temp);
  185. device->SetTransform( D3DTS_WORLD, &temp );
  186. // 分别渲染折射和反射场景
  187. RenderReflection();
  188. RenderRefraction();
  189. device->Clear( 0, NULL,D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, D3DCOLOR_XRGB((int)(198),(int)(210),(int)(255)), 1.0f, 0 );
  190. device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
  191. device->SetRenderState(D3DRS_ZWRITEENABLE,true);
  192. device->SetRenderState(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);
  193. device->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
  194. // 用GPU计算海面,从而达到更加逼真的效果
  195. if (seaBeSeen)
  196. {
  197. {
  198. HRESULT hr;
  199. device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE  );
  200. device->SetStreamSource( 0, seaVertices, 0, sizeof(SEAVERTEX) );
  201. device->SetFVF( D3DFVF_SEAVERTEX);
  202. device->SetIndices(seaIndices);
  203. pNoiseGenerator->UpdateVerticesNormal(pWave);
  204. float tnd = config->get_float(p_bNight_Day);
  205. device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE  );
  206. hr=SeaEffect->Begin(NULL,NULL);
  207. hr=SeaEffect->Pass(0);
  208. hr=SeaEffect->SetMatrix("mViewProj",&(pCamera->viewproj));
  209. hr=SeaEffect->SetMatrix("mView",&(pCamera->view));
  210. /*SeaEffect->SetFloat("sun_alfa", config->params[p_fSunPosAlpha].fData);
  211. SeaEffect->SetFloat("sun_theta", config->params[p_fSunPosTheta].fData);*/
  212. float sa = config->params[p_fSunPosAlpha].fData, 
  213. st = config->params[p_fSunPosTheta].fData * fabs(tnd * 2 - 1);
  214. hr=SeaEffect->SetVector("sun_vec",&D3DXVECTOR4(cos(st)*sin(sa), sin(st), cos(st)*cos(sa),0));
  215. hr=SeaEffect->SetFloat("sun_shininess", config->params[p_fSunShininess].fData);
  216. hr=SeaEffect->SetFloat("sun_strength", config->params[p_fSunStrength].fData);
  217. SeaEffect->SetFloat("reflrefr_offset", config->params[p_bReflRefrStrength].fData);
  218. SeaEffect->SetBool("diffuseSkyRef", config->params[p_bDiffuseRefl].bData);
  219. SeaEffect->SetVector("watercolour", &D3DXVECTOR4(config->params[p_fWaterColourR].fData,config->params[p_fWaterColourG].fData,config->params[p_fWaterColourB].fData,1));
  220. SeaEffect->SetFloat("LODbias", config->get_float(p_fLODbias) );
  221. SeaEffect->SetFloat("night_day", config->get_float(p_bNight_Day) );
  222. SeaEffect->SetVector("view_position", &D3DXVECTOR4(pCamera->position.x,pCamera->position.y,pCamera->position.z,1));
  223. SeaEffect->SetTexture("FresnelMap",FresnelMap);
  224. SeaEffect->SetTexture("Heightmap",pNoiseGenerator->heightMap);
  225. SeaEffect->SetTexture("Normalmap",pNoiseGenerator->normalMap);
  226. SeaEffect->SetTexture("Refractionmap",SeaRefraMap);
  227. SeaEffect->SetTexture("Reflectionmap",SeaReflaMap);
  228. device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, sizeX*sizeY, 0, 2*(sizeX-1)*(sizeY-1) );
  229. SeaEffect->End();
  230. }
  231. return true;
  232. }
  233. CSea::~CSea()
  234. {
  235. }
  236. void CSea::SetupMatrices(const CCamera *camera_view)
  237. {
  238. D3DXMATRIXA16 matWorld,matProj;
  239. D3DXMatrixIdentity(&matWorld);
  240. device->SetTransform( D3DTS_WORLD, &matWorld );
  241. device->SetTransform( D3DTS_VIEW, &(camera_view->view) );
  242. device->SetTransform( D3DTS_PROJECTION, &(camera_view->proj) );
  243. }
  244. float CSea::get_height_at( float x, float z )
  245. {
  246. if (pNoiseGenerator)
  247. return pNoiseGenerator->GetHeight(x,z);
  248. return 0.0f;
  249. }
  250. void CSea::RenderRefraction()
  251. {
  252. // **保存旧的渲染目标表面, 设置新的渲染目标表面**
  253. device->GetRenderTarget(0, &old_target);
  254. device->GetDepthStencilSurface(&old_depthstencil);
  255. SeaRefraMap->GetSurfaceLevel(0, &new_target);
  256. device->SetRenderTarget(0, new_target);
  257. device->SetDepthStencilSurface(new_depthstencil);
  258. // **清空后台缓冲区**
  259. float red=0.12f, green=0.22f, blue=0.29f;
  260. device->Clear( 0, NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB((int)(255*red),(int)(255*green),(int)(255*blue)), 1.0f, 0 );
  261. // **保存旧的世界变换矩阵, 设置新的世界变换矩阵**
  262. D3DXMATRIXA16 old_world, scale;
  263. device->GetTransform(D3DTS_WORLD,&old_world);
  264. D3DXMatrixScaling( &scale, 1, 0.75, 1 );
  265. device->MultiplyTransform(D3DTS_WORLD, &scale );
  266. device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  267. // **添加一个裁剪平面**
  268. float plane[4]={0, -1, 0, 0};
  269. plane[0] = 0;
  270. plane[1] = -1;
  271. plane[2] = 0;
  272. plane[3] = 10.0f;
  273. device->SetClipPlane(0,plane);
  274. // ***** 开始渲染 *****
  275. // 设置太阳光
  276. SetSunLight(rsm_refraction);
  277. int i;
  278. for(i=0; i<this->num_meshobj; i++)
  279. {
  280. if(ppMeshObj[i]->movement_mode == is_land || ppMeshObj[i]->movement_mode == moving_on_sea)
  281. {
  282. GPUDrawMeshObj( ppMeshObj[i] );
  283. }
  284. }
  285. device->SetRenderState( D3DRS_LIGHTING, false);
  286. device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW  );
  287. device->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
  288. device->SetRenderState( D3DRS_CLIPPLANEENABLE, 0);
  289. device->SetTransform(D3DTS_WORLD, &old_world);
  290. device->SetRenderTarget(0, old_target);
  291. device->SetDepthStencilSurface(old_depthstencil);
  292. }
  293. void CSea::RenderReflection()
  294. {
  295. // **保存旧的渲染目标表面和深度模版表面, 设置新的渲染目标表面和深度模版表面**
  296. device->GetRenderTarget(0, &old_target );
  297. device->GetDepthStencilSurface(&old_depthstencil);
  298. SeaReflaMap->GetSurfaceLevel( 0,&new_target );
  299. device->SetRenderTarget(0, new_target);
  300. device->SetDepthStencilSurface( new_depthstencil );
  301. // **清空后台缓冲区**
  302. device->Clear( 0, NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0, 1.0f, 0 );
  303. float red=0.12f, green=0.22f, blue=0.29f;
  304. //device->Clear( 0, NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB((int)(255*0.1f),(int)(255*0.5f),(int)(255*0.8)), 1.0f, 0 );
  305. // **保存旧的世界变换矩阵, 设置新的世界变换矩阵**
  306. D3DXMATRIXA16 old_world, scale;
  307. device->GetTransform(D3DTS_WORLD,&old_world);
  308. device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW  ); // 设置剔除模式
  309. // **添加一个裁剪平面**
  310. float plane[4];
  311. plane[0] = 0;
  312. plane[1] = -1;
  313. plane[2] = 0;
  314. plane[3] = 5.0f;
  315. device->SetClipPlane(0,plane);
  316. device->SetRenderState( D3DRS_CLIPPLANEENABLE, 1);
  317. // ***** 开始渲染 *****
  318. // 设置太阳光
  319. SetSunLight(rsm_reflection);
  320. D3DXMATRIXA16 store2, offset, yrot,scale2; // 旧世界变换矩阵, 平移矩阵, 旋转矩阵, 放缩矩阵
  321. // 获取旧的世界变换矩阵
  322. device->GetTransform(D3DTS_WORLD,&store2);
  323. int i;
  324. for(i=0; i<this->num_meshobj; i++){
  325. if(ppMeshObj[i]->movement_mode == fixed_down_sea)
  326. continue;
  327. device->MultiplyTransform(D3DTS_WORLD, &(ppMeshObj[i]->matWorld0));
  328. device->MultiplyTransform(D3DTS_WORLD, &(ppMeshObj[i]->matWorld) );
  329. // device->MultiplyTransform(D3DTS_WORLD, &(ppMeshObj[i]->rotate) );
  330. //if(ppMeshObj[i]->movement_mode == moving_up_freely)
  331. //{
  332. // 作用一个微镜面平移
  333. D3DXMatrixTranslation( &offset, 0,+2.0f, 0);
  334. device->MultiplyTransform(D3DTS_WORLD, &offset );
  335. //}
  336. // 在原世界变换矩阵上作用一个放缩
  337. //D3DXMatrixScaling( &scale2, ppMeshObj[i]->scale0.x,  ppMeshObj[i]->scale0.y,  ppMeshObj[i]->scale0.z);
  338. //device->MultiplyTransform(D3DTS_WORLD, &scale2 );
  339. // **依据不同的物体设置新的裁剪平面**
  340. SetClipPlane( ppMeshObj[i] );
  341. D3DXMatrixScaling( &scale, 1, -1, 1 ); // 生成反射成像的镜面变换矩阵
  342. device->MultiplyTransform(D3DTS_WORLD, &scale );
  343. // **打开光照**
  344. device->SetRenderState( D3DRS_LIGHTING, true);
  345. // **画**
  346. Draw_meshobj( ppMeshObj[i] );
  347. // **还原旧的世界变换矩阵**
  348. device->SetTransform(D3DTS_WORLD, &store2);
  349. }
  350. // **还原:关闭光照**
  351. device->SetRenderState( D3DRS_LIGHTING, false);
  352. device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW  );
  353. // **还原旧的世界变换矩阵和旧的渲染目标表面和深度模版表面**
  354. device->SetRenderState( D3DRS_CLIPPLANEENABLE, 0);
  355. device->SetTransform(D3DTS_WORLD, &old_world);
  356. device->SetRenderTarget(0, old_target);
  357. device->SetDepthStencilSurface( old_depthstencil );
  358. }
  359. // 光线反射(太阳光,火焰)
  360. void CSea::SetSunLight(int mode)
  361. {
  362. // 设置太阳光
  363. D3DLIGHT9 sun; 
  364. sun.Direction.x = -cos(config->get_float(p_fSunPosTheta))*sin(config->get_float(p_fSunPosAlpha));
  365. sun.Direction.y = -sin(config->get_float(p_fSunPosTheta));
  366. sun.Direction.z = -cos(config->get_float(p_fSunPosTheta))*cos(config->get_float(p_fSunPosAlpha));
  367. if(mode==rsm_reflection)
  368. {
  369. //sun.Direction.x = -sun.Direction.x;
  370. sun.Direction.y = -sun.Direction.y;
  371. //sun.Direction.z = -sun.Direction.z;
  372. }
  373. sun.Diffuse.r = 2.0f;
  374. sun.Diffuse.g = 2.0f;
  375. sun.Diffuse.b = 2.0f;
  376. sun.Diffuse.a = 1.0f;
  377. sun.Ambient.a = 1.0f;
  378. sun.Ambient.r = 0.2f;
  379. sun.Ambient.g = 0.3f;
  380. sun.Ambient.b = 0.3f;
  381. sun.Specular.r = 1.0f;
  382. sun.Specular.g = 1.0f;
  383. sun.Specular.b = 1.0f;
  384. sun.Specular.a = 1.0f;
  385. sun.Attenuation0 = 1.0f;
  386. sun.Type = D3DLIGHT_DIRECTIONAL;
  387. device->SetLight(0, &sun);
  388. device->LightEnable( 0, true);
  389. }
  390. // 设置裁减平面
  391. void CSea::SetClipPlane(CMeshObj *pM)
  392. {
  393. float plane[4];
  394. device->GetClipPlane(0,plane);
  395. if( pM->movement_mode == is_land ) // 如: 海中的小岛
  396. plane[3] = 0.1;
  397. else
  398. {
  399. if( pM->movement_mode == moving_on_sea )
  400. plane[3] = this->get_height_at(pM->position.x, pM->position.z) + 0.1;
  401. }
  402. device->SetClipPlane(0,plane);
  403. }
  404. void CSea::Draw_meshobj(CMeshObj *pM)
  405. {
  406. // 设置材质对漫反射光,镜面反射光,环境光的反射系数
  407. if(pM->draw_mtrls_state == not_have_mtrls)
  408. {
  409. device->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 );
  410. device->SetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR1 );
  411. device->SetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1 );
  412. }
  413. else
  414. {
  415. if(pM->draw_mtrls_state == have_mtrls)
  416. {
  417. device->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL );
  418. device->SetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL );
  419. device->SetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL );
  420. }
  421. }
  422. int i;
  423. for(i=0; i<pM->num_mtrls; i++)
  424. {
  425. if(pM->draw_mtrls_state == have_mtrls)
  426. device->SetMaterial( &(pM->pMeshMtrls[i]) );
  427. if(pM->draw_texs_state == have_mtrls)
  428. device->SetTexture(0, pM->pMeshTexs[i] );
  429. if(pM->draw_texs_state == load_texs )
  430. {
  431. if(pM->load_texs_mode == 0)
  432. device->SetTexture(0, pM->pMeshTexs[i]);
  433. else
  434. device->SetTexture(0, pM->pMeshTexs[0]);
  435. }
  436. pM->pMesh->DrawSubset(i);
  437. }
  438. }
  439. void CSea::GPUDrawMeshObj(CMeshObj *pM)
  440. {
  441. LPDIRECT3DVERTEXBUFFER9 vb;
  442. LPDIRECT3DINDEXBUFFER9 ib;
  443. pM->pMesh->GetVertexBuffer(&vb);
  444. pM->pMesh->GetIndexBuffer(&ib);
  445. device->SetStreamSource(0, vb, 0, pM->pMesh->GetNumBytesPerVertex());
  446. device->SetIndices(ib);
  447. device->SetFVF( pM->pMesh->GetFVF() );
  448. pM->pLoadEffect->Begin(NULL,NULL);
  449. pM->pLoadEffect->Pass(0);
  450. pM->pLoadEffect->SetMatrix("mWorld",&(pM->matWorld*pM->matWorld0));
  451. pM->pLoadEffect->SetMatrix("mViewProj",&(pCamera->viewproj));
  452. pM->pLoadEffect->SetMatrix("mView",&(pCamera->view));
  453. float sa = config->params[p_fSunPosAlpha].fData, st = config->params[p_fSunPosTheta].fData;
  454. pM->pLoadEffect->SetVector("sun_vec",&D3DXVECTOR4(cos(st)*sin(sa), sin(st), cos(st)*cos(sa),0));
  455. pM->pLoadEffect->SetFloat("sun_shininess", config->params[p_fSunShininess].fData);
  456. pM->pLoadEffect->SetFloat("sun_strength", config->params[p_fSunStrength].fData);
  457. pM->pLoadEffect->SetVector("watercolour", &D3DXVECTOR4(config->params[p_fWaterColourR].fData,config->params[p_fWaterColourG].fData,config->params[p_fWaterColourB].fData,1));
  458. pM->pLoadEffect->SetVector("view_position", &D3DXVECTOR4(pCamera->position.x,pCamera->position.y,pCamera->position.z,1));
  459. pM->pLoadEffect->SetTexture("texDiffuse",pM->pMeshTexs[pM->gpu_tex]);
  460. device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, pM->pMesh->GetNumVertices(), 0, pM->pMesh->GetNumFaces() );
  461. pM->pLoadEffect->End();
  462. }