国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Win 95/NT下OpenGL編程原理

2019-11-17 05:23:23
字體:
來源:轉載
供稿:網友

  ----科學計算可視化,計算機動畫和虛擬現實是現在計算機圖形學的三個熱點。而這三個熱點的核心都是三維真實感圖形的繪制。由于OpenGL(

OpenGraphicsLibrary)具有跨平臺性、簡便、高效、功能完善,目前已經成為了三維圖形制作方法中事實上的工業標準。自從WindowsNT3.51在微

機平臺上支持OpenGL以后,現在微軟公司在Windows95OSR2、WindowsNT4.0中連續性的提供OpenGL開發環境。VisualC++從4.2版本以后已經完全支持

OpenGL API,使三維世界的"平民化"已成為必然。

----Windows操作系統對OpenGL的支持

----具有Windows編程經驗的人都知道,在Windows下用GDI作圖必須通過設備上下文(DeviceContext簡寫DC)調用相應的函數;用OpenGL作圖也是

類似,OpenGL函數是通過"渲染上下文"(RenderingContext簡寫RC)完成三維圖形的繪制。Windows下的窗口和設備上下文支持"位圖格式"(

PIXELFORMAT)屬性,和RC有著位圖結構上的一致。只要在創建RC時與一個DC建立聯系(RC也只能通過已經建立了位圖格式的DC來創建),OpenGL的

函數就可以通過RC對應的DC畫到相應的顯示設備上。這里還有以下需要注重的方面:

----1.一個線程只能擁有一個渲染上下文(RC),也就是說,用戶假如在一個線程內對不同設備作圖,只能通過更換與RC對應的DC來完成,而RC在

線程中保持不變。(當然,刪除舊的RC后再創建新的是可以的)與此對應,一個RC也只能屬于一個線程,不能被不同線程同時共享。

----2.設定DC位圖格式等于設定了相應的窗口的位圖格式,并且DC和窗口的位圖格式一旦確定就不能再改變。這一點只能期望以后的Windows版本改

進了。

----3.一個RC雖然可以更換DC,在任何時刻只能利用一個DC(這個DC稱為RC的當前DC),但由于一個窗口可以讓多個DC作圖從而可以讓多個線程利

用多個RC在該窗口上執行OpenGL操作。

----4.現在的Windows下的OpenGL版本對OpenGL和GDI在同一個DC上作圖有一定的限制。當使用雙緩存用OpenGL產生動畫時,不能使用GDI函數向該DC

作圖。

----5.不建議用ANSIC在Windows下編寫OpenGL程序。這樣的程序雖然具有跨平臺的可移植性(比如很多SGI的例子程序),但是它們不能利用

Windows操作系統的很多特性,實用價值不大。

----用VC來編寫OpenGL程序

----經過上面的分析,用VC來調用OpenGL作圖的方法就很顯然了。步驟如下:

----1.先設置顯示設備DC的位圖格式(PIXELFORMAT)屬性。這通過填充一個PIXELFORMATDESCRipTOR的結構來完成(關于PIXELFORMATDESCRIPTOR中

各項數據的意義,請參照VC的幫助信息),該結構決定了OpenGL作圖的物理設備的屬性,比如該結構中的數據項dwFlags中PFD_DOUBLEBUFFER位假如

沒有設置(置1),通過該設備的DC上作圖的OpenGL命令就不可能使用雙緩沖來做動畫。有一些位圖格式(PIXELFORMAT)是DC支持的,而有一些DC

就不支持了。所以程序必須先用ChoosePixelFormat來選擇DC所支持的與指定位圖格式最接近的位圖格式,然后用SetPixelFormat設置DC的位圖格式



----2.利用剛才的設備DC建立渲染上下文RC(wglCreateContext),使得RC與DC建立聯系(wglMakeCurrent)。

----3.調用OpenGL函數作圖。由于線程與RC一一對應,OpenGL函數的參數中都不指明本線程RC的句柄(handle)

----4.作圖完畢以后,先通過置當前線程的RC為NULL(::wglMakeCurrent(NULL,NULL);),斷開當前線程和該渲染上下文的聯系,由此斷開與DC的

