2006년 1월 25일 수요일

Visual Studio .NET MFC + OpenGL

1. Create Project
File -> New -> Project -> Visual C++ Projects -> MFC Application
Project Name : oglMFCDialog
Application Type -> Dialog based -> Finish Button

2. Create the Control
Solution Explorer tabl -> Resource View(top right view들 중에 있음)
-> oglMFCDialog.rc -> Dialog -> IDD_OGLMFCDIALOG_DIALOG

View -> Toolbox -> Picture Control -> Drag하여 dialog window에 drop
(resize accordingly)
(사각형의 가장자리를 선택해야 선택이되고 사각형의 내부를 누르면 선택이 안되므로 주의)

Properties window (bottom right)
-> Behavior -> Visible -> False
-> ID -> (IDC_STATIC -> IDC_OPENGL로 바꿈)
(Visible을 true로 하면 이것이 OpenGL에서 그린것을 가려버리므로 false로 함)

3. Add the OpenGL Class
Class view -> oglMFCDialog + mouse right click -> Add Class
-> Add class wizard -> Generic C++ class -> Open button
Class name: COpenGLControl
Base class: CWnd
Access: public
Check Virtual destructor
Finish Button

OpenGLControl.h, OpenGLControl.cpp가 생성됨
afxwin.h가 include되고 cpp에 h가 include됨
class declaration과 definition이 됨.(이제 채워 넣으면 됨)

4. Add libraries
Class view -> oglMFCDialog + mouse right click -> Property
-> Linker -> Input -> opengl32.lib glu32.lib
(lib파일 사이에는 공백을 한 칸만 넣을 것)

5. Add member varible
#include
#include

class COpenGLControl : public CWnd
{
public:
/******************/
/* PUBLIC MEMBERS */
/******************/
// Timer
UINT_PTR m_unpTimer;

private:
/*******************/
/* PRIVATE MEMBERS */
/*******************/
// Window information
CWnd *hWnd;
HDC hdc;
HGLRC hrc;
int m_nPixelFormat;
CRect m_rect;
CRect m_oldWindow;
CRect m_originalRect;

6. Add the oglCreate Function
Class view -> COpenGLControl + mouse right -> Add -> Add function
void oglCreate(CRect rect, CWnd *parent);

7. Add the OnPaint()
Properties -> Messages button(Mouse hovering하면 bubble에 설명이 나옴, lightning bolt(번개) 아이콘 옆에 있음)
-> WM_PAINT -> "OnPaint"

COpenGLControl에 afx_msg void OnPaint() member function이 생긴다.

void COpenGLControl::OnPaint()
{
//CPaintDC dc(this); // device context for painting
ValidateRect(NULL);
}

8. Add the OnCreate()
Properties -> Messages button(Mouse hovering하면 bubble에 설명이 나옴, lightning bolt(번개) 아이콘 옆에 있음)
-> WM_CREATE -> "OnCreate"

int COpenGLControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;

oglInitialize();

return 0;
}

9. Add oglInitialize()
Class view -> COpenGLControl + mouse right -> Add -> Add function
void oglCreate(void);

void COpenGLControl::oglInitialize(void)
{
// Initial Setup:
//
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // bit depth
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, // z-buffer depth
0, 0, 0, 0, 0, 0, 0,
};

// Get device context only once.
hdc = GetDC()->m_hDC;

// Pixel format.
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);

// Create the OpenGL Rendering Context.
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);

// Basic Setup:
//
// Set color to use when clearing the background.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);

// Turn on backface culling
glFrontFace(GL_CCW);
glCullFace(GL_BACK);

// Turn on depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

// Send draw request
OnDraw(NULL);
}

10. Add the OnDraw()
-> 일종의 Message function이지만 OnPaint()와 달리 Properties에서 추가하지 않고 Add -> Add function으로 추가함.

afx_msg void OnDraw(CDC *pDC);

void COpenGLControl::OnDraw(CDC *pDC)
{
// TODO: Camera controls.
}

11. Add OnTimer()
Properties -> Messages button(Mouse hovering하면 bubble에 설명이 나옴, lightning bolt(번개) 아이콘 옆에 있음)
-> WM_TIMER -> "OnTimer"

void COpenGLControl::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 1:
{
// Clear color and depth buffer bits
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Draw OpenGL scene
// oglDrawScene();

// Swap buffers
SwapBuffers(hdc);

break;
}

default:
break;
}

CWnd::OnTimer(nIDEvent);
}

12. Add OnSize()
Properties -> Messages button(Mouse hovering하면 bubble에 설명이 나옴, lightning bolt(번개) 아이콘 옆에 있음)
-> WM_SIZE -> "OnSize"

void COpenGLControl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED) return;

// Map the OpenGL coordinates.
glViewport(0, 0, cx, cy);

// Projection view
glMatrixMode(GL_PROJECTION);

glLoadIdentity();

// Set our current view perspective
gluPerspective(35.0f, (float)cx / (float)cy, 0.01f, 2000.0f);

// Model view
glMatrixMode(GL_MODELVIEW);
}

13.
Class View -> CoglMEFDialogDlg + Mouse right -> Add -> Add function
private:
COpenGLControl m_oglWindow;

oglMFCDialogDlg.cpp::OnInitDialog()에 다음 내용 추가(retun 바로 앞에)

CRect rect;

// Get size and position of the picture control
GetDlgItem(IDC_OPENGL)->GetWindowRect(rect);

// Convert screen coordinates to client coordinates
ScreenToClient(rect);

// Create OpenGL Control window
m_oglWindow.oglCreate(rect, this);

// Setup the OpenGL Window's timer to render
m_oglWindow.m_unpTimer = m_oglWindow.SetTimer(1, 1, 0);


14. F5를 눌러 컴파일하면 됨, 그냥 까만 화면이 나옴

15, 16도 하면 화면이 나옴.
. 참고
http://www.codeguru.com/cpp/g-m/opengl/openfaq/article.php/c10975/

댓글 없음:

댓글 쓰기