OpenGL开发框架

//OpenGL.h

class OpenGL
{
public:
	OpenGL();
	virtual ~OpenGL();
	BOOL SetupPixelFormat(HDC hDc);      //检测安装OpenGL
	void init(int Width, int Height);    //初始化
	void Render();						 //OpenGL图像处理
	void CleanUp();						 //清除OpenGL

private:
	HDC hDC;		//GDI设备描述表
	HGLRC hRc;      //永久着色描述表
};
//OpenGL.cpp

#include "OpenGL.h"

extern HWND hWnd;
                                                      
OpenGL::OpenGL()
{
}

OpenGL::~OpenGL()
{
}

//检测安装OpenGL
BOOL OpenGL::SetupPixelFormat(HDC hDC0)
{
	int nPixelFormat;   //像素点格式
	hDC = hDC0;
	PIXELFORMATDESCRIPTOR pfd = {
		sizeof(PIXELFORMATDESCRIPTOR),      //pfd结构的大小
		1,                                  //版本号
		PFD_DRAW_TO_BITMAP |                //支持在窗口中绘图
		PFD_SUPPORT_OPENGL |                //支持OPenGL
		PFD_DOUBLEBUFFER,                   //双缓冲模式
		PFD_TYPE_RGBA,                      //RGBA颜色模式
		16,                                 //24位颜色深度
		0, 0, 0, 0, 0, 0,                   //忽略颜色位
		0,                                  //没有非透明度缓存
		0,                                  //忽略移位位
		0,                                  //无累加缓存
		0, 0, 0, 0,                         //忽略累加位
		16,                                 //32位深度缓存
		0,                                  //无模板缓存
		0,                                  //无辅助缓存
		PFD_MAIN_PLANE,                     //主层
		0,                                  //保留
		0, 0, 0                             //忽略层,可见性和损毁掩模
	};

	if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd)))
	{
		MessageBox(NULL, L"没找到合适的显示模式", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	}

	SetPixelFormat(hDC, nPixelFormat, &pfd);   //设置当前设备的像素点格式
	hRc = wglCreateContext(hDC);  //获取渲染描述句柄
	wglMakeCurrent(hDC, hRc);     //激活渲染描述句柄

	return TRUE;
}

void OpenGL::init(int Width, int Height)
{
	glViewport(0, 0, Width, Height);		    //设置OpenGL视图大小
	glMatrixMode(GL_PROJECTION);				//设置当前矩阵为投影矩阵
	glLoadIdentity();							//重置当前指定的矩阵为单位矩阵
	gluPerspective(								//设置透视图
		54.0f,									//透视角设置为45度
		(GLfloat)Width / (GLfloat)Height,       //窗口的宽与高比
		0.1f,									//视野透视尝试:近点1.0f
		3000.0f                                 //视野透视尝试:始点0.1f 远点1000.0f
		);
	//这和照相机很类似,第一个参数设置镜头广角度,第二个参数为长宽比,后面是远近剪切
	glMatrixMode(GL_MODELVIEW);                 //设置当前矩阵为模型视图矩阵
	glLoadIdentity();							//重置当前指定的矩阵为单位矩阵
}

//OpenGL图像处理
void OpenGL::Render()
{
	glClearColor(0.0f, 0.0f, 0.3f, 1.0f);				 //设置刷新背景色
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //刷新背景
	glLoadIdentity();									 //重置当前的模型观察矩阵

	glFlush();         //更新窗口
	SwapBuffers(hDC);  //切换缓冲区
}

//清除OpenGL
void OpenGL::CleanUp()
{
	wglMakeCurrent(hDC, NULL);        //清除OpenGL
	wglDeleteContext(hRc);		      //清除OpenGL
}
//main.cpp

#include "OpenGL.h"

//////////////////////////////////////////////////////////////
int Width = 800;    //窗口宽
int Height = 800;   //窗口高
int bits = 16;      //颜色深度
OpenGL *m_OpenGL;
HDC hDC;            //GDI设备句柄,将窗口连接到GDI(图形设备接口)
HGLRC hRc = NULL;   //渲染描述句柄,将OpenGL调用连接到设备描述表
HWND hWnd = NULL;   //保存windwos 分配给程序的窗口句柄