聯系。此時RC句柄的有效性在微軟自己的文檔中也沒有講清楚,所以在后面刪除RC的時候要先判定以下RC句柄的有效性(

if(m_hrc)::wglDeleteContext(m_hrc);)。再根據情況釋放(ReleaseDC)或者刪除(DeleteDC)DC

----所附程序說明

----所附的程序用MFC完成了一個簡單的OpenGL作圖,用OpenGL的輔助庫畫了一個有光照的實心圓球。OpenGL本身的函數這里就不解釋了,僅對用

MFC編OpenGL時需要注重的內容做一個簡要的說明:

----1.一旦設定了一個DC的位圖格式,該DC所聯系的窗口的位圖格式隨之設定。該窗口若含有子窗口或者有兄弟窗口,這些兄弟/子窗口的位圖格式

沒有設成與對應RC一致的格式,OpenGL在它們上面作圖就輕易出錯。故而OpenGL作圖的窗口必須具有WS_CLIPCHILDREN和WS_CLIPSIBLINGS風格,程

序中在主框窗的構造函數中用LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOWWS_CLIPCHILDRENWS_CLIPSIBLINGS,NULL,NULL);指定了主窗口的風

格。

----2.在ANSIC的OpenGL編程中,由auxReshapeFunc定義設置OpenGL視口大小和作圖尺寸的回調函數。在MFC中應該由WM_SIZ消息的處理函數來完成

。在ANSIC的OpenGL編程中,由EauxMainLoop定義作圖的回調函數。在MFC中應該由WM_PAINT消息的處理函數來處理。相應的,由OpenGL定義的鍵盤

、鼠標處理函數都應該由相應的Windows處理函數來響應。

----3.OpenGL自己有刷新背景的函數glClear,故而應禁止Windows刷新窗口背景。否則,當窗口需要重畫時,Windows會自動先發送WM_ERASEBKGND

,而缺省的處理函數使用白色的背景刷。當OpenGL使用的背景顏色不是白色時,作圖時有一幀白色的閃爍。這種現象在做動畫時非凡明顯。程序中

只需要在WM_ERASEBKGND的消息處理函數中禁止父窗口類的消息處理,簡單的返回一個TRUE即可。

----4.由于OpenGL的跨平臺性,它必須用操作系統的調色板。所以假如GL_INDEX_MODE作圖時,必須用VC自己定義調色板。不過一般情況下,用

GL_RGBA_MODE模式比較方便,很少用到GL_INDEX_MODE模式。

----5.在OpenGL作圖期間,RC對應的DC不能刪除或者釋放。

----6.由于OpenGL作圖時需要長時間占用DC,所以最好把作圖窗口類設成CS_OWNDC。MFC缺省的窗口類風格中沒有設這一屬性,程序中在主窗口C++

類的PReCreateWindow方法中自己注冊了一個窗口類,除了設定了CS_OWNDC屬性以外,還設定了CS_HREDRAW、CS_VREDRAW和CS_SAVEBITS。設定

CS_HREDRAW、CS_VREDRAW是為了讓窗口縮放時產生WM_PAINT消息,修正OpenGL視口和作圖尺寸;由于OpenGL作圖需要很多計算,設定CS_SAVEBITS是

為了在OpenGL窗口被遮蓋后顯現出來時,不產生WM_PAINT消息,用內存存儲的圖象來填充,從而用空間消耗換取計算時間。

----7.本程序中沒有對OpenGL函數的出錯情況作出處理。OpenGL出錯后返回錯誤碼,不會拋出異常;而且在某一個函數出錯以后,后繼函數也一般

不會出現異常,只是返回錯誤碼,一不小心就可能忽略某些錯誤。而對每一個OpenGL函數都做出錯與否的判定比較麻煩,所以編程序時對OpenGL的

函數應當非常小心。

----參考書籍:

----《OpenGLProgrammer'sGuide》SGIinc.

----《OpenGL三維圖形程序設計》廖朵朵、張華軍著,星球地圖出版社

----《VisualC++5.0聯機幫助》

----附程序:

----程序運行時必須確定OpenGL32.dll、glu.dll、glaux.dll在Windows的System目錄下。假如找不到這些文件,可以從Windows95OSR2的機器上面

