www.pudn.com > WaveSimulation.rar > OceanSimulation.cpp
// OceanSimulation.cpp : Defines the entry point for the application. // #include "stdafx.h" #include#include // OpenGL headers #include #include #include #include #include "Wave.h" #include "mydefine.h" #include "texture.h" #include "Input.h" #include "Bezier.h" #include "Particle.h" #include "terrian.h" ///////////////////////////////////////////// void Savememmap() { FILE *fp; fp = fopen("a.txt","w"); for (int i = 0; i < WAVETRAIN; i++) fprintf(fp,"%-8d",i); fwrite("\n",sizeof(char),1,fp); for(i = 0; i < WAVETRAIN; i++) { float lifeperiod; lifeperiod = g_cWave[i].m_Segment1.RemainTime / g_cWave[i].m_Segment1.StageTime; fprintf(fp,"%-8.4f",lifeperiod); } fwrite("\n",sizeof(char),1,fp); for(i = 0; i < WAVETRAIN - 1; i++) fprintf(fp,"%-8.4f",g_cWave[i + 1].m_tCurrentTime - g_cWave[i].m_tCurrentTime); fclose(fp); } void CalcPointNormal(int RowIndex,int ColIndex, float out[]) { if(RowIndex < 1) RowIndex = 1; if(RowIndex > WAVE_ARRAY_SIZE - 1 ) RowIndex = WAVE_ARRAY_SIZE - 1; if(ColIndex < 1) ColIndex = 1; if(ColIndex > WAVETRAIN - 1) ColIndex = WAVETRAIN - 1; WaveLine wl1,wl2,wl3; float v[3][3]; float a,b,a2,b2,ab; a = 0.8; b = 0.2; a2 = 0.64; b2 = 0.04; ab = 0.16; wl1.x = g_cWave[ColIndex].m_WaveLineArray[RowIndex].x; wl1.y = g_cWave[ColIndex].m_WaveLineArray[RowIndex].y * 0.8f + g_cWave[ColIndex - 1].m_WaveLineArray[RowIndex].y * 0.2f; wl1.z = g_cWave[ColIndex].m_WaveLineArray[RowIndex].z * 0.8f + g_cWave[ColIndex - 1].m_WaveLineArray[RowIndex].z * 0.2f; wl2.x = g_cWave[ColIndex].m_WaveLineArray[RowIndex].x * 0.8f + g_cWave[ColIndex + 1].m_WaveLineArray[RowIndex].x * 0.2f; wl2.y = g_cWave[ColIndex].m_WaveLineArray[RowIndex].y * a2 + g_cWave[ColIndex + 1].m_WaveLineArray[RowIndex].y * ab + g_cWave[ColIndex + 1].m_WaveLineArray[RowIndex + 1].y * b2 + g_cWave[ColIndex].m_WaveLineArray[RowIndex + 1].y * ab; wl2.z = g_cWave[ColIndex].m_WaveLineArray[RowIndex].y * a + g_cWave[ColIndex].m_WaveLineArray[RowIndex + 1].y * b; wl3.x = g_cWave[ColIndex].m_WaveLineArray[RowIndex].x * 0.8f + g_cWave[ColIndex - 1].m_WaveLineArray[RowIndex].x * 0.2f; wl3.y = g_cWave[ColIndex].m_WaveLineArray[RowIndex].y * a2 + g_cWave[ColIndex - 1].m_WaveLineArray[RowIndex].y * ab + g_cWave[ColIndex + 1].m_WaveLineArray[RowIndex + 1].y * b2 + g_cWave[ColIndex].m_WaveLineArray[RowIndex + 1].y * ab; wl3.z = wl2.z; //指定法向 v[0][0] = wl1.x; v[0][1] = wl1.y; v[0][2] = wl1.z; v[1][0] = wl2.x; v[1][1] = wl2.y; v[1][2] = wl2.z; v[2][0] = wl3.x; v[2][1] = wl3.y; v[2][2] = wl3.z; calcNormal(v,out); } void ComputeParticle() { g_cInput.SetGLState(); static long time0 = timeGetTime(); long timeCur = timeGetTime(); static bool run = true; if(GetAsyncKeyState('P')!=0) run = !run; float timedt = 0; static long timePre = time0; if(run) { float timescale = 150.0f; g_timet = (timeCur-time0) / timescale; timedt = (timeCur - timePre) / timescale; } timePre = timeCur; static bool direction = true; static float dtime = g_cWave[0].m_TPeriod / 15.0f; static float totaltime = g_cWave[0].m_TPeriod; static float remaintime = 5.0f * g_cWave[0].m_TPeriod; float dt = timedt * dtime / totaltime ; //调整时间,使之一致 if( fabs(g_cWave[0].m_tCurrentTime - g_cWave[WAVETRAIN - 1].m_tCurrentTime) < dt * 0.1f) { for(int i = 0; i < WAVETRAIN ; i++) g_cWave[i].m_tCurrentTime = g_cWave[0].m_tCurrentTime; } if(remaintime < timedt) { remaintime = 10.0f * g_cWave[0].m_TPeriod; direction = !direction; } else remaintime -= timedt; for(int i = 0; i < WAVETRAIN ; i++) { float time; if(direction)//由左往右加 time = dt * (float)i / WAVETRAIN; else //由右向左加 time = dt * (float)(WAVETRAIN - i) / WAVETRAIN; g_cWave[i].ComputeWave( ( i - WAVETRAIN / 2) / 1.5f,timedt + time); } ////////////rendering GLfloat TextureCorx,TextureCory; g_cTexture.UseTexture(g_cTexture.m_pTextures[5]); for(i = 0; i < WAVETRAIN - 1; i++) { for(int j = 0; j < WAVE_ARRAY_SIZE - 1; j++) { WaveLine wl1,wl2,wl3,wl4; wl1 = g_cWave[i].m_WaveLineArray[j]; wl2 = g_cWave[i + 1].m_WaveLineArray[j]; wl3 = g_cWave[i + 1].m_WaveLineArray[j + 1]; wl4 = g_cWave[i].m_WaveLineArray[j + 1]; float out1[3],out2[3],out3[3],out4[3]; CalcPointNormal(j,i,out1); CalcPointNormal(j,i + 1,out2); CalcPointNormal(j + 1,i + 1,out3); CalcPointNormal(j + 1 ,i,out4); glBegin(GL_TRIANGLES); glNormal3fv( out1 ); CWave::CompTextCor(wl1,TextureCorx,TextureCory); glTexCoord2f(TextureCorx, TextureCory); glVertex3fv((float*)&wl1); glNormal3fv( out3 ); CWave::CompTextCor(wl3,TextureCorx,TextureCory); glTexCoord2f(TextureCorx, TextureCory); glVertex3fv((float*)&wl3); glNormal3fv( out2 ); CWave::CompTextCor(wl2,TextureCorx,TextureCory); glTexCoord2f(TextureCorx, TextureCory); glVertex3fv((float*)&wl2); glEnd(); glBegin(GL_TRIANGLES); glNormal3fv( out1 ); CWave::CompTextCor(wl1,TextureCorx,TextureCory); glTexCoord2f(TextureCorx, TextureCory); glVertex3fv((float*)&wl1); glNormal3fv( out4 ); CWave::CompTextCor(wl4,TextureCorx,TextureCory); glTexCoord2f(TextureCorx, TextureCory); glVertex3fv((float*)&wl4); glNormal3fv( out3 ); CWave::CompTextCor(wl3,TextureCorx,TextureCory); glTexCoord2f(TextureCorx, TextureCory); glVertex3fv((float*)&wl3); glEnd(); } } } GLvoid glPrint(const char *fmt, ...) // Custom GL "Print" Routine { char text[256]; // Holds Our String va_list ap; // Pointer To List Of Arguments if (fmt == NULL) // If There's No Text return; // Do Nothing va_start(ap, fmt); // Parses The String For Variables vsprintf(text, fmt, ap); // And Converts Symbols To Actual Numbers va_end(ap); // Results Are Stored In Text glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits glListBase(base - 32); // Sets The Base Character to 32 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // Draws The Display List Text glPopAttrib(); // Pops The Display List Bits } void DisplayFrameRate() { //用来追踪显示侦率的变量 static int frames = 0; static long time1 = timeGetTime(); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D (0, width, 0, height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (0.375, 0.375, 0.); frames++; if (frames % 5 == 0) { fps=1000.0f * 5.0f / (timeGetTime() - time1); time1=timeGetTime(); } glColor4f(1.0,0.0,0.0,1.0); glRasterPos2f(20,20); glPrint("Current time : %-5.2f,fps: %-3.0f,WindSpeed: %4.2f", g_timet,fps,g_cWave[0].m_WindSpeed); glRasterPos2f(20,35); glPrint("Xeye: %-5.0f Zeye: %-5.0f Yeye: %5.0f ViewAngle: %5d",Xeye,Zeye,Yeye,(int)(ViewLineAngle * 180.0f / PI) % 360); } void HandleIdle() { static long LastRefreshtime = timeGetTime(); //检查键盘状态 if (GetAsyncKeyState(VK_ESCAPE)!=0) quit=1; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(Camera_HalfFov * 2,(GLfloat)width / (GLfloat)height,1.0,5000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Reset The View long temptime = timeGetTime(); if( (temptime - LastRefreshtime) > 20 ) { ViewLineAngle += (GLfloat)( ( (GetAsyncKeyState(VK_RIGHT)!=0) - (GetAsyncKeyState(VK_LEFT)!=0) ) / 60.0f); Yeye += (GLfloat)( ( (GetAsyncKeyState('A')!=0) - (GetAsyncKeyState('Z')!=0) ) / 3.0);// * 4.0f GLfloat ds = (GLfloat)( ( (GetAsyncKeyState(VK_UP)!=0) - (GetAsyncKeyState(VK_DOWN)!=0) ) / 3.0);// * 4.0 Xeye += ds * (GLfloat)cos(ViewLineAngle); Zeye += ds * (GLfloat)sin(ViewLineAngle); GLfloat dsslash = (GLfloat)( ( (GetAsyncKeyState('M')!=0) - (GetAsyncKeyState('N')!=0) ) / 3.0); Xeye += dsslash * (GLfloat)cosf(ViewLineAngle + PI / 2.0f); Zeye += dsslash * (GLfloat)sinf(ViewLineAngle + PI / 2.0f); LastRefreshtime = temptime; GLfloat dWinSpeed = (GLfloat)( ( (GetAsyncKeyState('K') != 0) - (GetAsyncKeyState('J') !=0 ) ) / 100.0); if(fabs(dWinSpeed) > 0.000001 ) { for(int i = 0; i < WAVETRAIN;i++) { g_cWave[i].m_WindSpeed += dWinSpeed; if(g_cWave[i].m_WindSpeed < 3.0f) g_cWave[i].m_WindSpeed = 3.0f; if( g_cWave[i].m_WindSpeed > 7.9f) { g_cWave[i].m_WindSpeed = 7.9f; } g_cWave[i].Init(); } } } int yoffset = 5; gluLookAt(Xeye ,Yeye + yoffset,Zeye, Xeye + ViewLineLength * cosf(ViewLineAngle), Yeye + yoffset, Zeye + ViewLineLength * sinf(ViewLineAngle) , 0.0,1.0,0.0); glColor4f(0.45f,0.55f,0.85f,0.85f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); g_cInput.ProcessKeys(); glEnable(GL_DEPTH_TEST); glDisable(GL_COLOR_MATERIAL); ////////////////////////////////////////////////////////////////////////////////// float bevel_mat_ambient1[] = {0.45f, 0.45f, 0.45f,0.6f};//1.0f,1.0f,1.0f glMaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient1 ); glColorMaterial(GL_FRONT, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); // glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // glEnable(GL_BLEND); ////////////////////////////////////////////////////////////////////////////////// g_cTerrian.DrawTerrain(); ComputeParticle(); float bevel_mat_ambient2[] = {1.0f,1.0f,1.0f,0.85f}; glMaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient2 ); glDisable(GL_TEXTURE_2D); glColor4f(0.8f,1.0f,0.9f,0.80f); for(int i = 2; i < WAVETRAIN - 1; i++) { CParticle * pParticle = &g_cWave[i].m_Particle; pParticle->DrawFoam(); } glDisable(GL_LIGHTING); // glDisable(GL_BLEND); DisplayFrameRate(); SwapBuffers(GLOBhDC); } // Select the pixel format for a given device context void SetDCPixelFormat(HDC hDC) { int nPixelFormat; static PIXELFORMATDESCRIPTOR pfd; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cRedBits = 0; pfd.cRedShift = 0; pfd.cGreenBits = 0; pfd.cGreenShift = 0; pfd.cBlueBits = 0; pfd.cBlueShift = 0; pfd.cAlphaBits = 0; pfd.cAlphaShift = 0; pfd.cAccumBits = 0; pfd.cAccumRedBits = 0; pfd.cAccumGreenBits = 0; pfd.cAccumBlueBits = 0; pfd.cAccumAlphaBits = 0; pfd.cDepthBits = 32; pfd.cStencilBits = 0; pfd.cAuxBuffers = 0; pfd.iLayerType = PFD_MAIN_PLANE; pfd.bReserved = 0; pfd.dwLayerMask = 0; pfd.dwVisibleMask = 0; pfd.dwDamageMask = 0; nPixelFormat = ChoosePixelFormat(hDC, &pfd); SetPixelFormat(hDC, nPixelFormat, &pfd); } // Viewport resizing void HandleResize(int w,int h) { if(h==0) h=1; /* int ow = w; ow = w*1/4; w = w-ow; */ glViewport(0,0,w,h); width=w; height=h; } void InitEngine() { g_cTexture.InitTexture(); g_cTerrian.InitTerrian(); for(int i = 0; i < WAVETRAIN; i++) g_cWave[i].Init(); glClearDepth(1.0); // Enables Clearing Of The Depth Buffer glDepthFunc(GL_LESS); // The Type Of Depth Test To Do glEnable(GL_DEPTH_TEST); // Hidden surface removal glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST ); // Really Nice Perspective Calculations ////////////////////////////////////////////////////////////////////////////////// GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; GLfloat diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat specular[] = { 0.65f, 0.55f, 0.5f, 1.0f }; GLfloat lightPos[] = { 1.0f,2.0f,-4.0f,0.0f};// direction light source 5.0f, 19.0f, -29.0f, glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient ); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse ); glLightfv(GL_LIGHT0, GL_SPECULAR, specular); static float lmodel_ambient[] = { 0.45f, 0.45f, 0.45f,0.5f};//0.2f,0.2f,0.2f,1.0f static float lmodel_twoside[] = { GL_TRUE };// GL_FALSE static float lmodel_local[] = { GL_TRUE };//GL_FALSE glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local); glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); // Water material properties static float bevel_mat_ambient[] = {0.45f, 0.45f, 0.45f,1.0f};//1.0f,1.0f,1.0f static float bevel_mat_diffuse[] = {2.0, 2.0, 2.0, 0.0f};// 2.0f,2.0f,2.0f,1.0f static float bevel_mat_specular[] = {3.0, 3.0, 3.0, 0.0}; static float bevel_mat_shininess[] = {50.0f}; glMaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient ); glMaterialfv(GL_FRONT, GL_DIFFUSE, bevel_mat_diffuse ); glMaterialfv(GL_FRONT, GL_SPECULAR, bevel_mat_specular ); glMaterialfv(GL_FRONT, GL_SHININESS, bevel_mat_shininess); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,LPARAM lParam) { switch (message) { case WM_CREATE: { GLOBhDC = GetDC(hWnd); SetDCPixelFormat(GLOBhDC); hRC = wglCreateContext(GLOBhDC); wglMakeCurrent(GLOBhDC, hRC); InitEngine(); ShowCursor(FALSE); break; } case WM_SIZE: { HandleResize(LOWORD(lParam),HIWORD(lParam)); break; } case WM_KEYDOWN: // Key Being Held Down { g_cInput.m_keys[wParam] = true; break; } case WM_KEYUP: // Key Is Released { g_cInput.m_keys[wParam] = false; break; } case WM_DESTROY: { quit=1; wglMakeCurrent(GLOBhDC,NULL); wglDeleteContext(hRC); ReleaseDC(hWnd,GLOBhDC); ChangeDisplaySettings(NULL,0); ShowCursor(TRUE); PostQuitMessage(0); } default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return 0; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; // Message Structure WNDCLASS wc; // Window Class structure wc.style = CS_HREDRAW | CS_VREDRAW| CS_OWNDC; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, NULL); wc.hCursor = LoadCursor(NULL, NULL); wc.hbrBackground= NULL; wc.lpszMenuName = NULL; wc.lpszClassName= "ANIMATE"; if (RegisterClass(&wc) == 0) { MessageBox( NULL, "Register window class failed!", "Error", MB_OK | MB_ICONERROR ); return FALSE; // Quit right away. } mainwindow = CreateWindow("animate", "animate", WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_POPUP|WS_VISIBLE, 0,0, 1024,768,//800,600,// NULL, NULL, hInstance, NULL); if (mainwindow==NULL) { MessageBox( NULL, "Create Window failed!", "Error", MB_OK | MB_ICONERROR ); return FALSE; } // create bitmaps for the device context font's first 256 glyphs wglUseFontBitmaps(GLOBhDC,0,256,1000); HFONT font; // Windows Font ID base = glGenLists(96); // Storage For 96 Characters font = CreateFont( -10, // Height Of Font 0, // Width Of Font 0, // Angle Of Escapement 0, // Orientation Angle FW_BOLD, // Font Weight FALSE, // Italic FALSE, // Underline FALSE, // Strikeout ANSI_CHARSET, // Character Set Identifier OUT_TT_PRECIS, // Output Precision CLIP_DEFAULT_PRECIS, // Clipping Precision NONANTIALIASED_QUALITY, // Output Quality FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch "MS Sans Serif"); // Font Name SelectObject(GLOBhDC,font); // Selects The Font We Want wglUseFontBitmaps(GLOBhDC,32,96,base); // Builds 96 Characters Starting At Character 32 while(!quit) { if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } HandleIdle(); } glDeleteLists(1000,256); return msg.wParam; } ////////////////////////////////////particle system /* g_cParticalManager.Refresh(g_timet); FoamPartical *newparticle = NULL; for(int i = 0; i < 30; i++) { newparticle = g_cParticalManager.GenerateFoam(50.0f); float x = 0,y=0,z=0; x += (rand() % 20 ) / 10.0f; y += (rand() % 20 ) / 10.0f; z += (rand() % 20 ) / 10.0f; if(newparticle != NULL) { newparticle->x = x; newparticle->y = y; newparticle->z = z; newparticle->hv = (rand() % 250) / 50.0f; newparticle->vv = (rand() % 250) / 50.0f; newparticle->life = (rand() % 250) / 150.0f; } } g_cParticalManager.DrawFoam(); */ // g_cBezier.DrawBezier();