BLOG main image
FunnyPR (32)
OpenGL (20)
PatternRecognition (7)
Tips (2)
XML (1)
DataMining (1)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
'FunnyPR'에 해당되는 글 32건
2014. 4. 20. 16:30

◆ OpenGL:  gluPerspective


원근 투영 방법


gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
 - 멀고 가까움을 표현함
 - gluPerspective(시야각, 종횡비, 전방전달면, 후방절단면)
   ex) gluPerspective(45.0, width/height, 1.0, 400.0);


void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far )



http://warmz.tistory.com/440


시야(FOV: Field of View):상하 y축 방향의 시야각(0 -180도) 

X축 방향의 시야는 종횡비(Aspect Ratio)에 의해 결정됨(폭 / 높이)




'OpenGL' 카테고리의 다른 글

OpenGL: Index of Vertex Array  (0) 2014.05.04
OpenGL: Geometric and Vertex  (0) 2014.05.04
OpenGL: Setting Viewport  (0) 2014.04.19
OpenGL: Setting Clipping region  (0) 2014.04.19
OpenGL: Basic knowledge for 3D programing  (0) 2014.04.19
2014. 4. 19. 20:40

◆ OPENGL - 뷰포트 설정


뷰포트를 설정하는 함수는 다음과 같다.

1
void glViewport(GLint xTopLeft, GLint yTopLeft, GLsizei width, GLsizei height)

 


xTopLeft, yTopLeft: 창 내에 위치한 뷰포트의 좌측 하단 좌표를 의미

width, height: 뷰포트의 너비와 높이 

2014. 4. 19. 20:34

◆ OPENGL - 클리핑 영역 설정


클리핑 영역을 조정하여 종횡비가 맞는 정사작형으로 만드는 일

aspect rate(종횡비): 아래 viewport에 보면 종횡비 aspect ratio = w/h 로 계산된다. 


http://www3.ntu.edu.sg/home/ehchua/programming/opengl/CG_Introduction.html


종횡비가 1일 경우 정사각형이며, 0.5일 경우 가로 2 세로가 1이기 때문에 가로가 늘려진 사각형임을 알 수 있음


뷰포트가 정사각형이 아닌 상태에서 정사각형 클리핑 영역을 매핑하게 되면 찌그러지게 되므로 적절한 클리핑 영역 설정을 통해 종횡비를 맞춰야 함


직교 투영 방식에서의 클리핑 영역 설정 방법

1
void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal);


3D 좌표계에서 

left와 right는 x축의 최솟값과 최댓값

bottom, top는 y축의 최솟값과 최댓값

near, far: z축의  최솟값과 최댓값

z 축의 경우 값이 작아질수록 관측자로 부터 멀어짐을 의미




http://warmz.tistory.com/440


두 그림을 비교해 보면 x 축의 최댓값과 최솟값이 변화여 viewport에 보이는 사각형이 비율에 따라 줄어든것을 확인할 수 있다. 아래 그림 두번째 보면 glOrtho에서 사용되는 변수들의 위치를 확인할 수 있다. 

즉, Viewport를 설정해 그릴 화면 영역을 잡고 x,y,z 종횡비를 설정하여 어떻게 투영해서 보여 줄것인가를 결정하면 된다. 


http://potatoland.org/glart/week3/


http://www.pling.org.uk/cs/cgv.html


투영함수 이전에 다음 두 함수 사용

1
2
3
   // Reset coordinate system
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();


glMatrixMode 함수는 투영을 위한 행렬 변환을 하는 부분

glLoadIdentity 함수는 행렬 처리가 이루어지기 전에 좌표계를 초기화 하는 역할을 함

    - glOrtho의 작동 방식이 새로운 클리핑 영역을 만는 것이 아니라 기존의 클리핑 영역과 행렬을 곱한 값을 새로운 클리핑 영역으로 지정하기 때문임


glOrtho 호출 전에 좌표를 초기화 하는 과정이 필요함을 알아 두자.


glOrtho를 호출 후 다음 두 함수 사용됨


1
2
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


------------

정사각형 유지를 위한 클리핑 영역 설정 

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
///////////////////////////////////////////////////////////
// Called by GLUT library when the window has chanaged size
void ChangeSize(int w, int h)
    {
    GLfloat aspectRatio;
 
    // Prevent a divide by zero
    if(h == 0)
        h = 1;
        
    // Set Viewport to window dimensions
    glViewport(0, 0, w, h);
 
    // Reset coordinate system
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
 
    // Establish clipping volume (left, right, bottom, top, near, far)
    aspectRatio = (GLfloat)w / (GLfloat)h;
    if (w <= h) 
        glOrtho (-100.0, 100.0, -100 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);
    else 
        glOrtho (-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0);
 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    }
 






