首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

MFC 浮動視窗架構下的 OpenGL 多視圖渲染實作

     編輯:關於VC++

專案需求與架構概覽

工程應用需在可停駐/浮動視窗中同時顯示三維模型的「主視圖」與兩個「子視圖」(如頂/前/側視圖)。核心挑戰:

  • 每個視圖需獨立 OpenGL Rendering Context (RC)
  • 繪圖前必須 wglMakeCurrent 切換至對應 RC
  • 浮動視窗動態建立/銷毀,RC 生命週期須同步
  • 視圖類型(頂/前/側)可執行期切換,繪圖邏輯須依類型分派

關鍵技術實作

1. 每視圖獨立 RC 建立與切換

CChildOGLView(子視圖基類)標準流程:


// Header
public:
    CClientDC* m_pDC;
    HGLRC m_hRC;

// OnCreate / OnInitialUpdate
m_pDC = new CClientDC(this);
m_hRC = wglCreateContext(m_pDC->GetSafeHdc());

// OnDraw / Render 函式
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC); // 切換至本視圖 RC
// ... OpenGL 指令 ...
glFinish();
SwapBuffers(wglGetCurrentDC());

注意:wglMakeCurrent 必須在**同一執行緒**呼叫;MFC 視圖類別天然符合單執行緒 UI 模型。

2. 視圖類型識別與切換管理

定義列舉:


enum ViewType { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };

主視圖類型存於 CMainFrame::m_ViewArrange.m_MainViewType;子視圖類型存於 m_ChildViewAType、m_ChildViewBType。

子視圖自我識別:因兩子視圖共用同一 CChildOGLView 類別,需在建立時指派唯一 ID:


// CChildOGLView.h
int m_ViewID; // 1 = ChildA, 2 = ChildB

// CMainFrame::OnCreate
void CMainFrame::AssignViewID() {
    CEdit3DMDoc* pDoc = (CEdit3DMDoc*)m_pMainView->GetDocument();
    POSITION pos = pDoc->GetFirstViewPosition();
    int id = 1;
    while (pos) {
        CView* pView = pDoc->GetNextView(pos);
        if (pView->IsKindOf(RUNTIME_CLASS(CChildOGLView))) {
            ((CChildOGLView*)pView)->m_ViewID = id++;
        }
    }
}

子視圖建立時自動註冊到文件:


// CChildOGLView::OnCreate
void CChildOGLView::AddMetoDoc() {
    CEdit3DMDoc* pDoc = (CEdit3DMDoc*)GetDocument();
    if (pDoc) pDoc->AddView(this); // 文件維護視圖清單
}

3. 繪圖分派邏輯

主視圖:


ViewType vt = ((CMainFrame*)GetParentFrame())->m_ViewArrange.m_MainViewType;
pDoc->m_3DMani.SetProjection(vt, 0);
pDoc->m_3DMani.DrawBound(vt);

子視圖:


ViewType vt = (m_ViewID == 1) ?
    ((CMainFrame*)AfxGetMainWnd())->m_ViewArrange.m_ChildViewAType :
    ((CMainFrame*)AfxGetMainWnd())->m_ViewArrange.m_ChildViewBType;
pDoc->m_3DMani.SetProjection(vt, 0);
pDoc->m_3DMani.DrawBound(vt);

執行效果

三視圖同步旋轉/縮放,浮動視窗拖曳分離無閃爍。

擴充建議

  • 將 CChildOGLView 模板化,支援任意數量子視圖
  • 引入 CViewArrangeManager 封裝類型切換/持久化邏輯
  • 整合 GLSL 著色器管線,替換固定功能管線 DrawBound
  • 支援 HiDPI:wglCreateContextAttribsARB + SetProcessDpiAwareness

完整專案碼已開源,歡迎依專案需求裁剪擴充。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved