본문 바로가기
ETC.../OpenGL

SDI MFC Application에서 OpenGL 기본 설정하기

by izen8 2011. 4. 14.
반응형

[ OpenGL Setting for SDI MFC App ]

1. Project for SDI application 생성

2. stdafx.h 파일에 해더 추가

//OpenGL Headers
#include <gl\gl.h>         //OpenGL Main Library Header
#include <gl\glu.h>        //OpenGL Utility Library Header
#include <gl\glaux.h>      //OpenGL Auxiliary Library Header
#include <gl\glut.h>       //OpenGL GLUT Library Header

3. project setting->object/modules에 라이브러리 추가   

opengl32.lib glu32.lib glut32.lib glaux.lib 추가

4. Window Style 설정

BOOL COpenGLView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs
    // An OpenGL Window must be created with the following flags

    cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

    return CView::PreCreateWindow(cs);
}

5. OnCreate()에서 OpenGL 초기화

// 아래 두 변수는 View Class 의 Member variable로 설정한다.
HGLRC m_hRC;  // Rendering Context
CDC* m_pDC;   // Device Context

// InitializeOpenGL()함수에 초기화 관련 내용을 넣는다.
int COpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    // TODO: Add your specialized creation code here
    // Initialize OpenGL Here

    InitializeOpenGL();

    return 0;
}

BOOL COpenGLView::InitializeOpenGL()
{
    // Get a DC for the Client Area
    m_pDC = new CClientDC(this)

    // Failure to Get DC
    if(m_pDC == NULL)
    {
        MessageBox("Error Obtaining DC");
        return FALSE;
    }

    // Failure to set the pixel format
    if(!SetupPixelFormat())
    {
        return FALSE;
    }

    // Create Rendering Context
    m_hRC = ::wglCreateContext (m_pDC->GetSafeHdc());

    // Failure to Create Rendering Context
    if(m_hRC == 0)
    {
        MessageBox("Error Creating RC");
        return FALSE;
    }

    // Make the RC Current
    if(::wglMakeCurrent (m_pDC->GetSafeHdc(), m_hRC)==FALSE)
    {
        MessageBox("Error making RC Current");
        return FALSE;
    }

    // Specify Black as the clear color
    ::glClearColor(0.0f,0.0f,0.0f,0.0f);

    // Specify the back of the buffer as clear depth
    ::glClearDepth(1.0f);

    // Enable Depth Testing
    ::glEnable(GL_DEPTH_TEST);  

    return TRUE;
}

BOOL COpenGLView::SetupPixelFormat()
{
    static PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd

        1,                              // version number

        PFD_DRAW_TO_WINDOW |            // support window
        PFD_SUPPORT_OPENGL |            // support OpenGL
        PFD_DOUBLEBUFFER,               // double buffered

        PFD_TYPE_RGBA,                  // RGBA type

        24,                             // 24-bit color depth

        0, 0, 0, 0, 0, 0,               // color bits ignored
        0,                              // no alpha buffer
        0,                              // shift bit ignored
        0,                              // no accumulation buffer
        0, 0, 0, 0,                  // accumulation bits ignored
        16,                             // 16-bit z-buffer
        0,                              // no stencil buffer
        0,                              // no auxiliary buffer
        PFD_MAIN_PLANE,                 // main layer
        0,                              // reserved
        0, 0, 0                         // layer masks ignored
   };

   int m_nPixelFormat =
                   ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);

   if ( m_nPixelFormat == 0 ) {
       return FALSE;
   }

   if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd)
        == FALSE)
 {
       return FALSE;
   }

   return TRUE;
} 

6. OnSize()함수 추가

void COpenGLView::OnSize(UINT nType, int cx, int cy)
{
    CView::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here
    GLdouble aspect_ratio; // width/height ratio

    if ( 0 >= cx || 0 >= cy )
    {
        return;
    }

    // select the full client area
    ::glViewport(0, 0, cx, cy);

    // compute the aspect ratio
    // this will keep all dimension scales equal
    aspect_ratio = (GLdouble)cx/(GLdouble)cy;

    // select the projection matrix and clear it
    ::glMatrixMode(GL_PROJECTION);
    ::glLoadIdentity();

    // select the viewing volume
    ::gluPerspective(45.0f, aspect_ratio, .01f, 200.0f);

    // switch back to the modelview matrix and clear it
    ::glMatrixMode(GL_MODELVIEW);
    ::glLoadIdentity();
}

7. OnDraw()함수 추가

void COpenGLView::OnDraw(CDC* pDC)
{
    COpenGLDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here

    // Clear out the color & depth buffers
    ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    RenderScene();

    // Tell OpenGL to flush its pipeline
    ::glFinish();

    // Now Swap the buffers
    ::SwapBuffers( m_pDC->GetSafeHdc() );
}

void COpenGLView::RenderScene ()
{
    // 실제로 렌더링 하는 부분은 여기에 추가
} 

8. OnEraseBkgnd(CDC* pDC) 함수 추가 : 깜박거림 문제 해결을 위해

BOOL COpenGLView::OnEraseBkgnd(CDC* pDC)
{
    // TODO: Add your message handler code here and/or call default
    // comment out the original call
    // return CView::OnEraseBkgnd(pDC);
    // Tell Windows not to erase the background
    return TRUE;
}

9. OnDestroy() 함수 추가

void COpenGLView::OnDestroy()
{
    CView::OnDestroy();

    // TODO: Add your message handler code here
    // Make the RC non-current
    if(::wglMakeCurrent (0,0) == FALSE)
    {
        MessageBox("Could not make RC non-current");
    }

    // Delete the rendering context
    if(::wglDeleteContext (m_hRC)==FALSE)
    {
        MessageBox("Could not delete RC");
    }

    // Delete the DC
    if(m_pDC)
    {
        delete m_pDC;
    }

    // Set it to NULL
    m_pDC = NULL;
}

반응형

'ETC... > OpenGL' 카테고리의 다른 글

OpenGL 함수 설명  (0) 2011.12.14

댓글