GDI 编程入门

游戏引擎实际上就是对图形库DirectX以及OpenGL的再封装而已,很多时候专业图形API的底层还需要借助GDI来实现很多功能,我们很难说在完全不了解GDI的情况下,就能直接利用专业的图形API来开发出自己心仪的游戏作品 

GDI是什么?

微软公司设计的一套API

为什么使用它?

GDI是图形显示程序与实际物理设备两者之间的桥梁,使得用户无需关心具体设备的细节,只需在一个逻辑设备中进行操作

怎么使用它?

需要把握一个核心:设备上下文(DC):显示器和以及显示器所有的配置 ,我们需要得到DC的句柄才可以去在上面进行绘图操作

怎么获得DC句柄呢?

  • BeginPaint(...)
  • GetDC(...)

使用GDI的目的:在Window屏幕上显示出好看的游戏画面,需要理解以下概念

  • 屏幕区域

        屏幕区:略

        客户区:见下图

        窗口区:在客户区周围包了一层窗口的边框,这些窗口边框包围着客户区,共同组成了窗口区

       

        

  • 坐标转换

        ClientToScreen(...)

        ScreenToClient(...)


搭建GDI程序通用框架,方便我们后续的学习

引入头文件,定义常量,定义全局变量,函数声明

#include <windows.h>

#define WINDOW_WIDTH	800					//使程序易修改		
#define WINDOW_HEIGHT	600							
#define WINDOW_TITLE	L"GDI程序核心框架"   //使程序易读

HDC		g_hdc=NULL;                         // 创建相应类型的设备环境句柄

LRESULT CALLBACK	WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
VOID							Game_Paint( HWND hwnd);
BOOL						Game_CleanUp(HWND hwnd );

 定义程序的入口函数

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
	
	WNDCLASSEX wndClass = { 0 };							
	wndClass.cbSize = sizeof( WNDCLASSEX ) ;			
	wndClass.style = CS_HREDRAW | CS_VREDRAW;	
	wndClass.lpfnWndProc = WndProc;					
	wndClass.cbClsExtra		= 0;								
	wndClass.cbWndExtra		= 0;							
	wndClass.hInstance = hInstance;						
	wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE); 
	wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );    
	wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);  
	wndClass.lpszMenuName = NULL;						
	wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";		

	
	if( !RegisterClassEx( &wndClass ) )				
		return -1;		

	
	HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,				
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
		WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );


	MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);		
	ShowWindow( hwnd, nShowCmd );  
	UpdateWindow(hwnd);						

	
	MSG msg = { 0 };				
	while( msg.message != WM_QUIT )		
	{
		if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   
		{
			TranslateMessage( &msg );		
			DispatchMessage( &msg );			
		}
	}


	UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); 
	return 0;  
}

 定义回调函数,游戏窗口的事件会通过Window的消息机制传递进来

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )      
{
	PAINTSTRUCT paintStruct;			

	switch( message )						
	{
	case WM_PAINT:						
		g_hdc = BeginPaint( hwnd, &paintStruct );  //得到设备环境句柄
		Game_Paint( hwnd);
		EndPaint( hwnd, &paintStruct );			
		ValidateRect(hwnd, NULL);		
		break;									

	case WM_KEYDOWN:					
		if (wParam == VK_ESCAPE)   
			DestroyWindow(hwnd);		
		break;									

	case WM_DESTROY:					
		Game_CleanUp(hwnd);			
		PostQuitMessage( 0 );			
		break;									

	default:										
		return DefWindowProc( hwnd, message, wParam, lParam );		
	}

	return 0;									
}

封装功能函数,将对应的事件处理过程外包出去


VOID Game_Paint( HWND hwnd )
{

}


BOOL Game_CleanUp( HWND hwnd )
{
	ReleaseDC(hwnd,g_hdc);
	return TRUE;
}

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值