zoukankan      html  css  js  c++  java
  • 3D游戏引擎一 win32编程


    Windows程序一般都等待用户进行一些操作,然后响应并採取行动。
    一般来说。对win32的程序的操作都会转换为系统事件队列中的消息,如按键消息WM_KEYDOWN,WM_MOUSECLICK等传递键盘以及鼠标的操作消息。

    系统消息传递给程序的本地事件队列。然后在传递给WinProc()函数进行主窗体的消息处理,处理完消息后。程序转到WinMain()主函数中,而此时一般主函数依旧在进行消息循环,于是又等待新的消息并运行。


    win32的程序都是有winmain開始,最简单的一个win32程序。从空项目開始:

    #define WIN32_LEAN_AND_MEAN             
    #include <Windows.h>
    
    
    int WINAPI WinMain(HINSTANCE hinstance,
    				   HINSTANCE hprevinstance,
    				   LPSTR lpcmdline,
    				   int ncmdshow)
    {
    	MessageBoxA(NULL,"TRY A TRY","MY TRY",
    		MB_OK | MB_ICONEXCLAMATION );
    	return (0);
    
    }

    winMain 函数

    MessageBox()函数

    SDK中一个简单的提示声音的函数 MessageBeep(UINT utype),參数值utype经常使用的有 MB_OK 系统默认声音,当然假设你将计算机系统中的系统声音设置为无声,就听不到声音的。




    从一个空项目開始创建一个完整的Windows程序的步骤:
    创建一个Windows类。


    创建一个事件处理程序WinProc


    向Windows注冊创建的Windows类:定义了Windows类后,还要通过注冊,让Windows操作系统知道这个类,注冊通过函数 RegisterClassEx()来完毕。接收一个指向Windows类的指针作为參数。

    调用政策函数之前,Windows系统还不知道有这个类,因此不能使用新的类名来引用它,而是用但钱储存的类的实际数据结构来进行注冊。


    使用Windows类创建一个窗体


    创建一个主事件循环,用于接收Windows消息并将其发送给事件处理程序。


    最后。一个简单的空白win32项目代码例如以下:

    //不载入MFC
    #define WIN32_LEAN_AND_MEAN             
    #include <Windows.h>
    #include <windowsx.h>
    
    //Windows类类名常量
    const char* MYCLASSNAME = "WINCLASS";
    
    //消息处理函数
    LRESULT CALLBACK WndProc(HWND hwnd,
    						 UINT msg,
    						 WPARAM wParam,
    						 LPARAM lParam)
    {
    	PAINTSTRUCT ps;
    	HDC hdc;
    	switch(msg){
    	case WM_CREATE:
    		{
    			//初始化代码
    		}break;
    	case WM_PAINT:
    		{
    			hdc = BeginPaint(hwnd,&ps);
    			//重绘
    			EndPaint(hwnd,&ps);
    		}break;
    	case WM_DESTROY:
    		{
    			//释放资源。关闭应用程序
    			PostQuitMessage(0);
    		}break;
    	default:
    		return (DefWindowProc(hwnd,msg,wParam,lParam));
    	}
    	return (0);
    }
    
    //主函数
    int WINAPI WinMain(HINSTANCE hInstance,
    				   HINSTANCE hprevInstance,
    				   LPSTR lpcmdline,
    				   int ncmdshow)
    {
    	WNDCLASSEX wcex;//创建的窗体类
    	HWND hwnd;//窗体句柄
    	MSG msg;//消息
    
    	//设置窗体类
    	wcex.cbSize = sizeof(WNDCLASSEX);
    	wcex.style			= CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc	= WndProc;
    	wcex.cbClsExtra		= 0;
    	wcex.cbWndExtra		= 0;
    	wcex.hInstance		= hInstance;
    	wcex.hIcon			= LoadIcon(NULL,IDI_APPLICATION);
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName	= NULL;
    	wcex.lpszClassName	= MYCLASSNAME;
    	wcex.hIconSm		= LoadIcon(NULL,IDI_APPLICATION);
    
    	//注冊窗体类
    	if(!RegisterClassEx(&wcex)){
    		return (0);
    	}
    
    	//创建窗体
    	if( !( hwnd = CreateWindowEx(NULL,MYCLASSNAME, "MY", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
          0, 0, 400, 500, NULL, NULL, hInstance, NULL) ) )
    	{
    		return(0);
    	}
    
    	//进入主循环
    	while( GetMessage(&msg,NULL,0,0) ){
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	//返回到操作系统
    	return msg.wParam;
    
    }
    

    但这为一般程序的基本结构。对于游戏。要构建一个实时事件循环,使其既能进行游戏逻辑处理,比如一个Game_main()函数,又能实时检測消息队列中的消息并处理。

    这里就要构建一个实时事件循环,使用函数PeekMessage ()  来检測消息队列中是否有消息。

    假设有。对其进行处理。否则继续处理其它游戏逻辑并反复循环。PeekMessage 函数原型例如以下:

    BOOL PeekMessage(
    LPMSG IpMsg, //消息 的指针
    HWND hWnd,//窗体句柄
    UINT wMSGfilterMin,//第一条消息
    UINT wMsgFilterMax,//最后一条消息
    UINT wRemoveMsg//删除标记
    );
    一般第一条消息和最后一条消息都设为0。而删除标记有三种:

    PM_NOREMOVE
    PeekMessage处理后,消息不从队列里除掉。


    PM_REMOVE
    PeekMessage处理后。消息从队列里除掉。
    PM_NOYIELD
    此标志使系统不释放等待调用程序空暇的线程。可将PM_NOYIELD任意组合到PM_NOREMOVE或PM_REMOVE。


    PM_NOREMOVE或PM_REMOVE是基本的标记,若使用不删除消息,就要配合GetMessage()来获得消息进行处理。若使用PM_REMOVE。则直接使用PeekMessage获得消息,相应的实时事件循环代码例如以下:

    	while(true){
    		//使用peekMessage获得消息,若没有直接进游戏逻辑
    		if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE)){
    			if(msg.message == WM_QUIT)//假设消息为WM_QUIT,则结束主循环
    				break;
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    		//主游戏处理逻辑
    		Game_Main();
    	}
    
    这里主游戏处理逻辑必须有返回,即生成一个动画帧或运行了一段游戏逻辑后必须返回。

  • 相关阅读:
    新闻资讯APP开发流程(一)需求分析
    药品查询APP开发流程(九)开发—yao_company.js
    药品查询APP开发流程(十一)开发—company_specs.js
    开发demo药品查询
    药品查询APP开发流程(十)开发—company.js
    药品查询APP开发流程(八)开发—yao_specs.js
    开发demo新闻资讯
    新闻资讯APP开发流程(三) app.js
    新闻资讯APP开发流程(二) APP模型设计
    药品查询APP开发流程(七)开发—yao.js
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5337070.html
Copyright © 2011-2022 走看看