2009年12月15日

编程常用快捷键

1. 调试快捷键
2. 编辑快捷键
3. 代码快捷键
4. 窗口快捷键


Ctrl+Tab 切换编辑主窗口中的代码选项页

Esc键关闭当前的非模式窗口 (比方说 查找窗口, 切误用 Alt + F4, 这样会连VS.net2005都关掉)

F5: 启动调试
Ctrl+F5: 开始执行(不调试)

Shift+F5: 停止调试
Ctrl+Shift+F5: 重启调试

F7: 生成解决方案
Ctrl+U: 生成当前项目

F11: 独句调试
F10: 过程调试

F9: 打断点 或 取消断点
Alt+F9: 显示断点窗口

F12: 定位到函数的实现体
???: 定位到函数的声明, 只能用右键--->选择A

Shift+Alt+Enter: 切换全屏编辑

Ctrl+F: 查找
Ctrl+Shift+F: 在文件中查找

F3: 查找下一个
Shift+F3: 查找上一个

Ctrl+H: 替换
Ctrl+Shift+H: 在文件中替换

Ctrl+左右箭头键: 一次可以移动一个单词
Ctrl+上下箭头键: 滚动代码屏幕,但不移动光标位置。

Ctrl+L: 删除当前行


Ctrl+M,M: 隐藏或展开当前嵌套的折叠状态
Ctrl+M,L: 将所有过程设置为相同的隐藏或展开状态 或者 右键 + L + O
Ctrl+M,P: 停止大纲显示 或者再按一次Ctrl+M,L  或者 右键 + L + O

Ctrl+G: 转到指定行
Shift+Alt+箭头键: 选择矩形文本
Alt+鼠标左按钮: 选择矩形文本
Ctrl+Shift+U: 全部变为大写
Ctrl+U: 全部变为小写

//有点难度的:
Ctrl+K, Ctrl+C: 注释   
Ctrl+K, Ctrl+U: 解除注释

Ctrl+Shift+A: 添加新项
//----------------------------------------
VAssistX: 操作
1. 定义标准的代码段, 并设置快捷键
2. Alt+M, 再打上函数名的前几个字母, 就会过滤掉很多函数, 最后按Enter定位到当前文件所查找的函数体
3. Shift+Alt+O, 查找文件, 输入文件名的前几个字母, 就会过滤掉很多文件, 最后按Enter定位到当前文件所查找的文件
4. Alt+O: 切换到.h和.cpp文件
5. 右键+查看所有引用 或 VassistX菜单中的Find References, Find References in Files : 查看函数引用的所有地方
6. Shift+Alt+S: 查找全局变量
//----------------------------------------
F7: 查看代码
Shift+F7: 查看窗体设计器

Windows键+E 打开资源管理器。
Windows键+D 显示桌面。
Windows键+M 最小化所有被打开的窗口。
Alt+Tab  切换任务栏中的激活窗口


 

posted @ 2009-12-15 06:12 RedLight 阅读(26) | 评论 (0)编辑 收藏

2009年12月11日

WOW地形Shader分析(转)

SPXG // 标识
// 用到5张图片:
{
   blendTexture  = 0
   layer0Texture = 1
   layer1Texture = 2
   layer2Texture = 3
   layer3Texture = 4
}
!!ARBfp1.0
// 定义常量:
PARAM c[1] = { { 1, 0.30000001, 0.69999999 } };
// 声明3个寄存器:
TEMP R0;
TEMP R1;
TEMP R2;
// 开始混合:
// 一.第0层和第1层使用第4张图的x通道作为alpha进行混合:
TEX R1, fragment.texcoord[0], texture[0], 2D;
TEX R0, fragment.texcoord[1], texture[1], 2D;
ADD R2, R0, -R1;
// r2=Tex1-Tex0
TEX R0, fragment.texcoord[4], texture[4], 2D;
MAD R2, R0.x, R2, R1;
// r2 = Tex4.x*r2+Tex0
// 说明:
// 其中的Tex4.x是对应第1层alpha值, 下面把Tex4.x当a1看
// 即 r2 = a1 * (Tex1-Tex0) + Tex0
// 转换一下即是: Tex0*(1-a1)+a1*Tex1, 呵呵,看到了吧,这就是混合公式!
// 二.第2层和前面结果使用第4张图的y通道作为alpha进行混合:
TEX R1, fragment.texcoord[2], texture[2], 2D;
ADD R1, R1, -R2;
// r1=Tex2-r2
MAD R2, R0.y, R1, R2;
// r2 = Tex4.y*r1+r2, 即 a2*r1+r2 = a2*(Tex2-r2)+r2, 即r2*(1-a2)+Tex2*a2, 其中r2即是上次0和1层混合后的结果
// 三.第3层和前面结果使用第4张图的z通道作为alpha进行混合:
TEX R1, fragment.texcoord[3], texture[3], 2D;
ADD R1, R1, -R2;
// r1=Tex3-r2
MAD R1, R0.z, R1, R2;
// r1=a3*r1+r2 , 即 a3*r1+r2 = a3*(Tex3-r2)+r2, 即r2*(1-a3)+Tex3*a3
// 这样r1就保存了最终的混合结果
// 四.让阴影地表光泽系数为0(Tex4.w即a通道代表地形的阴影,0为阴影,1为正常.而每层贴图中的a通道是光泽通道,所以R1.w保存的是最终的光泽通道值):
MUL R0.x, R1.w, R0.w;
// r0.x = r1.w(光泽)*Tex4.w(阴影值, 是阴影则=0,否则=1)
// 计算削减系数?
MAD R0.w, R0, c[0].y, c[0].z; // r0乘上0.3(削减了30%)再加上一个常量0.69999999
// 反射高光 = secondary_color(反射光)*光泽:
MUL R0.xyz, R0.x, fragment.color.secondary;
// 贴图最终color = 最终贴图混出的color*削减系数:
MUL R1.xyz, R1, R0.w;
// 贴图最终color * primary_color(光照色或是顶点色) + 反射高光:
MAD result.color.xyz, R1, fragment.color.primary, R0;
// alpha:
MOV result.color.w, c[0].x;
END
  
  

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/flipcode/archive/2008/03/03/2143452.aspx

posted @ 2009-12-11 02:04 RedLight 阅读(53) | 评论 (0)编辑 收藏

2009年12月5日

RedLight引擎原型初成

一直都没勇气去写一个游戏引擎,也许是太懒了,也许是太大了。虽然写了些零零碎碎的Test Case! 但你知道的,这始终不成气候!
最近我被安排到一个小组中,做的项目是一个体感游戏,之前考虑过用ogre开源引擎来做,可惜我对这东西又不熟的,听人家说还要用第三方类库CEGUI, 还要配置一些东西,一听头都大了,光学习理想都用半个月了,我们的工程只给两个月的时间,唉呀!算了吧,自己不是还有些乱七八糟的代码可用吗?狠下决心,决定干它一把!哪怕辛苦一点,做下来一个游戏引擎以后就容易干事了。
经过和另外一个同事两个月的时间奋斗,一路中虽说遇到些困难,也常加班的,项目终于也做完了。





一个游戏引擎原型基本蛋生了,我们命名它为 RedLight,它基本实现了

(0) Win32程序渲染框架
(1) UI的基本消息交互流程,XML窗体配置管理,UI皮肤配置管理,基本的UI控件库,多分辩率无缝UI拼图
(2) 室外场景管理
(3) 摄相机路径摄像
(4) 3D Max8模型及骨骼动画导出插件
(5) 模型渲染, 关键帧动画及骨骼动画控制
(6) 基本的水面反射效果
(7) 简单的面粒子系统
(8) 声音控制接口

这是一个单机游戏引擎的原型,功能有限,但它总算不辱使命完成了一个项目了,以后再扩展使它日益强大吧!

posted @ 2009-12-05 09:36 RedLight 阅读(56) | 评论 (0)编辑 收藏

超级工具-----NVPerfHUD分析Beijing 2008

     摘要:   阅读全文

posted @ 2009-12-05 09:06 RedLight 阅读(55) | 评论 (0)编辑 收藏

2009年12月1日

WOW字体研究报告

我喜欢玩WOW的UI风格,尤其是它的高清字体-------任务窗口的内容总感觉十分舒畅。这是从魔兽世界中任务窗口的游戏截图
                                      

经研究, 其实,上面的字体是用方正楷体(不是windows楷体)字体来做的, 用Freetype类库得到每个字符的对应图,并组装排版到一张预先创建好的空纹理中(256*256),  组成一张灰度图,这样可以防止重复字符贴图两遍,提高效率,就像活字印刷术一样灵活组合。
渲染的时候,采用字体颜色RGB + 灰度图合成最终效果。

也许你会发现,左图为什么这么清晰,右图好像稍差一点。对了,其实人的眼睛很奇怪,对颜色的识别是通过对比的,wow正是利用这一点,背景色采用以黄色为主色调,夹杂一些噪声,然后再渲上黑色的文字,这样可以给人感觉到很清晰。

其实wow中还是其他一些文字效果,比方说:阴影文字,原理是渲染两次同一字符,并在第二次遍渲染作偏移即可。当然,还有那种字体外边包起来的效果,不过这种我还没研究它的算法。

怎么说呢?一个游戏世界中,字体我觉得相当重要,丰富的字体表现会给人相当美满的效果,带给人美好的印象,所以还是相当重要的。我也在做我的文字配置系统,祝福我早日完成吧! 谢谢!

posted @ 2009-12-01 09:13 RedLight 阅读(74) | 评论 (1)编辑 收藏

2009年11月14日

BigWorld引擎初识大观

     摘要:   阅读全文

posted @ 2009-11-14 05:16 RedLight 阅读(79) | 评论 (0)编辑 收藏

D3D与OpenGL常用API对译

作为一个3D程序员, 我用了OpenGL两年多, 最近在搞一个项目, 从OpenGL转到D3D, 虽然工程外在的框架都封装得不错, 但想完全地从OpenGL转换到D3D, 看起来还是有难度的, 花了我两个星期的时间, 我终于转换过来了。
D3D与OpenGL的几点比较明显不同的地方:
(一)、正交投影时:OpenGL以屏幕左上角为(0,0), 而D3D却以屏幕中心为(0,0)
(二)、OpenGL使用右手坐标系, 而D3D使用左手坐标系
(三)、OpenGL使用旋转操作等转入的角度参数是 角度, 而D3D是 弧度,所以注意要PI * Angle / 180

下面我把具体地API对照关系列出来(不是很全,以后添加中.......)


1. 坐标变换
 pos = D3DXVECTOR3(0,2,-1.5);
 at  = D3DXVECTOR3(0,0,0);
 up  = D3DXVECTOR3(0,1,0);
 D3DXMatrixLookAtLH(&view,&pos,&at,&up);
 pd3dDevice->SetTransform(D3DTS_VIEW,&view);

2. 绘制
 pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);

    DrawPrimitive()
 DrawIndexedPrimitive()
 
 DrawPrimitiveUP()
 DrawIndexedPrimitiveUP()
3. 颜色


4. 片段测试

 (1) 深度测试
 g_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);           //glEnable(GL_DEPTH_TEST);  
 g_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);    //glDepthFunc(GL_LEQUAL);
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);      //glEnable(GL_CULL_FACE);

 
 (2) Alpha测试
 //-------------------------------------------------------------------------------------------------------- 
 g_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);                //glEnable(GL_ALPHA_TEST);
 g_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);    //glAlphaFunc(GL_GREATER, 0.1f);
 g_pDevice->SetRenderState(D3DRS_ALPHAREF, 0.1 * 255); //取值范围 0 ~ 255
 
 (3) 剪裁测试 (平面剪切)
 //--------------------------------------------------------------------------------------------------------
 // Enable clip plane for reflection map
 CMatrix44f pWorldViewProjIT=m_pWorldViewProj;
 //pWorldViewProjIT.Transpose();
 pWorldViewProjIT.Invert();   

 // Transform plane to clip-space
 float pClipSpacePlane[4];
 float pClipPlane[]= { 0, 0, 1, 0};   

 // Check if camera is below water surface, if so invert clip plane
 CVector3f pEye=(CVector3f)m_pCamera.GetPosition();
 if(-pEye.m_fZ<0.0)
 {
  pClipPlane[2]=-pClipPlane[2];
 }

 MatrixTransformPlane(pClipSpacePlane, pClipPlane, pWorldViewProjIT);

 // enable clip plane now
 g_pDevice->SetClipPlane(0, pClipSpacePlane);  
 g_pDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 1);
 
 
 
 (4) 模板测试
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
    g_pDevice->SetRenderState(D3DRS_STENCILFUNC, 3DCMP_ALWAYS);
    g_pDevice->SetRenderState(D3DRS_STENCILREF, 0x1); //取值范围 0 ~ 255
   
    Device->SetRenderState(D3DRS_STENCILPASS,  D3DSTENCILOP_KEEP);
 
5. 纹理操作
 
 g_pDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   g_pDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   g_pDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
   
 g_pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  g_pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

6. 缓冲区操作
  
 (1) 颜色缓冲
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
 g_pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x000000F);
 
 (2) 深度缓冲
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);           //glEnable(GL_DEPTH_TEST);
 g_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);        //glDepthMask(GL_TRUE);

 (3) 模板缓冲
 //--------------------------------------------------------------------------------------------------------
 
 (4) 渲染到纹理
 //--------------------------------------------------------------------------------------------------------
 // Render targets
 IDirect3DSurface9 *m_plD3DBackbufferSurf,
  *m_plD3DDepthStencilSurfAA,
  *m_plD3DDepthStencilSurf;

 CRenderTarget *m_pRTRefraction, *m_pRTReflection; //(自定义纹理类)

 //-----------------------------------------------------------------------------------

 // Get backbuffer
 g_pDevice->GetRenderTarget(0, &m_plD3DBackbufferSurf);
 
 // Get depthstencil
 g_pDevice->GetDepthStencilSurface(&m_plD3DDepthStencilSurfAA);
 

 // Restore previous states
 g_pDevice->SetRenderTarget(0, m_plD3DBackbufferSurf);
 g_pDevice->SetDepthStencilSurface(m_plD3DDepthStencilSurfAA);
 
 // (1)折射图--------------------------------------------------------------------------
 
 //下面的语句调用了 g_pDevice->CreateRenderTarget(iWidth, iHeight, (D3DFORMAT) iFormat, (D3DMULTISAMPLE_TYPE)iAASamples, 0, 0, &m_plD3Surf, 0));
 if(FAILED(m_pRTRefraction->Create(m_fWidth>>1, m_fHeight>>1, D3DFMT_A8R8G8B8)))
 {
  return APP_ERR_INITFAIL;
 }
 
 // Create depthstencil withouth multisampling
 g_pDevice->CreateDepthStencilSurface(m_fWidth, m_fHeight, D3DFMT_D24X8, (D3DMULTISAMPLE_TYPE)0, 0, 0, &m_plD3DDepthStencilSurf, 0);
 
 
 g_pDevice->SetRenderTarget(0, m_pRTReflection->GetSurface());
 
 g_pDevice->StretchRect(m_plD3DBackbufferSurf, 0, m_pRTRefraction->GetSurface(), 0, D3DTEXF_NONE);
 
 // (2)反射图-----------------------------------------------------------------------------------
 m_pRTReflection=new CRenderTarget;
 if(FAILED(m_pRTReflection->Create(m_fWidth>>2, m_fHeight>>2, D3DFMT_A8R8G8B8)))
 {
  return APP_ERR_INITFAIL;
 }
 
 g_pDevice->SetRenderTarget(0, m_pRTReflection->GetSurface());
 
 
 //-----------------------------------------------------------------------------------
 g_pDevice->SetRenderTarget(0, m_pRTReflection->GetSurface());
 g_pDevice->SetDepthStencilSurface(m_plD3DDepthStencilSurf);
 g_pDevice->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 128), 1.0f, 0);  
 SetViewport(m_pRTReflection->GetWidth(), m_pRTReflection->GetHeight());
 //-----------------------------------------------------------------------------------
 
 D3DXSaveTextureToFile("imageTex.jpg",D3DXIFF_JPG,(IDirect3DTexture9*)m_pWavesBump->GetTexture(),NULL);
 
7. 混合操作
 g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);    //glDisable(GL_BLEND);
 g_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);  //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 g_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
 

8. 灯光与材质
 g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); //glDisable(GL_LIGHTING);
 
 D3DMATERIAL9 mtrl;
 mtrl.Ambient  = a;
 mtrl.Diffuse  = d;
 mtrl.Specular = s;
 mtrl.Emissive = e;
 mtrl.Power    = p;
 Device->SetMaterial(&mtrl);  //在设置纹理前设定
 //设置当前使用的纹理
 

posted @ 2009-11-14 04:49 RedLight 阅读(45) | 评论 (0)编辑 收藏

2009年9月25日

wmo(wow map object) research

wmo(wow map object) research
The wmo是一个非常有趣的设计,wow中比较小的物体使用doodad,而building使用wmo,
这里的building可以是桥梁、了望台、简单的小房子、复杂点的旅馆这样的房屋、非常
复杂的建筑群(例如地下城场景),本文对wmo场景文件进行简单的介绍,关于wmo文件的具
体信息请参考wowmapview的source code,这里非常感谢ufoz所做的贡献。
1、命名规则
wmo保存在以.wmo结尾的文件中,这个文件使用数据块来保存数据。一个wmo通常由一个或多个
group组成,而group数据也保存在以.wmo结尾的文件中,不过文件名称存在不同,例如一个wmo
保存在name.wmo文件中,那么group文件名就为name_001.wmo name_002.wmo......
2、结构
wmo就组织结构来说包含两个层次,group和batch。一个group通常包含多个batch,其中group包含
一个AABB。batch是wmo最小的渲染单元,它保存了顶点索引列表,可以直接调用DP进行渲染。group
内保存一个标志位,可以将group分为indoor/outdoor两类,这一个信息非常重要,通过它wmo就将
building分成了内外两部分,outdoor group就是building的外壳,他通过portal与室内场景连接
在一起。
3、portal
wmo文件中保存了portal信息,在wmo中规定group必须通过portal进行连接,portal由PVS和PRS
两部分组成,PVS记录portal顶点信息,PRS记录portal和group的连接信息,PRS结构如下:
struct WMOPR {
int portal;
int group;
int dir;
};
需要注意的是dir,这个成员只有两个值-1或1,由于portal的顶点信息按照顺时针记录,因此group
位于portal的正面时dir为1,否则为-1,通过dir可以快速确定group到底位于portal的哪一侧。
通过wmo中记录的portal信息可以使用portal culling来检查group的可见性,但是这里还是有一些
难度,主要是指portal的记录方式。由于一个group可能有多个portal,而查找连接的portal只能
通过PRS,这样在大的场景中非常不方便。而且在wmo中竟然没有记录portal的plane信息,如何确定
camera到底是位于portal的正面还是反面呢?(现在wmo文件由于没有完全破解,存在一些wowmapview
未读入的数据块,例如MVER、MOPT、MOVV、MOVB等,其中MVER应该是wmo文件的版本号,MOPT怀疑是保
存所有plane信息,而MOVV可能是保存包围体顶点信息,而MOVB保存包围体信息,MOVV、MOVB应当用于
碰撞检测,这些暂时没有验证)我的做法是在载入时计算portal的plane信息,并将PRS信息转换为类似
Q3 BSP中portal的结构。
struct portal_t {
int othergroup;
int pvs;//pvs index
int dir;
};
struct group_t {
int firstportal;
int numportals;
};
4、碰撞检测
在wmo中并没有使用BSP、OC TREE这样的结构来进行场景管理,可能所有人都感觉非常困惑。
场景管理的功能主要是为了加速渲染和方便碰撞检测,由于存在portal,这样第一个功能已经完成。
而对于碰撞检测,我的想法应当是AABB TREE。仔细观察WOW的场景可以发现在indoor场景中曲面、斜面
这样的几何物体非常少,大多数是规则物体,因此可以判断在wmo中所有的物体都是严格按照轴对齐
方式进行建模,也就是对规则性物体AABB=OBB。由于MOVV和MOVB信息并没有完全研究透彻,因此关于
这一部分只能是我的猜测。
5、渲染
对wmo的渲染由于batch的存在从而变的简单化,但还有可以优化的地方。由于wmo中使用portal将其分割
成group,因此有大量的材质相同的model被分割成不同的batch,在渲染时将材质相同的batch合并到一起
渲染可以避免一些无谓的DP调用。wmo一个令人诟病的地方是使用vertex light,为了减少图元数量从而
使顶点数量降低,造成渲染的时候出现色带效果,应当加入lightmap,由于wmo的场景通常不大,预处理
时做radiosity的时间也不会太长。
6、动态载入
对于只包含几个group的小场景的wmo,由于载入时间不是太长,在动态载入时一次性载入对程序影响
并不会太大。但是对于超大场景的wmo就需要考虑载入策略,这样场景典型的就是wow中的地下城场景,
它一个wmo中包含了几百个group,一次性载入时间非常长,需要分段进行载入。此时就显示出wmo分
文件保存group的优势了,为了实现动态载入wmo场景,一种可能的做法是在载入wmo后需要根据camera
所在的group快速的建立group连接层次图,这个图通过PRS数据建立,建立流程如下:
一、将camera所在group作为当前group,获得所有相连的protal;
二、将protal连接的group保存到第一层列表中,遍历第一层列表中所有的group;
三、获得第一层列表中group的portal,检查portal所连接的group是否保存在第一层列表中,如果没有
    将其保存到第二层列表中;