將這些文件拷貝過來即可。OpenGL運行不需要注冊庫信息。在VC的STUDIO中運行程序時,工程文件中必須加入OpenGL.H、glu.h、glaux.h以及

OpenGL.lib、glu.lib、glaux.lib,這些文件由VC自帶。

----主窗口類定義(OpenGLWnd.h):

s#if !defined(AFX_OPENGLWND_H__3FB1AB28_0E70
_11D2_9ACA_48543300E17D__INCLUDED_)
#define AFX_OPENGLWND_H__3FB1AB28_0E70_11D2
_9ACA_48543300E17D__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include < afxwin.h >
#include "SimpleGLApp.h"
#include "resource.h"
// OpenGLWnd.h : header file
//
///////////////////////////////////////
//////////////////////////////////////
// COpenGLWnd frame

class COpenGLWnd : public CFrameWnd
{
DECLARE_DYNCREATE(COpenGLWnd)
public:
COpenGLWnd();
// protected constrUCtor used by dynamic creation
protected:
HGLRC m_hrc;
CClientDC *m_pDC;
// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COpenGLWnd)
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~COpenGLWnd();

// Generated message map functions
//{{AFX_MSG(COpenGLWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnDestroy();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

///////////////////////////////////////
//////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert
additional declarations immediately before the previous line.

#endif // !defined(AFX_OPENGLWND_H__3FB1AB28_
0E70_11D2_9ACA_48543300E17D__INCLUDED_)
主窗口類的實現(OpenGLWnd.cpp):
// OpenGLWnd.cpp : implementation file
//

#include "stdafx.h"
#include "OpenGLWnd.h"
#include "SimpleGLApp.h"
#include "gl/glu.h"
#include "gl/gl.h"
#include "gl/glaux.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////
//////////////////////////////////////
// COpenGLWnd

IMPLEMENT_DYNCREATE(COpenGLWnd, CFrameWnd)

COpenGLWnd::COpenGLWnd()
{
m_pDC = NULL;
m_hrc = 0;
LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW
WS_CLIPCHILDREN WS_CLIPSIBLINGS
,NULL,NULL );
}

COpenGLWnd::~COpenGLWnd()
{
}


BEGIN_MESSAGE_MAP(COpenGLWnd, CFrameWnd)
//{{AFX_MSG_MAP(COpenGLWnd)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()



BOOL COpenGLWnd::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Add your specialized
code here and/or call the base class
cs.lpszClass = AfxRegisterWndClass( CS_DBLCLKS
CS_HREDRAW
CS_VREDRAW
CS_SAVEBITS
CS_NOCLOSE
CS_OWNDC
,AfxGetApp( )-
> LoadStandardCursor(IDC_ARROW), 0 ,
AfxGetApp( )- >LoadStandardIcon(IDI_application));
return CFrameWnd::PreCreateWindow(cs);
}


int COpenGLWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

int pixelformat;

m_pDC = new CClientDC(this);//在客戶區作圖
ASSERT(m_pDC != NULL);

static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), //固定值
1, //固定值
PFD_DRAW_TO_WINDOW // support window
PFD_SUPPORT_OPENGL // support OpenGL
PFD_TYPE_RGBA, // RGBA模式,不用調色板
16, //程序在16位色彩下運行
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
};


if ( (pixelformat = ChoosePixelFormat
(m_pDC- >GetSafeHdc(), &pfd)) == 0 )
{
MessageBox("在該DC上找不到與PFD接近的位圖結構");
return -1;
}

if (SetPixelFormat(m_pDC- >
GetSafeHdc(), pixelformat, &pfd) == FALSE)
{
MessageBox("無法在該DC上設置位圖結構");
return -1;
}
m_hrc = wglCreateContext(m_pDC- >GetSafeHdc());
wglMakeCurrent(m_pDC- >GetSafeHdc(), m_hrc);

glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);

return 0;//OpenGL窗口構造成功
}

void COpenGLWnd::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
if(cy > 0)
{
glViewport(0, 0, cx, cy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (cx < = cy)
glOrtho(-3.0,3.0,-3.0 * (GLfloat)cx/(GLfloat)cy,
3.0 * (GLfloat)cx/(GLfloat)cy,-3.0,3.0);
else
glOrtho(-3.0,3.0,-3.0 * (GLfloat)cy/(GLfloat)cx,
3.0 * (GLfloat)cy/(GLfloat)cx,-3.0,3.0);
glMatrixMode(GL_MODELVIEW);
}
}

