游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3509|回复: 6

一个再简单不过的D3D9的小程序,为什么我的 MESH 变形了呢

[复制链接]

21

主题

112

帖子

118

积分

注册会员

Rank: 2

积分
118
发表于 2008-12-24 09:17:00 | 显示全部楼层 |阅读模式
我在上传了附件
里面有可执行程序和源代码
其实很简单的一个东西,就是一个立方体在窗体内运动,但是当它运动到窗体边缘时,立方体发生了严重的变形。。。
我试过把 MESH 换成别的,比如说“茶壶”,但是依然有这个问题,所以我觉得不是 MESH 本身的问题

大家在看源代码的时候,重点在“d3dxcreatemeshfvf.cpp”文件中的 Setup() 和 Display() 函数,其他的都是一个例题程序里面的,我都没有改动过

其实这个程序是一本书中的源代码,就是让一个立方体在屏幕中间固定,然后旋转,我只不过改变了一下它的X,Y坐标,Z坐标不变,相机也没动,但是它怎么就变形了呢??

注意:运行这个程序,需要安装 2008年8月的 Directx9 SDK,或者单独下载一个“d3dx9d_39.dll”也可以

sf_2008122491638.rar

29.56 KB, 下载次数:

14

主题

77

帖子

83

积分

注册会员

Rank: 2

积分
83
发表于 2008-12-24 21:01:00 | 显示全部楼层

Re:一个再简单不过的D3D9的小程序,为什么我的 MESH 变形

设置投影矩阵的时候,那个D3DXMatrixPerspectiveFovLH函数的视角参数不要太大。越大的视角可视范围越广,但是变形越严重。就像是透过门上的猫眼往外看似的,视角宽广而变形严重。我一般是用45度的。

1

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2008-12-27 17:58:00 | 显示全部楼层

Re:一个再简单不过的D3D9的小程序,为什么我的 MESH 变形

我想是你用的是骨骼动画,
主要是matrix 的变换
首先   要通过  骨骼matrix 变换到骨骼空间,
然后   要通过  TransformMatrix 变换, 可以形成动画,
最后   可以通过 外部的鼠标和键盘形成的CombinationMatrix 变换从而可以进行视角的变换,
一定要注意这3个matrix 的先后顺序,否则变形是肯定的,你研究一下导出x文件就能看到骨骼matrix 和 每个Frame下的TransformMatrix 了, 随时间的变化,TransformMatrix会变化,从而形成动画, 骨骼matrix的作用好象是把连散的空间点按照骨骼的次序进行重新组合,以便TranformMatrix可以起作用,


另外谁有原来的Common文件,就是包含 App类的那个Common,可以发给我吗?
fuiqy0202@163.com, 谢谢

21

主题

112

帖子

118

积分

注册会员

Rank: 2

积分
118
 楼主| 发表于 2008-12-28 00:06:00 | 显示全部楼层

Re:一个再简单不过的D3D9的小程序,为什么我的 MESH 变形

fuiqy0202 兄弟啊。。。
我还没有学到骨骼动画那里去啊。。。
这个立方体,是直接用 D3DXCreateMeshFVF 创建的。。。。
就是通过自己创建若干个顶点来实现的一个基本的MESH,骨骼动画完全没有涉及到。。
这是创建立方体的代码:

  1. bool Setup()
  2. {
  3.         HRESULT hr = 0;

  4.         //
  5.         // We are going to fill the empty mesh with the geometry of a box,
  6.         // so we need 12 triangles and 24 vetices.
  7.         //

  8.         hr = D3DXCreateMeshFVF(
  9.                 12,
  10.                 24,
  11.                 D3DXMESH_MANAGED,
  12.                 Vertex::FVF,
  13.                 Device,
  14.                 &Mesh);

  15.         if(FAILED(hr))
  16.         {
  17.                 ::MessageBox(0, "D3DXCreateMeshFVF() - FAILED", 0, 0);
  18.                 return false;
  19.         }

  20.         //
  21.         // Fill in vertices of a box
  22.         //
  23.         Vertex* v = 0;
  24.         Mesh->LockVertexBuffer(0, (void**)&v);

  25.         // fill in the front face vertex data
  26.         v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
  27.         v[1] = Vertex(-1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
  28.         v[2] = Vertex( 1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
  29.         v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

  30.         // fill in the back face vertex data
  31.         v[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
  32.         v[5] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f);
  33.         v[6] = Vertex( 1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
  34.         v[7] = Vertex(-1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);

  35.         // fill in the top face vertex data
  36.         v[8]  = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
  37.         v[9]  = Vertex(-1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
  38.         v[10] = Vertex( 1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);
  39.         v[11] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);

  40.         // fill in the bottom face vertex data
  41.         v[12] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
  42.         v[13] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f);
  43.         v[14] = Vertex( 1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f);
  44.         v[15] = Vertex(-1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);

  45.         // fill in the left face vertex data
  46.         v[16] = Vertex(-1.0f, -1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
  47.         v[17] = Vertex(-1.0f,  1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
  48.         v[18] = Vertex(-1.0f,  1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
  49.         v[19] = Vertex(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

  50.         // fill in the right face vertex data
  51.         v[20] = Vertex( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
  52.         v[21] = Vertex( 1.0f,  1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
  53.         v[22] = Vertex( 1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
  54.         v[23] = Vertex( 1.0f, -1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

  55.         Mesh->UnlockVertexBuffer();

  56.         //
  57.         // Define the triangles of the box
  58.         //
  59.         WORD* i = 0;
  60.         Mesh->LockIndexBuffer(0, (void**)&i);

  61.         // fill in the front face index data
  62.         i[0] = 0; i[1] = 1; i[2] = 2;
  63.         i[3] = 0; i[4] = 2; i[5] = 3;

  64.         // fill in the back face index data
  65.         i[6] = 4; i[7]  = 5; i[8]  = 6;
  66.         i[9] = 4; i[10] = 6; i[11] = 7;

  67.         // fill in the top face index data
  68.         i[12] = 8; i[13] =  9; i[14] = 10;
  69.         i[15] = 8; i[16] = 10; i[17] = 11;

  70.         // fill in the bottom face index data
  71.         i[18] = 12; i[19] = 13; i[20] = 14;
  72.         i[21] = 12; i[22] = 14; i[23] = 15;

  73.         // fill in the left face index data
  74.         i[24] = 16; i[25] = 17; i[26] = 18;
  75.         i[27] = 16; i[28] = 18; i[29] = 19;

  76.         // fill in the right face index data
  77.         i[30] = 20; i[31] = 21; i[32] = 22;
  78.         i[33] = 20; i[34] = 22; i[35] = 23;

  79.         Mesh->UnlockIndexBuffer();

  80.         //
  81.         // Specify the subset each triangle belongs to, in this example
  82.         // we will use three subsets, the first two faces of the cube specified
  83.         // will be in subset 0, the next two faces will be in subset 1 and
  84.         // the the last two faces will be in subset 2.
  85.         //
  86.         DWORD* attributeBuffer = 0;
  87.         Mesh->LockAttributeBuffer(0, &attributeBuffer);

  88.         for(int a = 0; a < 4; a++)
  89.                 attributeBuffer[a] = 0;

  90.         for(int b = 4; b < 8; b++)
  91.                 attributeBuffer[b] = 1;

  92.         for(int c = 8; c < 12; c++)
  93.                 attributeBuffer[c] = 2;

  94.         Mesh->UnlockAttributeBuffer();

  95.         //
  96.         // Optimize the mesh to generate an attribute table.
  97.         //

  98.         std::vector<DWORD> adjacencyBuffer(Mesh->GetNumFaces() * 3);
  99.         Mesh->GenerateAdjacency(0.0f, &adjacencyBuffer[0]);

  100.         hr = Mesh->OptimizeInplace(               
  101.                 D3DXMESHOPT_ATTRSORT |
  102.                 D3DXMESHOPT_COMPACT  |
  103.                 D3DXMESHOPT_VERTEXCACHE,
  104.                 &adjacencyBuffer[0],
  105.                 0, 0, 0);

  106.         //
  107.         // Load the textures and set filters.
  108.         //

  109.         D3DXCreateTextureFromFile(
  110.                 Device,
  111.                 "brick0.jpg",
  112.                 &Textures[0]);

  113.         D3DXCreateTextureFromFile(
  114.                 Device,
  115.                 "brick1.jpg",
  116.                 &Textures[1]);

  117.         D3DXCreateTextureFromFile(
  118.                 Device,
  119.                 "checker.jpg",
  120.                 &Textures[2]);

  121.         Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  122.         Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  123.         Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

  124.         //
  125.         // Disable lighting.
  126.         //

  127.         Device->SetRenderState(D3DRS_LIGHTING, false);

  128.         //
  129.         // Set camera.
  130.         //

  131.         D3DXVECTOR3 pos(0.0f, 0.f, -4.0f);
  132.         D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
  133.         D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

  134.         D3DXMATRIX V;
  135.         D3DXMatrixLookAtLH(
  136.                 &V,
  137.                 &pos,
  138.                 &target,
  139.                 &up);

  140.         Device->SetTransform(D3DTS_VIEW, &V);

  141.         //
  142.         // Set projection matrix.
  143.         //

  144.         D3DXMATRIX proj;
  145.         D3DXMatrixPerspectiveFovLH(
  146.                         &proj,
  147.                         D3DX_PI * 0.5f, // 90 - degree
  148.                         (float)Width / (float)Height,
  149.                         1.0f,
  150.                         1000.0f);
  151.         Device->SetTransform(D3DTS_PROJECTION, &proj);

  152.         return true;
  153. }
复制代码

21

主题

112

帖子

118

积分

注册会员

Rank: 2

积分
118
 楼主| 发表于 2008-12-29 14:15:00 | 显示全部楼层

Re:一个再简单不过的D3D9的小程序,为什么我的 MESH 变形

“核心”兄弟正解:
我按照你说的试了一下,把D3DXMatrixPerspectiveFovLH的角度由90度,改为45度,果然没有变形的问题了,你真是厉害啊。。。。

不过我还有一个题外话,人体双眼的视觉范围肯定要大于45度,那象CS这种第一人称射击游戏,它的视角应该设置为多大呢??需要完全模仿人的生理特征,设置一个很大的视角吗???

14

主题

77

帖子

83

积分

注册会员

Rank: 2

积分
83
发表于 2008-12-29 23:20:00 | 显示全部楼层

Re:一个再简单不过的D3D9的小程序,为什么我的 MESH 变形

我可不厉害……人眼视角是可变的。人的每只眼睛视角最大有120度(当观看开阔景物的时候),但是人通常只注意视野中心的部分,外侧的变形、模糊又不为人注意,只能算余光,能瞥见一些黑影什么的。
当人聚精会神盯着一个东西看的时候,视角只有25度左右。我觉得没必要较真,设置一个自己感觉舒服的就行了。

21

主题

112

帖子

118

积分

注册会员

Rank: 2

积分
118
 楼主| 发表于 2008-12-30 08:44:00 | 显示全部楼层

Re:一个再简单不过的D3D9的小程序,为什么我的 MESH 变形

哦。。。原来人聚精会神看东西的时候,视角只有25度啊。。。
我刚去 GOOGLE 了一下,人的左右双眼,视角还不一样。。。。

右眼:向右看:61.1±0.22,向左看:92.6±0.23,向上看:48.5±0.24,向下看:65.5±0.24
左眼:向左看:59.9±0.25,向右看:93.9±0.21,向上看:49.6±0.20,向下看:66.0±0.25

以上数字单位为“度”。。。

以后统一设置成45度就绰绰有余了,嘿嘿
核心兄弟,难道你是学医的。。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-20 14:34

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表