四、重复上述过程,直到整个层次图建立。
这个层次图可以预先建立然后保存到文件中运行时载入,这样wmo就是分层载入而不需要一次性载入。
(这里我考虑是否在wmo中也可以建立类似bsp的pvs数据呢?虽然pvs现在已经开始淘汰,但是如果
存在pvs就可以方便确定哪些group需要立即载入,只是不知被portal分割后的group到底是不是convex
hull,如果是的话可以建立pvs,但对建模时限制更加明显,两难的选择!!!)
7、建模
由于wmo是按照group对场景进行保存,因此为了建立wmo需要设计一个强力的模型构建工具,这个工具
主要功能就是对从建模工具(3DS MAX)中建立的场景模型进行分组和处理。美工在制作模型时需要非常
小心,所有的模型要严格的轴对齐(轴对齐的原因是需要模型的AABB=OBB),然后将模型导入工具中。
模型构建工具有以下功能:分组(group)功能、group选择、group显示/隐藏、指定portal,portal对
齐(考虑门、窗户这样天然的portal,手动指定portal时肯定无法与外表墙壁对齐,需要程序自动对齐)
、batch操作(分割、选择、显示/隐藏等)、图元级操作(triangle拣选,用于batch分割)、光照运算
(产生vertex light数据)、放置光源、放置doodad(场景中的道具,如桌子、椅子等)。可能还需要其
他一些功能,但是对比其他引擎的场景建模工具(hammer、sandbox)明显简单化许多。
8、优势及不足
当前处理室内场景的主流技术依然是bsp,但是随着硬件的发展bsp的优势在慢慢地丧失,bsp赖以生存的
预处理PVS现在已经完全被实时的portal culling所取代,bsp优势只剩下对图元排序(用于透明物体的
渲染)和基于brush的快速碰撞检测上,但是对比建模工具的复杂化和场景的限制,采用bsp的开销确实
显得太大。而基于纯portal引擎的结构开始流行,例如cryengine中处理室内场景时就完全抛弃bsp,
场景完全由一块块固定大小的墙壁组成,一块墙壁基本和bsp中brush类似,这样做的好处是建模工具变
的简单(不需要进行CSG运算),而且非常容易的产生portal,同时由于场景使用brush构成也兼具了
bsp方便进行碰撞检测的优势。wmo有些类似cryengine,但是在某些方面更具优势。
首先在建模方面,wmo的场景完全可以通过成熟的建模工具来构建,这样对于美工不需要重新学习新的
建模工具,可以节约大量的时间。其次模型构建工具需要的功能非常少,减少了程序的复杂性,缩短了
编写相关工具的时间。再次,场景管理简单化,相应代码量大幅度减少,同时由于portal的存在,可以方便
的与其他引擎相对接。可以说wmo是一种可以进行快速开发的场景结构。

posted @ 2009-09-25 08:39 RedLight 阅读(29) | 评论 (0)编辑 收藏

2009年9月17日

D3D常用API

D3DAPI大全,全部函数

//Direct3D 9.0 SDK 开发参考Direct3D 9.0 SDK 文档 (中文版)

词汇表

DirectX 8 教程

你也可以把 COM 对象就想象成一套为某个主题而设计的一整套库函数。DX 就提供了一套完整的设计3D游戏的库。

http://baike.baidu.com/view/1169027.htm

使用DirectX的不同组件,你需要链接不同的静态库。例如你要使用DirectDraw组件,你就需要ddraw.lib。

对于DirectDraw,这个头文件是ddraw.h。//com编程

D3D.H

http://wowe1314.blog.163.com/blog/static/2358876200751191213583/

在Direct3D编程中,我们要做的工作基本上可以归纳为:

调用适当的函数获取接口指针;

调用接口的方法(成员函数)来完成所需功能;

用完接口后,调用Release方法进行“释放”,注意释放顺序应该和获取它们的顺序相反。

http://www.lihuasoft.net/article/show.php?id=2928

Microsoft_DirectX_9.0c里的 9个DirectX的DLL

DX9和DX10在渲染流水线上都是有天壤之别的,好在DX高版本开发包运行库中包含了对低版本开发包运行库的实现,所以用DX8开发的程序,DX9运行库也能够很好的支持,在安装有D9运行库的系统上跑DX8开发的程序不需要再安装DX8运行库,但是这个兼容性支持在最近被微软逐渐放弃,有时候DX9的不同更新版本做的程序也不能向下兼容,比如DX9FEB2007SDK,同DX9AUG2006SDK在shader编译规则上也是不同的,2007放弃了VS2.0和PS2.0以下版本shader的支持,同时对于HLSL中#include相对路径引用的默认根目录也是有区别的.openGL的shader扩展不同的厂商有不同的扩展开发包,但是这种情况随着GLSL和openGL2.0的出现有所改观.同时OpenGL是跨平台的而DX不是,这意味着用OpenGL和GNU   C++规则开发的程序可以同时在Linux,unix和安装有GNU环境的Windows上同时运行。从效率上来看,DX由于数据时批量写入显存的,同OpenGL的单条函数写入来讲DX效率上要高一些,不过近来OpenGL也支持了批写入,只是支持批写入的OpenGL放弃了openGL一惯的优势也就是语言架构上的简洁使得函数的数目变得很冗杂。在效果上看DX9同支持GLSL或CG扩展的openGL可以实现相同的显示效果。但是有一点不同是DXUT和D3DX在一些基础绘制上比glu和openGL   ARB   Extend要差一点,比如绘制虚线,DX没有好的函数可以是实现这一功能。但是DX的扩展工具比openGL扩展工具又有多余的优势比如向量计算,GUI控件,mesh优化和曲面展开,PRT预计算等等和性能测试等等上又要强一点。DX10同OpenGL比较就感觉openGL不是同一个数量级上的产品,DX10在渲染流水线和架构上和能够实现的效果上要比DX9和openGL进步的多。要做面向未来的游戏产品尽量还是用DX10吧。

­

LPDIRECT3D9 D3D主接口

LPDIRECT3DDEVICE9 D3D硬件主接口

LPDZRECT3DVERTXBUFFER9 顶点缓冲区接口

LPD3DVIEWPORT9  视口接口

LPD3DDISPLAYMODE D3D设备显示模式接口

LPD3DPRESENT_PARAMETERS 创建结构用来保存设备的显示模式接口

LPD3DXVECTOR3  3D向量接口

LPDIRECT3DTEXTURE9 纹理接口

ID3DXSprite  精灵接口

g.pvb  成员函数

g_pD3D  成员函数

g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm) 获取显示模式

g_pd3dDevice 成员函数

g_pd3dDevice->SetRenderState(,BOOL) 是否开启灯光

g_pd3dDevice->SetTransform( D3DTS_WORLD, &(matWorld * matWorld_x));//将上面计算出来的旋转矩阵,设置为世界变换矩阵

g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );写入流

g_pd3dDevice->SetFVF() 设置FVF

g_pd3dDevice->DrawIndexedPrimitive( 画形状, 0, 0, 点个数, 0, 三角形个数 ); 画

timeGetTime 当前系统的时间

DIRECT3DTXTURE 文理接口

BITMAPPEILEHEADER 文件头

BITMAPINFOHEADER 信息头

fread 读一个数据块

biBitcout 每个象素占几个字节

bicompression 是否被压缩

fseek 跳,偏移指针

greatetxture 创建一个空文理

D3Dcaked_RECT 锁定结构体

setTexturestagestata 设置文理操作

CONSTD3DMATRIX*  进行变换的变换矩阵

结构体

D3DPRESENT_PARAMETERS 存储D3D设备信息

D3DXMATRIX  修改矩阵

数组

CUSTOMVERTEX 设置顶点位置颜色信息

­

矩阵函数

D3DXMATRIX * D3DXMatrixIdentity(POut,pM) 单位矩阵

D3DXMATRIX * D3DXMatrixTranspose(上)  矩阵转置

D3DXMATRIX * D3DXMatrixInverse(上中间加个FLOAT) 逆矩阵

D3DXMATRIX * D3DXMatrixTransformation()

D3DXMATRIX* D3DXMatrixTranslation(输出矩阵,X,Y,Z) 平移变换

D3DXMATRIX * D3DXMatrixScaling(上) 缩放变换

FLOAT D3DXPlaneDotCoord(pp,pv) 点和平面之见的关系

D3DXPLANE * D3DXPlaneFromPointNormal(POUT,PPOINT,PNORMAL) 构造子

D3DXPLANE * D3DXPlaneFromPoints(Pout,pv1,pv2,pv3) 通过点来描述平面

D3DXPLANE * D3DPlaneNormalize(POUT,PP) 标准化一个平面

D3DXPLANE * D3DXPlaneTransform(POUT,PP,PM) 平移平面

D3DXM

转换函数

D3DXMATRIX* D3DXMatrixLookAtLH(输出用于视图转换的矩阵,摄象机的位置,摄象机面向的位置,摄象机的正方向)  视图转换的矩阵

D3DXMATRIX* D3DXMatrixOrthoLH(输出用于正交投影的交换矩阵,取景宽,取景高,取景离摄象机的最近距离,取景离摄象机的最远距离) 正交投影变换矩阵

D3DXMATRIX* D3DXMatrixPerspectiveFovLH(输出用于透视投影的交换矩阵,摄象机镜头的夹角Y,平截台体的纵横比,近平截面的距离,远平截面的距离) 透视投影的矩阵

Direct3DCreate9(D3D版本) 创建D3D对象

设备函数

SetTransform(变换的类型,变换的变换矩阵) 设置左手或右手坐标

SetViewport(视口指针) 设置远近距离

GetClientRect(hWnd,*RECT) 获取窗口绘图区域

memcpy(指针,数组,长度) 拷贝

SetStreamSource(0,G.pvb接口指针,0,长度) 数据流

GetAdapterDisplayMode(指定显示卡序列号,存储显示模式的指针) 获取显卡的模式

HRESULT CreateDevice(显卡序列号,D3D设备类型,所属窗口句柄,D3D进行3D运算,存储D3D设备相关信息指针,返回D3D设备借口指针的地址) 创建设备借口

HRESULT CreateVertexBuffer(顶点缓冲区大小(字节),顶点缓冲区属性,灵活顶点格式,顶点缓冲区内存位置,顶点缓冲区指针地址,保留参数通常为0) 创建顶点缓冲

HRESULT CreateIndexBuffer(索引缓冲区大小(字节),顶点缓冲区属性,FMT颜色,顶点缓冲区内存位置,索引缓冲区指针地址,保留参数通常为0)   创建索引缓冲

HRESULT Lock(加锁内存起始地址,加锁内存大小,返回内存指针地址,加锁属性) 加缩内存

HRESULT UnLock() 解锁

HRESULT SetStreamSource(渲染数据流序列号,进行绑定连接的顶点缓冲区指针,进行绑定连接渲染数据流的起始位置,渲染数据流中一个顶点所占的内存大小) 顶点缓冲区和渲染数据流连接

HRESULT SetFVF(灵活顶点格式) 设置顶点格式

HRESULT DrawPrimitive(绘制的图元类型,绘制的开始顶点的索引值,绘制的图元数量)  画到后向缓冲区

HRESULT DrawPrimitiveup() 可以直接画

HRESULT Preesent(复制源的矩形区域指针,复制目的地的矩形区域指针,D3D设备窗口句柄,最小更新区域指针) 屏幕翻转

HRESULT SetIndices(使用的索引缓冲区指针) 设置当前绘制的索引数组

DrawIndexedPrimitive(图元类型,绘制到的索引缓冲区的开始地址,最小的索引数组元素的值,顶点的数目,开始的索引数组元素的值,绘制的数量) 同DrawPrimitive()

­

绘制函数

HRESULT DrawPrimitive(基本图元类型,起始顶点,绘制的图元的数量)  图元绘制

HRESULT Clear(清楚的矩形区域数量,清除的举行区域数组指针,清楚哪个缓冲区,清除后重置的颜色,清除后重置的深度,0-1.0,重置的摸版值) 清空图形绘制区

HRESULT BeginScene() 开始绘制

HRESULT EndScene() 结束绘制

­

纹理函数

CreateTexture()  创建D3D纹理对象

LoadBmpTeture() 装载文理函数

LoadBmpTexture24Bit (LPDIRECT3DDEVICE9 pDevice,LPCSTR  pSrcFile,LPDIRECT3DTEXTURE9* ppTexture) 24位纹理

D3DXCreateTextureFromFile(D3D设备指针,纹理图形文件,存储D3D文理的指针地址) 直接从磁盘获取纹理

D3DXCreateTextureFromFileEx(D3D设备指针,纹理图形文件,指定纹理宽,高,指定渐进纹理序列级数,纹理使用方式一般为0,指定纹理图形格式,纹理存放的内存类型一般位为0,纹理过滤方式,自动生成的纹理序列过滤方式,设置透明色,图形文件信息存放地址可设置0,调色板存储地址,创建的D3D文理的指针地址) 高级获取纹理

HRESULT SetTexture(多级纹理的索引0-7,D3D的纹理接口指针) 设置当前要渲染的纹理

HRESULT SetTextureStageState(多级纹理的索引,纹理渲染状态的类型,纹理渲染状态的值,与类型相对应) 设置纹理的渲染状态

HRESULT SetSamplerState(指定纹理属性0-7,纹理采样属性类型,设置纹理采样属性) 纹理采样

HRESULT CheckDeviceFormat(指定显卡序列号,D3D设备类型,指定显示模式格式,缓冲区属性,需要使用查询的格式的设备类型,需要查询的显示格式) 纹理压缩

HRESULT LockRect(指定加锁的纹理级别,指向D3DLOCKED_RECT结构,要加锁的RECT区域-0代表整个区域,加锁类型-取0或下表的值) 锁定纹理

HRESULT UnlockRect(解锁的纹理级别) 解锁纹理

向量函数

D3DXVECTOR3 * D3DXVer3Length(V) 向量模的计算

D3DXVECTOR3 * D3DXVec3Normalize(返回指针,V) 单位化

D3DXVECTOR3 * D3DXVec3Add(返回的指针,u,v) 向量加法

D3DXVECTOR3 * D3DXVec3Subtract(同上) 减法

D3DXVECTOR3 * D3DXVec3Cross(同上) 向量X乘

D3DXVECTOR3 * D3DXVec3Lerp(同上) 数乘

D3DXVECTOR3 * D3DXVec3Maximize(同上) 取最大值

D3DXVECTOR3 * D3DXVec3Minimize(同上) 取最小值

D3DXVECTOR3 * D3DXVec3Scale(返回指针,PV,FLOAT) 比例

FLOAT D3DXVec3Dot(pv1,pv2) 点乘

参见编程精粹.chm中的COM中模块的导出函数

Private Type D3DVECTOR

    x As Single

    y As Single

    z As Single

End Type

'返回3D向量的规格化向量

Private Declare Function D3DXVec3Normalize Lib "DX8VB.DLL" Alias "VB_D3DXVec3Normalize" (VOut As D3DVECTOR, v As D3DVECTOR) As Long

Private Declare Function D3DXVec3Add Lib "DX8VB.DLL" Alias "VB_D3DXVec3Add" (VOut As D3DVECTOR, v1 As D3DVECTOR, V2 As D3DVECTOR) As Long

Private Declare Function D3DXVec3Subtract Lib "DX8VB.DLL" Alias "VB_D3DXVec3Subtract" (VOut As D3DVECTOR, v1 As D3DVECTOR, V2 As D3DVECTOR) As Long

Private Declare Function D3DXVec3Length Lib "DX8VB.DLL" Alias "VB_D3DXVec3Length" (v As D3DVECTOR) As Single

D3DFVF 自由顶点的格式

D3DFVF_DIFFUSE 包含谩反射的信息

D3DFVF_NORMAL 包含法线信息

D3DFVF_PSIZE 顶点信息指明绘制点的大小

D3DFVF_SPECULAR 包含镜面反射的信息

D3DFVF_XYZ 包含未经转换的顶点坐标

D3DFVF_XYZRHW 包含经过转换的顶点坐标

D3DFVF_XYZB1 through D3DFVF_XYZB5 包含用于骨骼动化的顶点和顶点对骨骼的权重信息

D3DFVF_XYZW 包含经过转换和裁剪的顶点坐标

D3DTRANSFORMSTATETYPE 变换的类型

­

D3DPRIMITIVETYPE 定义基本图元

D3DPT_POINTLIST 一组点的集合

D3DPT_LINELIST 一组线的集合

D3DPT_LINESTRIP 首尾相连的线段的集合

D3DPT_TRIANGLELIST 一组三角形的集合

D3DPT_TRIANGLESTRIP 首尾相连的三角形,有两个顶点集合

D3DPT_TRIANGLEFAN   组成扇形的一组三角形集合

D3DPT_FORCE_DWORD 未定义的

D3DDISPLAYMODE 屏幕显示模式

