⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 0507003.htm

📁 VC知识库5_chm_decompile_20040520_210715
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title></title>
<link rel="stylesheet" type="text/css" href="../../vckbase.css">
</head>

<body>

<div align="justify">
  <table border="0" width="100%" class="font" height="57">
    <tr>
      <td width="27%" height="6" class="bigfont" bgcolor="#B8CFE7" align="center" bordercolor="#800080">
      <font color="#800080">VC知识库(五)</font>
      </td>
      <td width="73%" height="6" class="bigfont" bgcolor="#B8CFE7" align="center" bordercolor="#800080">
      <font color="#800080">www.vckbase.com</font>
      </td>
    </tr>
    <tr>
      <td width="100%" height="4" class="header" valign="top" align="center" colspan="2">
      <hr>
      </td>
    </tr>
    <tr>
      <td width="100%" height="17" class="header" valign="top" align="center" colspan="2">
      在Windows 95/NT 下 用OpenGL 编 程
      </td>
    </tr>
    <tr>
      <td width="100%" height="17" class="info" align="center" colspan="2">
      蔡 茂 
      </td>   
    </tr>   
    <tr>  
      <td width="100%" height="22" class="font" colspan="2"> 
        <hr> 
      </td>   
    </tr>  
    <tr>  
      <td width="100%" height="5" class="font" colspan="2">  
      ---- 科 学 计 算 可 视 化, 计 算 机 动 画 和 虚 拟 现 实 是 现 在 计 算 机 图 形 学 的 三 个 热 点。 而 这 三 个 热 点 的 核 心 都 是 三 维 真 实 感 图 形 的 绘 制。 由 于OpenGL(Open Graphics Library) 具 有 跨 平 台 性、 简 便、 高 效、 功 能 完 善, 目 前 已 经 成 为 了 三 维 图 形 制 作 方 法 中 事 实 上 的 工 业 标 准。 自 从Windows NT 3.51 在 微 机 平 台 上 支 持OpenGL 以 后, 现 在 微 软 公 司 在Windows 95 OSR2、Windows NT 4.0 中 连 续 性 的 提 供OpenGL 开 发 环 境。Visual C++ 从4.2 版 本 以 后 已 经 完 全 支 持OpenGL 
       API, 使 三 维 世 界 的“ 平 民 化” 已 成 为 必 然。Windows 操 作 系 统 对OpenGL 的 支 持---- 具 有Windows 编 程 经 验 的 人 都 知 道, 在Windows 下 用GDI 作 图 必 须 通 过 设 备 上 下 文(Device Context 简 写DC) 调 用 相 应 的 函 数; 用OpenGL 作 图 也 是 类 似,OpenGL 函 数 是 通 过“ 渲 染 上 下 文”(Rendering Context 简 写RC) 完 成 三 维 图 形 的 绘 制。Windows 下 的 窗 口 和 设 备 上 下 文 支 持“ 位 图 格 式”( PIXELFORMAT) 属 性, 和 R C 有 着 位 图 结 构 上 的 一 致。 只 要 在 创 建 R C 时 与 一 个 D C 建 立 联 系( R C 也 只 能 通 过 已 经 建 立 了 位 图 格 式 的 D C 来 创 建),OpenGL 的 函 数 就 可 以 通 过 R C 对 应 的 D C 画 到 相 应 的 显 示 设 备 上。 这 里 还 有 以 下 需 要 注 意 的 方 面:<br> 
      1. 一 个 线 程 只 能 拥 有 一 个 渲 染 上 下 文( R C), 也 就 是 说, 用 户 如 果 在 一 个 线 程 内 对 不 同 设 备 作 图, 只 能 通 过 更 换 与 R C 对 应 的 D C 来 完 成, 而 R C 在 线 程 中 保 持 不 变。( 当 然, 删 除 旧 的 R C 后 再 创 建 新 的 是 可 以 的) 与 此 对 应, 一 个 R C 也 只 能 属 于 一 个 线 程, 不 能 被 不 同 线 程 同 时 共 享。<br> 
      2. 设 定DC 位 图 格 式 等 于 设 定 了 相 应 的 窗 口 的 位 图 格 式, 并 且 D C 和 窗 口 的 位 图 格 式 一 旦 确 定 就 不 能 再 改 变。 这 一 点 只 能 期 望 以 后 的Windows 版 本 改 进 了。<br> 
      3. 一 个 R C 虽 然 可 以 更 换DC, 在 任 何 时 刻 只 能 利 用 一 个 D C( 这 个DC 称 为RC 的 当 前DC), 但 由 于 一 个 窗 口 可 以 让 多 个 D C 作 图 从 而 可 以 让 多 个 线 程 利 用 多 个 R C 在 该 窗 口 上 执 行OpenGL 操 作。<br> 
      4. 现 在 的Windows 下 的OpenGL 版 本 对OpenGL 和GDI 在 同 一 个DC 上 作 图 有 一 定 的 限 制。 当 使 用 双 缓 存 用OpenGL 产 生 动 画 时, 不 能 使 用GDI 函 数 向 该DC 作 图。<br> 
      5. 不 建 议 用 A N S I   C 在Windows 下 编 写OpenGL 程 序。 这 样 的 程 序 虽 然 具 有 跨 平 台 的 可 移 植 性( 比 如 很 多 S G I 的 例 子 程 序), 但 是 它 们 不 能 利 用Windows 操 作 系 统 的 很 多 特 性, 实 用 价 值 不 大。用 V C 来 编 写OpenGL 程 序---- 经 过 上 面 的 分 析, 用 V C 来 调 用OpenGL 作 图 的 方 法 就 很 显 然 了。 步 骤 如 下:<br> 
      1. 先 设 置 显 示 设 备 D C 的 位 图 格 式(PIXELFORMAT) 属 性。 这 通 过 填 充 一 个PIXELFORMATDESCRIPTOR 的 结 构 来 完 成( 关 于PIXELFORMATDESCRIPTOR 中 各 项 数 据 的 意 义, 请 参 照 V C 的 帮 助 信 息), 该 结 构 决 定 了OpenGL 作 图 的 物 理 设 备 的 属 性, 比 如 该 结 构 中 的 数 据 项dwFlags 中PFD_DOUBLEBUFFER 位 如 果 没 有 设 置( 置 1), 通 过 该 设 备 的 D C 上 作 图 的OpenGL 命 令 就 不 可 能 使 用 双 缓 冲 来 做 动 画。 有 一 些 位 图 格 式(PIXELFORMAT) 是DC 支 持 的, 而 有 一 些DC 就 不 支 持 了。 所 以 程 序 必 须 先 用ChoosePixelFormat 来 选 择DC 所 支 持 的 与 指 定 位 图 格 式 最 接 近 的 位 图 格 式, 然 后 用SetPixelFormat 设 置DC 的 位 图 格 式。<br> 
      2. 利 用 刚 才 的 设 备 D C 建 立 渲 染 上 下 文 R C(wglCreateContext), 使 得RC 与DC 建 立 联 系(wglMakeCurrent)。<br> 
      3. 调 用OpenGL 函 数 作 图。 由 于 线 程 与 R C 一 一 对 应,OpenGL 函 数 的 参 数 中 都 不 指 明 本 线 程 R C 的 句 柄(handle)<br> 
      4. 作 图 完 毕 以 后, 先 通 过 置 当 前 线 程 的 R C 为NULL(::wglMakeCurrent(NULL, NULL);), 断 开 当 前 线 程 和 该 渲 染 上 下 文 的 联 系, 由 此 断 开 与 D C 的 联 系。 此 时RC 句 柄 的 有 效 性 在 微 软 自 己 的 文 档 中 也 没 有 讲 清 楚, 所 以 在 后 面 删 除RC 的 时 候 要 先 判 断 以 下RC 句 柄 的 有 效 性(if (m_hrc) ::wglDeleteContext(m_hrc);)。 再 根 据 情 况 释 放(ReleaseDC) 或 者 删 除(DeleteDC) D C所 附 程 序 说 明<br> 
      ---- 所 附 的 程 序 用 M F C 完 成 了 一 个 简 单 的OpenGL 作 图, 用OpenGL 的 辅 助 库 画 了 一 个 有 光 照 的 实 心 圆 球。OpenGL 本 身 的 函 数 这 里 就 不 解 释 了, 仅 对 用MFC 编OpenGL 时 需 要 注 意 的 内 容 做 一 个 简 要 的 说 明:<br> 
      1. 一 旦 设 定 了 一 个DC 的 位 图 格 式, 该DC 所 联 系 的 窗 口 的 位 图 格 式 随 之 设 定。 该 窗 口 若 含 有 子 窗 口 或 者 有 兄 弟 窗 口, 这 些 兄 弟/ 子 窗 口 的 位 图 格 式 没 有 设 成 与 对 应RC 一 致 的 格 式,OpenGL 在 它 们 上 面 作 图 就 容 易 出 错。 故 而OpenGL 作 图 的 窗 口 必 须 具 有WS_CLIPCHILDREN 和 WS_CLIPSIBLINGS 风 格, 程 序 中 在 主 框 窗 的 构 造 函 数 中 用LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,NULL,NULL ); 指 定 了 主 窗 口 的 风 格。<br> 
      2. 在ANSI C 的OpenGL 编 程 中, 由auxReshapeFunc 定 义 设 置OpenGL 视 口 大 小 和 作 图 尺 寸 的 回 调 函 数。 在MFC 中 应 该 由WM_SIZ 消 息 的 处 理 函 数 来 完 成。 在ANSI C 的OpenGL 编 程 中, 由EauxMainLoop 定 义 作 图 的 回 调 函 数。 在MFC 中 应 该 由WM_PAINT 消 息 的 处 理 函 数 来 处 理。 相 应 的, 由OpenGL 定 义 的 键 盘、 鼠 标 处 理 函 数 都 应 该 由 相 应 的Windows 处 理 函 数 来 响 应。<br> 
      3. OpenGL 自 己 有 刷 新 背 景 的 函 数glClear, 故 而 应 禁 止Windows 刷 新 窗 口 背 景。 否 则, 当 窗 口 需 要 重 画 时,Windows 会 自 动 先 发 送WM_ERASEBKGND, 而 缺 省 的 处 理 函 数 使 用 白 色 的 背 景 刷。 当OpenGL 使 用 的 背 景 颜 色 不 是 白 色 时, 作 图 时 有 一 帧 白 色 的 闪 烁。 这 种 现 象 在 做 动 画 时 特 别 明 显。 程 序 中 只 需 要 在WM_ERASEBKGND 的 消 息 处 理 函 数 中 禁 止 父 窗 口 类 的 消 息 处 理, 简 单 的 返 回 一 个TRUE 即 可。<br> 
      4. 由 于OpenGL 的 跨 平 台 性, 它 必 须 用 操 作 系 统 的 调 色 板。 所 以 如 果GL_INDEX_MODE 作 图 时, 必 须 用VC 自 己 定 义 调 色 板。 不 过 一 般 情 况 下, 用GL_RGBA_MODE 模 式 比 较 方 便, 很 少 用 到GL_INDEX_MODE 模 式。<br> 
      5. 在OpenGL 作 图 期 间,RC 对 应 的DC 不 能 删 除 或 者 释 放。<br> 
      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 消 息, 用 内 存 存 储 的 图 象 来 填 充, 从 而 用 空 间 消 耗 换 取 计 算 时 间。<br> 
      7. 本 程 序 中 没 有 对OpenGL 函 数 的 出 错 情 况 作 出 处 理。OpenGL 出 错 后 返 回 错 误 码, 不 会 抛 出 异 常; 而 且 在 某 一 个 函 数 出 错 以 后, 后 继 函 数 也 一 般 不 会 出 现 异 常, 只 是 返 回 错 误 码, 一 不 小 心 就 可 能 忽 略 某 些 错 误。 而 对 每 一 个OpenGL 函 数 都 做 出 错 与 否 的 判 断 比 较 麻 烦, 所 以 编 程 序 时 对OpenGL 的 函 数 应 当 非 常 小 心。附 程 序:<br> 
      程 序 运 行 时 必 须 确 定OpenGL32.dll、glu.dll、glaux.dll 在Windows 的System 目 录 下。 如 果 找 不 到 这 些 文 件, 可 以 从Windows 95 OSR2 的 机 器 上 面 将 这 些 文 件 拷 贝 过 来 即 可。 OpenGL 运 行 不 需 要 注 册 库 信 息。 在VC 的STUDIO 中 运 行 程 序 时, 工 程 文 件 中 必 须 加 入OpenGL.H 、glu.h、glaux.h 以 及OpenGL.lib、glu.lib、glaux.lib, 这 些 文 件 由VC 自 带。<br> 
      主 窗 口 类 定 义(OpenGLWnd.h):<br> 
      <br> 
      #if !defined(AFX_OPENGLWND_H__3FB1AB28<br> 
      <br> 
      _0E70_11D2_9ACA_48543300E17D__INCLUDED_)<br> 
      <br> 
      #define AFX_OPENGLWND_H__3FB1AB28_0E70_11D2<br> 
      <br> 
      _9ACA_48543300E17D__INCLUDED_<br> 
      <br> 
      <br> 
      <br> 
      #if _MSC_VER >= 1000<br> 
      <br> 
      #pragma once<br> 
      <br> 
      #endif // _MSC_VER >= 1000<br> 
      <br> 
      <br> 
      <br> 
      #include&nbsp;<br>
      <br>
      #include "SimpleGLApp.h"<br> 
      <br> 
      #include "resource.h"<br> 
      <br> 
      // OpenGLWnd.h : header file<br> 
      <br> 
      //<br> 
      <br> 
      /////////////////////////////////////////////////////////////////////////////<br> 
      <br> 
      // COpenGLWnd frame<br> 
      <br> 
      <br> 
      <br> 
      class COpenGLWnd : public CFrameWnd<br> 
      <br> 
      {<br> 
      <br> 
	DECLARE_DYNCREATE(COpenGLWnd)<br> 
      <br> 
      public:<br> 
      <br> 
	COpenGLWnd();// protected constructor used by dynamic creation<br> 
      <br> 
      protected:<br> 
      <br> 
	HGLRC					m_hrc;<br> 
      <br> 
	CClientDC				*m_pDC;<br> 
      <br> 
      // Attributes<br> 
      <br> 
      public:<br> 
      <br> 
      <br> 
      <br> 
      // Operations<br> 
      <br> 
      public:<br> 
      <br> 
      <br> 
      <br> 
      // Overrides<br> 
      <br> 
	// ClassWizard generated virtual function overrides<br> 
      <br> 
	//{{AFX_VIRTUAL(COpenGLWnd)<br> 
      <br> 
	protected:<br> 
      <br> 
	virtual BOOL PreCreateWindow(CREATESTRUCT&amp; cs);<br> 
      <br> 
	//}}AFX_VIRTUAL<br> 
      <br> 
      <br> 
      <br> 
      // Implementation<br> 
      <br> 
      public:<br> 
      <br> 
	virtual ~COpenGLWnd();<br> 
      <br> 
      <br> 
      <br> 
	// Generated message map functions<br> 
      <br> 
	//{{AFX_MSG(COpenGLWnd)<br> 
      <br> 
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);<br> 
      <br> 
	afx_msg void OnSize(UINT nType, int cx, int cy);<br> 
      <br> 
	afx_msg void OnDestroy();<br> 
      <br> 
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);<br> 
      <br> 
	afx_msg void OnPaint();<br> 
      <br> 
	//}}AFX_MSG<br> 
      <br> 
	DECLARE_MESSAGE_MAP()<br> 
      <br> 
      };<br> 
      <br> 
      <br> 
      <br> 
      /////////////////////////////////////////////////////////////////////////////<br> 
      <br> 
      <br> 
      <br> 
      //{{AFX_INSERT_LOCATION}}<br> 
      <br> 
      // Microsoft Developer Studio will insert additional<br> 
      <br> 
 declarations immediately before the previous line.<br> 
      <br> 
      <br> 
      <br> 
      #endif // !defined(AFX_OPENGLWND_H__3FB1AB28<br> 
      <br> 
      _0E70_11D2_9ACA_48543300E17D__INCLUDED_)<br> 
      <br> 
 主 窗 口 类 的 实 现(OpenGLWnd.cpp):<br> 
      <br> 
      // OpenGLWnd.cpp : implementation file<br> 
      <br> 
      //<br> 
      <br> 
      <br> 
      <br> 
      #include "stdafx.h"<br> 
      <br> 
      #include "OpenGLWnd.h"<br> 
      <br> 
      #include "SimpleGLApp.h"<br> 
      <br> 
      #include "gl\glu.h"<br> 
      <br> 
      #include "gl\gl.h"<br> 
      <br> 
      #include "gl\glaux.h"<br> 
      <br> 
      <br> 
      <br> 
      #ifdef _DEBUG<br> 
      <br> 
      #define new DEBUG_NEW<br> 
      <br> 
      #undef THIS_FILE<br> 
      <br> 
      static char THIS_FILE[] = __FILE__;<br> 
      <br> 
      #endif<br> 
      <br> 
      <br> 
      <br> 
      /////////////////////////////////////////////////////////////////////////////<br> 
      <br> 
      // COpenGLWnd<br> 
      <br> 
      <br> 
      <br> 
      IMPLEMENT_DYNCREATE(COpenGLWnd, CFrameWnd)<br> 
      <br> 
      <br> 
      <br> 
      COpenGLWnd::COpenGLWnd()<br> 
      <br> 
      {<br> 
      <br> 
	m_pDC = NULL;<br> 
      <br> 
	m_hrc = 0;<br> 
      <br> 
	LoadFrame(IDR_MAINFRAME,WS<br> 
      <br> 
      _OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS<br> 
      <br> 
		,NULL,NULL );<br> 
      <br> 
      }<br> 
      <br> 
      <br> 
      <br> 
      COpenGLWnd::~COpenGLWnd()<br> 
      <br> 
      {<br> 
      <br> 
      }<br> 
      <br> 
      <br> 
      <br> 
      <br> 
      <br> 
      BEGIN_MESSAGE_MAP(COpenGLWnd, CFrameWnd)<br> 
      <br> 
	//{{AFX_MSG_MAP(COpenGLWnd)<br> 
      <br> 
	ON_WM_CREATE()<br> 
      <br> 
	ON_WM_SIZE()<br> 
      <br> 
	ON_WM_DESTROY()<br> 
      <br> 
	ON_WM_ERASEBKGND()<br> 
      <br> 
	ON_WM_PAINT()<br> 
      <br> 
	//}}AFX_MSG_MAP<br> 
      <br> 
      END_MESSAGE_MAP()<br> 
      <br> 
      <br> 
      <br> 
      <br> 
      <br> 
      <br> 
      <br> 
      BOOL COpenGLWnd::PreCreateWindow(CREATESTRUCT&amp; cs)&nbsp;<br>
      <br>
      {<br>
      <br>
	// TODO: Add your specialized code here and/or call the base class<br> 
      <br> 
      <br> 
      <br> 
	cs.lpszClass = AfxRegisterWndClass(	CS_DBLCLKS	|<br> 
      <br> 
						CS_HREDRAW	|&nbsp;<br>
      <br>
						CS_VREDRAW	|<br> 
      <br> 
						CS_SAVEBITS |&nbsp;<br>
      <br>
						CS_NOCLOSE	|<br> 
      <br> 
						CS_OWNDC<br> 
      <br> 
			, AfxGetApp( )->LoadStandardCursor(IDC_ARROW), 0 ,<br> 
      <br> 
										AfxGetApp( )<br> 
      <br> 
      - >LoadStandardIcon(IDI_APPLICATION));<br> 
      <br> 
	return CFrameWnd::PreCreateWindow(cs);<br> 
      <br> 
      }<br> 
      <br> 
      <br> 
      <br> 
      <br> 
      <br> 
      int COpenGLWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)&nbsp;<br>
      <br>
      {<br>
      <br>
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)<br> 
      <br> 
		return -1;<br> 
      <br> 
      <br> 
      <br> 
    int pixelformat;<br> 
      <br> 
      <br> 
      <br> 
    m_pDC = new CClientDC(this);// 在 客 户 区 作 图<br> 
      <br> 
	ASSERT(m_pDC != NULL);<br> 
      <br> 
      <br> 
      <br> 
	static PIXELFORMATDESCRIPTOR pfd =<br> 
      <br> 
	{<br> 
      <br> 
        sizeof(PIXELFORMATDESCRIPTOR),  // 固 定 值<br> 
      <br> 
        1,                              // 固 定 值<br> 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -