1.引擎在Win32平台的Platform类实现

这个引擎是基于win32架构写的, Platform可以理解成是整个引擎的入口。控制着引擎的整个生命周期,内部主要完成了openGL、win32窗口句柄的初始化;键盘鼠标事件分发;主循环控制。关闭程序的处理。

1.首先是执行了Platform中的静态函数SetWindowSize,设置了Win32窗口的初始化xy位置,以及窗口大小。

void CPlateForm::setWindowSize(int x, int y, int wid, int hei)
{
	window_x = x;
	window_y = y;
	windows_width = wid;
	windows_height = hei;
}

2.接着是构造Platform的单例类(当时代码有些不规范,Platform已经是单例类了,直接在Init的时候传递x、y、w、h,然后在Init函数里执行原本构造函数里的这些代码就好了。没有必要再写一个静态类专门来Save一下x、y、w、h这四个参数了)


CPlateForm::CPlateForm()
{
	hRC = NULL;
	hDC = NULL;
	hWnd = NULL;
	hInst = NULL;
	isPause = false;
	gameMode = PLAYING;
	ShowWindow(hWnd, SW_SHOWDEFAULT);
	UpdateWindow(hWnd);
	MyRegisterClass();// 执行应用程序初始化: 
	if (!InitInstance())
	{
		MessageBox(NULL, L"不能成功初始化", L"错误", MB_OK | MB_ICONEXCLAMATION);
	}
	HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(NULL));
	memset(&msg, 0, sizeof(MSG));
	
	m_Audio.Initialize(hWnd);
}

2.1.接着会调用MyRegisterClass对Win32窗口的大小、icon、光标、窗口风格进行设置,然后调用系统API把我们设置好的参数传递给操作系统。

ATOM CPlateForm::MyRegisterClass()
{
	WNDCLASSEXW wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInst;
	wcex.hIcon = LoadIcon(hInst,NULL);//托盘上的ICO图标
	wcex.hCursor = LoadCursorFromFileA("res/color/0081.ani");
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"myClass";
	wcex.hIconSm = LoadIcon(wcex.hInstance,NULL);//窗口上的ICO图标
	return RegisterClassExW(&wcex);
}

2.2 配置完成窗口配置后,会在这个函数里真正的创建一个Win32窗口,并返回一个窗口句柄(其实可以理解成系统给我们分配的一个窗口Id),接着初始化OpenGL。

扫描二维码关注公众号,回复: 14526103 查看本文章

BOOL CPlateForm::InitInstance()
{
	//hInst = hInstance; // 将实例句柄存储在全局变量中
	int nX = GetSystemMetrics(SM_CXFRAME) * 4;
	int nY = GetSystemMetrics(SM_CYFRAME) * 4 + GetSystemMetrics(SM_CYCAPTION);//+ GetSystemMetrics(SM_CYMENU);

	//创建Win32窗口,返回窗口句柄
	hWnd = CreateWindowW(L"myClass", L"荒岛求生_V1.1", WS_OVERLAPPEDWINDOW,
		window_x, window_y, windows_width + nX, windows_height + nY, nullptr, nullptr, NULL, nullptr);

	if (!hWnd)
	{
		return FALSE;
	}

	//初始化OpenGL配置
	InitGL();
	
	//初始化硬件获取纹理通道
	glewInit();

	//操作系统API,显示这个窗口
	ShowWindow(hWnd, true);

	//立即刷新窗口
	UpdateWindow(hWnd);



//顶点缓存上的,没有用到
	//使用VBO查询字符串为
//#ifndef NO_VBOS
//	g_fVBOSupported = IsExtensionSupported("GL_ARB_vertex_buffer_object");
//	//返回1为支持.
//	//下面声明VBO扩展函数
//	// VBO Extension Function Pointers
//	PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; // VBO Name Generation Procedure
//	PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; // VBO Bind Procedure
//	PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; // VBO Data Loading Procedure
//	PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; // VBO Deletion Procedure
//							
//	if (g_fVBOSupported) //获取函数地址
//	{
//		// 获得函数的指针
//		glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
//		glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
//		glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
//		glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
//	}
//#else 
//	g_fVBOSupported = false;
//#endif
	return TRUE;
}

2.3 这个函数比较长,其实主要干的事儿就是给OpenGL传递参数开启或者关闭开关,对OpenGL进行初始化,因为OpenGL需要设置的参数实在是太多了,具体备注代码上都有,大家直接看代码吧!


