MFC單文件程式中搭建OpenGL框架

2021-06-05 18:49:34 字數 3546 閱讀 1054

本部落格計算機圖形學系列文章索引:

windows gdi是通過裝置控制代碼(device context(裝置描述表)以下簡稱"dc")來繪圖,而opengl則需要繪製環境(rendering context(著色描述表),以下簡稱"rc")。每乙個gdi命令需要傳給它乙個dc,但與gdi不同,opengl使用當前繪製環境(rc)。但是rc並不能直接完成繪圖,只能與特定的dc聯絡起來,從而完成具體的繪圖工作。一旦在乙個執行緒中指定了乙個當前rc,在此執行緒中其後所有的opengl命令都使用相同的當前rc。雖然在單一視窗中可以使用多個rc,但在單一執行緒中只有乙個當前rc。下面我將首先產生乙個opengl rc並使之成為當前rc。這將分為三個步驟:

1、設定視窗畫素格式;

2、產生rc;

3、設定為當前rc。

用乙個圖表示如下所示,圖中介紹了需要在各個函式中設定的資訊:

本文以乙個單文件程式為例。新建乙個單文件名字為vcopengl2 其他的預設。

在stdafx裡面新增opengl的標頭檔案(當然也可以在其他檔案中新增,比如繪圖一般都是在檢視中的,可以在***view.cpp檔案中包含標頭檔案)。如下**所示:

#include #include
有幾點說明:

2.1、包含glut.h的同時就把gl.h和glu.h都包括了。因為開啟glut.h你可以看到如下圖所示的,已經包含了gl.h和glu.h。

視窗建立之前我們必須設定視窗風格包含

ws_clipchildren(建立父視窗使用的windows風格,用於重繪時裁剪子視窗所覆蓋的區域)和ws_clipsiblings(建立子視窗使用的windows風格,用於重繪時剪裁其他子視窗所覆蓋的區域),

從而避免opengl繪製到其他視窗中去。這些應該放在precreatewindow()中。**如下:

首先向vcopengl2view類中新增幾個保護的成員變數和公共的成員函式。如下:

hglrc m_hrc;    //rendering context著色描述表

cclientdc* m_pdc; //device context裝置描述表

bool initializeopengl(); //初始化 opengl

bool setuppixelformat(); //設定畫素格式

void renderscene(); //繪製場景

別忘了在vcopengl2view的建構函式中設定 m_hrc = null; m_pdc = null;

產生乙個rc的第一步是定義視窗的畫素格式。畫素格式決定視窗著所顯示的圖形在記憶體中是如何表示的。由畫素格式控制的引數包括:顏色深度、緩衝模式和所支援的繪畫介面。在下面將在setuppixelformat()函式中對這些引數的設定。**如下:

bool cvcopengl2view::setuppixelformat(void)

; int pixelformat;

// 為裝置描述表得到最匹配的畫素格式

if((pixelformat = choosepixelformat(m_pdc->getsafehdc(), &pfd)) == 0)

// 設定最匹配的畫素格式為當前的畫素格式

if(setpixelformat(m_pdc->getsafehdc(), pixelformat, &pfd) == false)

return true;

}

現在畫素格式已經設定,我們下一步工作是產生繪製環境(rc)並使之成為當前繪製環境,即編寫initializeopengl()函式。**如下:

bool cvcopengl2view::initializeopengl(void)

n=::getpixelformat(m_pdc->getsafehdc());

::describepixelformat(m_pdc->getsafehdc(), n,sizeof(pfd),&pfd);

// 建立繪圖描述表

m_hrc=wglcreatecontext(m_pdc->getsafehdc());

if(m_hrc == null)

// 使繪圖描述表為當前呼叫現程的當前繪圖描述表

if( wglmakecurrent(m_pdc->getsafehdc(),m_hrc) == false)

glcleardepth(1.0f);

glenable(gl_depth_test);

return true;

}

別忘了再oncreate()函式中呼叫 initializeopengl()函式。如下所示:

int cvcopengl2view::oncreate(lpcreatestruct lpcreatestruct)

return 0;

}

void cvcopengl2view::onsize(uint ntype, int cx, int cy)

//設定視口與視窗的大小

glviewport(0,0,m_wide,m_heigth);

}

void cvcopengl2view::renderscene(void)

8.1 為了使改變視窗大小時嚴重的閃爍,在onerasebkgnd()裡做一些操作,避免windows自己的視窗重新整理閃爍。onerasebkgnd()函式需要重寫。如下:

bool cvcopengl2view::onerasebkgnd(cdc* pdc)

8.2 為了避免記憶體洩露,ondestroy()函式中加一些**,如下:

void cvcopengl2view::ondestroy()

if(m_hrc) }

if(m_pdc)

m_pdc = null;

}

至此乙個單文件的框架就弄好了。下面貼出所畫的立方體,如下圖:

MFC單文件程式架構解析

首先我們了解到的是 圖 一 圖 二 csingledoctemplate pdoctemplate pdoctemplate new csingledoctemplate idr mainframe,runtime class cmainframe main sdi frame windon 這裡體...

MFC單文件程式架構解析

mfc單文件程式架構解析 這裡我以科院楊老師的單文件程式來分析一下mfc單文件的程式架構,純屬個人見解,不當之處煩請指教!首先我們了解到的是 圖 一 圖 二 csingledoctemplate pdoctemplate pdoctemplate new csingledoctemplate idr...

MFC學習(七) 單文件程式

1 mfc單文件程式的主要類 1 文件類 document 即應用程式處理的資料物件,文件一般從 mfc 中 cdocument 中派生。cdocument 類用於相應資料檔案的讀取以及儲存 cview 類所需要觀察和處理的資訊。2 視類 view 視相當於文件在應用程式中的觀察視窗,它確定了使用者...