D3DFMT_UNKNOWN  未知的象素格式

D3DFMT_R8G8B8  24位色,RGB各占8位

D3DFMT_A8R8G8B8  32位色,@RGB各占8位

D3DFMT_X8R8G8B8  32位色,X为保留8位 RGB各占8位

D3DFMT_R5G6B5  16位色,R占5,G占6,B占5位

D3DFMT_X1R5G5B5  16位色,保留1位,RGB各占5位

D3DFMT_A1R5G5B5  16位色,@占1位,RG5各占5位

D3DFMT_A4R4G4B4  16位色,@RGB各占4位

D3DFMT_R3G3B2  8位色,R3,G3,B2位

D3DFMT_A8  只有8位@

D3DFMT_A8R3G3B2  16位色,@8,R3,G3,B2位

D3DFMT_X4R4G4B4  16位色

D3DFMT_A2B10G10R10 32位色,@占2位,RGB各10位

D3DFMT_A8B8G8R8  32位色

D3DFMT_X8B8G8R8  32位色

D3DFMT_G16R16  32位色,只有红和绿

D3DFMT_A2R10G10B10 32位色

D3DFMT_A16B16G16R16 64位色

D3DFMT_A8P8  8位色,8位表示半透明,8位表示颜色

D3DFMT_P8  8位色,用牙色索引值表示

D3DFMT_L8  8位色,只表示亮度

D3DFMT_L16  16位色,只表示亮度

D3DFMT_A8L8  16位色,8位表示半透明,8位表示亮度

D3DFMT_A4L4  8位色,4位表示半透明,4位表示亮度

D3DDEVTYPE_HAL   硬件抽象层,通过显示硬件来完成图形渲染工作

D3DDEVTYPE_NULLREF  

D3DDEVTYPE_REF   参考光栅器,一般用语测试显示卡不支持的D3D功能

D3DDEVTYPE_SW   用语支持第三方的软件

D3DDEVTYPE_FORCE_DWORD  扩展的

D3DCREATE 3D运算的方式

D3DCREATE_ADAPTERGROUP_DEVICE

D3DCREATE_DISABLE_DRIVER_MANAGEMENT

D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX

D3DCREATE_FPU_PRESERVE   激活双精度浮点运算或浮点运算异常检测,设置该项会降低系统性能

D3DCREATE_HARDWARE_VERTEXPROCESSING 由D3D硬件进行顶点预算

D3DCREATE_MIXED_VERTEXPROCESSING 由混合方式进行顶点运算

D3DCREATE_MULTITHREADED   支持多线程绘制,设置该项会降低系统性能

D3DCREATE_NOWINDOWCHANGES  

D3DCREATE_PUREDEVICE   禁用D3D的GET*()函数,禁止D3D使用虚拟设备模拟顶点运算

D3DCREATE_SCREENSAVER  

D3DCREATE_SOFTWARE_VERTEXPROCESSING 由D3D软件进行顶点运算

D3DSWAPEFFECT 取值列表

D3DSWAPEFFECT_DISCARD    后台缓冲区复制到前台时,清除后台缓冲区内容

D3DSWAPEFFECT_FLIP    后台缓冲区内容复制后,保持不变,有多个后台缓冲区时使用

D3DSWAPEFFECT_COPY    后台缓冲区内容复制后,保持不变,只有1个后台缓冲区时使用

D3DSWAPEFFECT_FORCE_DWORD   强迫该直作为32位存储,通常不用

D3DPRESENT 屏幕反转模式列表

D3DPRESENT_DONOTWAIT  

D3DPRESENT_INTERVAL_DEFAULT 默认的同ONE

D3DPRESENT_INTERVAL_ONE  当屏幕刷新一次时前台后台进行交换

D3DPRESENT_INTERVAL_TWO  当屏幕刷新二次时前台后台进行交换

D3DPRESENT_INTERVAL_THREE 当屏幕刷新三次时前台后台进行交换

D3DPRESENT_INTERVAL_FOUR 当屏幕刷新四次时前台后台进行交换

D3DPRESENT_INTERVAL_IMMEDIATE 图形绘制完成时立即进行交换

D3DPRESENT_LINEAR_CONTENT

D3DUSAGE 缓冲区属性值列表

D3DUSAGE_AUTOGENMIPMAP  

D3DUSAGE_DEPTHSTENCIL

D3DUSAGE_DMAP  

D3DUSAGE_DONOTCLIP 禁用裁剪,表示顶点缓冲区中的顶点不进行裁剪,当设置该属性时,渲染状态D3DRS_CLIPPING必须设为FALSE

D3DUSAGE_DYNAMIC 使用动态内存分配

D3DUSAGE_NPATCHES 使用顶点缓冲区绘制N-patches曲线

D3DUSAGE_POINTS  使用顶点缓冲区绘制点

D3DUSAGE_RENDERTARGET

D3DUSAGE_RTPATCHES 使用顶点缓冲区绘制曲线

D3DUSAGE_SOFTWAREPROCESSING 使用软件进行顶点运算,否则使用硬件计算

D3DUSAGE_WRITEONLY 只写属性,不能进行读操作,设置该属性可以提高系统性能

D3DPOOL  缓冲区资源内存位置列表

D3DPOOL_DEFAULT  默认的,顶点缓冲区尽可能存在与显存中

D3DPOOL_MANAGED  由D3D自动调度顶点缓冲区内存位置(显存和内存)

D3DPOOL_SCRATCH  顶点缓冲区位于计算机的临时内存中,这种类型的顶点缓冲区不能直接进行渲染,只能进行内存枷锁,拷贝等操作

D3DPOOL_SYSTEMMEM 顶点缓冲区位于内存中

D3DLOCK  缓冲区加锁

D3DLOCK_DISCARD  更新整个缓冲区

D3DLOCK_DONOTWAIT

D3DLOCK_NO_DIRTY_UPDATE 在加锁的过程中系统进行其他操作(默认有Dirty标记)

D3DLOCK_NOOVERWRITE 保证不腹稿缓冲区数据,设置该属性可以立即返回内存指针,提高系统性能

D3DLOCK_NOSYSLOCK 在加锁的过程中系统可能执行其他操作

D3DLOCK_READONLY 设置缓冲区位只读属性

D3DXVECTOR3 向量算法

D3DXVECTOR3u(x,y,z);

D3DXVECTOR3v(x,y,z);

float 变量=D3DXVec3Dot(u指针,v指针) 点乘

D3DXMATRIX 矩阵

D3DXMatrixIdentity 单位矩阵

D3DXMatrixInverse 逆矩阵

D3D实现图形变换

D3DXMatrixTranslation 平移矩阵

D3DXMatrixLockAtLH 观察矩阵

D3DXMatrixIdentity  将一个矩阵单位化

D3DXMatrixRotationY 绕Y轴转

D3DXMatrixRotationX 绕X轴转

D3DXMatrixRotationZ 绕Z轴转

D3DXMatrixScaling 缩放变换

D3DXMatrixMuLationAxis 围绕任意一个轴旋转

D3DXMatrixMultiply 组合变换

D3DUSAGE 纹理使用

D3DUSAGE_AUTOGENMIPMAP 自动生成多级渐进纹理序列,该方式在资源处于D3DPOOL_SYSTEMMEM时无效

D3DUSAGE_DEPTHSTENCIL 深度模版缓冲区,只在资源处于D3DPOOL_default时有效

D3DUSAGE_DMAP  该纹理是一个置换纹理

D3DUSAGE_DONOTCLIP

D3DUSAGE_DYNAMIC

D3DUSAGE_NPATCHES

D3DUSAGE_POINTS

D3DUSAGE_RENDERTARGET 该文理是一个渲染目标缓冲区

D3DUSAGE_RTPATCHES

D3DUSAGE_SOFTWAREPROCESSING 应用坐标变换

D3DUSAGE_WRITEONLY

D3DTEXTURESTAGESTATETYPE 渲染状态类型

D3DTSS_COLOROP   1 文理层的颜色混合方式

D3DTSS_COLORARG1  2 颜色混合的第一个参数

D3DTSS_COLORARG2  3 颜色混合的第二个参数

D3DTSS_ALPHAOP   4 指定纹理层的Alpha透明

D3DTSS_ALPHAARG1  5 Alpha混合的第一个参数

D3DTSS_ALPHAARG2  6 Alpha混合的第二个参数

D3DTSS_BUMPENVMAT00  7 绘制凹凸纹理时

D3DTSS_BUMPENVMAT01  8 绘制凹凸纹理时

D3DTSS_BUMPENVMAT10  9 绘制凹凸纹理时

D3DTSS_BUMPENVMAT11  10 绘制凹凸纹理时

D3DTSS_TEXCOORDINDEX  11 该纹理层使用的纹理坐标的索引

D3DTSS_BUMPENVLSCALE  22 绘制凹凸纹理的缩放参数

D3DTSS_BUMPENVLOFFSET   23 绘制凹凸纹理的平移参数

D3DTSS_TEXTURETRANSFORMFLAGS  24 控制纹理坐标的转换标志

D3DTSS_COLORARG0  26 指定混合过程的第三个颜色

D3DTSS_ALPHAARG0  27 Alpha混合的第三个参数

D3DTSS_RESULTARG  28 颜色混合的结果输出寄存器

D3DTSS_CONSTANT  32 颜色混合的常量寄存器

D3DTSS_FORCE_DWORD  0x7fffffff 强制转换为32位,通常不用

D3DSAMPLERSTATETYPE 纹理采样属性

D3DSAMP_ADDRESSU  1 包装纹理

D3DSAMP_ADDRESSV  2 包装纹理

D3DSAMP_ADDRESSW  3 包装纹理

D3DSAMP_BORDERCOLOR  4