// 此处开始对OpenGL进行所有设置
GLboolean CPlateForm::InitGL(GLvoid)						
{
	static PIXELFORMATDESCRIPTOR pfd =		// /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
	{
		sizeof(PIXELFORMATDESCRIPTOR),		// 上述格式描述符的大小
		1,								// 版本号
		PFD_DRAW_TO_WINDOW |			// 格式支持窗口
		PFD_SUPPORT_OPENGL |			// 格式必须支持OpenGL
		PFD_DOUBLEBUFFER,				// 必须支持双缓冲
		PFD_TYPE_RGBA,					// 申请 RGBA 格式
		24,								// 选定色彩深度
		0, 0, 0, 0, 0, 0,				// 忽略的色彩位
		0,								// 无Alpha缓存
		0,		   						// 忽略Shift Bit
		0,								// 无累加缓存
		0, 0, 0, 0,						// 忽略聚集位
		16,								// 16位 Z-缓存 (深度缓存)
		1,								// 无蒙板缓存
		0,								// 无辅助缓存
		PFD_MAIN_PLANE,					// 主绘图层
		0,								// Reserved
		0, 0, 0							// 忽略层遮罩
	};

	if (!(hDC = GetDC(hWnd)))					// 取得设备描述表了么?
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能创建一种相匹配的像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
		// 返回 FALSE
	}

	GLuint PixelFormat = ChoosePixelFormat(hDC, &pfd);	// Windows 找到相应的象素格式了吗?
	if (!SetPixelFormat(hDC, PixelFormat, &pfd))		// 能够设置象素格式么?
		return false;

	// 能否取得着色描述表?
	if (!(hRC = wglCreateContext(hDC)))			
		return false;

	// 尝试激活着色描述表
	if (!wglMakeCurrent(hDC, hRC))				
		return false;

	// Windows 找到相应的象素格式了吗?
	if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))				
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;							// 返回 FALSE
	}

	if (!SetPixelFormat(hDC, PixelFormat, &pfd))				// 能够设置象素格式么?
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;							// 返回 FALSE
	}

	if (!(hRC = wglCreateContext(hDC)))						// 能否取得着色描述表?
	{
		KillGLWindow();										// 重置显示区
		MessageBox(NULL, L"不能创建OpenGL渲染描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;										// 返回 FALSE
	}

	if (!wglMakeCurrent(hDC, hRC))							// 尝试激活着色描述表
	{
		KillGLWindow();										// 重置显示区
		MessageBox(NULL, L"不能激活当前的OpenGL渲然描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;										// 返回 FALSE
	}

	glStencilMask(0);										//蒙版缓冲区置为0
	glShadeModel(GL_SMOOTH);								// 启用阴影平滑
	glClearColor(0.0f,0.0f, 0.0f,1.0f);						// 背景
	glClearDepth(1.0f);										// 设置深度缓存
	glEnable(GL_DEPTH_TEST);								// 启用深度测试
	glDepthFunc(GL_LEQUAL);									// 所作深度测试的类型
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);		// 真正精细的透视修正,告诉系统对透视进行修正
	glFrontFace(GL_CCW);									//多边形逆时针方向为正面
	glClearStencil(0);													
	glEnable(GL_CULL_FACE);                                 //只显示正面
	ReSizeGLScene(windows_width, windows_height);			//设置openGL窗口大小
	InitGeometry();

	return TRUE;											// 初始化 OK
}

2.4 InitGeometry 是初始化操作的最后一个函数,函数里面干的事儿主要就是设置光源位置,设置环境光、漫反射、高光的颜色。开启了范围雾、设置了雾的开始Z值 和 结束Z值,其实这些代码也能放到InitGL函数里面,但是考虑到InitGL函数太长了,这些代码干的事儿主要是初始化光源和雾气配置,所以细分了一下函数,就给拆出来了。

void CPlateForm::InitGeometry()
{
	glEnable(GL_NORMALIZE);
 	GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
 	GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
 	GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
 	GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };
 
	glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
	glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);

	GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };		// 雾气的模式
	GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };		// 雾的颜色设为灰色
	glFogi(GL_FOG_MODE, GL_LINEAR);		// 设置雾气的模式
	glFogfv(GL_FOG_COLOR, fogColor);			// 设置雾的颜色
	glFogf(GL_FOG_DENSITY,0.05f);			// 设置雾的密度
	glHint(GL_FOG_HINT, GL_DONT_CARE);			// 设置系统如何计算雾气
	glFogf(GL_FOG_START,2000.0f);				// 雾气的开始位置
	glFogf(GL_FOG_END,4000.0f);				// 雾气的结束位置
}

3.Run起来!初始化都完成之后,程序当然就要Run起来了,这个引擎其实只能说是一个Demo引擎,逻辑线程和渲染线程当时给放到一块儿了,Render函数里其实不光是做了DrawElement这件事儿,而且还做了逻辑的update这件事儿,所以现在要我做的话肯定要分两个线程来做,而且Render里面的Update函数也得拆出来。每次循环都会Clear颜色缓冲区和深度缓冲区,清理了前台缓冲区后,立马使用SwapBuffers把后台的缓冲区交换到前台来,这样可以保证画面不会出现闪屏的现象。


void CPlateForm::run()
{
	U3D::CEngineButton::getInstance()->InitAll();
	U3D::CResouceManage::getInstance()->Init();
	U3D::CResourceCompound::getInstance()->init();
	CEffects::getInstance()->init();
	label = new U3D::CUI_Label("A","宋体",24);

	//1:m_pos 2:m_ssssslook 3:m_up 4:m_right
	Vector3D pos[4] = {
	{ Vector3D(0,500,0)},
	{ Vector3D(0,0,1) },
	{ Vector3D(0,1,0) },
	{ Vector3D(1,0,0) } };
	godCamera = new freeCamera(pos);
	godCamera->rightRotate(90);


	LARGE_INTEGER nFreq;
	QueryPerformanceFrequency(&nFreq);
	LARGE_INTEGER nAnimationInterval;
	nAnimationInterval.QuadPart = (LONGLONG)(1.0 / FPS * nFreq.QuadPart);
	LARGE_INTEGER nLast;
	LARGE_INTEGER nNow;
	QueryPerformanceCounter(&nLast);
	ZeroMemory(&msg, sizeof(msg));

	while (msg.message != WM_QUIT)
	{
		if (!PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
		{
			QueryPerformanceCounter(&nNow);
			if (nNow.QuadPart - nLast.QuadPart > nAnimationInterval.QuadPart)
			{
				nLast.QuadPart = nNow.QuadPart;
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);					// 清除屏幕和深度缓存
				Render();
				SwapBuffers(hDC);											// 交换缓存 (双缓存)
			}
			else { Sleep(0); }continue;
		}

		TranslateMessage(&msg);															//翻译消息
		DispatchMessage(&msg);	
														//分发消息
	}

}

3.1 这个Render不一般,里面既实现了不同的模式下对透视矩阵和正交矩阵的切换,也实现了引擎的update,还实现了输入控制器的刷新。

