游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3718|回复: 10

这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减能

[复制链接]

36

主题

109

帖子

109

积分

注册会员

Rank: 2

积分
109
发表于 2005-6-24 09:59:00 | 显示全部楼层 |阅读模式

void CFrustum::ExtractFrustum( void )
{
        float        proj[16];                                                                        // For Grabbing The PROJECTION Matrix
        float        modl[16];                                                                        // For Grabbing The MODELVIEW Matrix
        float        clip[16];                                                                        // Result Of Concatenating PROJECTION and MODELVIEW
        float        t;                                                                                        // Temporary Work Variable
       
        glGetFloatv( GL_PROJECTION_MATRIX, proj );                        // Grab The Current PROJECTION Matrix
        glGetFloatv( GL_MODELVIEW_MATRIX, modl );                        // Grab The Current MODELVIEW Matrix

        // Concatenate (Multiply) The Two Matricies
        clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
        clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
        clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
        clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];

        clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
        clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
        clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
        clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];

        clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
        clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
        clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
        clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];

        clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
        clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
        clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
        clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];


        // Extract the RIGHT clipping plane
        frustum[0][0] = clip[ 3] - clip[ 0];
        frustum[0][1] = clip[ 7] - clip[ 4];
        frustum[0][2] = clip[11] - clip[ 8];
        frustum[0][3] = clip[15] - clip[12];

        // Normalize it
        t = (float) sqrt( frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2] );
        frustum[0][0] /= t;
        frustum[0][1] /= t;
        frustum[0][2] /= t;
        frustum[0][3] /= t;


        // Extract the LEFT clipping plane
        frustum[1][0] = clip[ 3] + clip[ 0];
        frustum[1][1] = clip[ 7] + clip[ 4];
        frustum[1][2] = clip[11] + clip[ 8];
        frustum[1][3] = clip[15] + clip[12];

        // Normalize it
        t = (float) sqrt( frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2] );
        frustum[1][0] /= t;
        frustum[1][1] /= t;
        frustum[1][2] /= t;
        frustum[1][3] /= t;


        // Extract the BOTTOM clipping plane
        frustum[2][0] = clip[ 3] + clip[ 1];
        frustum[2][1] = clip[ 7] + clip[ 5];
        frustum[2][2] = clip[11] + clip[ 9];
        frustum[2][3] = clip[15] + clip[13];

        // Normalize it
        t = (float) sqrt( frustum[2][0] * frustum[2][0] + frustum[2][1] * frustum[2][1] + frustum[2][2] * frustum[2][2] );
        frustum[2][0] /= t;
        frustum[2][1] /= t;
        frustum[2][2] /= t;
        frustum[2][3] /= t;


        // Extract the TOP clipping plane
        frustum[3][0] = clip[ 3] - clip[ 1];
        frustum[3][1] = clip[ 7] - clip[ 5];
        frustum[3][2] = clip[11] - clip[ 9];
        frustum[3][3] = clip[15] - clip[13];

        // Normalize it
        t = (float) sqrt( frustum[3][0] * frustum[3][0] + frustum[3][1] * frustum[3][1] + frustum[3][2] * frustum[3][2] );
        frustum[3][0] /= t;
        frustum[3][1] /= t;
        frustum[3][2] /= t;
        frustum[3][3] /= t;


        // Extract the FAR clipping plane
        frustum[4][0] = clip[ 3] - clip[ 2];
        frustum[4][1] = clip[ 7] - clip[ 6];
        frustum[4][2] = clip[11] - clip[10];
        frustum[4][3] = clip[15] - clip[14];

        // Normalize it
        t = (float) sqrt( frustum[4][0] * frustum[4][0] + frustum[4][1] * frustum[4][1] + frustum[4][2] * frustum[4][2] );
        frustum[4][0] /= t;
        frustum[4][1] /= t;
        frustum[4][2] /= t;
        frustum[4][3] /= t;


        // Extract the NEAR clipping plane.  This is last on purpose (see pointinfrustum() for reason)
        frustum[5][0] = clip[ 3] + clip[ 2];
        frustum[5][1] = clip[ 7] + clip[ 6];
        frustum[5][2] = clip[11] + clip[10];
        frustum[5][3] = clip[15] + clip[14];

        // Normalize it
        t = (float) sqrt( frustum[5][0] * frustum[5][0] + frustum[5][1] * frustum[5][1] + frustum[5][2] * frustum[5][2] );
        frustum[5][0] /= t;
        frustum[5][1] /= t;
        frustum[5][2] /= t;
        frustum[5][3] /= t;
}






bool CFrustum:ointInFrustum(float x, float y, float z)
{
        int p;
        for( p = 0; p < 6; p++ )
        {
                if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <=0  )
                {
                        return false;
                }
        }

        return true;
}