D3DSAMP_MAGFILTER  5 处理放大过滤

D3DSAMP_MINFILTER  6 处理缩小过滤

D3DSAMP_MIPFILTER  7 多纹理过滤

D3DSAMP_MIPMAPLODBIAS  8 多级文理级数偏移值,初试直为0

D3DSAMP_MAXMIPLEVEL  9 最大多纹理级别,初试值为0

D3DSAMP_MAXANISOTROPY  10 各向异性,初试值为1

D3DSAMP_SRGBTEXTURE  11

D3DSAMP_ELEMENTINDEX   12

D3DSAMP_DMAPOFFSET  13

D3DSAMP_FORCE_DWORD  0x7fffffff 强制转换32位,通常不用

纹理寻址

D3DTADDRESS_WRAP  1 包装纹理寻址

D3DTADDRESS_MIRROR  2 镜像纹理寻址

D3DTADDRESS_CLAMP  3 夹取纹理寻址

D3DTADDRESS_BORDER  4 边框颜色纹理寻址

D3DTADDRESS_MIRRORONCE  5 一次镜像纹理寻址

D3DTADDRESS_FORCE_DWORD 0x7fffffff强制转换32位,通常不用

世界变换

D3DTS_WORLD  世界变换

posted @ 2009-09-17 07:55 RedLight 阅读(128) | 评论 (0)编辑 收藏

2009年9月12日

D3d9的一些更新 (转)

由于Aug 8造成的D3D9恐惧症已经完全消除了,这一章将会给大家介绍将3D引擎转向D3D9的各个方面,包括终于出现的全屏幕模式。从这章以后,我将使用D3D9作为讲解的语言继续D2D教程。

【OP结束,开始正片】

『Why?』

  估计大家首先要问的就是“Why?”为什么要前进到D3D9?理由如下:
1、D3D9修复了D3D8已知的所有Bug,因此运行起来更稳定,速度也要快。
2、D3D9提供了许多便利的新功能,虽然绝大多数是面向3D的,但是也有不少2D适用的,比如IDirect3DDevice9::StretchRect,以及对IDirect3DSurface9的改进等等。D3DX库就更多了,比如D3DXSaveSurfaceToFileInMemory,一开始没发现这个函数有啥用处,现在基本离不开了。
3、HLSL。就像上一话我说的那样,D2D教程以后会有PixelShader的内容。我可不想拿汇编来写Shader,会死人的(祝贺我吧,终于抛弃汇编Shader了……)。虽然说这不是决定性的理由,因为还有Cg什么的,不过我想编写显卡无关的代码,因此我不去研究Cg(反正和HLSL差不多)以及R2VB之类。
4、ID3DXFont,往下看你就知道了。

《D3D的变化》

『界面名称变化』

  一句话:8改成9就行。

『“创建”型方法的一个统一变化』

  许多Create*()方法,比如创建设备、创建纹理、创建顶点缓冲等等,多了一个HANDLE* pSharedHandle参数,无用,NULL之(看来微软原打算弄个共享句柄之类,不过被D3D10巨大的变化浮云了)

『创建D3D设备的变化』

  D3DPRESENT_PARAMS的FullScreen_PresentationInterval变成了PresentationInterval,也就是说即使在窗口模式下也可以做到垂直同步来防止撕裂现象(2D的福音啊)。相应的,D3DSWAPEFFECT_COPY_VSYNC消失了,反正这个效果也不咋的,消失了也好。
  要做到垂直同步需要给PresentationInterval赋值D3DPRESENT_INTERVAL_DEFAULT或D3DPRESENT_INTERVAL_ONE。其中D3DPRESENT_INTERVAL_ONE的效果比D3DPRESENT_INTERVAL_DEFAULT好一点,不过相应的也会占用多一点点系统资源……真的只有一点点而已,实在是无所谓的……
  如果不要垂直同步,想要看看实际祯速的话,D3DPRESENT_INTERVAL_IMMEDIATE。
  注意在窗口模式下,你只能使用这三种Present模式,全屏幕模式下就可以使用别的(但是要首先检测D3DCAPS9以查看显卡是否支持)。不过我感觉对99%的游戏来说,有这三个就足够了。
  另外在窗口模式下,BackBufferFormat也可以设置成D3DFMT_UNKNOWN,D3D会自动获取当前桌面的格式设定成后备缓冲的格式,省去GetDisplayMode。实际上,窗口模式下的后备缓冲已经不需要和桌面格式相同,你可以通过IDirect3D9::CheckDeviceFormatConversion来检查,如果这个设备支持这两种颜色格式之间的转换,就可以给程序的后备缓冲设定上不同的格式。我试过在桌面格式为32Bit(D3DFMT_X8R8G8B8)时将程序的后备缓冲格式设置为D3DFMT_R5G6B5(16Bit),发现了速度提升,也就是说这个设定是有意义的。
  可创建的设备类型多了一种D3DDEVTYPE_NULLREF,在安装了D3D SDK的机子上等同于D3DDEYTYPE_REF,在其他的机子上,这种设备实际上没有创建真正意义的D3D设备,只是允许你创建的纹理、表面等资源,但是Render、Present等操作都会无效(实际上这些资源都创建在了D3DPOOL_SCRATCH池里,不管你设定使用的是什么POOL)。也就是说,仅仅在模拟基本的运行而已。你可以用这个设备来编写一个利用D3DX函数库进行图像格式转换的程序,比如把一大堆不同的格式转换成易于D3D9使用的DDS格式。因为实际上没有创建设备,你甚至可以编写成控制台的,通过GetConsoleWindow的方法获得HWND。Mercury 3用的MIF格式的转换器就是这么做出来的。注意D3DDEVTYPE_NULLREF只能用在IDirect3D::CreateDevice时,其他的方法都不行。

『创建表面的变化』

  创建表面(Surface)的方法变成了IDirect3DDevice9::CreateOffscreenPlainSurface,参数很简单不用多说,需要注意的是可以选择POOL了。

『设定FVF的变化』

  设定FVF时,原来通过IDirect3DDevice8::SetVertexShader,现在有了一个专门用来设定FVF的方法:IDirect3DDevice9::SetFVF。这是个很好的变化,省得把FVF和Shader弄混(题外话:也就是因为这个变化,让Shader在设备Reset后得以保存,不错不错)

『获取后备缓冲』

  D3D9现在允许有多个后备缓冲交换链,不过对于2D来说,基本不需要这种东西,IDirect3DDevice9::GetBackBuffer多出来的第一个参数赋值0即可。如果你有兴趣,可以去研究一下这个玩意,有时候可以用来做分场。

SetStreamSource』

  这个方法的功能被扩展了,对比参数就可以知道,多出来的OffsetInBytes允许你选择一个顶点缓冲的Offset,D3D9将从这个Offset之后开始读取数据。因此你可以把几组用来渲染纹理的正方形顶点存储到一个顶点缓冲里面。

SetSamplerState』

  这个是D3D9的新方法,把原先SetTextureStageState的一些功能独立了出来,和2D关系最密切的就是纹理过滤了。原先的D3DTSS_MINFILTER变成了D3DSAMP_MINFILTER,相应的D3DTSS_MAGFILTER也变成D3DSAMP_MAGFILTER,D3DTSS_MAXANISOTROPY变成D3DSAMP_MAXANISOTROPY。另外还有更多的,比如纹理寻址等。你去看一下D3DSAMPLERSTATETYPE枚举类型的内容就知道它“迁移”了些什么。
  这个变化对于Shader来说很方便。改成Sampler的东西在PixelShader过程也会有效,而没有更改的东西在PixelShader就不会有效了。D3D8时候把这些全都放在了一起,容易造成混乱。

SetRenderTarget』

  D3D9现在允许多重RenderTarget存在,不过我们基本上只用一个,RenderTargetIndex设为0,第二个参数仍然是需要设定的表面。与D3D8相同的是,在设定之前仍然需要先通过GetSurfaceLevel获得表面才行。

『顶点缓冲的锁定』

  注意IDirect3DVertexBuffer9::Lock的第三个参数,从原来的BYTE**变成了void**。也就是这样了……

『其他的一些变化』

1、CopyRects变成了UpdateSurface。和UpdateTexture一样,只能从D3DPOOL_SYSTEMMEM拷贝到D3DPOOL_DEFAULT
2、增加了一个比较有用的IDirect3DDevice9::ColorFill方法,作用是向D3DPOOL_DEFAULT的某个区域填充颜色,和Clear的功能类似,但是在使用目的上要比Clear明确的多,并且由于不牵扯深度缓冲之类,速度要快一些。
3、增加了一个IDirect3DDevice9::StretchRect方法,通过这个方法就可以在D3DPOOL_DEFAULT的表面或纹理之间进行带过滤器的缩放操作,免去利用Render的过程,非常有用。不过这个方法由于使用了硬件处理,限制较多,请大家仔细看SDK文档的Remarks部分。

《D3DX的变化》

  D3DX的变化实际上相当的多,但正如我一开始所说,基本都是面向3D的。需要我们注意的有以下几种:
1、D3DX***FromFile之类的函数支持的图像格式增加了,不过所增加的都是很少见的格式。平时基本上还是用BMP、TGA和PNG就足够。
2、增加了D3DXSave***ToFileInMemory,将会把文件写入内存。这个函数的作用似乎不是很容易想到,但是如果你要写一个集成了转换、打包功能的工具,这个就很有用了,省去了通过临时文件操作造成的各种问题。另外如果你熟悉某种图形文件的格式的话,还可以通过直接访问这个文件获得RAW信息。注意,这类函数写入的是一个ID3DXBuffer,这个东西很简单,只有两个特定的方法,一看便懂,不再多言。
3、增加了一个ID3DXLine,可以方便你在2D上画线,创建ID3DXLine的方法是D3DXCreateLine。这个东西也不复杂,使用方法有点像ID3DXSprite,稍微研究一下就能弄懂,注意每次Draw的是D3DPT_LINESTRIP。用它比直接用顶点缓冲的好处是可以方便的打开反锯齿,效果嘛……基本满意。
4、增加了一个ID3DXRenderToSurface,“理论上来说”方便了利用RenderTarget的过程……不过我感觉反而弄得复杂了。创建的方法是D3DXCreateRenderToSurface,有心情的朋友自己研究看看吧,我就不讲了。

  ID3DXSprite和ID3DXFont在Summer 2004的DX9 SDK(也就是第一版DX9.0c)开始发生了很大变化,下面详述:

『ID3DXSprite』

  你会发现ID3DXSprite::DrawTransform不见了,取而代之的是其功能被整合到ID3DXSprite::SetTransform里面,也就是说为了缩放和旋转,我们不得不和矩阵打交道了。其实也不会太复杂,因为我们只是做一些矩阵运算,学过线性代数的朋友肯定会很熟悉,就算你不怎么熟悉线性代数,也没关系,D3DX函数库提供了现成的矩阵运算函数,你只要用就行了。

D3DXMatrixScaling
D3DXMatrixRotationZ
D3DXMatrixTranslation

  按照顺序调用这三个函数……或许学过3D的马上就想到这点了,的确是没错啦。注意顺序哦:Scaling -> Rotation -> Translation,简称SRT(看过全金属狂潮吗?看过的话这个单词很好记吧^_^),弄错了可是得不到正确结果的。
  你是不是想到把同一个D3DXMATRIX当作参数使用三次?错啦!你要用矩阵乘法。创建三个D3DXMATRIX,比如mat1、mat2、mat3,分别用这三个函数将其创建为缩放矩阵、旋转矩阵和平移矩阵,然后在ID3DXSprite::SetTransform时,这样写:

SetTransform(mat1 * mat2 * mat3);

  有够麻烦的是不?ID3DXSprite方便了做3D的,可害苦了做2D的,所以我已经不直接用这个了(什么叫不直接用?往下看)。

『ID3DXFont』

  大家来欢呼吧!Summer 2004改进的ID3DXFont彻底枪毙掉了上一话那个字体引擎……
  这东西的改进,怎么说呢,应该说是改头换面吧,速度、效果都和以前不是一个数量级。可怜的PixelFont,才存在了一话就要被抛弃了。
  ID3DXFont多出来的几个方法,Preload*()这类的,就是把一些常用的字的字模提前读取到内存里面加快速度,同时还可以使用ID3DXSprite渲染,进一步加快速度。虽然内部仍然有GDI的部分,不过很明显工作方式发生了极大的变化。根据我的估计,这次的ID3DXFont很聪明的利用GDI获得文字的轮廓,然后通过纹理来渲染。这样的速度就快得多了,而且文字质量也得到了很好的控制,基本和直接用GDI的质量相同了。
  由于PreloadCharacters()和PreloadGlyphs()不是那么好理解,一般用PreloadText()就行。建议将所有ASCII字符、标点符号和部分汉字预读进去。这个预读过程略微有点慢,而且根据预读的文字数量和你创建文字的字号,占用的内存也不同。这里给大家一堆文字,你Copy过去就行:

引用

const char strPreloadText[] = " 1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM~!@#$%^&*()-=[]\\;',./_+{}|:\"<>? 、。·ˉˇ¨〃—~‖…‘’“”〔〕〈〉《》「」『』〖〗【】!"#¥%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}我人有的和主产不为这工要在第一上是中国经已发了民同";

  注意第一个字符是空格哦!把空格预读进去可是很重要的^_^
  看上去并不多,因为要考虑到内存占用及速度,我只预读了一些符号和五笔的一键字。这些字符在24号字时候已经占用了快1MB了,比起PixelFont字库占用的要大得多。天知道ID3DXFont到底预读了些什么……
  PreloadText()的第二个参数不要用strlen,sizeof(strPreloadText)即可。
  然后就是利用ID3DXSprite来渲染。注意ID3DXFont::DrawText的第一个参数就是LPD3DXSPRITE,因此如果要利用ID3DXSprite,要将ID3DXFont::DrawText放到ID3DXSprite::Begin和ID3DXSprite::End之间。这就是我刚才说的不直接用ID3DXSprite的意思,ID3DXFont会完成ID3DXSprite的全部调用,你不用担心。
  另外你应该注意到ID3DXSprite::Begin增加了参数,实际上DX文档里面没说,但是示例里面有,如果想让ID3DXSprite发挥作用并且最大幅度的提升效率,参数上设定D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE即可。意思很明白:打开Alpha过滤和纹理筛选。这里DX文档上有个错误一直没改:文档里给出的是D3DXSprite__SORT_TEXTURE,但是你可以试试,绝对报错。
  剩下的就没啥了,ID3DXFont的使用方法上一话已经讲过。要注意的是D3DXCreateFont和D3DXCreateFontIndirect都发生了变化。D3DXCreateFont已经不再牵扯GDI了,D3DXCreateFontIndirect所使用的结构也变成了D3DXFONT_DESC,相对于LOGFONT结构,除去了一些用不着的参数,增加了一个MipLevels,就是MipMap等级啦,不用多说,2D下只用1。其他的上一话都有。实际上由于D3DXCreateFont已经不再关联GDI,D3DXCreateFontIndirect的存在仅仅是由于历史原因(为了兼容像我这种人的使用习惯),大家还是用D3DXCreateFont吧,省事。
  截图就不贴了,没啥意义。你可能觉得直接向后备缓冲上DrawText还不够好看,那么就先画到一张纹理上,然后将纹理错位渲染到后备缓冲并且打开线型过滤,就可以达到和PixelFont相同的效果了。
  速度嘛……我画了整整一屏幕字,在不缓冲文字的情况下(这个“缓冲文字”和ID3DXFont的文字缓冲可不是一回事啊!看过上一话的都应该知道我这里指的是什么),速度仍然在120FPS以上。或许你会觉得速度还是有点慢,但是,如果用D3D8的ID3DXFont画上这么一屏幕,基本就只剩20FPS了。
  使用ID3DXFont替换掉PixelFont的优势就是可以方便的自定义字体字号了,并且也不再受GB2312字库的限制。所以大家都换了吧……都换了吧……把PixelFont忘了吧……

『稳定的DX9 SDK版本』

  我现在用的是April 2006,而且应该会用很长时间。August 2006我是肯定不会去用啦!即使我不再恐惧D3D9,也会对这个SDK避让三分的。其实对于2D,我感觉用到April 2006就足够了,之后的DX9 SDK主要在D3DX的3D函数库部分进行更改……其实也是秋后的蚂蚱蹦达不了几天,D3D10马上就要出来了。要说D3D10啊……你还是看我另外一篇日志好了,总之打死我都不拿它做2D。

  实际上仅仅是2D的话,从D3D8转向D3D9并没有多少变化,主要是稳定嘛!只要你不调用一些D3D9专用的功能,即使拿D3D9来做2D,在绝大多数显卡上还是能够运行的。嗯……GF2等级以上吧,GF2之前的,也太老了,无视好了。

《再上点菜好了:全屏幕模式》

  其实并不是多么复杂的问题,让我拖了这么久……不拖了,这里就教给大家如何做全屏幕模式以及如何处理设备丢失的问题。

『创建全屏幕模式』

  D3DPRESENT_PARAMS里面,Windowed设定为false,并且一定要设定BackBufferWidth和BackBufferHeight,完毕。
  哈哈,就这么简单,或许早就有人尝试过了,但是你试试按下Alt+Tab,再切换回去,保证你什么都看不到。
  之前曾经说过,DX8之前的版本,在全屏幕下工作比在窗口下容易,到DX8之后就则完全颠倒过来。因为在窗口模式下不用担心设备丢失(除非你更改桌面分辨率),全屏幕模式下就会有这个问题了。下面详述:

『设备、资源丢失』

  设备丢失会发生在全屏幕模式下切换回桌面时(不论是通过Alt+Tab还是QQ上有人给你发了张图片-_-bbb),而且如果在调用IDirect3DDevice9::Reset(从现在开始就是D3D9了啊!忘记D3D8吧……)的时候发生错误,设备也会丢失。
  设备丢失会造成资源丢失:所有创建在D3DPOOL_DEFAULT池的资源都会丢失,需要重新创建,其内容当然也会消失,需要重写。
  然而创建在D3DPOOL_SYSTEMMEM和D3DPOOL_SCRATCH池的资源不会受到影响。创建在D3DPOOL_MANAGED池的资源也不会丢失,而且在设备重新可用的时候,D3DPOOL_MANAGED池的资源也可以立即投入使用,内容也不会改变。看这个池名字:托管池就能知道,D3D帮你处理了所有问题。
  因此避免设备丢失后资源丢失的简易方法就是将所有资源创建在D3DPOOL_MANAGED池内。不过这并不是个好方法,这意味着不能用渲染对象——记得吗?RenderTarget只能创建在D3DPOOL_DEFAULT。实际上最好的方法是跟踪所有D3DPOOL_DEFAULT资源,比如利用std::list,将所有D3DPOOL_DEFAULT资源勾住,在设备发生丢失的时候释放掉资源,设备可以继续使用的时候重新创建资源,记得把数据写回去。对于其他的池就不用这么折腾了。

『当设备丢失之后』

  不论通过任何方式发生了设备丢失,所有的操作几乎都会失效,只有Release()可以用——其实D3D会保证有部分操作可以成功,但是也仅仅是“可以”成功而不是“一定”成功,所以你还不如认定丢失的时候全都会失败比较好——以及IDirect3DDevice9::TestCooperativeLevel。因此在设备丢失之后,你应该停止整个游戏循环,而通过反复调用IDirect3DDevice9::TestCooperativeLevel判断设备是否可用。

