DirectX怪像之一,我的模型不见了

转载 2015年07月07日 17:03:59

引言

对于刚刚编写DirectX程序的朋友来说,经常遇到的一个问题就是,风风火火写了一大堆代码,编译-运行!哇塞,窗口里黑乎乎一片,啥也没有,或者是之前运行好好的程序,不只修改了哪里,导致以前渲染的画面现在都没有了。我在学习的过程中也经常遇到这种问题,索性总结下来,与大家分享。希望能给刚入门的兄弟们一个提醒。

场景为何消失?

根据我自己的经验,如果渲染场景中某些东西不见了,一般有以下几个主要的原因

光照设置不正确

很简单,在一个伸手不见五指的黑夜里,你能指望看见什么呢?光照是D3D中必不可少的东西,用来计算顶点的最终颜色。但是并不是所有的顶点格式都需要光照,有些定点格式,如果设置了光照反而会导致模型无法显示,比如LT(Lit and Transformed)格式。我们来看看D3D中的光照原理。

  • 如果将光照设置为enable(通过D3DRS_LIGHTING=TRUE设置),那么系统会对所有法向量不为0的顶点进行光照计算,即使输入的顶点中包含颜色信息,也将被丢弃。
  • 如果将光照设置为disable,那么对于LT格式,将使用顶点自带的颜色信息,而对于其他类型的顶点,将没有光照计算,也就无法显示。
  • 创建并开启了depth buffer,但是并没有enable lighting,这个有待确定,目前上不知原因。

所以如果顶点是LT格式的,而且设置了光照为enable,那么模型也是无法显示的,因为LT格式的顶点不包含法向量,没有法向量是无法完成光照计算的。

视图矩阵设置不正确

这个也很简单,在一个阳光明媚的日子,一位绝色美女站在你旁边,可是你却背对着她!如何欣赏到她的美呢?有了光照,有了场景,可是如果场景不在你的视野内,你依然什么都看不见,比如模型绘制在X轴正半轴上,而视线却指向X轴负半轴。所以,正确的设置视图矩阵也是看见场景的重要因素。DirectX使用左手系,Z轴指向屏幕内部的方向为正,一般来说模型都绘制在坐标系的原点,而观察点也设置为原点,眼睛的位置只要设置成Z轴负半轴上的某个位置就可以了。下面就是一个典型的设置代码,也就是说,eyePt的z坐标一般都是负值,如果你一不小心将其设置为正值,那么屏幕上肯定会空无一物的。

D3DXVECTOR3 lookCenter(0.0f0.0f0.0f) ;
D3DXVECTOR3 upVec(
0.0f1.0f0.0f) ;
D3DXVECTOR3 eyePt(
0.0f0.0f-20.0f) ;

剔除方式不正确

D3D默认的剔除方式是逆时针,也就是CULL_CCW,如果你的顶点是按照逆时针顺序定义的,而且使用了默认的剔除方式,那么肯定什么都看不见。所以一定要确保顶点定义的顺序和剔除顺序是相反的,也就是说,如果程序中定义了顺时针剔除,那么你的顶点就应该保持逆时针顺序。在D3D中可以指定如下三种剪裁方式:

D3DCULL_CW  顺时针

D3DCULL_CCW  逆时针

D3DCULL_NONE   不剪裁

如何诊断剪裁问题?

如果你怀疑程序可能是由于剪裁导致了错误,那么可以将剪裁方式指定为D3DCULL_NONE,并按照下面步骤诊断。

  • 问题不存在了,这说明是剔除方式不对,可以分别试试D3DCULL_CW和D3DCULL_CCW这两种方式。
  • 问题依旧,这说明不是剔除的问题,因为D3DCULL_NONE不进行任何剔除操作,所有的面都该显示。应该是其他原因引起的。

转换矩阵设置不正确

比如不小心将模型平移到了视野之外。如果有多个模型,要为每个模型单独设置world matrix,且这些world matrix之间不能互相影响。

启用了ZBuffer却没有清除ZBuffer

如果在创建Device的时候启用了ZBuffer,如下:

d3dpp_.EnableAutoDepthStencil = TRUE ;
d3dpp_.AutoDepthStencilFormat    = D3DFMT_D16 ;

那么在clear render target的时候一定要记得clear ZBuffer,如下:

d3ddevice_->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x4F94CD, 1.0f, 0);

如果是下面这样,那么将什么也看不见。

d3ddevice_->Clear(0, NULL, D3DCLEAR_TARGET, 0x4F94CD, 0.0f, 0);

注意,如果在创建Device的时候像上面那样指定了ZBuffer,那么就不用显示设置开启ZBuffer了。因为D3D会自动设置ZBuffer为开启状态,也就是下面的代码其实是多余的。

d3ddevice_->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

模型颜色与窗口背景色一致

这也算是一个低级错误了,是在StackOverFlow上看到的一个问题,有一哥们将窗口背景设置为白色,输出的模型也是白色,结果,啥也看不见。

没有绘制内容

这个原因听起来很滑稽,不过不可否认的是,我曾多次犯了这个错误,程序中没有绘制任何东西!其实这个问题的原因往往是修改代码造成的,一开始程序的行为是正确的,但是后来为了修改某些功能为Render函数就行修改,可能会无意间注释掉某些内容,如果将绘制的代码注释掉,那肯定就什么也看不见了。

总结

当然,看不见模型的原因远不止这些,本文只是抛砖引玉,欢迎大家补充指正!

相关文章推荐

reset命令不见了!!调试u-boot遇到的怪问题

在调试一款MIPS高通CPU的u-boot时,reset命令不能正常使用。通过跟踪发现,原来是lds设置导致了.got段在relocate时多做了几个byte的范围,从而引起了命令模块的异常。修改了l...

关机按钮不见了怎么办?

  • 2013年01月14日 15:03
  • 12KB
  • 下载

解决jsp从数据库中读出来的数据放进textarea显示,格式不见了的问题

1.问题背景 你有没有遇到过这样的问题? jsp中有个textarea控件,当你存数据进数据库中的时候。再取出来,放到textarea中,你会发现,样式不见了?原来好好的样式,现在排成一行了 ? ...

电脑桌面的照片文件不见了怎么办

我总是喜欢将新编写的资料放到桌面上,这样好利于我的拷贝,但是,昨天刚刚编辑好的资料文件,放在桌面上,准备今天早上拷贝到u盘里去,当我早上起床打开电脑准备拷贝的时候突然发现桌面上的文件居然不见了,在回收...

摇一摇窗口不见了—Windows 7功能

  • 2008年12月17日 14:20
  • 197KB
  • 下载

桌面上"我的电脑"不见了

  • 2008年12月25日 15:07
  • 21KB
  • 下载

win7语言栏或输入法图标不见了

我想方法可能很多人都知道:只要找出输入法设置窗口就可以修改了,本文中导致输入法不见了的3个原因中的2个和这个对话框有关。但问题也正是出在了这里,因为输入法图标消失了很多人不知道从什么地方调出输入法设置...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DirectX怪像之一,我的模型不见了
举报原因:
原因补充:

(最多只允许输入30个字)