bool CFrustum::SphereInFrustum(float x, float y, float z, float radius)
{
        int p;

        for( p = 0; p < 6; p++ )
        {
                if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <= -radius )
                        return false;
        }

        return true;
}

bool CFrustum::CuboidInFrustum(vector3d *point1 , vector3d *point2)////////立方体
{
        int i ;
        vector3d vertex[8];
        vertex[0].v[0]=point1->v[0]; vertex[0].v[1]=point1->v[1]; vertex[0].v[2]=point1->v[2];
        vertex[1].v[0]=point1->v[0]; vertex[1].v[1]=point1->v[1]; vertex[1].v[2]=point2->v[2];
        vertex[2].v[0]=point1->v[0]; vertex[2].v[1]=point2->v[1]; vertex[2].v[2]=point1->v[2];
        vertex[3].v[0]=point1->v[0]; vertex[3].v[1]=point2->v[1]; vertex[3].v[2]=point2->v[2];
        vertex[4].v[0]=point2->v[0]; vertex[4].v[1]=point1->v[1]; vertex[4].v[2]=point1->v[2];
        vertex[5].v[0]=point2->v[0]; vertex[5].v[1]=point1->v[1]; vertex[5].v[2]=point2->v[2];
        vertex[6].v[0]=point2->v[0]; vertex[6].v[1]=point2->v[1]; vertex[6].v[2]=point1->v[2];
        vertex[7].v[0]=point2->v[0]; vertex[7].v[1]=point2->v[1]; vertex[7].v[2]=point2->v[2];
        for( i = 0 ; i < 8 ; i++)
        {
                if(PointInFrustum( vertex.x , vertex.y , vertex.z ))
                                return true;
        }
        return false;
}

=======================================


这个是一个3D游戏引擎中,判断一个物体是否在截投体中的数学计算程序,相信大部分的游戏引擎都有这段程序。但我记得我看OpenGL图形学的时候,书中好像说过,OpenGL定义截投体的时候,截投体以外的目标就自动被裁减掉了,是不是这样的呢?请指教。

33

主题

118

帖子

173

积分

注册会员

Rank: 2

积分
173
发表于 2005-6-24 10:30:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

在3D API里都提供clip的功能,但是通常在CPU里还是需要进行frustum culling操作,这是因为首先可以减少AGP的负担,其次是可以在CPU里控制culling的内容,而在API里你是无法控制clip的内容的。

190

主题

1801

帖子

2096

积分

金牌会员

Rank: 6Rank: 6

积分
2096
QQ
发表于 2005-6-24 11:20:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

一个是clip per face, 一个是clip bounding box, 会快点儿

27

主题

379

帖子

829

积分

高级会员

Rank: 4

积分
829
发表于 2005-6-24 13:18:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

带宽是有限的

36

主题

109

帖子

109

积分

注册会员

Rank: 2

积分
109
 楼主| 发表于 2005-6-24 16:52:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

大家说详细一点好吗?可能是我菜鸟的缘故,看的糊里糊涂的。

4

主题

65

帖子

65

积分

注册会员

Rank: 2

积分
65
QQ
发表于 2005-6-24 19:14:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

opengl的是基于每个面的裁剪.而通过计算得到的视锥体,可以一下子将许多不在其中的面裁去.
例如:
bool CFrustum::SphereInFrustum(float x, float y, float z, float radius) 就是判断一个包围球是否在视锥体中.这个球所包含的空间中可能有许多的面.你只需要检测一次就可以了.如果包围球不在视锥体中,里面的面就不再需要渲染了,这样是不是就快了很多.

36

主题

109

帖子

109

积分

注册会员

Rank: 2

积分
109
 楼主| 发表于 2005-6-24 21:11:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

原来这样,厉害,怪我天资愚顿,呵呵。

2

主题

177

帖子

177

积分

注册会员

Rank: 2

积分
177
发表于 2005-6-25 02:58:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

最主要的除了上面的朋友所说的可以自已定义裁减方法,还有就是这样一来你只用将需要显示的图元传送到显卡,可以大大节省总线带宽

36

主题

109

帖子

109

积分

注册会员

Rank: 2

积分
109
 楼主| 发表于 2005-6-25 09:38:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

这里的牛人真是多啊!越来越喜欢这里的论坛了,能学到好多东西。

13

主题

978

帖子

978

积分

高级会员

Rank: 4

积分
978
发表于 2005-6-25 15:11:00 | 显示全部楼层

Re:这段程序都应该看过,但我疑惑的是OpenGL自己没有裁减

再弱弱的问一个问题:ogl的api裁减有硬件支持吗?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-27 07:58

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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