////////////////////////////////////////////////////////////////
LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);  //窗口回调函数
void GameLoop();  //游戏的消息循环


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)
{
	//注册窗口类
	bool fullScreen = TRUE;
	DWORD dwExStyle;    //Window 扩展风格
	DWORD dwStyle;      //Window 窗口风格
	RECT windwoRect;    //窗口尺寸
	int nX = 0, nY = 0;

	if (IDNO == MessageBox(NULL, L"使用全屏模式吗?", L"将进入OpenGL选择显示模式",
		MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL))
	{
		fullScreen = FALSE;
	}

	if (fullScreen)  //全屏模式
	{
		DEVMODE dmScr;  //设备模式
		memset(&dmScr, 0, sizeof(dmScr));  //确保内存分配
		dmScr.dmSize = sizeof(dmScr);      //Devmode结构的大小
		dmScr.dmPelsWidth = Width;         //屏幕宽
		dmScr.dmPelsHeight = Height;       //屏幕高
		dmScr.dmBitsPerPel = 16;           //色彩深度
		dmScr.dmDisplayFrequency = 75;     //刷屏速度
		dmScr.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
		if (ChangeDisplaySettings(&dmScr, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
			fullScreen = FALSE;
		}
		dwExStyle = WS_EX_APPWINDOW;   //windwo 扩展风格
		dwStyle = WS_POPUP;            //window 窗口风格
		ShowCursor(FALSE);             //隐藏鼠标
	}
	else
	{
		dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   //使窗口具有3D外观
		dwStyle = WS_OVERLAPPEDWINDOW;                    //使用标准窗口
		//WS_OVERLAPPEDWINDOW是有标题栏,窗口菜单,最大、是小化按钮和可调整尺寸的窗口
		
		int wid = GetSystemMetrics(SM_CXSCREEN);	      //获取当前屏幕宽
		int hei = GetSystemMetrics(SM_CYSCREEN);          //获取当前屏幕高
		
		//计算屏幕居中
		nX = (wid - Width) / 2;
		nY = (hei - Height) / 2;
	}

	//根据窗口风格来调整窗口尺寸达到要求的大小
	AdjustWindowRectEx(&windwoRect, dwStyle, FALSE, dwExStyle);

	LPCWSTR cc = L"tml";
	WNDCLASSEX wc = {
		sizeof(WNDCLASSEX),
		CS_CLASSDC, MsgProc, 0L, 0L,
		GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
		cc, NULL };


	RegisterClassEx(&wc);
	m_OpenGL = new OpenGL();
	hWnd = CreateWindowEx(NULL, cc, L"OpenGL程序框架",
		dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
		nX, nY, Width, Height,
		NULL, NULL, hInstance, NULL
		);								//创建窗口
	ShowWindow(hWnd, SW_SHOWDEFAULT);   //显示窗口
	UpdateWindow(hWnd);					//更新窗口
	GameLoop();							//进入消息循环

	return 0;
}

void GameLoop()
{
	MSG msg;
	BOOL fMessage;
	PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
	while ( msg.message != WM_QUIT )
	{
		fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
		if (fMessage)  //有消息
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			m_OpenGL->Render();  //无消息
		}
	}
}

LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CREATE:
		hDC = GetDC(hWnd);		//获取当前窗口的设备句柄
		m_OpenGL->SetupPixelFormat(hDC);   //调用显示模式安装功能
		break;
	case WM_CLOSE:
		m_OpenGL->CleanUp();
		PostQuitMessage(0);
		break;
	case WM_SIZE:
		Height = HIWORD(lParam);	//窗口的高
		Width = LOWORD(lParam);	    //窗口的宽
		if (Height == 0)
			Height = 1;
		m_OpenGL->init(Width, Height);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYUP:
		switch (wParam)
		{
		case VK_ESCAPE:
			m_OpenGL->CleanUp();
			PostQuitMessage(0);
			break;
		default:
			break;
		}
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
posted @ 2018-07-22 12:18  cpluspluser  阅读(965)  评论(0编辑  收藏  举报