DirectX如何构建一个太阳系
基本上都是之前学过的知识,要运用好!总结运用的知识有:1 物体移位选择(transformation)
2 树形数据结构管理整个场景的信息
3 根据时间控制恒星旋转
首先设置太阳系各恒星的数据结构
枚举太阳,恒星和月亮三个对象类
[cpp]
// We classify the objects in our scene as one of three types.
enum SolarType
{
SUN,
PLANET,
MOON
};
数据结构保存各个信息:
[cpp]
struct SolarObject
{
void set(SolarType type, D3DXVECTOR3 p, float yRot,
int parentIndex, float s, IDirect3DTexture9* t)
{
typeID = type;
pos = p;
yAngle = yRot;
parent = parentIndex;
size = s;
tex = t;
}
// Note: The root's "parent" frame is the world space.
SolarType typeID;//据此确定是什么类型,好确定相对应的纹理,大小等。
D3DXVECTOR3 pos; // 相对父母节点的位置.
float yAngle; // 相对父母节点的角度.
int parent; // 父母索引根节点为-1
float size; // 大小就是相对于世界坐标的大小了.
IDirect3DTexture9* tex;
D3DXMATRIX toParentXForm;
D3DXMATRIX toWorldXForm;
};
定义一个数组保存三个节点的信息,含根节点,则需要10个节点,如下:
[cpp]
static const int NUM_OBJECTS = 10;
SolarObject mObject[NUM_OBJECTS];
mObject[j]的父母节点是mObject[mObject[j].parent]。
下面是设置其整个太阳系各个恒星的坐标位置及相关信息的代码:
// Create the textures.
HR(D3DXCreateTextureFromFile(gd3dDevice, "sun.dds", &mSunTex));
HR(D3DXCreateTextureFromFile(gd3dDevice, "planet1.dds", &mPlanet1Tex));
HR(D3DXCreateTextureFromFile(gd3dDevice, "planet2.dds", &mPlanet2Tex));
HR(D3DXCreateTextureFromFile(gd3dDevice, "planet3.dds", &mPlanet3Tex));
HR(D3DXCreateTextureFromFile(gd3dDevice, "moon.dds", &mMoonTex));
D3DXVECTOR3 pos[NUM_OBJECTS] =
{
D3DXVECTOR3(0.0f, 0.0f, 0.0f),
D3DXVECTOR3(7.0f, 0.0f, 7.0f),
D3DXVECTOR3(-9.0f, 0.0f, 0.0f),
D3DXVECTOR3(7.0f, 0.0f, -6.0f),
D3DXVECTOR3(5.0f, 0.0f, 0.0f),
D3DXVECTOR3(-5.0f, 0.0f, 0.0f),
D3DXVECTOR3(3.0f, 0.0f, 0.0f),
D3DXVECTOR3(2.0f, 0.0f, -2.0f),
D3DXVECTOR3(-2.0f, 0.0f, 0.0f),
D3DXVECTOR3(0.0f, 0.0f, 2.0f)
};
mObject[0].set(SUN, pos[0], 0.0f, -1, 2.5f, mSunTex); // Sun
mObject[1].set(PLANET, pos[1], 0.0f, 0, 1.5f, mPlanet1Tex); // P1
mObject[2].set(PLANET, pos[2], 0.0f, 0, 1.2f, mPlanet2Tex); // P2
mObject[3].set(PLANET, pos[3], 0.0f, 0, 0.8f, mPlanet3Tex); // P3
mObject[4].set(MOON, pos[4], 0.0f, 1, 0.5f, mMoonTex); // M1P1
mObject[5].set(MOON, pos[5], 0.0f, 1, 0.5f, mMoonTex); // M2P1
mObject[6].set(MOON, pos[6], 0.0f, 2, 0.4f, mMoonTex); // M1P2
mObject[7].set(MOON, pos[7], 0.0f, 3, 0.3f, mMoonTex); // M1P3
mObject[8].set(MOON, pos[8], 0.0f, 3, 0.3f, mMoonTex); // M2P3
mObject[9].set(MOON, pos[9], 0.0f, 3, 0.3f, mMoonTex); // M3P3
然后根据这些信息构建好各个对象的转换到世界坐标的矩阵。
[cpp]
void SolarSysDemo::buildObjectWorldTransforms()
{
// First, construct the transformation matrix that transforms
// the ith bone into the coordinate system of its parent.
D3DXMATRIX R, T;
D3DXVECTOR3 p;
for(int i = 0; i < NUM_OBJECTS; ++i)
{
p = mObject[i].pos;
D3DXMatrixRotationY(&R, mObject[i].yAngle);
D3DXMatrixTranslation(&T, p.x, p.y, p.z);
mObject[i].toParentXForm = R * T;
}//构建每个节点到父母节点的坐标
// For each object...
for(int i = 0; i < NUM_OBJECTS; ++i)
{
// 跟节点的矩阵.
D3DXMatrixIdentity(&mObject[i].toWorldXForm);
// 循环计算各个节点转换到世界坐标的矩阵.
int k = i;
while( k != -1 ) //-1作为一个标兵,用好标兵技术很好的.
{
mObject[i].toWorldXForm *= mObject[k].toParentXForm;
k = mObject[k].parent; // Move up the ancestry chain.
}
}
}
让太阳系动起来:
[cpp]
void SolarSysDemo::updateScene(float dt)
{
// dt是时间,各个恒星随时间流逝而转动.
for(int i = 0; i < NUM_OBJECTS; ++i)
{
switch(mObject[i].typeID)
{
case SUN:
mObject[i].yAngle += 1.5f * dt;
break;
case PLANET:
mObject[i].yAngle += 2.0f * dt;
break;
&nbs
补充:软件开发 , C++ ,
上一个:从内存角度理解指针和数组(三)
下一个:浮点数的绝对值
- 更多C/C++疑问解答:
- 关于c++的cout输出的问题。
- 在学校里学过C和C++,不过学的很一般,现在自学C#,会不会很难?
- 全国计算机二级C语言笔试题
- 已知某树有2个2度结点,3个3度结点,4个4度结点,问有几个叶子结点?
- c++数据结构内部排序问题,整数排序
- 2012九月计算机二级C语言全国题库,,急求急求
- 如果assert只有一个字符串作为参数,是什么意思呢?
- C语言中,哪些运算符具有左结合性,哪些具有右结合性,帮忙总结下,谢谢了!
- 为什么用结构体编写的程序输入是,0输不出来啊~~~
- 将IEEE—754的十六进制转化为十进制浮点类型,用C或C++都行,多谢各位大侠啊,非常感谢!
- 为什么这个程序求不出公式?
- 这个链表倒置的算法请大家分析下
- c语言函数库调用
- C语言unsigned int纠错
- C语言快排求解啊