GLvoid CPlateForm::Render()
{
	if (Input::getKeyDown(VK_TAB))
		gameMode = gameMode == EDITMODE ? PLAYING : EDITMODE;
	
	if (currentEnvironment == NIGHT)
		selectNight();
	else if (currentEnvironment == DAYTIME)
		selectDaytime();


	switch (gameMode)
	{
	case TIELEMODE:
	{
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else
			U3D::CSceneManage::getInstance()->pause(updateTime());

		select2DSpace();
		U3D::CSceneManage::getInstance()->draw2D();
	}break;
	case EDITMODE:
	{
		glViewport(0, 0, 840, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 840.0f / 760.0f, 0.1f, 15000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		godCamera->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else
			U3D::CSceneManage::getInstance()->pause(updateTime());

		godCamera->drawFrustum();
		if (Fog)
			glEnable(GL_FOG);
		else
			glDisable(GL_FOG);
		/
		//右边2d
		glViewport(840, 0, 440, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, 440, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		U3D::CSceneManage::getInstance()->drawDebug();
		U3D::CEngineButton::getInstance()->_draw();

		glPushMatrix();
		glLoadIdentity();
		label->setString("0l,2,3切换图片,右击存");
		label->setPosition(850, 0, 1);
		label->draw();

		label->setString("鼠标X:%f鼠标Y:%f", mousePos.x, mousePos.y);
		label->setPosition(850, 30, 0);
		label->draw();

		label->setString("小键盘0开关线段模式");
		label->setPosition(850, 60, 0);
		label->draw();

		label->setString("当前渲染对象数量:%d", objNumber);
		label->setPosition(850, 90, 0);
		label->draw();

		label->setString("TAB:开/关编辑模式");
		label->setPosition(850, 120, 0);
		label->draw();

		label->setString("FPS:%f", getFPS());
		label->setPosition(850, 150, 0);
		label->draw();

		glColor4f(1,1,1,1);
		glPopMatrix();

		if (Input::getKeyDown(VK_F2))
			light = light == false ? 1 : 0;
		if (Input::getKeyDown(VK_F3))
			Fog = Fog == false ? 1 : 0;
		if (Input::getKeyDown(VK_NUMPAD0))
			lines = lines == false ? true : false;

		if (light)
		{
			glEnable(GL_LIGHTING);	glEnable(GL_LIGHT0);
		}
		else
		{
			glDisable(GL_LIGHTING); glDisable(GL_LIGHT0);
		}
		if (lines)
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		else
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}break; 
	case IN_SPACE:
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		Camera::getInstance()->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, windows_width, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		U3D::CSceneManage::getInstance()->draw2D();
	}break;
	
	case FALLING://陨落的场景
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		Camera::getInstance()->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

	}break;
	case PLAYING:
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		Camera::getInstance()->update();
		

		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

		//partic->draw(0.2);

		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, windows_width, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		U3D::CSceneManage::getInstance()->draw2D();
		label->setString("-FPS:%f", getFPS());
		label->setPosition(0, 920, 0);
		label->draw();
	}break;
	case FLY://逃离这个星球
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		Camera::getInstance()->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

		label->setString("-FPS:%f", getFPS());
		label->setPosition(0, 920, 0);
		label->draw();
	}break;
	case END://结尾的场景
	{
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, windows_width, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		U3D::CSceneManage::getInstance()->draw2D();
		
	}break;
	}

	Input::flush();
}

4.WndProc函数是注册进操作系统的回调,监听了用户的鼠标键盘响应事件,收到后丢给场景管理器去处理了系统传过来的事件。


