欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++ Opengl旋转功能附源码下载

程序员文章站 2022-03-15 08:28:03
项目开发环境:开发语言:c++和ide:vs2017,操作系统windows版本windows sdk8.1,三方库:opengl。项目功能:是图形旋转起来。项目源码如下:/*************...

项目开发环境:
开发语言:c++和ide:vs2017,操作系统windows版本windows sdk8.1,三方库:opengl。

项目功能:
是图形旋转起来。

项目源码如下:

/*********************包含链接的库文件*******************************************************************************************/
#pragma comment( lib, "opengl32.lib" )				
#pragma comment( lib, "glu32.lib" )	
#pragma comment( lib, "glut32.lib")
#pragma comment( lib, "glew32.lib")
#pragma comment( lib, "glaux.lib")
#pragma comment( lib, "vfw32.lib" )	
/********************************************************************************************************************************/

#include <windows.h>		// windows的头文件
#include "glew.h"			// 包含最新的gl.h,glu.h库
#include "glut.h"			// 包含opengl实用库

hdc			hdc = null;		// 窗口着色描述表句柄
hglrc		hrc = null;		// opengl渲染描述表句柄
hwnd		hwnd = null;		// 保存我们的窗口句柄
hinstance	hinstance;		// 保存程序的实例

bool	keys[256];			// 保存键盘按键的数组
bool	active = true;		// 窗口的活动标志,缺省为true
bool	fullscreen = true;	// 全屏标志缺省,缺省设定成全屏模式
/***********************************新添的代码***********************************************************************************/
glfloat		rtri;			// 用于三角形的角度
glfloat		rquad;			// 用于四边形的角度
/********************************************************************************************************************************/

lresult	callback wndproc(hwnd, uint, wparam, lparam);	// wndproc的定义

