⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.cpp

📁 一个基于有限差分法的水滴动画模拟
💻 CPP
字号:
#include"test.h"
#include"CFLF.h"
int  nngrid=10201;
int  nsizex=100;
int  nsizey=100;
long double dt=0.20;
long double nn_time=0.0;
long double Time=20.0;
long double ndxy=4.0;
long double gx[3],gy[3],gz[3];
//int static count=0;
CFLF test(dt,nn_time,nngrid,nsizex,nsizey,ndxy);
void drawpartdam()
{
	long double t=0.4,t2=-10.0;
    GLfloat BACK11,BACK12,BACK13,BACK21,BACK22,BACK23;
	GLfloat BACK31,BACK32,BACK33,BACK41,BACK42,BACK43;
    GLfloat A11,A12,A13,A21,A22,A23,A31,A32,A33,A41,A42,A43;
    GLfloat B1,B2,B3,B4;
    GLfloat C1,C2,C3;
	glDisable(GL_TEXTURE_2D);
	for(int i=1;i<test.sizex;i++)//分行列存储
	for(int j=1;j<test.sizey;j++)
		{
//		    glColor3f(0.0, 0.0,1.0);
//		    glBegin(GL_TRIANGLE_STRIP);	
            A11=test.gridx[i][j]+1-150;
			A12=test.gv1[i][j]-5;
			A13=(test.gridy[i][j]+1-200);
            A21=(test.gridx[i][j+1]+1-150);
			A22=(test.gv1[i][j+1]-5);
			A23=(test.gridy[i][j+1]+1-200);
            A31=(test.gridx[i+1][j+1]+1-150);
			A32=(test.gv1[i+1][j+1]-5);
			A33=test.gridy[i+1][j+1]+1-200;
            A41=(test.gridx[i+1][j]+1-150);
			A42=(test.gv1[i+1][j]-5);
			A43=(test.gridy[i+1][j]+1-200);
           gx[0]=A11;gy[0]=A13;gz[0]=A12;
           gx[1]=A21;gy[1]=A23;gz[1]=A22;
           gx[2]=A31;gy[2]=A33;gz[2]=A32;
 //        getNormal(BACK41,BACK42,BACK43);
           B1=(BACK11+BACK21+BACK31+BACK41)/4.0;
           B2=(BACK12+BACK22+BACK32+BACK42)/4.0;
           B3=(BACK13+BACK23+BACK33+BACK43)/4.0;
	 //       glBegin(GL_QUADS);
            glClearColor(1.0, 1.0, 1.0, 1.0); //白色背景xxxxxxxxxxxxxxx
             glColor3f (0.0, 0.0, 0.0);       //xxxxxxxxxxxxxxxxxxx
	        glBegin(GL_LINE_LOOP);
		    glNormal3f(B1,B2,B3);
			glVertex3f(t*A11,t2*A12,t*A13);  
			glVertex3f(t*A21,t2*A22,t*A23);
			glVertex3f(t*A31,t2*A32,t*A33);
            glVertex3f(t*A41,t2*A42,t*A43);
			//glEnd();
			glEnd();	
	}
	glEnable(GL_TEXTURE_2D);
}
AUX_RGBImageRec *LoadBMP(char *Filename)				// 读取位图图象
{
	FILE *File=NULL;									// 文件句柄

	if (!Filename)										// 确定文件名已给出
	{
		return NULL;									// 如果文件名未给出则返回NULL
	}

	File=fopen(Filename,"r");							// 检测文件是否存在

	if (File)											// 文件是否存在?
	{
		fclose(File);									// 关闭文件
		return auxDIBImageLoad(Filename);				// 读取位图并返回一个指针
	}

	return NULL;										//如果调用文件失败则返回NULL
}

