MFC (OpenGLglut.cpp):
#include <afxwin.h> #include "OpenGLglut.h" #include "glut.h" class DocBoxy : public CDocument { public: CClientDC *m_pDC; HGLRC hrc; DECLARE_DYNCREATE(DocBoxy) //宣告run-time類別 }; IMPLEMENT_DYNCREATE(DocBoxy, CDocument) //宣告DocBoxy為run-time類別 class FrameBoxy : public CFrameWnd { public: afx_msg void OnExit() { //宣告關閉檔案事件 if(MessageBox( TEXT("Are you sure you want to close this window?"), TEXT("DocViewBoxy"), MB_OKCANCEL | MB_ICONQUESTION ) == 1 ) { DestroyWindow(); } } afx_msg void OnAbout() { //宣告關於事件 MessageBox( TEXT("DocViewBoxy Version 1.0\nCopyright (C) 2013, By QQBoxy Huang.\nEmail: gs1458@gmail.com"), TEXT("About"), MB_OK ); } DECLARE_DYNCREATE(FrameBoxy) //宣告run-time類別 DECLARE_MESSAGE_MAP() //宣告訊息映射表 }; IMPLEMENT_DYNCREATE(FrameBoxy, CFrameWnd) //宣告FrameBoxy為run-time類別 BEGIN_MESSAGE_MAP(FrameBoxy, CFrameWnd) //建立訊息映射表 ON_COMMAND(ID_FILE_EXIT, OnExit) ON_COMMAND(ID_HELP_ABOUT, OnAbout) END_MESSAGE_MAP() class ViewBoxy : public CView { public: void OnDraw(CDC * aDC) { //必須覆寫的虛擬函數 DocBoxy *doc = (DocBoxy *)GetDocument(); ASSERT_VALID(doc); //斷言,確認doc是否存在(在發行版本不會執行) glLoadIdentity(); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glTranslatef(0.0f,0.0f,-1.0f); glColor3f(0.0f,0.0f,0.0f); /*glBegin(GL_LINES); glVertex3f(0.0f, 1.0, 0.0f); glVertex3f(-1.0, -1.0, 0.0f); glVertex3f(-1.0f, -1.0, 0.0f); glVertex3f(1.0f, -1.0, 0.0f); glVertex3f(1.0f, -1.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glEnd();*/ glBegin(GL_TRIANGLES); glColor3f(1.0f,0.0f,0.0f); //Red glVertex3f( 0.0f, 1.0f, 0.0f); // Top glColor3f(0.0f,1.0f,0.0f); //Green glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left glColor3f(0.0f,0.0f,1.0f); //Blue glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right glEnd(); glFinish(); //繪圖完畢 SwapBuffers( doc->m_pDC->GetSafeHdc() ); // } BOOL PreCreateWindow(CREATESTRUCT& cs) { cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; //加入 WS_CLIPSIBLINGS 及 WS_CLIPCHILDREN 旗標 return CView::PreCreateWindow(cs); //避免OpenGL畫到別的視窗 } BOOL OnEraseBkgnd(CDC* pDC) { return true; //不要重繪視窗 } void OnDestroy() { //清除記憶體 DocBoxy *doc = (DocBoxy *)GetDocument(); HGLRC hRC; hRC= wglGetCurrentContext(); wglMakeCurrent(NULL, NULL); if (doc->hrc) wglDeleteContext(hRC); if (doc->m_pDC) delete doc->m_pDC; CView::OnDestroy(); } bool bSetupPixelFormat() { DocBoxy *doc = (DocBoxy *)GetDocument(); static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // 像素的結構大小 1, // 版本號 PFD_DRAW_TO_WINDOW | // 緩衝特性:視窗支援 PFD_SUPPORT_OPENGL | // 緩衝特性:OpenGL支援 PFD_DOUBLEBUFFER, // 緩衝特性:雙精度緩衝 PFD_TYPE_RGBA, // 設定顏色類型為RGBA 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, // accum bits ignored 32, // 深度緩衝:32-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 pixelformat; if ( (pixelformat = ChoosePixelFormat(doc->m_pDC->GetSafeHdc(), &pfd)) == 0 ) { MessageBox(_TEXT("ChoosePixelFormat failed")); return false; } if (SetPixelFormat(doc->m_pDC->GetSafeHdc(), pixelformat, &pfd) == false) { MessageBox(_TEXT("SetPixelFormat failed")); return false; } return true; } void init() { int n; DocBoxy *doc = (DocBoxy *)GetDocument(); PIXELFORMATDESCRIPTOR pfd; //宣告一個PixelFormat物件 doc->m_pDC = new CClientDC(this); //建立一個視窗繪圖物件 ASSERT_VALID(doc->m_pDC); //斷言,確認視窗繪圖物件是否存在(在發行版本不會執行) if (!bSetupPixelFormat()) return; //設定應用所需的像素格式 n = GetPixelFormat(doc->m_pDC->GetSafeHdc()); //從Windows裡找尋符合我們設定的 DescribePixelFormat(doc->m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd); //PixelFormat的索引值,並將之指定給pfd doc->hrc = wglCreateContext(doc->m_pDC->GetSafeHdc()); //將RC物件給DC物件 wglMakeCurrent(doc->m_pDC->GetSafeHdc(), doc->hrc); //讓這個RC設定為作用中的物件 glDepthFunc(GL_GREATER); //深度資訊 glEnable(GL_DEPTH_TEST); //深度測試 glClearDepth(-2.0f); //初始化深度 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //初始化顏色 //PixelFormat:視窗的所有3D特徵設定,包括緩衝區、 顏色深度等集合的名稱 //RC:背景渲染,OpenGL裡負責紀錄目前顏色,狀態設定等資訊的物件 } int OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CView::OnCreate(lpCreateStruct) == -1) { //判斷視窗生成 return -1; } init(); return 0; } void OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); GLfloat nRange = 5.0f; //比例係數 if(cy == 0) { //防止分母為零 cy = 1; } glMatrixMode(GL_PROJECTION); //透視場景 glLoadIdentity(); //重新設定矩陣 if (cx <= cy) { //調整視窗比例 glOrtho(-nRange, nRange, -nRange*cy/cx, nRange*cy/cx, -nRange, nRange); } else { glOrtho(-nRange*cx/cy, nRange*cx/cy, -nRange, nRange, -nRange, nRange); } glMatrixMode(GL_MODELVIEW); //重新設定觀點矩陣 glViewport(0, 0, cx, cy); //設定觀點 } DECLARE_DYNCREATE(ViewBoxy) //宣告run-time類別 DECLARE_MESSAGE_MAP() //宣告訊息映射表 }; IMPLEMENT_DYNCREATE(ViewBoxy, CView) //宣告ViewBoxy為run-time類別 BEGIN_MESSAGE_MAP(ViewBoxy, CView) //建立訊息映射表 ON_WM_DESTROY() ON_WM_CREATE() ON_WM_SIZE() //ON_WM_KEYDOWN() //ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() class AppBoxy : public CWinApp { public: BOOL InitInstance() { CDocument *doc; //宣告指向文件的指標 CSingleDocTemplate* DocTemplate; //宣告指向單文件樣版物件的指標 DocTemplate = new CSingleDocTemplate( //建立具有單文件樣版物件 IDR_MENU, //用於單文件框架之資源的識別子 RUNTIME_CLASS(DocBoxy), //單文件視窗的Document RUNTIME_CLASS(FrameBoxy), //單文件視窗的視窗框架 RUNTIME_CLASS(ViewBoxy) //單文件視窗的View ); AddDocTemplate(DocTemplate); //將單文件樣版物件設定給MyApp doc = DocTemplate->CreateNewDocument(); //建立新的文件 m_pMainWnd = DocTemplate->CreateNewFrame( doc, NULL ); //建立一個視窗框架 DocTemplate->InitialUpdateFrame ( (CFrameWnd*)m_pMainWnd, doc ); //起始化視窗框架物件,並連結View物件 m_pMainWnd->ShowWindow(SW_SHOW); //顯示視窗 return true; } }; AppBoxy appboxy; //建立應用程式物件
說明:
基礎MFC使用OpenGL繪製面。
沒有留言:
張貼留言