问题2-D3D Color

ncopy.gif


这次是学习DX中对颜色的处理。使用ColorVertex这种结构体保存带有染色的顶点,然后对物体进行渲染。

问题描述:

在窗口中显示两个立方体,其中一个使用D3DSHADE_GOURAUD渲染模式,一个使用D3DSHADE_FLAT渲染模式;并且使两个立方体各自绕X,Y,Z轴自转的同时,两个立方体同时绕Y轴公转。

color.jpg

为了要使用带颜色的定点,我们可以先在头文件里定义颜色常量,

const D3DXCOLOR WHITE( D3DCOLOR_XRGB(255, 255, 255) );
const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) );


可以像这样定义自己想要的颜色。然后定义带颜色的顶点:

struct ColorVertex
{
ColorVertex(){}
ColorVertex(float x,float y,float z,D3DCOLOR c)
{
_x = x;
_y = y;
_z = z;
_color = c;
}
float _x,_y,_z;
D3DCOLOR _color;
static const DWORD FVF;
};
const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;


这里的结构和不带颜色的定点结构是一样的,只不过就多了一个color参数。这种定点的结构也可以当成公式一样记忆下来。要画出一个立方体,我们这里要使用设备的CreateVertexBuffer和CreateIndexBuffer,这里要注意一点,一个立方体有8个顶点,所以我们的顶点数是8,但是index的话,就有36个了,立方体是6个面,一个面是6个index,因为在画每一个面的时候,是用2个三角形组合而成的,每个三角形都要用3个index,在一个四边形中画条对角线,就可以知道了,2个三角形,虽然2个顶点是一样的,但是还是要算在总数里面,所以6×6就是36个index。

Device->CreateVertexBuffer(
8 * sizeof(ColorVertex),
D3DUSAGE_WRITEONLY,
ColorVertex::FVF,
D3DPOOL_MANAGED,
&VB,
0);
ColorVertex* v;

VB->Lock(0,0,(void**)&v,0);

v[0] = ColorVertex(-1.0f, -1.0f, -1.0f, d3d::BLUE);
v[1] = ColorVertex(-1.0f, 1.0f, -1.0f, d3d::PURPLE);
v[2] = ColorVertex( 1.0f, 1.0f, -1.0f, d3d::RED);
v[3] = ColorVertex( 1.0f, -1.0f, -1.0f, d3d::MAGENTA);
v[4] = ColorVertex(-1.0f, -1.0f, 1.0f, d3d::CYAN);
v[5] = ColorVertex(-1.0f, 1.0f, 1.0f, d3d::GREEN);
v[6] = ColorVertex( 1.0f, 1.0f, 1.0f, d3d::YELLOW);
v[7] = ColorVertex( 1.0f, -1.0f, 1.0f, d3d::WHITE);

VB->Unlock();


Device->CreateIndexBuffer(
36 * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&IB,
0);

WORD* indices = 0;
IB->Lock(0, 0, (void**)&indices, 0);

// front side
indices[0] = 0; indices[1] = 1; indices[2] = 2;
indices[3] = 0; indices[4] = 2; indices[5] = 3;

// back side
indices[6] = 4; indices[7] = 6; indices[8] = 5;
indices[9] = 4; indices[10] = 7; indices[11] = 6;

// left side
indices[12] = 4; indices[13] = 5; indices[14] = 1;
indices[15] = 4; indices[16] = 1; indices[17] = 0;

// right side
indices[18] = 3; indices[19] = 2; indices[20] = 6;
indices[21] = 3; indices[22] = 6; indices[23] = 7;

// top
indices[24] = 1; indices[25] = 5; indices[26] = 6;
indices[27] = 1; indices[28] = 6; indices[29] = 2;

// bottom
indices[30] = 4; indices[31] = 0; indices[32] = 3;
indices[33] = 4; indices[34] = 3; indices[35] = 7;

IB->Unlock();


上面的代码就是分别设置顶点缓冲和index缓冲,VB,IB分别是

IDirect3DVertexBuffer9* VB = 0;
IDirect3DIndexBuffer9* IB = 0;


在设置顶点和index前一定要调用Lock方法,在设置完成后也一定要Unlock。还有一点要注意的地方,就是在设置index的时候,顺序是有讲究的,也就是说所有三角形(也就是indices[0] = 0; indices[1] = 1; indices[2] = 2;这里决定的三角形)画线的方向必须一致。也就是说所有三角形都是顺时针方向或都是反时针方向。

立方体画好了后,就要设置它的旋转了。上篇文章中已经讲了绕轴自转的方法。这里主要说一下公转的方法。其实公转和简单,我之前也搞不懂,想了很久,在网上问了很多朋友,还是没有解决,最后在一次不经意的测试中发现了公转的秘密。呵呵~

前面说过了,让物体在替他坐标点自转,需要用平移向量点乘旋转向量,而且要注意方向,也就是平移向量要放在前面,如果这2个顺序换一下,把旋转向量放在前面,会出现什么结果呢??答案正是我们想要的公转!所以这里我们只需要交换点乘前后参数的位子就可以了。比如:

D3DXMatrixMultiply(&Position1,&Position1, &Ry);

这样就可以让物体绕Y轴公转,公转后再让物体自转就可以到达我们的要求了。

最后在窗口中显示物体(当然设定投影和摄像机这里省略了):

Device->SetStreamSource(0, VB, 0, sizeof(ColorVertex));
Device->SetIndices(IB);
Device->SetFVF(ColorVertex::FVF);

Device->SetTransform(D3DTS_WORLD,&Position1);
Device->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD);
Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);


要显示另一个立方体,再使用后面三句就可以了,不过要改变显示的坐标哦。程序完成后,就可以看到2种不同渲染方法的差别了。

*原创文章,转载请注明出处*

发表留言

只对管理者显示

No title

斜体の文你好!刚进来看了一下,真是眼花燎乱啊!看不懂,感觉你好厉害只能佩服了,
自我介绍

Author:三只熊熊
大家好,欢迎来到我的blog!
目前我正在韩国攻读游戏工学研究生,现在在虚拟现实实验室。
作为刚踏入游戏开发领域的初学者,希望大家多多帮助!

잘 부탁드립니다~ ^_^

最新文章
最新留言
最新引用
月份存档
类别
计数器
搜寻栏
RSS连结
连结
Powered By FC2博客

马上开始博客吧!!

Powered By FC2博客