游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4661|回复: 11

求3d透视投影后对齐次齐坐标裁减算法的内容

[复制链接]

190

主题

1801

帖子

2096

积分

金牌会员

Rank: 6Rank: 6

积分
2096
QQ
发表于 2006-7-30 10:07:00 | 显示全部楼层 |阅读模式
代码或者文章都可,谢谢

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2006-7-30 18:43:00 | 显示全部楼层

Re:求3d透视投影后对齐次齐坐标裁减算法的内容

《3D图形学原理与算法》

190

主题

1801

帖子

2096

积分

金牌会员

Rank: 6Rank: 6

积分
2096
QQ
 楼主| 发表于 2006-7-30 21:55:00 | 显示全部楼层

Re:求3d透视投影后对齐次齐坐标裁减算法的内容

没这书啊,难道去书店抄嘛?

1

主题

43

帖子

43

积分

注册会员

Rank: 2

积分
43
发表于 2006-8-9 18:45:00 | 显示全部楼层

Re:求3d透视投影后对齐次齐坐标裁减算法的内容

既然已经“3d透视投影后对齐次齐坐标”,为什么还要3D裁减,打算裁减什么。
另外裁减都是显卡的工作了. 把cpu节省下来做高一级的场景管理或其他而不是裁减
几何体。

190

主题

1801

帖子

2096

积分

金牌会员

Rank: 6Rank: 6

积分
2096
QQ
 楼主| 发表于 2006-8-9 23:23:00 | 显示全部楼层

Re:求3d透视投影后对齐次齐坐标裁减算法的内容

没有显卡,底层实现,谢谢

1

主题

43

帖子

43

积分

注册会员

Rank: 2

积分
43
发表于 2006-8-10 01:52:00 | 显示全部楼层

Re: 求3d透视投影后对齐次齐坐标裁减算法的内容

哈哈。
我给你tricks 3d的代码吧,不知道能不能满足你。
softe:软件ddraw写的render,t3dlib8.cpp估计就是你要的。
clip:     一个立方体的clip测试。在release下,直接运行。
代码在vc6 sp5 + xp sp2 psdk + dx9(2002 12 19)编译过。

1

主题

43

帖子

43

积分

注册会员

Rank: 2

积分
43
发表于 2006-8-10 01:54:00 | 显示全部楼层

Re: 求3d透视投影后对齐次齐坐标裁减算法的内容

。。。
附件怎么上传不了,晕,我不大会论坛的 [em4]

190

主题

1801

帖子

2096

积分

金牌会员

Rank: 6Rank: 6

积分
2096
QQ
 楼主| 发表于 2006-8-10 22:22:00 | 显示全部楼层

Re:求3d透视投影后对齐次齐坐标裁减算法的内容

谢谢你,恐怕我看不懂这样的代码,没有win32的基础,我有一些实现代码的,但是这些代码都没有原理解释,一大堆数字很难看懂

190

主题

1801

帖子

2096

积分

金牌会员

Rank: 6Rank: 6

积分
2096
QQ
 楼主| 发表于 2006-8-10 22:24:00 | 显示全部楼层

Re:求3d透视投影后对齐次齐坐标裁减算法的内容

3d线段裁减我写出来了,我现在搞不明白齐次坐标怎么写,新的坐标怎么生成

29

主题

157

帖子

163

积分

注册会员

Rank: 2

积分
163
发表于 2006-8-12 19:35:00 | 显示全部楼层

Re:求3d透视投影后对齐次齐坐标裁减算法的内容

在很多计算机图形学的书后面的附录里都有写~
透视投影生成的矩阵R(如:OpenGL中的glFrustum( l, r, b, t, n ,f)  ):

                   | 2n/(r-l),            0,       (r+l)/(r-l),                0|
  R =            |         0,   2n/(t-b),    (t+b)/(t-b),                0|
                   |         0,            0,    -(f+n)/(f-n),     -2fn/(f-n)|
                   |         0,            0,                 -1,                0|

仅当 l != r, t != b, n != f 时, 矩阵R才存在

然后通过几个矩阵求出组成视锥的6个剪切面的平面方程的系数, 将要剪切的点分别代入6个方程, 如果值大于0,则点在视锥之外,小于0在视锥之内, 等于0则在剪切面上.