LRESULT CALLBACK CPlateForm::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	U3D::CSceneManage::getInstance()->MsgProc(hWnd, message, wParam, lParam);
	U3D::CSceneManage::getInstance()->my2DMsgProc(hWnd, message, wParam, lParam);
	
	switch (message)
	{
	case WM_ACTIVATE:
		
	case WM_SIZE:
		switch (wParam)
		{
		case SIZE_MINIMIZED:
			break;
		}
		break;
		
	case WM_RBUTTONDOWN:
		oldMousePos.x= LOWORD(lParam);
		oldMousePos.y= HIWORD(lParam);
		_mouseIsDown = true;
		break;

	case WM_MOUSEMOVE:
	{
		mousePos.x = LOWORD(lParam);
		mousePos.y = HIWORD(lParam);
		if (_mouseIsDown)
		{
			offset= oldMousePos - mousePos;
		}
		oldMousePos = mousePos;
	}break;
		
	case WM_RBUTTONUP:
		_mouseIsDown = false;
		break;

	case WM_KEYDOWN:
	{
		switch (wParam)
		{
			break;
		case VK_F1:
			isDebug = true;
			break;

		case VK_F2:
			break;

		case VK_F3:break;

		case VK_F11:break;

		case VK_F12:break;

		}

	}break;
 
	case WM_CLOSE:
	{
		getInstance()->KillGLWindow();
		delete Instance;
		PostQuitMessage(0);
	}break;

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

完整代码(Platform.h)

#pragma once

#define _WINDOW_WID_ 1280.0f
#define _WINDOW_HEI_ 960.0f


enum ENVIRONMENT	//环境:白天和晚上
{
	DAYTIME,
	NIGHT
};

enum GameMode		//游戏模式:
{
	TIELEMODE,
	IN_SPACE,		//在宇宙里
	FALLING,		//落下
	PLAYING,		//在玩
	EDITMODE,		//编辑模式
	FLY,			//飞走(后面会是END)
	DEAD,			//死亡
	END				//结束(胜利以后的)
};


class CPlateForm
{
private:
	U3D::CUI_Label *label;
	GameMode gameMode;
	ENVIRONMENT currentEnvironment=DAYTIME;	  //当前环境默认是白天
private:
	int AxisMode = 1;				//轴模式 拖动:1 缩放:3 旋转:3
	int objNumber = 0; 

private:
	const int FPS =120;		//FPS每一秒60帧
	HINSTANCE hInst;		// 当前实例
	HGLRC     hRC; 			// 窗口着色描述表句柄
	HDC       hDC;			// OpenGL渲染描述表句柄
	HWND      hWnd;			// 保存我们的窗口句柄
	MSG		  msg;			//消息
	static wchar_t IcoName;	//Icona名字
	static bool isPause;    //游戏暂停
	static int windows_width;
	static int windows_height;
	static int window_x;
	static int window_y;
	bool isAutoSort = false;
	static bool isDebug;
	static bool _mouseIsDown;
	bool g_fVBOSupported = false;//是否支持顶点缓存 
	static CPlateForm*Instance;

public:
	CAudio4Bass m_Audio;
	int m_MusicIndex;
	static Vector2 mousePos;
	static Vector2 oldMousePos;
	static Vector2	offset;
	freeCamera *godCamera;
	
	///Other/
	void  run();
	float updateTime();												//时间差:秒
	void initObjNum() { objNumber = 0; }
	void Resume() { isPause = false; }	//恢复
	void Pause() { isPause = true; }	//暂停
	void InitGeometry();
	GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
	GLboolean InitGL(GLvoid);
	GLvoid KillGLWindow(GLvoid);
	GLvoid Render();
	ATOM MyRegisterClass();
	int getObjNumber() { return objNumber; }
	BOOL InitInstance();
	void OpenEditor();
	Vector3D CPlateForm::MouseTransfrom(int mouse_x, int mouse_y);
	bool IsExtensionSupported(char* szTargetExtension);
	static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

	///Set/
	static void setIco(wchar_t ico) { IcoName = ico; }
	static void setWindowSize(int x, int y, int wid, int hei);
	void setGameMode(GameMode mode);
	void setObjNumber(int n) { this->objNumber = n; }
	void setAutoSort(bool autoSort);
	void setAxisMode(int Axis);
	void setEnvironment(ENVIRONMENT V){this->currentEnvironment=V;}

	///Get///
	static CPlateForm *getInstance();
	float getFPS();
	HDC getHdc() { return hDC; }
	HWND getHwnd() { return hWnd; }
	UINT Get_win_width() { return windows_width; }
	UINT Get_win_height() { return windows_height; }
	bool getIsDebugMode();
	bool getAutoSort();
	CAudio4Bass getAudioBass() { return m_Audio; }
	bool getMouseIsDown();
	bool getfVBOSupported() { return g_fVBOSupported; }
	int getAxisMode();
	GameMode getGameMode();
	ENVIRONMENT getEnvironment(){return currentEnvironment;}


	void select2DSpace();
	void select3DSpace();
	sColor selectDaytime();
	sColor selectNight();
	CPlateForm();
	~CPlateForm();
};

完整代码Platform.cpp

#include "Engine.h"
#include "resource.h"
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//

bool CPlateForm::isPause = false;
int CPlateForm::windows_width = 1080;
int CPlateForm::windows_height = 720;
int CPlateForm::window_x = 0;
int CPlateForm::window_y = 0;
wchar_t CPlateForm::IcoName=NULL;
CPlateForm*CPlateForm::Instance = NULL;
bool CPlateForm::isDebug = false; 
bool CPlateForm::_mouseIsDown = false;

Vector2 CPlateForm::mousePos;
Vector2 CPlateForm::oldMousePos;
Vector2 CPlateForm::offset;

// 
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+



CPlateForm::CPlateForm()
{
	hRC = NULL;
	hDC = NULL;
	hWnd = NULL;
	hInst = NULL;
	isPause = false;
	gameMode = PLAYING;
	ShowWindow(hWnd, SW_SHOWDEFAULT);
	UpdateWindow(hWnd);
	MyRegisterClass();// 执行应用程序初始化: 
	if (!InitInstance())
	{
		MessageBox(NULL, L"不能成功初始化", L"错误", MB_OK | MB_ICONEXCLAMATION);
	}
	HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(NULL));
	memset(&msg, 0, sizeof(MSG));
	
	/*char *MusicList[5] = { "res/小酒窝.mp3","res/爱.mp3","res/爱要怎么说出口.mp3"
			,"res/江南.mp3","res/Where Them Girls At.mp3" };

		m_Audio.Initialize(0);
		for (int i = 0;i < 5;i++)
		{
			m_MusicIndex = m_Audio.LoadFile(MusicList[i], BASS_MUSIC_FLOAT);
		}
		MusicLen=m_Audio.ChannelBytes2Seconds(m_MusicIndex, m_Audio.GetChannelLength(m_MusicIndex, BASS_MUSIC_LOOP));
		m_Audio.ChannelPlay(m_MusicIndex, true);*/
	m_Audio.Initialize(hWnd);
 	//m_MusicIndex = m_Audio.LoadFile("res/音效/主场景主被攻击.mp3", BASS_MUSIC_LOOP/*BASS_MUSIC_FX*/);
	//m_Audio.ChannelPlay(m_MusicIndex,false);
}


CPlateForm *CPlateForm::getInstance()
{
	if (Instance == NULL)
	{
		Instance = new CPlateForm;
	}
	return Instance;

}

void CPlateForm::setWindowSize(int x, int y, int wid, int hei)
{
	window_x = x;
	window_y = y;
	windows_width = wid;
	windows_height = hei;
}

float CPlateForm::updateTime()
{
	static float previousTime = GetTickCount() / 1000.0f;
	float currentTime = GetTickCount() / 1000.0f;
	float elapsedTime = currentTime - previousTime;
	previousTime = currentTime;
	return elapsedTime;
}

