DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之7: Chap9: Color

    这一章先是讲了DirectX中的颜色的各种相关知识。其实专门为颜色这一块内容开辟单独的一章没有太大的必要,所以作者扯了点其他话题,让我们能够画出“机械波”。并且这块“离题”讲述的知识在后面还会以各种姿态出现(毕竟,这是目前我们能够画出来的除了DX自带的茶壶以外最炫丽的3D图形了)。

    当然,顺带而来的还有对顶点结构的更新以及对vertex shaders和pixel shaders的改进。

    这一章引入了一个比较重要的结构体:D3DXCOLOR。这个结构体(其实就是一个class,不过它的成员变量都是public)提供了很多方法,最惹人注目的就是各种运算符的重载了。

    本人做了一个小小的控制台程序来测试它的一些方法,下载地址如下:

点击打开链接

 

    然后,各位可以发现,D3DXCOLOR的算术运算是不会进行“边界检查”的,得到的结果颜色的分量的范围可能在[0, 1]之外;这个大家看看程序运行的结果就能够信服了。

    那么将这种越界的颜色值赋给顶点的颜色成分或者直接赋给像素的话会怎么样呢?为了研究这个问题,我编了一个D3D小程序,叫做ColoredSquare,基本就是书上的ColoredCube程序的2D版本。这里你可以改变各个顶点的颜色值来研究不同的颜色效果。它的下载地址如下:

点击打开链接

 

    然后在这里我就发现了一件有趣的事情:把color.fx文件中的pixelshader——float4 ColorPS(float4 c : COLOR0) : COLOR的函数体

return c;

改成

return 2*c;

那么出现的效果不一样了!具体地说,就是正方形的斜对角线的影响范围更广了(从图上来看,就是白色部分更多了)。这到底是为什么呢?希望有兴趣的同学一起来研究一下!

 

这是改变return语句之前的程序运行的截图:

DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之7: Chap9: Color_第1张图片

这是改变return语句之后的程序运行的截图:

DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之7: Chap9: Color_第2张图片

 

    这一章的内容总体来讲还是很简单的。“机械波”部分如果感觉有点吃力的话,请复习高中数学知识。

    

    那么下面我们来研究一下习题吧!


习题1部分:

 

    这道题原先的电子版上有点问题,况且很简单,而且我前面给出的控制台程序应该已经有很好的引导作用了。另外值得注意的是,要实现分量相乘运算,需要调用D3DXColorModulate函数。


习题2部分:

 

    这道题很简单,如果用非shader方法,那么在主文件的drawScene方法中正式绘制图形之前添加如下语句即可:

HR(gd3dDevice->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_FLAT));

    如果用shader方法,那么实现起来更加方便,只需要在你所需要使用的technique中的pass内部添加如下语句就OK了:

ShadeMode = Flat;

 

    至于效果,就是每个三角形的颜色等于该三角形第一个顶点的颜色值。如果是设为Gouraud状态的话,那么实现方法完全同理;不过由于这是默认的状态,所以只有在该状态发生改变的时候才需要去设置。

 

 

 

习题3部分:

 

    这道题要我们重新做第7章(看好了,不是第8章)的习题3和习题4,不过这次要我们给顶点增加颜色。

    为了简略,我只重新做了第7章的习题3,并且只用了shader方法。

    其实要完成任务很简单,只需要把这章的ColoredCube的color.fx中的technique下的pass内部增加以下三个语句之一就OK了:

CullMode = NONE;

CullMode = CCW;

CullMode = CW;

 

    不过,为了更加好玩,我增加了通过用户输入来切换不同的CullMode的方法。这一道题的下载地址参见:

点击打开链接

 

    其实这个代码和第7章的第3题的答案很相像,不过由于用了shader方法,所以变化还是比较明显的。

    本来我想将CullMode作为一个effect parameter传递进fx文件的。其实如果把CullMode作为一个整数进行传递的话是完全没有问题的,但是问题是这里的整数只是作为一个参考值,要利用这个信息的话就要在pass的内部增加if/else语句(或者,更聪明的读者会想到用switch语句);然而非常可惜的是,HLSL语言并不支持在pass内部存在if/else语句。所以我的这种“一蹴而就”的方案就泡汤了。

    没办法,我只好建立了三个不同的technique,然后不把CullMode作为effect parameter,而是在主程序中根据当前的CullMode而采用相应的technique。所以在主程序的updateScene函数内部就需要更新mhTech的值。

    可以想见,这种方法是比较笨拙的:如果需要改变的状态很多,那么technique的数目就会“噌噌噌”地往上升。不过我还没有想到更好的解决方法。不知道聪明的读者你有什么好主意呢?

    

这是程序运行时的三个截图。可以发现,D3DCULL_NONE情形的效果是D3DCUL_CCW的效果是一样的(不确信的话请自己编译然后从各个角度进行观察)。不知道读者朋友能否知道其中的缘由呢?

DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之7: Chap9: Color_第3张图片

DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之7: Chap9: Color_第4张图片

DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之7: Chap9: Color_第5张图片


习题4部分:

 

    这一道题让我们来产生一个方向波。这个很简单,我们在书上原有的ColoredWaves程序基础上、根据9.4.3节的内容进行适当改动就OK了。下面是我写的程序运行时的截图:

DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之7: Chap9: Color_第6张图片

    当然,和书上的有点不一样。这也难怪,因为书上也没有给出这个方向波的表达式。实际上,你也可以改变这些正弦波的振幅、角波数、初相位等等,甚至还可以改变正弦波的数目,达到不同的效果。

 

    这一题的答案的下载地址:

点击打开链接


你可能感兴趣的:(C++,游戏开发,DirectX,游戏编程,习题答案)