//获得剪切板6个面的方程系数
void CCamera::UpdateFrustumClipBoard()
{
   GLfloat   clip[16];    //用来存储剪切矩阵
   GLfloat   proj[16];   //用来存储投影矩阵
   GLfloat   modl[16];  //用来存储模型-视点矩阵
   GLfloat   t;

   // 获得当前的投影矩阵
   glGetFloatv( GL_PROJECTION_MATRIX, proj );

   // 获得当前的模型-视点矩阵
   glGetFloatv( GL_MODELVIEW_MATRIX, modl );

   //用模型矩阵乘以投影矩阵得到剪切矩阵
      clip[ 0] = modl[ 0] * proj[ 0];
      clip[ 1] = modl[ 1] * proj[ 5];
      clip[ 2] = modl[ 2] * proj[10] + modl[ 3] * proj[14];
      clip[ 3] = modl[ 2] * proj[11];
      
      clip[ 4] = modl[ 4] * proj[ 0];
      clip[ 5] = modl[ 5] * proj[ 5];
      clip[ 6] = modl[ 6] * proj[10] + modl[ 7] * proj[14];
      clip[ 7] = modl[ 6] * proj[11];
      
      clip[ 8] = modl[ 8] * proj[ 0];
      clip[ 9] = modl[ 9] * proj[ 5];
      clip[10] = modl[10] * proj[10] + modl[11] * proj[14];
      clip[11] = modl[10] * proj[11];
      
      clip[12] = modl[12] * proj[ 0];
      clip[13] = modl[13] * proj[ 5];
      clip[14] = modl[14] * proj[10] + modl[15] * proj[14];
      clip[15] = modl[14] * proj[11];
      
      // 获得右剪切面的系数
      m_Frustum[0][0] = clip[ 3] - clip[ 0];
      m_Frustum[0][1] = clip[ 7] - clip[ 4];
      m_Frustum[0][2] = clip[11] - clip[ 8];
      m_Frustum[0][3] = clip[15] - clip[12];
      
       // 把结果单位化
      t = GLfloat(sqrt( m_Frustum[0][0] * m_Frustum[0][0] + m_Frustum[0][1] *
                             m_Frustum[0][1] + m_Frustum[0][2] * m_Frustum[0][2] ));
      m_Frustum[0][0] /= t;
      m_Frustum[0][1] /= t;
      m_Frustum[0][2] /= t;
      m_Frustum[0][3] /= t;
      
       // 获得左剪切面的系数
      m_Frustum[1][0] = clip[ 3] + clip[ 0];
      m_Frustum[1][1] = clip[ 7] + clip[ 4];
      m_Frustum[1][2] = clip[11] + clip[ 8];
      m_Frustum[1][3] = clip[15] + clip[12];
      
       // 把结果单位化
      t = GLfloat(sqrt( m_Frustum[1][0] * m_Frustum[1][0] + m_Frustum[1][1] *  
                                m_Frustum[1][1] + m_Frustum[1][2] * m_Frustum[1][2] ));
      m_Frustum[1][0] /= t;
      m_Frustum[1][1] /= t;
      m_Frustum[1][2] /= t;
      m_Frustum[1][3] /= t;
      
      // 获得下剪切面的系数
      m_Frustum[2][0] = clip[ 3] + clip[ 1];
      m_Frustum[2][1] = clip[ 7] + clip[ 5];
      m_Frustum[2][2] = clip[11] + clip[ 9];
      m_Frustum[2][3] = clip[15] + clip[13];
      
      // 把结果单位化
      t = GLfloat(sqrt( m_Frustum[2][0] * m_Frustum[2][0] + m_Frustum[2][1] *
                                  m_Frustum[2][1] + m_Frustum[2][2] * m_Frustum[2][2] ));
      m_Frustum[2][0] /= t;
      m_Frustum[2][1] /= t;
      m_Frustum[2][2] /= t;
      m_Frustum[2][3] /= t;
      
      // 获得上剪切面的系数
      m_Frustum[3][0] = clip[ 3] - clip[ 1];
      m_Frustum[3][1] = clip[ 7] - clip[ 5];
      m_Frustum[3][2] = clip[11] - clip[ 9];
      m_Frustum[3][3] = clip[15] - clip[13];
      
      // 把结果单位化
      t = GLfloat(sqrt( m_Frustum[3][0] * m_Frustum[3][0] + m_Frustum[3][1] *
                                  m_Frustum[3][1] + m_Frustum[3][2] * m_Frustum[3][2] ));
      m_Frustum[3][0] /= t;
      m_Frustum[3][1] /= t;
      m_Frustum[3][2] /= t;
      m_Frustum[3][3] /= t;
      
      // 获得远剪切面的系数
      m_Frustum[4][0] = clip[ 3] - clip[ 2];
      m_Frustum[4][1] = clip[ 7] - clip[ 6];
      m_Frustum[4][2] = clip[11] - clip[10];
      m_Frustum[4][3] = clip[15] - clip[14];
      
       // 把结果单位化
      t = GLfloat(sqrt( m_Frustum[4][0] * m_Frustum[4][0] + m_Frustum[4][1] *
                                  m_Frustum[4][1] + m_Frustum[4][2] * m_Frustum[4][2] ));
      m_Frustum[4][0] /= t;
      m_Frustum[4][1] /= t;
      m_Frustum[4][2] /= t;
      m_Frustum[4][3] /= t;
      
      // 获得近剪切面的系数
      m_Frustum[5][0] = clip[ 3] + clip[ 2];
      m_Frustum[5][1] = clip[ 7] + clip[ 6];
      m_Frustum[5][2] = clip[11] + clip[10];
      m_Frustum[5][3] = clip[15] + clip[14];
      
      // 把结果单位化
      t = GLfloat(sqrt( m_Frustum[5][0] * m_Frustum[5][0] + m_Frustum[5][1] *
                       m_Frustum[5][1] + m_Frustum[5][2] * m_Frustum[5][2] ));
      m_Frustum[5][0] /= t;
      m_Frustum[5][1] /= t;
      m_Frustum[5][2] /= t;
      m_Frustum[5][3] /= t;
}


//判断点是否在视锥之内,是则返回TRUE
bool CCamera:ointInFrustum(GLfloat x, GLfloat y, GLfloat z, GLfloat fRadius, int nMode)
{

      for(int i = 0; i < 6; i++)
      {
           //判断点与平面的关系
            if(m_Frustum[0] * x + m_Frustum[1] * y + m_Frustum[2] * z +
                                              m_Frustum[3] <= -fRadius)
            {
        return(FALSE);
             }

        }

        return(TRUE);

}

就是这样了, 如果你数学不错的话, 那么你可以把那两个矩阵写出来,然后按照这种法则写一下,应该会弄懂, 如果你知道了为什么要这样写, 请告诉我, 我到现在也每弄明白呢.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-25 03:43

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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