float CPlateForm::getFPS()
{
	static float timeNow = GetTickCount() / 1000.0f;
	static DWORD dwRenderedFrame = 0;
	float tFrame = GetTickCount() / 1000.0f - timeNow;
	timeNow += tFrame;
	static float fps = 0;
	if (fmodf(timeNow, 1) < tFrame)
	{
		fps = dwRenderedFrame + fmodf(timeNow, 1) / tFrame; //计算FPS
		dwRenderedFrame = 0;
	}
	dwRenderedFrame++;
	return fps;
}

GLboolean CPlateForm::InitGL(GLvoid)						// 此处开始对OpenGL进行所有设置
{
	static PIXELFORMATDESCRIPTOR pfd =		// /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
	{
		sizeof(PIXELFORMATDESCRIPTOR),		// 上述格式描述符的大小
		1,								// 版本号
		PFD_DRAW_TO_WINDOW |			// 格式支持窗口
		PFD_SUPPORT_OPENGL |			// 格式必须支持OpenGL
		PFD_DOUBLEBUFFER,				// 必须支持双缓冲
		PFD_TYPE_RGBA,					// 申请 RGBA 格式
		24,								// 选定色彩深度
		0, 0, 0, 0, 0, 0,				// 忽略的色彩位
		0,								// 无Alpha缓存
		0,		   						// 忽略Shift Bit
		0,								// 无累加缓存
		0, 0, 0, 0,						// 忽略聚集位
		16,								// 16位 Z-缓存 (深度缓存)
		1,								// 无蒙板缓存
		0,								// 无辅助缓存
		PFD_MAIN_PLANE,					// 主绘图层
		0,								// Reserved
		0, 0, 0							// 忽略层遮罩
	};

	if (!(hDC = GetDC(hWnd)))					// 取得设备描述表了么?
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能创建一种相匹配的像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
		// 返回 FALSE
	}

	GLuint PixelFormat = ChoosePixelFormat(hDC, &pfd);	// Windows 找到相应的象素格式了吗?
	if (!SetPixelFormat(hDC, PixelFormat, &pfd))		// 能够设置象素格式么?
		return false;

	if (!(hRC = wglCreateContext(hDC)))			// 能否取得着色描述表?
		return false;

	if (!wglMakeCurrent(hDC, hRC))				// 尝试激活着色描述表
		return false;

	//GLuint	PixelFormat;

	if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))				// Windows 找到相应的象素格式了吗?
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;							// 返回 FALSE
	}

	if (!SetPixelFormat(hDC, PixelFormat, &pfd))				// 能够设置象素格式么?
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;							// 返回 FALSE
	}

	if (!(hRC = wglCreateContext(hDC)))					// 能否取得着色描述表?
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能创建OpenGL渲染描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;							// 返回 FALSE
	}

	if (!wglMakeCurrent(hDC, hRC))						// 尝试激活着色描述表
	{
		KillGLWindow();							// 重置显示区
		MessageBox(NULL, L"不能激活当前的OpenGL渲然描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;							// 返回 FALSE
	}

	glStencilMask(0);									//蒙版缓冲区置为0
	glShadeModel(GL_SMOOTH);								// 启用阴影平滑
	glClearColor(0.0f,0.0f, 0.0f,1.0f);				    // 背景
	glClearDepth(1.0f);										// 设置深度缓存
	glEnable(GL_DEPTH_TEST);								// 启用深度测试
	glDepthFunc(GL_LEQUAL);									// 所作深度测试的类型
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);		// 真正精细的透视修正,告诉系统对透视进行修正
	glFrontFace(GL_CCW);      //多边形逆时针方向为正面
	glClearStencil(0);													
	glEnable(GL_CULL_FACE);                                 //只显示正面
	ReSizeGLScene(windows_width, windows_height);			//设置openGL窗口大小
	InitGeometry();

	return TRUE;											// 初始化 OK
}



void CPlateForm::InitGeometry()
{
	//quadratic = gluNewQuadric();
	//gluQuadricNormals(quadratic, GLU_SMOOTH);	// 使用平滑法线
	//gluQuadricTexture(quadratic, GL_TRUE);		// 使用纹理

	glEnable(GL_NORMALIZE);
 	GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
 	GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
 	GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
 	GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };
 
	glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
	glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);

	GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };		// 雾气的模式
	GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };		// 雾的颜色设为灰色
	glFogi(GL_FOG_MODE, GL_LINEAR);		// 设置雾气的模式
	glFogfv(GL_FOG_COLOR, fogColor);			// 设置雾的颜色
	glFogf(GL_FOG_DENSITY,0.05f);			// 设置雾的密度
	glHint(GL_FOG_HINT, GL_DONT_CARE);			// 设置系统如何计算雾气
	glFogf(GL_FOG_START,2000.0f);				// 雾气的开始位置
	glFogf(GL_FOG_END,4000.0f);				// 雾气的结束位置
 
}


GLvoid CPlateForm::ReSizeGLScene(GLsizei width, GLsizei height)
{
	//glPushMatrix();
	视口
	glViewport(0, 0, width, height);
	投影
	//glMatrixMode(GL_PROJECTION);
	glOrtho(0, windows_width, windows_height, 0, -1, 1);    //2D
	//glLoadIdentity();
	//gluPerspective(45.0f,1.0, 0.1f, 100.0f);  //3D
	视图
	//glMatrixMode(GL_MODELVIEW);						// 选择模型观察矩阵
	//glLoadIdentity();								// 重置模型观察矩阵
	//glPopMatrix();

}


