Main.cpp
上传用户:henghua
上传日期:2007-11-14
资源大小:7655k
文件大小:17k
- //************************************************************************************************
- // 2007年春《计算机图形学》课程大作业 **
- // 课题:海洋模拟系统
- // 课题描述:此系统充分考虑了海洋环境中各个因素,包括实现海面的起伏,物体在海面上的倒影 **
- // 水下物体的折射,太阳在海面上产生的粼粼波光,大气中雾气的影响,丰富变化的天气效果 **
- // 诸如降雪,日出日落,阴晴转换,海上明月的美丽景色,天空盒实现了云彩的漂移,此外系 **
- // 统中还载入了舰船模型,并可以让用户进行控制,而其中最有价值的是我们通过对二维偏微 **
- // 波方程的离散数值求解,实现了船在行进时在水面生成的尾迹。 **
- // 使用技术:多重Perlin噪声场的叠加,投影网格无限平面绘制技术,菲涅尔效应,数值求解二维 **
- // 偏微波方程。 // 小组成员 徐潇然、杨阳、房路 **
- //
- //************************************************************************************************
- #include <Windows.h>
- #include <mmsystem.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <DShow.h>
- //-----------------------------------------
- #include "comman.h"
- #include "dxmouse.h"
- #include "camera.h"
- #include "Sea.h"
- #include "Configuration.h"
- #include "NoiseGenerator.h"
- #include "MeshObj.h"
- #include "ParticleSystem.h"
- #include "BoatWave.h"
- #include "skydome.h"
- #include "weather.h"
- #include "weathercontrol.h"
- #include "trailfrag.h"
- #include "ddutil.h"
- //-----------------------------------------
- // *****主场景*****
- CSea *sea;
- CSkyDome *skydome;
- CSnow *snow;
- CWeatherControl *weatherctrl;
- int gridsize_x = 128, gridsize_y = 256;
- long int ssss,tttt;
- // *****输入控制*****
- // 1 鼠标
- dxmouse *mouse;
- // 2 键盘
- bool keys[256];
- // *****3D模型*****
- enum objName_3d
- {
- island_3d,
- boat_3d,
- underwater_island_3d,
- beacon_3d,
- island2_3d,
- ship_3d,
- carrier_3d
- };
- #define num_3d 7
- CMeshObj *g_ppMeshObj[num_3d];
- // *****参量集*****
- CConfiguration *config;
- // *****视角*****
- #define n_cameras 3
- CCamera *cameras[n_cameras];
- int current_camera = 0;
- bool camera_boat = false;
- // *****粒子系统*****
- CParticleSystem *g_pParticleSystem;
- // *****船尾迹*****
- CBoatWave *pWave;
- // D3D全局变量
- LPDIRECT3D9 g_pD3D = NULL;
- LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
- LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
- LPDIRECT3DVERTEXBUFFER9 g_pVBproj = NULL;
- LPDIRECT3DVERTEXBUFFER9 g_referencePlaneVB = NULL;
- LPD3DXFONT g_pd3dxFont = NULL;
- LPDIRECT3DSURFACE9 g_depthstencil = NULL;
- LPDIRECT3DTEXTURE9 terrain_texture = NULL;
- LPD3DXEFFECT terrain_effect = NULL;
- D3DLIGHT9 sun;
- // 背景音乐部分
- long int currentT, lastT;
- /* 指向Filter Graph的指针,用于控制声音的播放 */
- IGraphBuilder *pGraph;
- IMediaControl *pMediaControl;
- void TestMP3(LPCWSTR xxx)
- {
- CoInitialize(NULL);
- CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph);
- pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
- pGraph->RenderFile(xxx, NULL);
- pMediaControl->Run();
- //pMediaControl->Stop(); //Pause();
- /* 停止播放 */
- //pMediaControl->Release();
- /* 释放对象 */
- //pGraph->Release();
- /* 程序结束时调用 */
- //CoUninitialize();
- }
- //-----------------------------------------------------------------------------
- // 初始化D3D的有关设置
- // 说明:g_pD3D,g_pd3dDevice,g_depthstencil被赋值
- //-----------------------------------------------------------------------------
- HRESULT InitD3D( HWND hWnd )
- {
- HRESULT hr;
- // 创建D3D对象
- if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
- return E_FAIL;
- // 创建D3D设备
- D3DPRESENT_PARAMETERS d3dpp;
- ZeroMemory( &d3dpp, sizeof(d3dpp) );
- d3dpp.Windowed = TRUE;
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
- d3dpp.EnableAutoDepthStencil = TRUE;
- d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
- d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
- if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
- D3DCREATE_HARDWARE_VERTEXPROCESSING,
- &d3dpp, &g_pd3dDevice ) ) )
- {
- return E_FAIL;
- }
- g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
- g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
- g_pd3dDevice->GetDepthStencilSurface(&g_depthstencil);
- return S_OK;
- }
- //-----------------------------------------------------------------------------
- // 总初始化函数
- // 说明: 初始化所有的类
- //-----------------------------------------------------------------------------
- HRESULT InitGeometry(HWND hWnd, HINSTANCE hInst)
- {
- // 初始化视角类
- cameras[0] = new CCamera(D3DXVECTOR3(0,45,-150),0,0,0,45,1.33,0.3,5000.0);
- // 初始化参量集
- config = new CConfiguration();
-
- config->set_float( p_bReflRefrStrength,0.1f );
- config->set_float( p_bNight_Day, 1);
- config->set_float( p_fWaterColourR, 0.12f );
- config->set_float( p_fWaterColourG, 0.22f );
- config->set_float( p_fWaterColourB, 0.29f );
- config->set_float( p_fLODbias, 10.0f);
- config->set_bool( p_bDiffuseRefl, true );
- config->set_float( p_fSunPosAlpha, 0.0f );
- config->set_float( p_fSunPosTheta, 0.5f);
- config->set_float( p_fSunShininess, 1263.0f );
- config->set_float( p_fSunStrength, 208.0f );
- config->set_bool(p_bisSnowing, false);
- config->set_bool(p_bFogActive, true);
- // 初始话鼠标控制
- mouse = new dxmouse(hWnd,hInst);
- mouse->Init();
- // 初始化各种模型对象
- cmeshobjconfig cm_config[num_3d];
-
- cm_config[island_3d].draw_mtrls_state = have_mtrls;
- cm_config[island_3d].draw_texs_state = load_texs;
- cm_config[island_3d].movement_mode = is_land;
- cm_config[island_3d].rotate = D3DXVECTOR3(0, 0, 0);
- cm_config[island_3d].translate = D3DXVECTOR3(1000, 100, 2000);
- cm_config[island_3d].scale = D3DXVECTOR3(5, 2, 10);
- g_ppMeshObj[island_3d] = new CMeshObj(g_pd3dDevice, "models\island.x", &cm_config[island_3d]);
- g_ppMeshObj[island_3d]->Init();
- g_ppMeshObj[island_3d]->LoadTexture("textures\hill_tex3.png", -1);
- g_ppMeshObj[island_3d]->LoadEffect("fx\Underwater.fx");
- cm_config[island2_3d].draw_mtrls_state = have_mtrls;
- cm_config[island2_3d].draw_texs_state = load_texs;
- cm_config[island2_3d].movement_mode = is_land;
- cm_config[island2_3d].rotate = D3DXVECTOR3(0, 0, 0);
- cm_config[island2_3d].translate = D3DXVECTOR3(80, 30, 00);
- cm_config[island2_3d].scale = D3DXVECTOR3(1, 5, 1);
- g_ppMeshObj[island2_3d] = new CMeshObj(g_pd3dDevice, "models\island.x", &cm_config[island2_3d]);
- g_ppMeshObj[island2_3d]->Init();
- g_ppMeshObj[island2_3d]->LoadTexture("textures\hill_tex3.png", -1);
- g_ppMeshObj[island2_3d]->LoadEffect("fx\Underwater.fx");
- cm_config[underwater_island_3d].draw_mtrls_state = have_mtrls;
- cm_config[underwater_island_3d].draw_texs_state = load_texs;
- cm_config[underwater_island_3d].movement_mode = is_land;
- cm_config[underwater_island_3d].rotate = D3DXVECTOR3(0, 0, 0);
- cm_config[underwater_island_3d].translate = D3DXVECTOR3(1000, -5, 1900);
- cm_config[underwater_island_3d].scale = D3DXVECTOR3(15, 1, 15);
- g_ppMeshObj[underwater_island_3d] = new CMeshObj(g_pd3dDevice, "models\island.x", &cm_config[underwater_island_3d]);
- g_ppMeshObj[underwater_island_3d]->Init();
- g_ppMeshObj[underwater_island_3d]->LoadTexture("textures\hill_tex3.png", -1);
- g_ppMeshObj[underwater_island_3d]->LoadEffect("fx\Underwater.fx");
- cm_config[beacon_3d].draw_mtrls_state = have_mtrls;
- cm_config[beacon_3d].draw_texs_state = load_texs;
- cm_config[beacon_3d].movement_mode = fixed_up_sea;
- cm_config[beacon_3d].rotate = D3DXVECTOR3(0, 0, 0);
- cm_config[beacon_3d].translate = D3DXVECTOR3(1000, 100, 2000);
- cm_config[beacon_3d].scale = D3DXVECTOR3(0.1, 0.1, 0.1);
- g_ppMeshObj[beacon_3d] = new CMeshObj(g_pd3dDevice, "models\beacon_3d.x", &cm_config[beacon_3d]);
- g_ppMeshObj[beacon_3d]->Init();
- g_ppMeshObj[underwater_island_3d]->LoadTexture("textures\hill_tex3.png", -1);
- cm_config[boat_3d].draw_mtrls_state = have_mtrls;
- cm_config[boat_3d].draw_texs_state = have_texs;
- cm_config[boat_3d].movement_mode = moving_on_sea;
- cm_config[boat_3d].rotate = D3DXVECTOR3(0, D3DX_PI/2, 0);
- cm_config[boat_3d].translate = D3DXVECTOR3(10, -1, -40);
- cm_config[boat_3d].scale = D3DXVECTOR3(5, 5, 5);
- g_ppMeshObj[boat_3d] = new CMeshObj(g_pd3dDevice, "models\warship4.x", &cm_config[boat_3d]);
- g_ppMeshObj[boat_3d]->Init();
- g_ppMeshObj[boat_3d]->gpu_tex = 1;
- g_ppMeshObj[boat_3d]->LoadEffect("fx\Underwater.fx");
- cm_config[ship_3d].draw_mtrls_state = have_mtrls;
- cm_config[ship_3d].draw_texs_state = have_texs;
- cm_config[ship_3d].movement_mode = is_land;
- cm_config[ship_3d].rotate = D3DXVECTOR3(0, D3DX_PI/5, 0);
- cm_config[ship_3d].translate = D3DXVECTOR3(-600, -5, 50);
- cm_config[ship_3d].scale = D3DXVECTOR3(8, 8, 8);
- g_ppMeshObj[ship_3d] = new CMeshObj(g_pd3dDevice, "models\warship2.x", &cm_config[ship_3d]);
- g_ppMeshObj[ship_3d]->Init();
- g_ppMeshObj[ship_3d]->gpu_tex = 1;
- g_ppMeshObj[ship_3d]->LoadEffect("fx\Underwater.fx");
- cm_config[carrier_3d].draw_mtrls_state = have_mtrls;
- cm_config[carrier_3d].draw_texs_state = have_texs;
- cm_config[carrier_3d].movement_mode = is_land;
- cm_config[carrier_3d].rotate = D3DXVECTOR3(0, D3DX_PI/5, 0);
- cm_config[carrier_3d].translate = D3DXVECTOR3(-500, -8, 500);
- cm_config[carrier_3d].scale = D3DXVECTOR3(15, 15, 15);
- g_ppMeshObj[carrier_3d] = new CMeshObj(g_pd3dDevice, "models\carrier.x", &cm_config[carrier_3d]);
- g_ppMeshObj[carrier_3d]->Init();
- g_ppMeshObj[carrier_3d]->gpu_tex = 1;
- g_ppMeshObj[carrier_3d]->LoadEffect("fx\Underwater.fx");
- // 粒子对象
- cparticleconfig cp_config[3];
- cp_config[0].dwDiscard = 2048*4;
- cp_config[0].dwFlush = 512*2;
- cp_config[0].fRadius = -0.4f;
- strcpy(cp_config[0].tex_file_name , "textures\Particle.bmp");
- D3DXVec3Normalize( &(cp_config[0].src_dir), &(D3DXVECTOR3(-1,-1,0)) );
- cp_config[0].src_pos1 = D3DXVECTOR3(1,0,-3);
- cp_config[0].src_pos2 = D3DXVECTOR3(-1,0,-3);
- cp_config[0].src_vec = 9;
- cp_config[1].dwDiscard = 2048*4;
- cp_config[1].dwFlush = 512*2;
- cp_config[1].fRadius = 0.0f;
- strcpy(cp_config[1].tex_file_name , "textures\Particle.bmp");
- D3DXVec3Normalize( &(cp_config[1].src_dir), &(D3DXVECTOR3(1,1,0)) );
- cp_config[1].src_pos1 = D3DXVECTOR3(1,0,1);
- cp_config[1].src_pos2 = D3DXVECTOR3(1,0,-1);
- cp_config[1].src_vec = 9;
- cp_config[2].dwDiscard = 2048*4;
- cp_config[2].dwFlush = 512*2;
- cp_config[2].fRadius = 0.0f;
- strcpy(cp_config[2].tex_file_name , "textures\Particle.bmp");
- D3DXVec3Normalize( &(cp_config[2].src_dir), &(D3DXVECTOR3(0,1,1)) );
- cp_config[2].src_pos1 = D3DXVECTOR3(-4,0,1);
- cp_config[2].src_pos2 = D3DXVECTOR3(4,0,1);
- cp_config[2].src_vec = 9;
- g_ppMeshObj[boat_3d]->InitParSys(cp_config);
- // 初始化船尾迹对象
- pWave = new CBoatWave( g_ppMeshObj[boat_3d]->position.x, g_ppMeshObj[boat_3d]->position.y);
- // 初始化海洋对象
- sea = new CSea(g_pd3dDevice,cameras[current_camera], config, g_ppMeshObj, num_3d, pWave);
- // 初始化天气控制对象
- weatherctrl = new CWeatherControl(g_pd3dDevice, config);
- weatherctrl->Init();
- // 初始化雪对象
- snow = new CSnow(g_pd3dDevice, config, 3000, D3DXVECTOR3(0, 10, 0), 15);
- snow->cam = &sea->pCamera;
- snow->Init();
- // 初始化天空盒对象
- skydome = new CSkyDome(g_pd3dDevice, config, 10, 0.001, 0.01);
- skydome->cam = &sea->pCamera;
- skydome->Init();
- g_pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, 0xffffffff);
- g_pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_EXP2);
- float fogStart = 0.000235;
- g_pd3dDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)&fogStart);
- g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
- return S_OK;
- }
- VOID Cleanup()
- {
- if( g_pVB != NULL )
- g_pVB->Release();
- if( g_pd3dDevice != NULL )
- g_pd3dDevice->Release();
- if( g_pD3D != NULL )
- g_pD3D->Release();
- }
- //-----------------------------------------------------------------------------
- // 渲染函数
- // 说明: 所有的数据更新和场景绘制在这里完成
- //-----------------------------------------------------------------------------
- void Render()
- {
- // *****背景音乐刷新部分*****
- currentT = timeGetTime();
- if (currentT-lastT>3500)
- {
- pMediaControl->Stop(); //Pause();
- /* 停止播放 */
- pMediaControl->Release();
- /* 释放对象 */
- pGraph->Release();
- /* 程序结束时调用 */
- CoUninitialize();
- TestMP3(L"media\water.wav");
- lastT=currentT;
- }
- // *****数据更新部分*****
- // 视角更新
- mouse->Update();
- if(current_camera == 0)
- {
- cameras[current_camera]->UpdataKey();
- cameras[current_camera]->UpdataMouse(mouse);
- }
- else
- {
- if(current_camera == 1)
- cameras[current_camera]->UpdateBoat(mouse, g_ppMeshObj[boat_3d]);
- }
- // 其他类更新
- pWave->Update(g_ppMeshObj[boat_3d]->position.x,g_ppMeshObj[boat_3d]->position.z, g_ppMeshObj[boat_3d]->velosity);
- sea->pCamera = cameras[current_camera];
- sea->Update();
- skydome->Update();
- snow->Update();
- weatherctrl->Update();
-
- // *****场景绘制部分*****
- if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
- {
-
- sea->Render();
- skydome->Render();
- snow->Render();
- g_pd3dDevice->SetDepthStencilSurface(g_depthstencil);
- g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, true);
- g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00909090 );
-
- g_ppMeshObj[0]->Render();
- g_ppMeshObj[1]->seaHeight = sea->get_height_at(g_ppMeshObj[1]->position.x, g_ppMeshObj[1]->position.z);
- g_ppMeshObj[1]->Render();
- g_ppMeshObj[2]->Render();
- g_ppMeshObj[3]->Render();
- g_ppMeshObj[4]->Render();
- g_ppMeshObj[5]->seaHeight = sea->get_height_at(g_ppMeshObj[5]->position.x, g_ppMeshObj[5]->position.z);
- g_ppMeshObj[5]->Render();
- g_ppMeshObj[6]->seaHeight = sea->get_height_at(g_ppMeshObj[6]->position.x, g_ppMeshObj[6]->position.z);
- g_ppMeshObj[6]->Render();
- g_pd3dDevice->EndScene();
- }
-
- g_pd3dDevice->Present(NULL, NULL, NULL, NULL );
- }
- //-----------------------------------------------------------------------------
- // 消息处理函数
- // 说明: 处理与用户交互的信息
- //-----------------------------------------------------------------------------
- LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
- {
- switch( msg )
- {
- case WM_DESTROY:
- Cleanup();
- PostQuitMessage( 0 );
- return 0;
- case WM_KEYDOWN:
- keys[wParam] = TRUE;
- if(current_camera==1)
- g_ppMeshObj[1]->GetKey(wParam);
- g_ppMeshObj[3]->GetKey(wParam);
- cameras[0]->GetKey(wParam);
- if( keys[27])
- {
- Cleanup();
- exit(0);
- }
- if (keys['C'])
- {
- weatherctrl->set(CLOUDY);
- return 0;
- }
- if(keys['M'])
- {
- weatherctrl->set(SNOWING);
- return 0;
- }
- if(keys['F'])
- {
- weatherctrl->set(FINE);
- return 0;
- }
- if(keys['O'])
- {
- if(!config->get_bool(p_bFogActive))
- {
- g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
- config->set_bool(p_bFogActive, true);
- }
- else
- {
- config->set_bool(p_bFogActive, false);
- g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
- }
- }
- if(keys['N'])
- {
- if(!config->get_bool(p_bisNight))
- weatherctrl->set(NIGHT);
- else
- weatherctrl->set(DAY);
- return 0;
- }
- if(keys['B'])
- {
- if(current_camera == 1)
- {
- current_camera = 0;
- }
- else if(current_camera == 0)
- {
- current_camera = 1;
- if(camera_boat == false)
- cameras[1] = new CCamera( D3DXVECTOR3(g_ppMeshObj[boat_3d]->position.x,10,g_ppMeshObj[boat_3d]->position.z), 0,0,0,45,1.33,0.3,5000.0);
- camera_boat = true;
- }
- }
- if(keys['P'])
- {
- float *p_A = &(sea->pNoiseGenerator->A);
- if( *p_A < 1.0f)
- *p_A +=0.05;
- }
- if(keys['L'])
- {
- float *p_A = &(sea->pNoiseGenerator->A);
- if( *p_A >0.1f)
- *p_A -=0.05;
- }
- return 0;
- case WM_KEYUP:
- keys[wParam] = FALSE;
- g_ppMeshObj[1]->LostKey(wParam);
- g_ppMeshObj[3]->LostKey(wParam);
- cameras[0]->LostKey(wParam);
- return 0;
- }
- return DefWindowProc( hWnd, msg, wParam, lParam );
- }
- //-----------------------------------------------------------------------------
- // 主函数
- // 说明: DirectX图形程序开发的基本流程
- //-----------------------------------------------------------------------------
- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
- {
- // 注册窗口类
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
- GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
- "OceanFlame", NULL };
- RegisterClassEx( &wc );
- // 创建应用程序窗口
- HWND hWnd = CreateWindow( "OceanFlame", "OceanFlame——徐潇然、杨阳、房路",
- WS_OVERLAPPEDWINDOW, 100, 100, 1024, 768,
- GetDesktopWindow(), NULL, wc.hInstance, NULL );
- currentT=lastT = timeGetTime();
- TestMP3(L"media\water.wav");
- // 初始化D3D
- if( SUCCEEDED( InitD3D( hWnd ) ) )
- {
- // 初始化场景数据
- if( SUCCEEDED( InitGeometry( hWnd, hInst) ) )
- {
- // 显示窗口
- ShowWindow( hWnd, SW_SHOWDEFAULT );
- UpdateWindow( hWnd );
- // 进入消息循环
- MSG msg;
- ZeroMemory( &msg, sizeof(msg) );
- while( msg.message!=WM_QUIT )
- {
- if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- else
- Render();
- }
- }
- }
- UnregisterClass( "OceanFlame", wc.hInstance );
- return 0;
- }