『IDirect3DDevice9::TestCooperativeLevel』

  这个方法检测当前的设备状态。返回值有四种:D3D_OK一切正常,D3DERR_DEVICELOST设备丢失,D3DERR_DEVICENOTRESET设备可以Reset。另外还有D3D9新增的D3DERR_DRIVERINTERNALERROR,遇到这个你就完蛋了,基本不可能恢复了,终止程序吧。
  按照顺序来讲,如果游戏在正常运行,D3D_OK会返回;如果发生了设备丢失并且在这个时候不能恢复,比如全屏幕模式的时候用户切换到了Windows桌面,就会返回D3DERR_DEVICELOST;如果用户又切换回了游戏,设备可以恢复了(还没恢复呢!只是“可以”恢复而已),就会返回D3DERR_DEVICENOTRESET
  另外,IDirect3DDevice9::Present也会返回类似的值,不过你最好别指望这个,老老实实的用TestCooperativeLevel。因为Present在设备可以恢复的时候还是返回D3DERR_DEVICELOST(外一句:D3D10的时候TestCooperativeLevel就会完全整合到Present里面了,可喜可贺可喜可贺)

『处理设备丢失』

  看下面的伪代码:

switch (IDirect3DDevice9::TestCooperativeLevel()){
  case D3D_OK:
    GameLoop();
    break;
  case D3DERR_DEVICELOST:
    break;
  case D3DERR_DEVICENOTRESET
    OnLostDevice();
    IDirect3DDevice9::Reset();
    OnResetDevice();
    break;
  default:
    QuitGame();
    break;
}

  GameLoop()就是你的游戏运行的过程了。把这个switch写在我们游戏框架的GameMain()部分,具体的位置可以看任何一话附带的源代码。
  好像我一直没有讲IDirect3DDevice9::Reset的参数啊?因为只有一个参数,就是指向D3DPRESENT_PARAMS的指针。把你第一次创建设备时使用的D3DPRESENT_PARAMS结构保存起来,供Reset来用。
  OnLostDevice()就是Release掉所有D3DPOOL_DEFAULT的资源,OnResetDevice()就是Create*()恢复啦!你可能注意到ID3DXFont、ID3DXSprite等等都有同名的方法,就是在这个时候调用的。如果你没有这么做,也就是说还保留着任何D3DPOOL_DEFAULT的资源的话,IDirect3DDevice9::Reset就一定会失败。
  另外在OnResetDevice里面你还要重新进行SetRenderState、SetSamplerState等等,Reset之后这些东西也丢失了。实际上Reset和重新创建一次设备类似,所不同的是重新创建设备的话你需要连D3DPOOL_MANAGED的资源也Release掉。这个话题就不讨论了。
  从代码可以看出来,D3DERR_DEVICELOST时程序什么都没做,只是在傻等。我认为这是一个好习惯,因为实在不能保证在D3DERR_DEVICELOST时除了Release还能干什么,与其这样还不如等设备能用了再说。

  实在懒得管资源的话,全部D3DPOOL_MANAGED好了。至于渲染对象?自己想办法。

『人工制造“设备丢失”』

  “干嘛还要制造设备丢失啊?”如果更改游戏分辨率、色深、切换全屏幕及窗口状态,进行这样的操作也要通过Reset,同样的,Reset之前也要释放掉所有D3DPOOL_DEFAULT资源(其实严格来说,还有更多的资源也要释放,不过在2D下基本不会创建这类资源,你就不用管了)并且调用ID3DXSprite::OnLostDevice之类的方法。这就是人工制造“设备丢失”了。实际上在这个过程设备并没有真正的丢失,只是会有一段时间处于不可用的状态,此时Reset尚未返回,整个D3D设备就好像死了一样。举个例子,你切换桌面分辨率,会有那么一段时间显示器上什么都不显示,然后很快就正常了。和这个现象是同一个原因。Reset成功后记得恢复资源。
  你可能注意到这里的Reset和上面的Reset不是一回事。的确是这样,这里是为了重设状态而不是恢复设备。因此更改分辨率、色深的Reset需要写到switch外面,也就是别和它搅和的意思-_-bb。而且你只需要OnLostDevice -> Reset -> OnResetDevice。记住:正确的调用Reset不会造成设备丢失,这个概念别弄混了。

『切换全屏幕模式时的注意事项』

  注意WindowStyle的变化。切换成全屏幕模式后,只能使用WS_POPUP,不然显示会变得怪怪的,你可以通过SetWindowLongPtr函数更改窗口外观,第二个参数指定GWL_STYLE即可。别忘了WS_VISIBLE啊!不然你什么都看不见。

『更详细的文档』

  我这里只是简单讨论了造成设备丢失的原因及处理方法,更详细的内容你可以参考DX SDK文档的Lost Device文章,人家是权威的。

【以上,正片结束,后面是ED】

  我们前进到了D3D9,赶上了时代。
  我们创建了全屏幕游戏,赶上了时代。
  我却变得一脑子浆糊,被观众抛弃了。
  哈哈,开玩笑啦,不过这一话很乱倒是真的,因为不论是更新到D3D9还是设备丢失,牵扯的东西都太散太杂,结果弄得这一话也是一盘散沙(居然又没有附带代码)。唉,大家就忍了吧,忍不了的话就来PIA我吧。

  关于更新至D3D9更多的内容,你可以参考SDK文档的《Converting to Direct3D 9》。

【以上,ED结束,后面是……】

  第一季完结了……
  回过头来看看,从第一话创建一个Windows窗口,到这一话的设备丢失,话题的层次一直在深入,现在已经深入到了不再是“学习”而是“研究”的范围。我也不再想仅仅是搞“教学”而是想和大家“讨论”。不过第一季主要还是教学吧。能坚持着看D2D教程到现在的,应该基本能够写出完整的2D Demo来了吧。如果有什么问题的话,欢迎提出,我在看到后会立刻回答的……只要你这个问题不太RP的话……
  那么,第二季会是什么样子?
  第二季就不再是教学了,而开始我和大家的讨论过程。第二季的第一话,也就是第09话,我将提供一些高级技巧给大家,并希望有兴趣的朋友和我一起进行这些技巧的研究。另外在第二季里面,我们还要创建一个2D图形引擎。原来打算给大家讲解Medux 2,不过现在感觉这东西实在小儿科,绝对会让大家B4的。那么既然如此,干脆介绍Mercury 3好了,有意见无?
  透漏一点下一话的内容吧:模糊精度和多次纹理渲染,嘿嘿,听上去挺高深的是不?实际上超级简单,就看你能不能想到而已。
  希望你在看完这一话之后,返回去再把前面的内容看看,相信你会得到新的收获。搞不好你还能抓出几个Bug呢!因为我是想到什么写什么,没个章法,Bug是难免的。
 


附加:

Direct3D中的字体与文本显示
图形系统中为了获得当前运行程序的相关信息,往往需要在屏幕上显示文本,Direct3D的功能扩展接口ID3DXFont对此提供了方便的解决方法。

 

 

创建ID3DXFont对象

使用接口ID3DXFont绘制文本,首先需要通过函数D3DXCreateFont()创建ID3DXFont字体对象。ID3DXFont接口封装了Windows字体和Direct3D设备指针,D3DXCreateFont()函数通过Windows字体和Direct3D设备指针创建ID3DXFont对象,该函数的声明如下:

Creates a font object for a device and font.

HRESULT D3DXCreateFont(  LPDIRECT3DDEVICE9 pDevice,  INT Height,  UINT Width,  UINT Weight,  UINT MipLevels,  BOOL Italic,  DWORD CharSet,  DWORD OutputPrecision,  DWORD Quality,  DWORD PitchAndFamily,  LPCTSTR pFacename,  LPD3DXFONT * ppFont);
Parameters
pDevice
[in] Pointer to an IDirect3DDevice9 interface, the device to be associated with the font object.
Height
[in] The height of the characters in logical units.
Width
[in] The width of the characters in logical units.
Weight
[in] Typeface weight. One example is bold.
MipLevels
[in] The number of mipmap levels.
Italic
[in] True for italic font, false otherwise.
CharSet
[in] The character set of the font.
OutputPrecision
[in] Specifies how Windows should attempt to match the desired font sizes and characteristics with actual fonts. Use OUT_TT_ONLY_PRECIS for instance, to ensure that you always get a TrueType font.
Quality
[in] Specifies how Windows should match the desired font with a real font. It applies to raster fonts only and should not affect TrueType fonts.
PitchAndFamily
[in] Pitch and family index.
pFacename
[in] String containing the typeface name. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.
ppFont
[out] Returns a pointer to an ID3DXFont interface, representing the created font object.
Return Values
If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DXERR_INVALIDDATA, E_OUTOFMEMORY.

Remarks
The creation of an ID3DXFont object requires that the device supports 32-bit color.

The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXCreateFontW. Otherwise, the function call resolves to D3DXCreateFontA because ANSI strings are being used.

If you want more information about font parameters, see The Logical Font.

示例代码如下:

D3DXCreateFont(g_device, 50, 20, 20, 0, FALSE, DEFAULT_CHARSET, 0, 0, 0, "Arial", &g_font);

posted @ 2009-09-12 07:40 RedLight 阅读(157) | 评论 (0)编辑 收藏

仅列出标题  下一页
<2010年2月>
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

导航

统计

公告


Name: Galen
QQ: 88104725

常用链接

留言簿(5)

随笔分类

随笔档案

文章分类

相册

My Friend

搜索

最新评论

阅读排行榜

评论排行榜