bool CPlateForm::IsExtensionSupported(char* szTargetExtension)
{
	const unsigned char *pszExtensions = NULL;
	const unsigned char *pszStart;
	unsigned char *pszWhere, *pszTerminator;

	pszWhere = (unsigned char *)strchr(szTargetExtension, ' ');
	if (pszWhere || *szTargetExtension == '\0')
		return false;

	// 返回扩展字符串
	pszExtensions = glGetString(GL_EXTENSIONS);

	// 在扩展字符串中搜索
	pszStart = pszExtensions;
	for (;;)
	{
		pszWhere = (unsigned char *)strstr((const char *)pszStart, szTargetExtension);
		if (!pszWhere)
			break;
		pszTerminator = pszWhere + strlen(szTargetExtension);
		if (pszWhere == pszStart || *(pszWhere - 1) == ' ')
			if (*pszTerminator == ' ' || *pszTerminator == '\0')
				//如果存在返回True
				return true;
		pszStart = pszTerminator;
	}
	return false;
}



GLvoid CPlateForm::KillGLWindow(GLvoid)
{
	if (hRC)								// 我们拥有OpenGL渲染描述表吗?
	{
		if (!wglMakeCurrent(NULL, NULL))
		{
			MessageBox(NULL, L"释放DC或RC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
		}

		if (!wglDeleteContext(hRC))					// 我们能否删除RC?
		{
			MessageBox(NULL, L"释放RC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
		}
		hRC = NULL;
	}

	if (hDC && !ReleaseDC(hWnd, hDC))
	{
		MessageBox(NULL, L"释放DC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
		hDC = NULL;
	}
}

ATOM CPlateForm::MyRegisterClass()
{
	WNDCLASSEXW wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInst;
	wcex.hIcon = LoadIcon(hInst,NULL);//托盘上的ICO图标
	//wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
	//wcex.hCursor=gameMode ==PLAYING ? LoadCursorFromFileA("res/color/Prcs_IcP.ani"):LoadCursor(nullptr, IDC_ARROW);
	wcex.hCursor = LoadCursorFromFileA("res/color/0081.ani");
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"myClass";
	wcex.hIconSm = LoadIcon(wcex.hInstance,NULL);//窗口上的ICO图标
	return RegisterClassExW(&wcex);
}


BOOL CPlateForm::InitInstance()
{
	//hInst = hInstance; // 将实例句柄存储在全局变量中

	int nX = GetSystemMetrics(SM_CXFRAME) * 4;
	int nY = GetSystemMetrics(SM_CYFRAME) * 4 + GetSystemMetrics(SM_CYCAPTION);//+ GetSystemMetrics(SM_CYMENU);

	hWnd = CreateWindowW(L"myClass", L"荒岛求生_V1.1", WS_OVERLAPPEDWINDOW,
		window_x, window_y, windows_width + nX, windows_height + nY, nullptr, nullptr, NULL, nullptr);

	if (!hWnd)
	{
		return FALSE;
	}
	InitGL();
	glewInit();//初始化硬件获取纹理通道

	ShowWindow(hWnd, true);
	UpdateWindow(hWnd);



//顶点缓存上的,可是没有用到··
	//使用VBO查询字符串为
//#ifndef NO_VBOS
//	g_fVBOSupported = IsExtensionSupported("GL_ARB_vertex_buffer_object");
//	//返回1为支持.
//	//下面声明VBO扩展函数
//	// VBO Extension Function Pointers
//	PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; // VBO Name Generation Procedure
//	PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; // VBO Bind Procedure
//	PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; // VBO Data Loading Procedure
//	PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; // VBO Deletion Procedure
//							
//	if (g_fVBOSupported) //获取函数地址
//	{
//		// 获得函数的指针
//		glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
//		glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
//		glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
//		glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
//	}
//#else 
//	g_fVBOSupported = false;
//#endif

	return TRUE;
}


LRESULT CALLBACK CPlateForm::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	U3D::CSceneManage::getInstance()->MsgProc(hWnd, message, wParam, lParam);
	U3D::CSceneManage::getInstance()->my2DMsgProc(hWnd, message, wParam, lParam);
	//CMouseTrack::getInstance()->MsgProc(hWnd, message, wParam, lParam);
	
	switch (message)
	{
	case WM_ACTIVATE:
		switch (wParam)
		{
		case WA_CLICKACTIVE:
		case WA_ACTIVE:
			//isPause = false;
			break;
		case WA_INACTIVE:
			//isPause = true;
			break;
		}
		break;

	case WM_SIZE:
		switch (wParam)
		{
		case SIZE_MINIMIZED:
			break;
		}
		break;
		
	case WM_RBUTTONDOWN:
		oldMousePos.x= LOWORD(lParam);
		oldMousePos.y= HIWORD(lParam);
		_mouseIsDown = true;
		break;

	case WM_MOUSEMOVE:
	{
		mousePos.x = LOWORD(lParam);
		mousePos.y = HIWORD(lParam);
		if (_mouseIsDown)
		{
			offset= oldMousePos - mousePos;
		}
		oldMousePos = mousePos;
	}break;
		
	case WM_RBUTTONUP:
		_mouseIsDown = false;
		break;

	case WM_KEYDOWN:
	{
		switch (wParam)
		{
			break;
		case VK_F1:
			isDebug = true;
			break;

		case VK_F2:
			break;

		case VK_F3:break;

		case VK_F11:break;

		case VK_F12:break;

		}

	}break;
 
	 
	case WM_CLOSE:
	{
		getInstance()->KillGLWindow();
		delete Instance;
		PostQuitMessage(0);
	}break;

	/*case WM_DESTROY:
	{
		if (MessageBox(hWnd, L"亲~要保存所有对象吗?", L"温馨提示", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
		{
			U3D::CSceneManage::getInstance()->getCurrentScene()->EngineSave();
			U3D::CSceneManage::getInstance()->getCurrentScene()->UserSaveData();
		}
		getInstance()->KillGLWindow();
		delete Instance;
		PostQuitMessage(0);
	}break;*/
		

		//LOWORD:取出无符号长整形的低16位
		//HIWORD:取出无符号长整形的高16位
		//WPARAM:word类型,    最早是16位通常用来存储小段信息  现在类型:unsigned int
		//LPARAM:long int类型  通常用于存储消息所需的对象      现在类型:long int
	case WM_MOUSEWHEEL: {}break;
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}


void CPlateForm::run()
{
	U3D::CEngineButton::getInstance()->InitAll();
	U3D::CResouceManage::getInstance()->Init();
	U3D::CResourceCompound::getInstance()->init();
	CEffects::getInstance()->init();
	label = new U3D::CUI_Label("A","宋体",24);

	//1:m_pos 2:m_ssssslook 3:m_up 4:m_right
	Vector3D pos[4] = {
	{ Vector3D(0,500,0)},
	{ Vector3D(0,0,1) },
	{ Vector3D(0,1,0) },
	{ Vector3D(1,0,0) } };
	godCamera = new freeCamera(pos);
	godCamera->rightRotate(90);


	LARGE_INTEGER nFreq;
	QueryPerformanceFrequency(&nFreq);
	LARGE_INTEGER nAnimationInterval;
	nAnimationInterval.QuadPart = (LONGLONG)(1.0 / FPS * nFreq.QuadPart);
	LARGE_INTEGER nLast;
	LARGE_INTEGER nNow;
	QueryPerformanceCounter(&nLast);
	ZeroMemory(&msg, sizeof(msg));

	while (msg.message != WM_QUIT)
	{
		if (!PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
		{
			QueryPerformanceCounter(&nNow);
			if (nNow.QuadPart - nLast.QuadPart > nAnimationInterval.QuadPart)
			{
				nLast.QuadPart = nNow.QuadPart;
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);					// 清除屏幕和深度缓存
				Render();
				SwapBuffers(hDC);											// 交换缓存 (双缓存)
			}
			else { Sleep(0); }continue;
		}

		TranslateMessage(&msg);															//翻译消息
		DispatchMessage(&msg);	
														//分发消息
	}

}


static bool lines = 0;
static bool Fog = 1;
static bool light = 1;

GLvoid CPlateForm::Render()
{
	if (Input::getKeyDown(VK_TAB))
		gameMode = gameMode == EDITMODE ? PLAYING : EDITMODE;
	
	if (currentEnvironment == NIGHT)
		selectNight();
	else if (currentEnvironment == DAYTIME)
		selectDaytime();


	switch (gameMode)
	{
	case TIELEMODE:
	{
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else
			U3D::CSceneManage::getInstance()->pause(updateTime());

		select2DSpace();
		U3D::CSceneManage::getInstance()->draw2D();
	}break;
	case EDITMODE:
	{
		glViewport(0, 0, 840, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 840.0f / 760.0f, 0.1f, 15000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		godCamera->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else
			U3D::CSceneManage::getInstance()->pause(updateTime());

		godCamera->drawFrustum();
		if (Fog)
			glEnable(GL_FOG);
		else
			glDisable(GL_FOG);
		/
		//右边2d
		glViewport(840, 0, 440, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, 440, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		U3D::CSceneManage::getInstance()->drawDebug();
		U3D::CEngineButton::getInstance()->_draw();

		glPushMatrix();
		glLoadIdentity();
		label->setString("0l,2,3切换图片,右击存");
		label->setPosition(850, 0, 1);
		label->draw();

		label->setString("鼠标X:%f鼠标Y:%f", mousePos.x, mousePos.y);
		label->setPosition(850, 30, 0);
		label->draw();

		label->setString("小键盘0开关线段模式");
		label->setPosition(850, 60, 0);
		label->draw();

		label->setString("当前渲染对象数量:%d", objNumber);
		label->setPosition(850, 90, 0);
		label->draw();

		label->setString("TAB:开/关编辑模式");
		label->setPosition(850, 120, 0);
		label->draw();

		label->setString("FPS:%f", getFPS());
		label->setPosition(850, 150, 0);
		label->draw();

		glColor4f(1,1,1,1);
		glPopMatrix();

		if (Input::getKeyDown(VK_F2))
			light = light == false ? 1 : 0;
		if (Input::getKeyDown(VK_F3))
			Fog = Fog == false ? 1 : 0;
		if (Input::getKeyDown(VK_NUMPAD0))
			lines = lines == false ? true : false;

		if (light)
		{
			glEnable(GL_LIGHTING);	glEnable(GL_LIGHT0);
		}
		else
		{
			glDisable(GL_LIGHTING); glDisable(GL_LIGHT0);
		}
		if (lines)
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		else
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}break; 
	case IN_SPACE:
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		Camera::getInstance()->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, windows_width, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		U3D::CSceneManage::getInstance()->draw2D();
	}break;
	
	case FALLING://陨落的场景
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		Camera::getInstance()->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

	}break;
	case PLAYING:
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		Camera::getInstance()->update();
		

		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

		//partic->draw(0.2);

		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, windows_width, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		U3D::CSceneManage::getInstance()->draw2D();
		label->setString("-FPS:%f", getFPS());
		label->setPosition(0, 920, 0);
		label->draw();
	}break;
	case FLY://逃离这个星球
	{
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
		glLoadIdentity();
		gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		Camera::getInstance()->update();
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());

		label->setString("-FPS:%f", getFPS());
		label->setPosition(0, 920, 0);
		label->draw();
	}break;
	case END://结尾的场景
	{
		if (!isPause)
			U3D::CSceneManage::getInstance()->run(updateTime());
		else if (isPause)
			U3D::CSceneManage::getInstance()->pause(updateTime());
		glViewport(0, 0, windows_width, windows_height);
		glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
		glLoadIdentity();
		gluOrtho2D(0, windows_width, windows_height, 0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		U3D::CSceneManage::getInstance()->draw2D();
		
	}break;
	}

	Input::flush();
}



Vector3D CPlateForm::MouseTransfrom(int mouse_x, int mouse_y)
{
	Vector3D pos;
	GLint    viewport[4];
	GLdouble modelview[16];
	GLdouble projection[16];
	GLfloat  winX, winY, winZ;
	GLdouble posX, posY, posZ;
	glPushMatrix();
	glGetIntegerv(GL_VIEWPORT, viewport); // 得到的是最后一个设置视口的参数
	glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
	glGetDoublev(GL_PROJECTION_MATRIX, projection);
	glPopMatrix();
	winX = (float)mouse_x;
	winY = viewport[3] - (float)mouse_y;
	glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
	gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

	//if (Input::getMouseWheel(&mouseNow))
	//{
	//	pos3D.z += mouseNow.scroll;
	//}
	pos.x = posX;
	pos.y = posY;
	pos.z = posZ;
	return pos;
}

void CPlateForm::OpenEditor() { gameMode = EDITMODE; }
bool CPlateForm::getMouseIsDown() { return _mouseIsDown; }
bool CPlateForm::getIsDebugMode() { return isDebug; }
void CPlateForm::setAutoSort(bool autoSort) { this->isAutoSort = autoSort; }
bool CPlateForm::getAutoSort() { return isAutoSort; }
int CPlateForm::getAxisMode() { return AxisMode; }
void CPlateForm::setAxisMode(int Axis) { this->AxisMode = Axis; }
void CPlateForm::setGameMode(GameMode mode) { this->gameMode = mode; }
GameMode CPlateForm::getGameMode() { return gameMode; }

void CPlateForm::select2DSpace()
{
	glViewport(0, 0, _WINDOW_WID_, _WINDOW_HEI_);
	glMatrixMode(GL_PROJECTION);					// 选择投影矩阵
	glLoadIdentity();
	gluOrtho2D(0, _WINDOW_WID_, _WINDOW_HEI_, 0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void CPlateForm::select3DSpace()
{
	glViewport(0, 0, _WINDOW_WID_, _WINDOW_HEI_);
	glMatrixMode(GL_PROJECTION);	// 选择投影矩阵
	glLoadIdentity();
	gluPerspective(80.0f,1280.0f/960.0f, 0.1f, 5000.0f);//透视远近
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

sColor CPlateForm::selectDaytime()
{
	glEnable(GL_NORMALIZE);
	GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
	GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
	GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
	GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };

	glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
	glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);

	GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };		// 雾气的模式
	GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };		// 雾的颜色设为灰色
	glFogi(GL_FOG_MODE, GL_LINEAR);		// 设置雾气的模式
	glFogfv(GL_FOG_COLOR, fogColor);			// 设置雾的颜色
	glFogf(GL_FOG_DENSITY, 0.05f);			// 设置雾的密度
	glHint(GL_FOG_HINT, GL_DONT_CARE);			// 设置系统如何计算雾气
	glFogf(GL_FOG_START, 2000.0f);				// 雾气的开始位置
	glFogf(GL_FOG_END, 4000.0f);				// 雾气的结束位置
	
	currentEnvironment=DAYTIME;
	return sColor (1.0f, 1.0f, 1.0f, 1.0f);
}

sColor CPlateForm::selectNight()
{
	glEnable(GL_NORMALIZE);
	GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
	GLfloat LightAmb[] = { 0.1f,0.1f,0.1f,1.0f };
	GLfloat LightDif[] = { 0.1f,0.1f,0.1f,1.0f };
	GLfloat LightSpe[] = { 0.1f,0.1f,0.1f,1.0f };

	glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
	glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);

	GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };		// 雾气的模式
	GLfloat fogColor[4] = { 0.15f, 0.15f, 0.15f, 1.0f };		// 雾的颜色设为灰色
	glFogi(GL_FOG_MODE, GL_LINEAR);		// 设置雾气的模式
	glFogfv(GL_FOG_COLOR, fogColor);			// 设置雾的颜色
	glFogf(GL_FOG_DENSITY, 0.05f);			// 设置雾的密度
	glHint(GL_FOG_HINT, GL_DONT_CARE);			// 设置系统如何计算雾气
	glFogf(GL_FOG_START,1600.0f);				// 雾气的开始位置
	glFogf(GL_FOG_END, 5000.0f);				// 雾气的结束位置

	currentEnvironment=NIGHT;
	return sColor(0.1f, 0.1f, 0.1f, 1.0f);
}


CPlateForm::~CPlateForm()
{
	if (hRC)
	{
		wglMakeCurrent(NULL, NULL);
		wglDeleteContext(hRC);
	}
	if (hDC)
	{
		ReleaseDC(hWnd, hDC);
	}


	U3D::CResouceManage::getInstance()->~CResouceManage();//析构时有错
	U3D::CEngineButton::getInstance()->~CEngineButton();
	CEffects::getInstance()->~CEffects();
	U3D::CSceneManage::getInstance()->~CSceneManage();
	m_Audio.Release();
	m_Audio.clear_allMusic();
}


ps:刚毕业的时候对工程的理解不深刻,代码里有很多不规范的地方,比如把游戏的具体逻辑给写道了引擎里去了,这些当时想拆出来的,但是后来工作一忙还没有拆干净也就不了了之了。

ps2:本来想从具体的引擎模块开始写起的,但是发现还是从主入口写会更好理解吧,所以就从平台类开始写了。准备文章写完后就把整个工程传到gitee上去,供大家学习。也可以一起修改,有任何问题都可以加q群716872510大家可以一起交流吹b!

猜你喜欢

转载自blog.csdn.net/qq_33531923/article/details/126672036