2014. 4. 19. 18:12

◆ OPENGL - 3D 프로그래밍을 위한 기본적인 지식들 


실시간 3D 그래픽을 위한 API 프로그래밍 방식은 크게 두 가지로 나뉨

1. 보류 모드(Retained Mode)

- 물체나 장면에 대한 정보를 API 또는 툴킷에 제공

- API 또는 툴킷은 내부적인 처리를 거쳐 화면에 출력할 이미지를 만들어 내는 방식

- 사용자는 카메라의 위치나 방향을 조정하거나 장면 내의 다른 ㅁㄹ체에 대한 약간의 정보 정도만 다루면 됨

적용 예: 광선 추적기, 비행 시뮬레이션, 이미지 생성기 

- 장면 내의 모드 물체들과 그 사이의 관계를 미리 만들어진 데이터 구조로 만들어 두고, 이 구조에 축적인 약간의 정보들만 제공하여 완성된 이미지 만들어 냄

- 렌더링에 대한 세부적인 부분까지 신경 쓸 필요가 없다는 장점. 사용이 편함

- 최종 이미지 생산을 위해 중간 단계 구조(Scene graph)를 가지는 특징이 있음


2. 즉시 모드(Immediate Mode)

- 이미 실행된 명령에 대해서는 그 후에 내려진 명령이 아무런 영향을 주지 못함



▶ 좌표체계

OpenGL을 포함한 대부분의 3D API에서는 화면 내에 무언가를 그리고자 할 때 어떤 좌표계(Coordinate System)을 사용할 것인지, 그리고 그 좌표가 물리적인 화면의 픽셀과 어떻게 대응될 것인지 함께 지정해야 함

2D, 3D 

좌표계 설정 - OpenGL 은 오른손 좌표계를 사용함 

픽셀 설정이 필요함






http://www.hyperzoid.com/csc492/rendering.html


▶ 좌표의 클리핑(Clipping: 자르기)

클리핑 영역을 설정할때 참고 해야 함

http://lueseypid.tistory.com/37


▶ 뷰포트: 드로잉 좌표와 창 좌표의 매핑

클리핑 영역과 창의 픽셀 수가 정확히 맞아떨어지는 경우는 드물다. 따라서 논리적 직교 좌표를 물리적ㅇ니 화면 픽셀 좌료로 전화하는 과정이 필요한데, 이때 사용되는 것이 뷰포트(Viewport)라는 개념이다.

클리핑 영역에 두배 크기로 설정된 뷰포트



클리핑 영역과 같은 크기로 설정된 뷰포트



▶ 투영: 3D를 2D로 설정



우리가 보는 영상이 3D라도 실제 화면에 나타나는 것은 2D이다. 따라서 3D 이미지들이 2D로 투영되여 화면에 나타나는데 두가지 방법이 사용된다. 


1. 직교 투영(Orthographic Projection)

- 모든 물체들이 거리에 관계없이 동일한 크기 비율로 투영됨

- 주로 건축물의 설계도나 디자인 문서 등에 주로 사용됨


2. 원근 투영(Perspective Projection)

- 물체가 얼마나 가까이 또는 멀리 있는가에 따라 거리를 고려하여 투영



http://www3.ntu.edu.sg/home/ehchua/programming/opengl/CG_Introduction.html







2014. 4. 19. 15:46

◆ 윈도우즈 OPENGL - 창 만들기 


장치 컨텍스트 얻기 및 해제

- 장치 컨텍스를 얻고 드로잉 후 가능한 빨리 해제 하는 것이 좋음 (시스템 자원 관리)

HDC hDC = GetDC(hWnd);

ReleaseDC(hWnd, hDC);


윈도우즈 OPenGL 프로그램을 만들기 위한 단계를 다음과 같다.

[step 1] 랜더링 컨텍스트 초기화 

[step 2] 픽셀 포맷 지정