int LoadGLTextures()									//调用Bitmap并转换成纹理
{
	int Status=FALSE;									//状态确定
	AUX_RGBImageRec *TextureImage[1];					//为纹理创建存储空间
	memset(TextureImage,0,sizeof(void *)*1);           	//将指针设为NULL
	//读取位图,检查错误。如果位图不存在则退出
	if (TextureImage[0]=LoadBMP("Data/water.bmp"))
	{
		Status=TRUE;									//设Status为TRUE
		glGenTextures(3, &texture[0]);					//创建纹理
		//用位图中的数据进行典型的纹理生成
		//创建使用最近NEAREST过滤器的纹理
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		//创建使用线性LINEAR过滤器的纹理
		glBindTexture(GL_TEXTURE_2D, texture[1]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		//创建经过MipMapped的纹理
		glBindTexture(GL_TEXTURE_2D, texture[2]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
	}
	if (TextureImage[0])									//纹理是否存在
	{
		if (TextureImage[0]->data)							//纹理图象是否存在
		{
			free(TextureImage[0]->data);					//释放纹理图象所占用内存
		}
		free(TextureImage[0]);								//释放图象结构
	}
	return Status;										//返回Status的值
}

void SceneInit(int w, int h)
{
	LoadGLTextures();
	glEnable(GL_TEXTURE_2D);	
//	glShadeModel(GL_SMOOTH);							//允许平滑着色
	glClearColor( 0.0, 0.0, 0.0, 0.5 );
	glClearDepth(1.0f);									//设置深度缓冲区
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);								//深度测试的类型
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);		//设置环境光
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);		//设置漫反射光
	glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);	//光源的位置
	glEnable(GL_LIGHT1);
	glColor4f(1.0f, 1.0f, 1.0f, 0.5);					//全亮度,50%alpha值(新)
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);					//基于alpha值半透明的混合方式(新)
 	glDepthFunc(GL_LESS);
	glEnable(GL_DEPTH_TEST);
//	glEnable(GL_LIGHTING);			// 使用光照(*******)
//	glEnable(GL_NORMALIZE);
	glShadeModel(GL_FLAT);

   test.form();


}

void SceneResizeViewport(GLsizei w, GLsizei h)
{
	if(h==0) 
	{	
		h=1;
	}
	aspect = (GLfloat)w/(GLfloat)h;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);						//选择投影矩阵
	glLoadIdentity();
	gluPerspective(45.0f, aspect, 0.1f, 100.0f );
	glMatrixMode(GL_MODELVIEW);		
	glLoadIdentity();
}

void SceneShow(GLvoid)									//这里进行所有的绘图工作
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	//清屏和清除深度缓冲区
	glLoadIdentity();									//重置当前Modelview矩阵
	glTranslatef(0.0f,0.0f,z);	
	glScalef(0.025,0.025,0.025);
    glRotatef(xrot,1.0f,0.0f,0.0f);
    glRotatef(yrot,0.0f,1.0f,0.0f);
//    glRotatef(zrot,0.0f,0.0f,1.0f);
	glBindTexture(GL_TEXTURE_2D,texture[filter]);

//        if ((rand() % 100) == 0) 
//		  {
//	            test.gv1[50][50]=-10.0;
//			    test.gv2[50][50]=0.0;
//			    test.gv3[50][50]=0.0;

//				test.gv1[60][60]=-10.0;
//			    test.gv2[60][60]=0.0;
//			    test.gv3[60][60]=0.0;
//		   }

if (nn_time<=Time)
	test.compute(dt, nn_time);

 
    drawpartdam();
//	glLoadIdentity();
//	::SwapBuffers(m_pDC->GetSafeHdc());		//交互缓冲区
//	return TRUE;;
	xrot+=xspeed;
	yrot+=yspeed;
//	return TRUE;
}







void EnableOpenGL()
{
	PIXELFORMATDESCRIPTOR pfd;
	int iFormat;

	hDC = GetDC( hWnd );

	ZeroMemory( &pfd, sizeof( pfd ) );
	pfd.nSize = sizeof( pfd );
	pfd.nVersion = 1;
	pfd.dwFlags =   PFD_DRAW_TO_WINDOW |
					PFD_SUPPORT_OPENGL |
					PFD_DOUBLEBUFFER;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 16;
	pfd.cDepthBits = 16;
	pfd.iLayerType = PFD_MAIN_PLANE;

	iFormat = ChoosePixelFormat( hDC, &pfd );

	SetPixelFormat( hDC, iFormat, &pfd );

	hRC = wglCreateContext( hDC );
	wglMakeCurrent( hDC, hRC );
}


// 取消 OpenGL 
void DisableOpenGL()
{
	wglMakeCurrent( NULL, NULL );
	wglDeleteContext( hRC );
	ReleaseDC( hWnd, hDC );
}

