Search Results for 'Frustum Culling'

ATOM Icon

1 POSTS

  1. 2006/03/21 Frustum Culling by chungki

Frustum Culling

Frustum Culling은 많이 공개되어서 특별한 것은 없지만 단지 Directx와 Opengl에서 구현할 때  행렬문제로 인해 실수가 경우가 많다.  그래서 OpenGL 구현코드를 직접 적는다.

행렬을 아래와 같이 정의한다. t_를 붙인 이유는 보통 행행렬을 많이 사용하지만 OpenGL에서는 열행렬이기 때문에 transpose라는 의미에서 t_라고 붙였다.

 

 

 

struct TMATRIX16

  1. {  
  2. union  
  3. {         
  4. struct   {           float t_m11,t_m21,t_m31,t_m41;
  5.                      float t_m12,t_m22,t_m32,t_m42;
  6.                      float t_m13,t_m23,t_m33,t_m43;
  7.                      float t_m14,t_m24,t_m34,t_m44;
  8.           };           
  9.    float  m_MX[16];    
  10.    };
  11. };



현재 세팅된 Projection Matrix와 ModelViewMatrix를 가져온다.

  1. TMATRIX16 mxModelView, mxProjView;
  2. ::glGetFloatv(GL_MODELVIEW_MATRIX,mxModelView.m_MX); ::glGetFloatv(GL_PROJECTION_MATRIX,mxProjView.m_MX);



많이 실수한 경우인데
Frustum Matrix = ModelView Matrix * Projection Matrix 순서로 해야 한다.
이 순서를 바꾸어서 하는 바람에 Culling계산이 잘 안되는 원인을 찾기 힘들었다.

TMATRIX16 mxFrustum;
MultiMatrix(mxModelView, mxProjView, mxFrustum);


Frustum 의 면을 정의한다.
 typedef struct tagFrustumPlane
{
    union
    {
         struct
         {
              float x;
              float y;
              float z;
              float d;
         };
         float _m[4];
    };
} FRUSTUM_PLANE;

typedef enum emViewPlane
{
    VP_LEFT,
    VP_RIGHT,
    VP_TOP,
    VP_BOTTOM,
    VP_NEAR,
    VP_FAR,
};


6면을 계산한다.
 _Plans[VP_LEFT].x=mxFrustum.t_m41+mxFrustum.t_m11;
_Plans[VP_LEFT].y=mxFrustum.t_m42+mxFrustum.t_m12;
_Plans[VP_LEFT].z=mxFrustum.t_m43+mxFrustum.t_m13;
_Plans[VP_LEFT].d=mxFrustum.t_m44+mxFrustum.t_m14;

_Plans[VP_RIGHT].x=mxFrustum.t_m41-mxFrustum.t_m11;
_Plans[VP_RIGHT].y=mxFrustum.t_m42-mxFrustum.t_m12;
_Plans[VP_RIGHT].z=mxFrustum.t_m43-mxFrustum.t_m13;
_Plans[VP_RIGHT].d=mxFrustum.t_m44-mxFrustum.t_m14;

// _Plans[VP_TOP].x=mxFrustum.t_m41-mxFrustum.t_m21; _Plans[VP_TOP].y=mxFrustum.t_m42-mxFrustum.t_m22; _Plans[VP_TOP].z=mxFrustum.t_m43-mxFrustum.t_m23; _Plans[VP_TOP].d=mxFrustum.t_m44-mxFrustum.t_m24;

_Plans[VP_BOTTOM].x=mxFrustum.t_m41+mxFrustum.t_m21; _Plans[VP_BOTTOM].y=mxFrustum.t_m42+mxFrustum.t_m22; _Plans[VP_BOTTOM].z=mxFrustum.t_m43+mxFrustum.t_m23; _Plans[VP_BOTTOM].d=mxFrustum.t_m44+mxFrustum.t_m24;

_Plans[VP_NEAR].x=mxFrustum.t_m41+mxFrustum.t_m31; _Plans[VP_NEAR].y=mxFrustum.t_m42+mxFrustum.t_m32; _Plans[VP_NEAR].z=mxFrustum.t_m43+mxFrustum.t_m33; _Plans[VP_NEAR].d=mxFrustum.t_m44+mxFrustum.t_m34;

_Plans[VP_FAR].x=mxFrustum.t_m41-mxFrustum.t_m31; _Plans[VP_FAR].y=mxFrustum.t_m42-mxFrustum.t_m32; _Plans[VP_FAR].z=mxFrustum.t_m43-mxFrustum.t_m33; _Plans[VP_FAR].d=mxFrustum.t_m44-mxFrustum.t_m34;



Frustum의 6면을 구하였다. 이제 작업해야 할것은 이 6면이 이루는 Frustum의 공간안에 우리가 그리고자 하는 물체가 포함하는가 아닌가를 판단해야하는 일이다.
제일 기본이 Point(점)이기 때문에 한 점이 Frustum 내부에 있나 외부에 있나만을 확인 할수 있으면 된다. Point(점)만 확인가능하면 Sphere(구), Cubic(직육면체)도 확인할 수 있다.

확인하는 방법은 면과 점의 거리 정확히 얘기하면 면의 앞쪽에 있는지 뒤쪽에 있는지를 확인하면 된다. 즉 면과 점의 거리르 계산해서 +이면 면의 앞쪽에 있는 것이고 -이면 면의 뒤쪽에 있는 것이 된다.

그러므로  Frustum의 6면과  점의 거리를 계산해서 모두 + 이면 Frustum안에 있는 거라고 할 수 있다.


Posted by chungki

2006/03/21 18:03 2006/03/21 18:03
, ,
Response
No Trackback , No Comment
RSS :
http://www.chungki.net/tc/rss/response/200


블로그 이미지

Nice !!!!!!!!

- chungki

Notices

Archives

Authors

  1. chungki

Calendar

«   2012/05   »
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Site Stats

Total hits:
73375
Today:
6
Yesterday:
20