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

📄 lesson6.cpp

📁 能够具有三维效果的3D旋转体
💻 CPP
字号:
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glaux.h>
#include <stdio.h>
#include <io.h>

HWND		hWnd;
HDC			hDC;
HGLRC		hRC=NULL;		//定义渲染环境
HINSTANCE	hInstance;		//得到程序的例子

RECT		rect;

int			sw = 640;
int			sh = 480;
	
bool		fullscreen  = 1;

GLfloat		aspect;

GLfloat	xrot;				// X轴旋转 ( 新 )
GLfloat	yrot;				// Y轴旋转 ( 新 )
GLfloat	zrot;				// Z轴旋转 ( 新 )

GLuint	texture[1];			//纹理的存储空间 ( 新 )

#pragma comment( lib, "opengl32.lib" )							// 链接时使用OpenGL32.lib
#pragma comment( lib, "glu32.lib" )								// 链接时使用GLu32.lib 
#pragma comment( lib, "glaux.lib" )								// 链接时使用GLaux.lib

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/TX.bmp"))
	{
		Status=TRUE;									//设Status为TRUE

		glGenTextures(1, &texture[0]);					//创建纹理

		//用位图中的数据进行典型的纹理生成
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}

	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( 1.05f, 0.5f, 0.05f, 0.5f );
	glClearDepth(1.0f);									//设置深度缓冲区
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);								//深度测试的类型
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

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.05f,0.1f,-5.0f);

	glRotatef(xrot,1.5f,0.0f,0.0f);
	glRotatef(yrot,0.5f,1.0f,0.0f);
	glRotatef(zrot,1.0f,0.0f,1.0f);

	glBindTexture(GL_TEXTURE_2D, texture[0]);

	glBegin(GL_QUADS);
		// 前面
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		// 后面
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		// 顶面
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		// 底面
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		// 右面
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		// 左面
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.5f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
	glEnd();

	xrot-=0.5f;
	yrot+=xrot;
	zrot+=0.5f;

}

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;
			}
			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",
								"3D作业",
								WS_POPUP |  WS_CLIPSIBLINGS | WS_VISIBLE,
								0, 0,
								GetSystemMetrics( SM_CXSCREEN ),
								GetSystemMetrics( SM_CYSCREEN ),
								NULL, NULL,
								hInstance,
								NULL );
	}else
	{
		hWnd = CreateWindow(
							"Name",
							"3D作业",
							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 + -