bool ChangeResolution(int w, int h, int bitdepth)
{
	DEVMODE devMode;
	int   modeSwitch;
	int   closeMode = 0;

	EnumDisplaySettings(NULL, closeMode, &devMode);

	devMode.dmBitsPerPel = bitdepth;
	devMode.dmPelsWidth  = w;
	devMode.dmPelsHeight = h;
	devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

	modeSwitch = ChangeDisplaySettings(&devMode, CDS_FULLSCREEN);

	if(modeSwitch == DISP_CHANGE_SUCCESSFUL)
	{
		return true;
	}
	else
	{
		ChangeDisplaySettings(NULL, 0);
		return false;
	}
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
						  WPARAM wParam, LPARAM lParam )
{

	switch ( message )
	{
		case WM_CREATE:
			GetWindowRect(hWnd, &rect);
			sw = rect.right - rect.left;
			sh = rect.bottom - rect.top;
			SceneResizeViewport(sw, sh);
			return 0;

		case WM_SIZE:

			if(!fullscreen)
			{
				GetWindowRect(hWnd, &rect);
				sw = rect.right - rect.left;
				sh = rect.bottom - rect.top;
				if(sw>0 && sh>0)
					SceneResizeViewport(sw, sh);
			}
			else
			{
				SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),
									 GetSystemMetrics( SM_CYSCREEN ));
			}

			return 0;

		case WM_CLOSE:
			ShowWindow (hWnd, SW_HIDE);
			PostQuitMessage( 0 );
			return 0;

		case WM_DESTROY:
			return 0;

		case WM_KEYDOWN:
			switch( wParam )
			{
			case VK_ESCAPE:
				PostMessage(hWnd, WM_CLOSE, 0, 0);
				break;
			case 'F':
				if (!fp)
				{
					fp=TRUE;
					filter+=1;
					if (filter>2)
					{
						filter=0;
					}
				}
				else
				{
					fp=FALSE;
				}
				break;
			case VK_PRIOR:
				z-=0.02f;
				break;
			case VK_NEXT:
				z+=0.02f;
				break;
			case VK_UP:
				xspeed-=0.01f;
				break;
			case VK_DOWN:
				xspeed+=0.01f;
				break;
			case VK_RIGHT:
				yspeed+=0.01f;
				break;
			case VK_LEFT:
				yspeed-=0.01f;
				break;
            case 'B':
				if(!bp)
				{
					bp=TRUE;
					blend = !blend;
					if(blend)
					{
						glEnable(GL_BLEND);			// 打开混合功能
						glDisable(GL_DEPTH_TEST);	// 关闭深度测试
					}
					else
					{
						glDisable(GL_BLEND);		// 关闭混合功能
						glEnable(GL_DEPTH_TEST);	// 打开深度测试
					}
				}
				else
				{
					bp=FALSE;
				}
				break;
			case 'L':
				if(!lp)
				{
					lp=TRUE;
					light=!light;
					if (!light)
					{
						glDisable(GL_LIGHTING);
					}
					else
					{
						glEnable(GL_LIGHTING);
					}
				}
				else
				{
					lp=FALSE;
				}
				break;
			}
			return 0;
		default:
		return DefWindowProc( hWnd,message, wParam, lParam );
	}
}


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	WNDCLASS wc;
	MSG msg;
	bool bQuit = false;



	if (MessageBox(NULL,"是否选择全屏显示模式?", "全屏方式运行?",MB_YESNO|MB_ICONQUESTION)==IDNO)
	{
		fullscreen=0;							//窗口模式
	}

	wc.style = CS_OWNDC;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	wc.hCursor = LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "Name";
	RegisterClass( &wc );


	if(fullscreen)
	{
		ChangeResolution(640, 480, 16);
		hWnd = CreateWindow(
								"Name",
								"Lesson1",
								WS_POPUP |  WS_CLIPSIBLINGS | WS_VISIBLE,
								0, 0,
								GetSystemMetrics( SM_CXSCREEN ),
								GetSystemMetrics( SM_CYSCREEN ),
								NULL, NULL,
								hInstance,
								NULL );
	}else
	{
		hWnd = CreateWindow(
							"Name",
							"Lesson1",
							WS_TILEDWINDOW | WS_VISIBLE,
							GetSystemMetrics( SM_CXSCREEN )/2-sw/2,
							GetSystemMetrics( SM_CYSCREEN )/2-sh/2,
							sw,
							sh,
							NULL, NULL,
							hInstance,
							NULL );
		ChangeDisplaySettings(NULL, 0);
	}
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	//Initialisation
	EnableOpenGL();
	SceneInit(sw, sh);

	if(!fullscreen)
	{
		GetWindowRect(hWnd, &rect);
		sw = rect.right - rect.left;
		sh = rect.bottom - rect.top;
		if(sw>0 && sh>0)
			SceneResizeViewport(sw, sh);
	}
	else
	{
		SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),
							 GetSystemMetrics( SM_CYSCREEN ));
	}

	while ( !bQuit )
	{
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
			if ( msg.message == WM_QUIT )
				bQuit = true;
			else 
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
		else
		{
          
			// OpenGL 动画
			SceneShow();
			SwapBuffers(hDC);

		}
	}

	//关闭,退出程序
	DisableOpenGL();

	ShowWindow (hWnd, SW_HIDE);
	DestroyWindow( hWnd );

	ChangeDisplaySettings(NULL, 0);

	return msg.wParam;

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -