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

📄 rotate3dpic.cpp

📁 可以旋转球体与正方体 三维透视 程序每步有具体说明
💻 CPP
字号:
/*
需要OPENGL的glut工具包,请自行下载,并将相应文件放到相应的位置

 */

#include <windows.h>		
#include <gl\gl.h>			
#include <gl\glu.h>			
#include <gl\glut.h>        
#include <gl\glaux.h>		

HDC			hDC=NULL;		 
HGLRC		hRC=NULL;		// 设置渲染上下文
HWND		hWnd=NULL;		// 保存windows分配的句柄
HINSTANCE	hInstance;		// 保存应用程序句柄

bool	keys[256];			// Array Used For The Keyboard Routine
bool	active=TRUE;		// 窗口是否被最小化,如果最小化,则将该程序挂起(后面实现)
//bool	fullscreen=TRUE;	// 是否全屏显示

GLfloat	rsphere;			// 球的旋转弧度
GLfloat	rcube;			    // 六面体的旋转弧度

LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	

GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		// 调整窗口大小时调用
{
	if (height==0)								
	{
		height=1;										
	}

	glViewport(0,0,width,height);						// 重设视角

	glMatrixMode(GL_PROJECTION);						// 设置矩阵模型为投影矩阵
	glLoadIdentity();									// 重置当前指定的矩阵为单位矩阵

	// 计算窗口宽高比
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);							// 设置矩阵模型为投影矩阵
	glLoadIdentity();									// 重置当前指定的矩阵为单位矩阵
}

int InitGLWindow(GLvoid)								// 初始化OpenGL设置
{
	glShadeModel(GL_SMOOTH);							// 打开平滑阴影,平滑着色
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// 背景色为黑色
	glClearDepth(1.0f);									// 设置深度缓存
	glEnable(GL_DEPTH_TEST);							
	glDepthFunc(GL_LEQUAL);								
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// 视图修正为最佳
	return TRUE;										
}

int Draw3DPic(GLvoid)									// 画图部分
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// 清屏,清除缓存
	glLoadIdentity();									// 重置场景


	rsphere+=0.2f;									
	rcube-=0.15f;
    
	//<--绘制球体及旋转球体代码开始
	glTranslatef(1.5f,0.0f,-6.0f);	// 将图形的中心(参照点为(0,0,0))左移1.5个单位
	                                //并向屏幕内部移动6个单位

	glRotatef(rsphere,1.0f,1.0f,0.0f);	   //绕向量(1.0,1.0,0.5)转动rsphere(弧度)
    
   /*	

    这是本分程序是最初画空心球,后来发现了glut中有直接做的函数
	GLUquadricObj *pobj;
    pobj=gluNewQuadric();
    gluQuadricDrawStyle(pobj,GLU_LINE);//确定几何体的绘制模式(GLU_LINE)
    gluSphere(pobj,1.0,10,10);
  
  */		
    
	glColor3f(0.0, 0.0, 1.0);               //设置当前颜色为红色
    glutWireSphere(1, 25, 10);              //空心球体

   //绘制球体代码结束-->
	
	//<--绘制及旋转立方体代码开始
	glLoadIdentity();							// 重置场景
	glTranslatef(-1.5f,0.0f,-7.0f);				// 移动图形中心点
	glRotatef(rcube,1.0f,1.0f,1.0f);	    	// 绕向量(0.0,1.0,1.0)转动rcube(弧度)
    glColor3f(0.0, 0.0, 1.0);	
   
	//顶点坐标数组
	short vertices[ 3 * 8 ] = {
                               1,1,-1, 1,1,1,
                               1,-1,-1, 1,-1,1,
                               -1,-1,-1, -1,-1,1,
                               -1,1,-1, -1,1,1,};
	

   //顶点索引数组
	BYTE byIndex[36] ={
		               0,4,6, 0,2,4,
		               0,6,7, 0,7,1,
			           0,3,2, 0,1,3,
			           5,2,3, 5,4,2,
		               5,6,4, 5,7,6, 
			           5,1,7, 5,3,1,};
   //颜色数组
	static GLfloat colors[] = { 0.0f,1.0f,0.0f,
		                        1.0f,0.0f,0.0f,
								0.0f,0.0f,1.0f,
								1.0f,1.0f,0.0f,
								1.0f,0.0f,1.0f,
								0.0f,1.0f,1.0f};


     glEnableClientState(GL_VERTEX_ARRAY);//启用顶数组
     glVertexPointer(3,GL_SHORT,0,vertices);
     glEnableClientState(GL_COLOR_ARRAY);//启用颜色数组
     glColorPointer(3,GL_FLOAT,0,colors);
     //使用数组绘制12个三角形,组成一个正方体
     glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_BYTE,byIndex);    //边长为2的空心立方体				
										
 				
	return TRUE;										
}




 
BOOL CreateGLWindow(char* title, int width, int height, int bits)
{
	GLuint		PixelFormat;			// 像素点格式
	WNDCLASS	wc;						 
	DWORD		dwExStyle;				// 扩展窗口模式
	DWORD		dwStyle;				// 窗口模式
	RECT		WindowRect;				//保存窗口左上角和右上角的值
	WindowRect.left=(long)0;			
	WindowRect.right=(long)width;		
	WindowRect.top=(long)0;				
	WindowRect.bottom=(long)height;		

	hInstance			= GetModuleHandle(NULL);				
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;// 强制窗口在调整尺寸时重绘,私有窗口
	wc.lpfnWndProc		= (WNDPROC) WndProc;					
	wc.cbClsExtra		= 0;									
	wc.cbWndExtra		= 0;									
	wc.hInstance		= hInstance;							
	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			 
	wc.hbrBackground	= NULL;									 
	wc.lpszMenuName		= NULL;									
	wc.lpszClassName	= "OpenGL";							

	if (!RegisterClass(&wc))									
	{
		MessageBox(NULL,"注册窗口类失败!","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;											
	}
	
    dwExStyle=WS_EX_WINDOWEDGE;
	dwStyle=WS_OVERLAPPEDWINDOW;
	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);	// 调整窗口大小为制定尺寸

	if (!(hWnd=CreateWindowEx(	dwExStyle,							
								"OpenGL",							
								title,								
								dwStyle |							
								WS_CLIPSIBLINGS |					
								WS_CLIPCHILDREN,					
								0, 0,								
								WindowRect.right-WindowRect.left,	
								WindowRect.bottom-WindowRect.top,	
								NULL,								
								NULL,								
								hInstance,							
								NULL)))								
	{							
		MessageBox(NULL,"窗口创建失败!","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	static	PIXELFORMATDESCRIPTOR pfd=				
	{
		sizeof(PIXELFORMATDESCRIPTOR),				
		1,											
		PFD_DRAW_TO_WINDOW |						
		PFD_SUPPORT_OPENGL |						
		PFD_DOUBLEBUFFER,							
		PFD_TYPE_RGBA,								
		bits,										
		0, 0, 0, 0, 0, 0,							
		0,											
		0,											
		0,											
		0, 0, 0, 0,									
		16,											 
		0,											
		0,											
		PFD_MAIN_PLANE,								
		0,											
		0, 0, 0										
	};
	
	if (!(hDC=GetDC(hWnd)))							
	{
								
		MessageBox(NULL,"创建设备上下文失败!","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							
	}

	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	
	{
								
		MessageBox(NULL,"找不到相应的像素点格式!","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		
	{
						
		MessageBox(NULL,"设置像素点格式失败!","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if (!(hRC=wglCreateContext(hDC)))				
	{
							
		MessageBox(NULL,"创建渲染上下文失败!","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	if(!wglMakeCurrent(hDC,hRC))				
	{

		MessageBox(NULL,"激活渲染上下文失败.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	ShowWindow(hWnd,SW_SHOW);						// 显示窗口
	SetForegroundWindow(hWnd);						// 将窗口置前
	SetFocus(hWnd);									// 将焦点设置到该窗口
	ReSizeGLScene(width, height);					// 设置窗口大小

	if (!InitGLWindow())						
	{
						
		MessageBox(NULL,"初始化失败!","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								
	}

	return TRUE;									//窗口创建成功
}

LRESULT CALLBACK WndProc(	HWND	hWnd,			
							UINT	uMsg,		
							WPARAM	wParam,			
							LPARAM	lParam)			
{
	switch (uMsg)								
	{
		case WM_ACTIVATE:							
		{			
			if ((LOWORD(wParam) != WA_INACTIVE) && !((BOOL)HIWORD(wParam)))
				active=TRUE;						
			else
				active=FALSE;						

			return 0;							
		}

		case WM_SYSCOMMAND:							
		{
			switch (wParam)							
			{
				case SC_SCREENSAVE:				
				case SC_MONITORPOWER:			
				return 0;						
			}
			break;									
		}

		case WM_CLOSE:								
		{
			PostQuitMessage(0);						
			return 0;								
		}

		case WM_KEYDOWN:							
		{
			keys[wParam] = TRUE;					
			return 0;								
		}

		case WM_KEYUP:								
		{
			keys[wParam] = FALSE;					
			return 0;								
		}

		case WM_SIZE:								
		{
			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  
			return 0;							
		}
	}

	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}


int WINAPI WinMain(	HINSTANCE	hInstance,			
					HINSTANCE	hPrevInstance,		
					LPSTR		lpCmdLine,			
					int			nCmdShow)			
{
	MSG		msg;									
	BOOL	done=FALSE;								

	
	if (!CreateGLWindow("旋转的3D图形",640,480,16))
	{
		return 0;									
 	}

	while(!done)								
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	
		{
			if (msg.message==WM_QUIT)				
			{
				done=TRUE;							
			}
			else								
			{
				TranslateMessage(&msg);			
				DispatchMessage(&msg);			
			}
		}
		else									
		{
			
			if ((active && !Draw3DPic()) || keys[VK_ESCAPE])	
			{
				done=TRUE;						
			}
			else								
			{
				SwapBuffers(hDC);				
			}

		}
	}

								
	return (msg.wParam);						
}

⌨️ 快捷键说明

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