[step 3] 랜더링 컨텍스트 활성화 

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
32
33
34
35
int COpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CView::OnCreate(lpCreateStruct) == -1) return -1;
    
    int nPixelFormat;                    // Pixel format index
    m_hDC = ::GetDC(m_hWnd);            // Get the Device context
    static PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),    // Size of this structure
        1,                                // Version of this structure    
        PFD_DRAW_TO_WINDOW |            // Draw to Window (not to bitmap)
        PFD_SUPPORT_OPENGL |            // Support OpenGL calls in window
        PFD_DOUBLEBUFFER,                // Double buffered mode
        PFD_TYPE_RGBA,                    // RGBA Color mode
        24,                                // Want 24bit color 
        0,0,0,0, 0,0,0,0, 0,0,0,0,0,    // Not used to select mode
        32,                                // Size of depth buffer
        0,0,
        PFD_MAIN_PLANE,                    // Draw in main plane
        0,0,0,0};                        // Not used to select mode
    
    // Choose a pixel format that best matches that described in pfd
        nPixelFormat = ChoosePixelFormat(m_hDC, &pfd);
    // Set the pixel format for the device context
        VERIFY(SetPixelFormat(m_hDC, nPixelFormat, &pfd));
    // Create the rendering context
        m_hRC = wglCreateContext(m_hDC);
    // Make the rendering context current, perform initialization, then
    // deselect it
        VERIFY(wglMakeCurrent(m_hDC,m_hRC));
        GLSetupRC(m_hDC);
        wglMakeCurrent(NULL,NULL);
    // Create the palette if needed
        InitializePalette();
    return 0;
}


[step 4] 드로잉 코드 호출 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void COpenGLView::OnDraw(CDC* /*pDC*/)
{
    CProjectOpenGLDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;
    
    // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
 
    // Make the rendering context current
    wglMakeCurrent(m_hDC,m_hRC);
    
    // Call our external OpenGL code
    GLRenderScene();
    
    // Swap our scene to the front
    SwapBuffers(m_hDC);
    
    // Allow other rendering contexts to co-exist
    wglMakeCurrent(m_hDC,NULL);
}

SwapBuffers함수: 장치 컨텍스를 인자를 받고 이중 버퍼 렌더링을 위한 버퍼 교환을 수행하는 것. 이것이 렌더링 작업에 작업 컨텍스트를 빠르게 이용할 수 있어야 하는 이유 중 하나


1
2
3
4
5
// OpenGL의 영역을 그립니다.
void GLRenderScene()
{
    //OpenGL 드로잉 코드 
}


[step 5] 종료시 현재 렌더링 컨텍스트 해제 및 제거 

Colored By Color Scripter

1
2
3
4
5
6
7
8
9
void OnDestroy()
{
    // Clean up rendering context stuff
    wglDeleteContext(m_hRC);
    ::ReleaseDC(m_hWnd,m_hDC);
    
    CView::OnDestroy();
    // TODO: 여기에 메시지 처리기 코드를 추가합니다.
}


주의사항 

윈도우즈 프로그래밍에서 창을 만들때 반드시 아래 스타일을 선언해야 함

 - WS_CLIPCHILDREN | WS_CLIPSIBLINGS

 - OpenGL 랜더링 컨텍스트가 다른 창에 렌더링 하는 것을 막기 위함


GDI 렌더링과 OpenGL 이중 버퍼 페이지 전환 시 모든 장치 컨텍스트가 필요하기 때문에 창스타일에 CS_OWNDC 설정 필요


1
2
3
4
5
6
7
BOOL PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: CREATESTRUCT cs를 수정하여 여기에서
    //  Window 클래스 또는 스타일을 수정합니다.
    cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_OWNDC);
    return CView::PreCreateWindow(cs);
}

MFC에서 호출해야 하는 함수 
OnDestroy, : 종료시 OpenGL 랜더링 컨텍스트 해제
PreCreateWindow,  :: 윈도우 창 속성 설정
OnCreate, : 랜더링 컨텍스트 및 픽셀 포맷 설정
OnSize, : 사이즈 조절
OnPaint, : 드로잉 
OnEraseBkgnd : 사이즈 조절시 깜빡임 방지 

1
2
3
4
5
6
7
BOOL COpenGLView::OnEraseBkgnd(CDC* pDC)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
 
    // return CView::OnEraseBkgnd(pDC);
    return true;
}




'OpenGL' 카테고리의 다른 글

OpenGL: Setting Clipping region  (0) 2014.04.19
OpenGL: Basic knowledge for 3D programing  (0) 2014.04.19
Windows OpenGL: Rendering Context  (0) 2014.04.19
Windows OpenGL: Setting and selecting Pixel format  (0) 2014.04.19
OPENGL color define  (0) 2014.04.16