void COpenGLWnd::OnDestroy()
{

CFrameWnd::OnDestroy();
::wglMakeCurrent(NULL, NULL);
if (m_hrc)
::wglDeleteContext(m_hrc);
if (m_pDC)
delete m_pDC;
// TODO: Add your message handler code here
}

BOOL COpenGLWnd::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message
handler code here and/or call default
return TRUE;
//return CFrameWnd::OnEraseBkgnd(pDC);
}

void COpenGLWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting

GLfloat light_position[]={2.0f,0.0f,4.0f,0.0f};

// TODO: Add your message handler code here

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glTranslatef(0.0f, 0.0f, -2.0f);
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
auxSolidSphere(1.0);

glPopMatrix();

glFinish();

// Do not call CFrameWnd::OnPaint() for painting messages
}
應用程序類的定義(SimpleGLApp.h):
#if !defined(AFX_SIMPLEGLAPP_H__3FB1AB29
_0E70_11D2_9ACA_48543300E17D__INCLUDED_)
#define AFX_SIMPLEGLAPP_H__3FB1AB29_0E70
_11D2_9ACA_48543300E17D__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// SimpleGLApp.h : header file
//
#include < afxwin.h >
#include "OpenGLWnd.h"
#include "resource.h"

///////////////////////////////////////
//////////////////////////////////////
// CSimpleGLApp thread

class CSimpleGLApp : public CWinApp
{
DECLARE_DYNCREATE(CSimpleGLApp)
public:
CSimpleGLApp();
// protected constructor used by dynamic creation

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSimpleGLApp)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CSimpleGLApp();

// Generated message map functions
//{{AFX_MSG(CSimpleGLApp)
afx_msg void OnAppExit();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

///////////////////////////////////////
//////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert
additional declarations
immediately before the previous line.

#endif // !defined(AFX_SIMPLEGLAPP_H__3FB1AB29_
0E70_11D2_9ACA_48543300E17D__INCLUDED_)
應用程序類的實現(SimpleGLApp.cpp):
// SimpleGLApp.cpp : implementation file
//

#include "stdafx.h"
#include "SimpleGLApp.h"
#include "OpenGLWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////
//////////////////////////////////////
// CSimpleGLApp

IMPLEMENT_DYNCREATE(CSimpleGLApp, CWinApp)

CSimpleGLApp::CSimpleGLApp()
{
}

CSimpleGLApp::~CSimpleGLApp()
{
}

BOOL CSimpleGLApp::InitInstance()
{
// TODO: perform and per-thread initialization here
m_pMainWnd = new COpenGLWnd();
m_pMainWnd- >ShowWindow(m_nCmdShow);
m_pMainWnd- >UpdateWindow();
return TRUE;
}

int CSimpleGLApp::ExitInstance()
{
return CWinApp::ExitInstance();
}

BEGIN_MESSAGE_MAP(CSimpleGLApp, CWinApp)
//{{AFX_MSG_MAP(CSimpleGLApp)
ON_COMMAND(ID_APP_EXIT, OnAppExit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////
//////////////////////////////////////
// CSimpleGLApp message handlers
void CSimpleGLApp::OnAppExit()
{
// TODO: Add your command handler code here
CWinApp::OnAppExit();
}

CSimpleGLApp SimpleGLApp;


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 绥化市| 安乡县| 东海县| 中山市| 凤台县| 临海市| 布尔津县| 保康县| 翼城县| 青岛市| 慈利县| 清流县| 湾仔区| 德保县| 莆田市| 大丰市| 休宁县| 曲沃县| 通榆县| 弋阳县| 介休市| 左云县| 寿阳县| 西丰县| 运城市| 六枝特区| 天津市| 滨海县| 西乌珠穆沁旗| 赤峰市| 桂平市| 宁陕县| 顺义区| 海盐县| 江山市| 陆河县| 黄龙县| 自治县| 景宁| 衡水市| 丽江市|