glvoid resizeglscene(glsizei width, glsizei height)		// 重置opengl窗口大小
{
	if (height == 0)										// 防止被零除
	{
		height = 1;										// 将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 initgl(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;										// 初始化 ok
}

int drawglscene(glvoid)									// 从这里开始进行所有的绘制
{
	glclear(gl_color_buffer_bit | gl_depth_buffer_bit);	// 清除屏幕和深度缓存
	glloadidentity();									// 重置当前的模型观察矩阵
	gltranslatef(-1.5f, 0.0f, -6.0f);						// 左移 1.5 单位,并移入屏幕 6.0
/***********************************新添的代码***********************************************************************************/
	glrotatef(rtri, 0.0f, 1.0f, 0.0f);						// 绕y轴旋转三角形
/********************************************************************************************************************************/
	glbegin(gl_triangles);								// 绘制三角形
	glcolor3f(1.0f, 0.0f, 0.0f);						// 设置当前色为红色
	glvertex3f(0.0f, 1.0f, 0.0f);					// 上顶点
	glcolor3f(0.0f, 1.0f, 0.0f);						// 设置当前色为绿色
	glvertex3f(-1.0f, -1.0f, 0.0f);					// 左下
	glcolor3f(0.0f, 0.0f, 1.0f);						// 设置当前色为蓝色
	glvertex3f(1.0f, -1.0f, 0.0f);					// 右下
	glend();											// 三角形绘制结束
	gltranslatef(3.0f, 0.0f, 0.0f);						// 右移3单位

	glcolor3f(0.5f, 0.5f, 1.0f);							// 一次性将当前色设置为蓝色
/***********************************新添的代码***********************************************************************************/
	glloadidentity();									// 重置模型观察矩阵
	gltranslatef(1.5f, 0.0f, -6.0f);						// 右移1.5单位,并移入屏幕 6.0
	glrotatef(rquad, 1.0f, 0.0f, 0.0f);					// 绕x轴旋转四边形
	rtri += 0.2f;											// 增加三角形的旋转变量
	rquad -= 0.15f;										// 减少四边形的旋转变量
/********************************************************************************************************************************/
	glbegin(gl_quads);									// 绘制正方形
	glvertex3f(-1.0f, 1.0f, 0.0f);					// 左上
	glvertex3f(1.0f, 1.0f, 0.0f);					// 右上
	glvertex3f(1.0f, -1.0f, 0.0f);					// 左下
	glvertex3f(-1.0f, -1.0f, 0.0f);					// 右下
	glend();											// 正方形绘制结束
	return true;										// 一切 ok
}

glvoid killglwindow(glvoid)								// 正常销毁窗口
{
	if (fullscreen)										// 我们处于全屏模式吗?
	{
		changedisplaysettings(null, 0);					// 是的话,切换回桌面
		showcursor(true);								// 显示鼠标指针
	}

	if (hrc)											//我们拥有opengl描述表吗?
	{
		if (!wglmakecurrent(null, null))					// 我们能否释放dc和rc描述表?
		{
			messagebox(null, "释放dc或rc失败。", "关闭错误", mb_ok | mb_iconinformation);
		}

		if (!wgldeletecontext(hrc))						// 我们能否删除rc?
		{
			messagebox(null, "释放rc失败。", "关闭错误", mb_ok | mb_iconinformation);
		}
		hrc = null;										// 将rc设为 null
	}

	if (hdc && !releasedc(hwnd, hdc))					// 我们能否释放 dc?
	{
		messagebox(null, "释放dc失败。", "关闭错误", mb_ok | mb_iconinformation);
		hdc = null;										// 将 dc 设为 null
	}

	if (hwnd && !destroywindow(hwnd))					// 能否销毁窗口?
	{
		messagebox(null, "释放窗口句柄失败。", "关闭错误", mb_ok | mb_iconinformation);
		hwnd = null;										// 将 hwnd 设为 null
	}

	if (!unregisterclass("openg", hinstance))			// 能否注销类?
	{
		messagebox(null, "不能注销窗口类。", "关闭错误", mb_ok | mb_iconinformation);
		hinstance = null;									// 将 hinstance 设为 null
	}
}

/*	这个函数创建我们opengl窗口,参数为:									*
 *	title			- 窗口标题												*
 *	width			- 窗口宽度												*
 *	height			- 窗口高度												*
 *	bits			- 颜色的位深(8/16/32)									*
 *	fullscreenflag	- 是否使用全屏模式,全屏模式(true),窗口模式(false)		*/

bool createglwindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
	gluint		pixelformat;			// 保存查找匹配的结果
	wndclass	wc;						// 窗口类结构
	dword		dwexstyle;				// 扩展窗口风格
	dword		dwstyle;				// 窗口风格
	rect		windowrect;				// 取得矩形的左上角和右下角的坐标值
	windowrect.left = (long)0;			// 将left  设为 0
	windowrect.right = (long)width;		// 将right 设为要求的宽度
	windowrect.top = (long)0;				// 将top  设为 0
	windowrect.bottom = (long)height;		// 将bottom 设为要求的高度

	fullscreen = fullscreenflag;			// 设置全局全屏标志

	hinstance = getmodulehandle(null);				// 取得我们窗口的实例
	wc.style = cs_hredraw | cs_vredraw | cs_owndc;	// 移动时重画,并为窗口取得dc
	wc.lpfnwndproc = (wndproc)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;									// gl不需要背景
	wc.lpszmenuname = null;									// 不需要菜单
	wc.lpszclassname = "openg";							// 设定类名字

	if (!registerclass(&wc))									// 尝试注册窗口类
	{
		messagebox(null, "注册窗口失败", "错误", mb_ok | mb_iconexclamation);
		return false;											// 退出并返回false
	}

	if (fullscreen)												// 要尝试全屏模式吗?
	{
		devmode dmscreensettings;								// 设备模式
		memset(&dmscreensettings, 0, sizeof(dmscreensettings));	// 确保内存清空为零
		dmscreensettings.dmsize = sizeof(dmscreensettings);		// devmode 结构的大小
		dmscreensettings.dmpelswidth = width;				// 所选屏幕宽度
		dmscreensettings.dmpelsheight = height;				// 所选屏幕高度
		dmscreensettings.dmbitsperpel = bits;					// 每象素所选的色彩深度
		dmscreensettings.dmfields = dm_bitsperpel | dm_pelswidth | dm_pelsheight;

		// 尝试设置显示模式并返回结果。注: cds_fullscreen 移去了状态条
		if (changedisplaysettings(&dmscreensettings, cds_fullscreen) != disp_change_successful)
		{
			// 若模式失败,提供两个选项:退出或在窗口内运行。
			if (messagebox(null, "全屏模式在当前显卡上设置失败!\n使用窗口模式?", "xq g", mb_yesno | mb_iconexclamation) == idyes)
			{
				//如果用户选择窗口模式,变量fullscreen 的值变为false,程序继续运行
				fullscreen = false;		// 选择窗口模式(fullscreen=false)
			}
			else
			{
				//如果用户选择退出,弹出消息窗口告知用户程序将结束。并返回false告诉程序窗口未能成功创建。程序退出。
				messagebox(null, "程序将被关闭", "错误", mb_ok | mb_iconstop);
				return false;									// 退出并返回 false
			}
		}
	}

	if (fullscreen)												// 仍处于全屏模式吗?
	{
		dwexstyle = ws_ex_appwindow;								// 扩展窗体风格
		dwstyle = ws_popup;										// 窗体风格
		showcursor(false);										// 隐藏鼠标指针
	}
	else
	{
		dwexstyle = ws_ex_appwindow | ws_ex_windowedge;			// 扩展窗体风格
		dwstyle = ws_overlappedwindow;							// 窗体风格
	}

	adjustwindowrectex(&windowrect, dwstyle, false, dwexstyle);		// 调整窗口达到真正要求的大小

	// 创建窗口
	if (!(hwnd = createwindowex(dwexstyle,							// 扩展窗体风格
		"openg",							// 类名字
		title,								// 窗口标题
		dwstyle |							// 必须的窗体风格属性
		ws_clipsiblings |					// 必须的窗体风格属性
		ws_clipchildren,					// 必须的窗体风格属性
		0, 0,								// 窗口位置
		windowrect.right - windowrect.left,	// 计算调整好的窗口宽度
		windowrect.bottom - windowrect.top,	// 计算调整好的窗口高度
		null,								// 无父窗口
		null,								// 无菜单
		hinstance,							// 实例
		null)))								// 不向wm_create传递任何东东
	{
		killglwindow();								// 重置显示区
		messagebox(null, "窗口创建错误", "错误", mb_ok | mb_iconexclamation);
		return false;								// 返回 false
	}

	static	pixelformatdescriptor pfd =				//pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
	{
		sizeof(pixelformatdescriptor),				// 上述格式描述符的大小
		1,											// 版本号
		pfd_draw_to_window |						// 格式支持窗口
		pfd_support_opengl |						// 格式必须支持opengl
		pfd_doublebuffer,							// 必须支持双缓冲
		pfd_type_rgba,								// 申请 rgba 格式
		bits,										// 选定色彩深度
		0, 0, 0, 0, 0, 0,							// 忽略的色彩位
		0,											// 无alpha缓存
		0,											// 忽略shift bit
		0,											// 无累加缓存
		0, 0, 0, 0,									// 忽略聚集位
		16,											// 16位 z-缓存 (深度缓存) 
		0,											// 无蒙板缓存
		0,											// 无辅助缓存
		pfd_main_plane,								// 主绘图层
		0,											// 不使用重叠层
		0, 0, 0										// 忽略层遮罩
	};

	if (!(hdc = getdc(hwnd)))							// 取得设备描述表了么?
	{
		killglwindow();								// 重置显示区
		messagebox(null, "不能创建一个窗口设备描述表", "错误", mb_ok | mb_iconexclamation);
		return false;								// 返回 false
	}

	if (!(pixelformat = choosepixelformat(hdc, &pfd)))	// windows 找到相应的象素格式了吗?
	{
		killglwindow();								// 重置显示区
		messagebox(null, "不能创建一种相匹配的像素格式", "错误", mb_ok | mb_iconexclamation);
		return false;								// 返回 false
	}

	if (!setpixelformat(hdc, pixelformat, &pfd))		// 能够设置象素格式么?
	{
		killglwindow();								// 重置显示区
		messagebox(null, "不能设置像素格式", "错误", mb_ok | mb_iconexclamation);
		return false;								// 返回 false
	}

	if (!(hrc = wglcreatecontext(hdc)))				// 能否取得opengl渲染描述表?
	{
		killglwindow();								// 重置显示区
		messagebox(null, "不能创建opengl渲染描述表", "错误", mb_ok | mb_iconexclamation);
		return false;								// 返回 false
	}

	if (!wglmakecurrent(hdc, hrc))					// 尝试激活着色描述表
	{
		killglwindow();								// 重置显示区
		messagebox(null, "不能激活当前的opengl渲然描述表", "错误", mb_ok | mb_iconexclamation);
		return false;								// 返回 false
	}

	showwindow(hwnd, sw_show);						// 显示窗口
	setforegroundwindow(hwnd);						// 略略提高优先级
	setfocus(hwnd);									// 设置键盘的焦点至此窗口
	resizeglscene(width, height);					// 设置透视 gl 屏幕

	if (!initgl())									// 初始化新建的gl窗口
	{
		killglwindow();								// 重置显示区
		messagebox(null, "初始化失败", "错误", mb_ok | mb_iconexclamation);
		return false;								// 返回 false
	}

	return true;									// 成功
}

lresult callback wndproc(hwnd	hwnd,			// 窗口的句柄	
	uint	umsg,			// 窗口的消息
	wparam	wparam,			// 附加的消息内容
	lparam	lparam)			// 附加的消息内容
{
	switch (umsg)									// 检查windows消息
	{
	case wm_activate:							// 监视窗口激活消息
	{
		if (!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:								// 收到close消息?
	{
		postquitmessage(0);						// 发出退出消息
		return 0;								// 返回
	}

	case wm_keydown:							// 有键按下么?
	{
		keys[wparam] = true;					// 如果是,设为true
		return 0;								// 返回
	}

	case wm_keyup:								// 有键放开么?
	{
		keys[wparam] = false;					// 如果是,设为false
		return 0;								// 返回
	}

	case wm_size:								// 调整opengl窗口大小
	{
		resizeglscene(loword(lparam), hiword(lparam)); // loword=width,hiword=height
		return 0;								// 返回
	}
	}

	// 向 defwindowproc传递所有未处理的消息。
	return defwindowproc(hwnd, umsg, wparam, lparam);
}

int winapi winmain(hinstance	hinstance,			// 当前窗口实例
	hinstance	hprevinstance,		// 前一个窗口实例
	lpstr		lpcmdline,			// 命令行参数
	int			ncmdshow)			// 窗口显示状态
{
	msg		msg;									// windowsx消息结构
	bool	done = false;								// 用来退出循环的bool 变量


	fullscreen = false;							// false为窗口模式


	// 创建opengl窗口
/***********************************新添的代码***********************************************************************************/
	int scrwidth, scrheight;
	rect rect;
	scrwidth = getsystemmetrics(sm_cxscreen);
	scrheight = getsystemmetrics(sm_cyscreen);
	bool res = createglwindow("旋转实例", 640, 480, 16, fullscreen);
	if (res)
	{
		getwindowrect(hwnd, &rect);
		setwindowpos(hwnd, hwnd_topmost, (scrwidth - rect.right) / 2, (scrheight - rect.bottom) / 2, rect.right - rect.left, rect.bottom - rect.top, swp_showwindow);
	}
	else
	{
		return 0;						// 如果窗口未能创建,程序退出
	}
	while (!done)									// 保持循环直到 done=true
	{
		if (peekmessage(&msg, null, 0, 0, pm_remove))	// 有消息在等待吗?
		{
			if (msg.message == wm_quit)				// 收到退出消息?
			{
				done = true;							// 是,则done=true
			}
			else									// 不是,处理窗口消息
			{
				translatemessage(&msg);				// 翻译消息
				dispatchmessage(&msg);				// 发送消息
			}
		}
		else										// 如果没有消息
		{
			// 绘制场景。监视esc键和来自drawglscene()的退出消息
			if (active)								// 程序激活的么?
			{
				if (keys[vk_escape])				// esc 按下了么?
				{
					done = true;						// esc 发出退出信号
				}
				else								// 不是退出的时候,刷新屏幕
				{
					drawglscene();					// 绘制场景
					swapbuffers(hdc);				// 交换缓存 (双缓存)
				}
			}

			if (keys[vk_f1])						// f1键按下了么?
			{
				keys[vk_f1] = false;					// 若是,使对应的key数组中的值为 false
				killglwindow();						// 销毁当前的窗口
				fullscreen = !fullscreen;				// 切换 全屏 / 窗口 模式
				// 重建 opengl 窗口
/***********************************新添的代码***********************************************************************************/
				if (!createglwindow("旋转实例", 640, 480, 16, fullscreen))
					/********************************************************************************************************************************/
				{
					return 0;						// 如果窗口未能创建,程序退出
				}
			}
		}
	}

	// 关闭程序
	killglwindow();									// 销毁窗口
	return (msg.wparam);							// 退出程序
}

项目演示:

C++ Opengl旋转功能附源码下载

项目完整下载地址:

链接: https://pan.baidu.com/s/1qg1pwvd78ze-qgrvmrmvow 提取码: us6g

总结

到此这篇关于c++ opengl旋转功能附源码下载的文章就介绍到这了,更多相关c++ opengl旋转源码内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!