- 窗口的定义,注册,创建,显示流程。事件处理器,即WinProcLRESULT CALLBACK WindowProc(窗口句柄,消息标识,左参数,右参数)。WM_PAINT:对于DirectX可以30-60帧/秒重画窗口,但对于Windows程序就切力了。
基本windows应用程序框架
主事件循环:
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); //虚拟加速键翻译器,输入工具
DispatchMessage(&msg); //调用WinProc()
}
主程序入口:定义窗口类→注册窗口→创建窗口→主事件循环;且每个Windows程序都有独立的事件句柄WinProc
一个实时事件循环:加入测试消息队列机制,PeekMessage(),使用PM_REMOVE
对应同一个窗口类的多个窗口的消息
第五章_ DirectX基础和COM
COM对象:实际上就是实现大量界面的一个C++类或一套C++类
COM对象的分布或包含,如何实现即插即用特性
> GUID(全局单值标识符),或称IID(界面标识符) ← 可以利用微软的GUIDGEN.EXE生成
> 创建COM
1,定义界面: struct IGraphics : IUnknown { }
2,创建界面容器类(核心) class COM_OBJECT : public IGraphics, ISound, IInput { }
> DLL才是COM对象
> COM和函数指针
第六章_初次邂逅DirectDraw
> 组合使用接口
第七章_高级DirectDraw和位图图形
IDIRECTDRAWSURFACE7::Blt()
IDIRECTDRAWSURFACE7::BltFast() 需要剪裁时用前者,不需要时用后者
基础裁剪知识(像素裁剪、位图裁剪),3D裁剪将会十分复杂
像素按视口裁剪
位图裁剪技巧
使用IDirectDrawClipper进行DirectDraw裁剪
步骤1,创建DirectDraw裁剪器对象,CreateClipper()
2, 创建Clipper序列 //最麻烦,需要填写RGNDATA结构
3,用IDIRECTDRAWCLIPPER::SetClipList
4,用IDIRECTDRAWSURFACE7::SetClipper
使用位图
载入.bmp文件 (位图头文件,位图信息段(有调色板的话),位图数据段)
载入8bit位图 SetEntries
载入16bit位图 (24bit转16bit)
载入24bit位图
离屏表面
创建的表面跟主表面是兼容的,具有一致的色深
在离屏表面上进行blitting
装载位图,创建表面,使用blitting
色彩键
源色彩键 DDCOLORKEY Object优先于background
目标色彩键,方法跟源色彩键相同SetColorKey,需要改变2个标志位
源叠加色彩键
目标叠加色彩键
如何更新DirectDraw调色板项
256色模式下的色彩旋转(Color Roation)
模拟水或液体的流动效果
使用RGB模式的技巧
1,利用手动色彩变换或查询表
2,采用新的DirectX彩色和Gamma补偿,实时地在主表面上执行色彩操作
手动色彩变换及查询表
透明·alpha混合·光照·暗化处理
DirectX新的色彩和Gamma控制接口
IDirectDrawColorControl可以控制高度,对比度,色调,饱和度,锐度和Gamma值
各种效果:如水下感觉,屏幕闪烁,灯光,黑暗
将GDI和DirectX联用
只需在DirectDraw中找到一个兼容DC
在独占模式下,Windows不能够用GDI在任何DirectDraw表面绘制
主DirectDraw对象
GetCaps获得HEL,HAL,用于获取任意表面能力
GetPixelFormat或GetSurfaceDesc结构DDSURFACEDESC2::ddpfPixelFormat
在窗口模式下使用DirectDraw
必须考虑使用者可能在任意分辨率和任意色彩深度模式下启动游戏
在窗口中绘制像素
1,主表面是整个屏幕,GetWindowRect()实际上获得的是整个窗口
2,不知道色深,GetPixelFormat()以决定色彩的深度
查找实际客户区
AdjustWindowRectEx 计算不同样式的窗口尺寸
剪裁DirectX窗口
裁剪只对blitter起作用
CreateClipper()
SetHWnd() 将裁剪器同窗口相关联
SetCClipper() 裁剪器同想要裁剪的表面相连
本章总结:
高彩模式,blitter,裁剪,彩色键,采样理论,窗口方式的DirectDraw
第八章_矢量光栅化及2D变换
绘制线条
问题1,计算机屏幕是一个由整数坐标表示的2D网格,如何显示浮点型坐标
Bresenham算法
解决实际问题:把像素以最接近实际直线的位置从点p1到点p2进行填充的这个过程成为光栅化。
1,计算斜率K
2,画点(x0,y0)
3, 在x方向上每前进1.0个单位,在y方向上就前进K个单位,把这两个值加到(x0,y0)上
基础2D图形裁剪知识
图像空间级(像素级)裁剪,对象空间级裁剪
两直线之交点
利用矩阵式求逆阵
裁剪直线
Cohen-Sntherland算法
判断线段跟矩形(剪裁区域)的情况
线框多边形
在游戏中,集中注意一件事,那就是速度!
为了画多边形,所要做的就是对顶点循环,并连接点与点
2D平面里的变换
平移
旋转(计算机中sin、cos采用弧度而不是角度)
坐标变换很像极坐标向笛卡尔坐标的转变
旋转时,逆时针θ为正,顺时针θ为负。在显示屏上,y轴是相反方向,正负也相反
实时程序中使用三角函数很糟糕,需要建立一个查询表,将算好的0-360度的sin、cos值保存在查询表内
关于精度,选择int还是float还是double
缩放,每个坐标乘以缩放因子
矩阵引论
基础的矩阵知识已经在《3D数学基础》内补完,这里学起来就异常轻松了。
使用矩阵进行各种变换(平移,缩放,旋转)
填充实心多边形
第一个约束条件,多边形必须为凸多边形
第二个约束条件,确定所要画的多边形到底有多复杂
绘制三角形和四边形
每个端点变成整数之前加0.5
四边形光栅化的一般情况
多边形的三角化
递归分割思想
通用凸N边形渲染算法
多边形碰撞检测
边界球/圆
对象具有一个平均半径,然后检测半径是否重叠(会有漏判)
开方函数sqrt会消耗大量CPU周期,想办法优化
1,只计算一次float差
2,泰勒级数展开
边界盒、边界箱
Find_Bounding_Box_Poly2D
点包含
测试一个点是否被包含在一个矩形内部
↓如何判断一个点是否被包含在任意凸多边形之内
半空间检测(Halfspace Test)需要运用到向量点积
深入定时和同步
基于Win32函数GetTickCount()
卷轴和摇镜头
页面卷轴Page Scrolling
均匀平铺显示引擎
采用基于tile的数据结构表示场景卷动
稀疏位图平铺显示引擎(适合太空射击游戏)
伪3D等轴测引擎
等轴测Isometric,即采用一定倾斜视角的游戏
方法一,基于单元,全2D
方法二,基于全屏,具有一些2D或3D的碰撞网络
方法三,采用全3D数学运算,使用一个固定的视角
采用工具画碰撞对象非常消耗时间,且对画面的任何变动都意味着返工
T3DLIB1函数库
2D引擎架构,可以先全屏再调整窗口大小到窗口程序
基本定义
可用宏
数据类型和结构
BOB(Billter Object Engine)
全局定义
DirectDraw接口
DDraw_Init
DDraw_Shutdown
DDraw_Attach_Clipper
DDraw_Create_Surface
DDraw_Flip
DDraw_Wait_For_Vsync
DDraw_Fill_Surface
DDraw_Lock_Surface
DDraw_UnLock_Surface
2D多边形函数
Draw_Triangle_2D
Draw_TriangleFP_2D
Draw_QuadFP_2D
Draw_Filled_Polygon2D
Translate_Polygon2D
Rotate_Polygon2D
Draw_Line
Draw_Pixel
Draw_Rectangle
Draw_HLine
Draw_VLine
Screen_Transitions
Draw_Text_GDI
数学和误差函数
Fast_Distance_2D //3.5% error
Fast_Distance_3D //11% error
Find_Bounding_Box_Poly2D
Open_Error_File
Close_Error_File
Write_Error
位图函数
Load_Bitmap_File
UnLoad_Bitmap_File
Create_Bitmap_File
Destroy_Bitmap
Load_Image_Bitmap
Flip_Bitmap
Scroll_Bitmap
Copy_Bitmap
调色板函数
Set_Palette_Entry
Get_Palette_Entry
Save_Palette_To_File
Load_Palette_From_File
Rotate_Colors
*Blink_Colors
实用工具函数
Get_Clock
Start_Clock
Wait_Clock
Collision_Test
Color_Scan //另一种碰撞检测法
BOB引擎
BOB基本上是由一个或多个DirectDraw表面(最大到64个)