. e$ u; c$ v) L: B" c,而缺省的处理函数使用白色的背景刷。当OpenGL使用的背景颜色不是白色时,作图时有一帧白色的闪烁。这种现象在做动画时特别明显。程序中3 J0 A8 P+ f |0 Z7 B7 w7 L
: D: h5 u, ?* h& | w
只需要在WM_ERASEBKGND的消息处理函数中禁止父窗口类的消息处理,简单的返回一个TRUE即可。/ z+ o+ ^3 V K' d4 ~# D
" ~, ~4 j+ ?( W# f4 H5 `& x. d----4.由于OpenGL的跨平台性,它必须用操作系统的调色板。所以如果GL_INDEX_MODE作图时,必须用VC自己定义调色板。不过一般情况下,用" J1 c0 c: c1 l# m* p
4 ]7 o' K, R+ u0 W/ ~9 s- n
GL_RGBA_MODE模式比较方便,很少用到GL_INDEX_MODE模式。2 ]* j' T8 L, Q/ V
* R8 v, F" i! N( `4 }/ t8 S类的PreCreateWindow方法中自己注册了一个窗口类,除了设定了CS_OWNDC属性以外,还设定了CS_HREDRAW、CS_VREDRAW和CS_SAVEBITS。设定0 ], s: K e) \. z0 J" a
8 c2 r2 B+ H3 L3 n$ U% GCS_HREDRAW、CS_VREDRAW是为了让窗口缩放时产生WM_PAINT消息,修正OpenGL视口和作图尺寸;由于OpenGL作图需要很多计算,设定CS_SAVEBITS是$ w* ]& e0 Y' |9 E
; Q( Q, A7 |. m. @' Y
为了在OpenGL窗口被遮盖后显现出来时,不产生WM_PAINT消息,用内存存储的图象来填充,从而用空间消耗换取计算时间。& m" P# M% o* r( |: c
- L A+ `4 H* |- j! u----7.本程序中没有对OpenGL函数的出错情况作出处理。OpenGL出错后返回错误码,不会抛出异常;而且在某一个函数出错以后,后继函数也一般; {8 b+ M, i$ [5 @" E a# a5 e0 T
3 u% `. w. `" x3 d
不会出现异常,只是返回错误码,一不小心就可能忽略某些错误。而对每一个OpenGL函数都做出错与否的判断比较麻烦,所以编程序时对OpenGL的 7 ^, w8 c C+ R I7 L! t- l! i T4 B7 Q8 P' W+ b
函数应当非常小心。 % k) B# K$ n3 E& F# r/ V. l& I8 e2 b1 V' u7 M! H
----参考书籍: 5 w/ a) z/ v. D" l : t1 o$ v- d% l! L----《OpenGLProgrammer'sGuide》SGIinc.& a" M- h, i) M% q' h
4 {3 o2 c, `4 ?7 f$ f+ S9 P----《OpenGL三维图形程序设计》廖朵朵、张华军著,星球地图出版社 ( |- Y+ y4 V: m0 g, D- B: ^; |) o. `+ R& s/ q ~# w K- N1 v
----《VisualC++5.0联机帮助》 0 T0 C& L- F8 D: x8 G 9 ^% @6 J% l6 ?3 _! l----附程序: ! I8 |% X/ U% l$ @7 |4 `" a: h# f* Q, z9 `2 Z! @1 H
----程序运行时必须确定OpenGL32.dll、glu.dll、glaux.dll在Windows的System目录下。如果找不到这些文件,可以从Windows95OSR2的机器上面! I. \ N$ r( F3 K) p
9 _0 b) U* [% R$ G; j' s* n将这些文件拷贝过来即可。OpenGL运行不需要注册库信息。在VC的STUDIO中运行程序时,工程文件中必须加入OpenGL.H、glu.h、glaux.h以及 + q7 J' E3 I( D 1 E) i! @6 Z, D: Q$ o4 x3 _OpenGL.lib、glu.lib、glaux.lib,这些文件由VC自带。 7 k! `6 s% ?5 _) Z / x# q5 V7 Y$ S) [----主窗口类定义(OpenGLWnd.h):! A7 }8 D% f" M" Z: w
2 c6 J- {0 n2 i
s#if !defined(AFX_OPENGLWND_H__3FB1AB28_0E70 " T7 C+ T" {) U_11D2_9ACA_48543300E17D__INCLUDED_)7 ^0 }9 b: U+ |! E1 K9 \; r* I
#define AFX_OPENGLWND_H__3FB1AB28_0E70_11D2& e" o" M- c+ W
_9ACA_48543300E17D__INCLUDED_" k8 h9 c4 w0 I2 R, v) m. W
D4 }$ L" `8 H7 M1 P2 l. m
#if _MSC_VER &= 1000 ) _7 X0 ?) `, D$ K" E: Y: u# f* i" z#pragma once . K0 q! Q* I- E* T- i0 v#endif // _MSC_VER &= 10003 E& Q* a* s0 e% E c
9 k+ D8 q0 J0 Q! |#include & afxwin.h &. z1 e' i2 u( k2 d% p4 x
#include "SimpleGLApp.h" R3 Y' J2 Z! ?! A; E% h+ F#include "resource.h": y: Y7 S! Q1 K6 |7 u/ [( a
// OpenGLWnd.h : header file5 \( P* Z% R# N/ v/ _) t
// 8 {" G/ Q! }/ X# L" ~. Z///////////////////////////////////////0 \+ x9 P7 P1 y6 _$ u; Z9 @
////////////////////////////////////// l' ^1 |1 Z3 G0 ^
// COpenGLWnd frame ( ]/ ]0 g `3 n7 C1 z$ w& u0 H( L' s7 L1 x$ P, T: K
class COpenGLWnd : public CFrameWnd 1 i" x y; k+ z% {$ Q% f{5 i N O; O1 Y" e( L: v2 D
DECLARE_DYNCREATE(COpenGLWnd) ' I) y) a. w v# t6 Q' |; J0 r! opublic: % [8 _* ]# ~5 O# u: fCOpenGLWnd();&& ' Y \6 e) x+ |+ ^/ b// protected constructor used by dynamic creation5 [; Q; Q2 L- F+ K8 O: k& u% ]& r
protected: # N# [/ K G0 S/ T2 T7 JHGLRC m_hrc; * [" X7 _% |7 M5 yCClientDC *m_pDC; & n0 F' c" b! R& `5 Q// Attributes & B6 @* E! k! k, d, T* Hpublic:! Q+ D! l; G& J( [3 {0 T3 V6 h
/ J/ N8 `5 Z7 N- q# y
// Operations ; n, ~, K# R6 {" j! gpublic: 9 [ R) u. W0 n( \" F# c: K9 x8 c# R6 ~' k* _6 |4 S
// Overrides : m" Q- I, W/ J9 S* }5 j/ j// ClassWizard generated virtual function overrides ( i; m* v) H. s. A//{{AFX_VIRTUAL(COpenGLWnd) - v) y" I* k' ~4 Y3 w0 cprotected:5 ?4 T% B' K9 R, T0 a p$ B6 o" i! }
virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - p0 ^: _$ y2 G' d//}}AFX_VIRTUAL& \% z Q: v8 j3 E0 I& X
\( r4 y- T) `3 l+ _+ ~// Implementation # p5 D+ n; x) E. s8 f9 Apublic: 6 z- q) Z3 W' e3 jvirtual ~COpenGLWnd(); " C1 Q7 y/ @: \) X: j/ q# p % f* {3 G0 h4 U3 t, x// Generated message map functions( r O( h/ Y& v
//{{AFX_MSG(COpenGLWnd)6 s1 r) g: d* ?# b1 M& y: m
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);% \) l' Z8 H; f
afx_msg void OnSize(UINT nType, int cx, int cy); * a9 P6 ^) W8 E' v3 d3 xafx_msg void OnDestroy(); ) z, \, C% f: T& Fafx_msg BOOL OnEraseBkgnd(CDC* pDC);1 j ^5 _7 q2 [! C* E. j* J
afx_msg void OnPaint(); 7 u# G; p% Q5 }* k//}}AFX_MSG8 s' J1 n" \0 w* j. b
DECLARE_MESSAGE_MAP() " i3 d$ ^% l- e# z) ~}; 8 N8 D/ \. c# V1 p$ u3 B9 e: W. }. R$ n* j7 S: v- j
/////////////////////////////////////// / }9 N5 [8 V* L; Q8 |0 d! q% C5 C9 ^////////////////////////////////////// + D; |$ p2 ?, C |5 r: v1 w5 P# v. I, W4 M2 c
//{{AFX_INSERT_LOCATION}} 3 A2 v. B; |6 o+ Z, X- l4 A// Microsoft Developer Studio will insert / t8 A7 j2 Z1 t; Q1 h' [+ U% u
additional declarations immediately before the previous line. 8 `$ x6 p+ k' `; O& B $ |( f! j( p: e7 H* c#endif // !defined(AFX_OPENGLWND_H__3FB1AB28_! ?# O) h$ |7 i c6 N p
0E70_11D2_9ACA_48543300E17D__INCLUDED_)4 x8 P* b+ k8 V6 M4 N1 }
主窗口类的实现(OpenGLWnd.cpp): & z1 y J8 P$ J0 j* n" ]// OpenGLWnd.cpp : implementation file & I8 K* a7 Y3 U//4 Z5 v$ h4 I' ]) q, P* N3 Y% D. b) Y
; }) a% U0 O( x- J! d2 q9 e! Y5 n6 r
#include "stdafx.h"# S# g; y+ I& l, j* ]
#include "OpenGLWnd.h" $ z! H4 \+ D* B5 p, O7 f6 z" I#include "SimpleGLApp.h" 9 ~3 Y8 E* B5 C/ G1 T8 i2 ]# s#include "gl\glu.h"' A' r$ G, `: j0 Y8 j& s# e
#include "gl\gl.h" . L& G: y# o) V! V& Z, _#include "gl\glaux.h"$ o" O1 C; ~! Y" Z, ~# {' b
1 y( m0 I; Q* T% R) O5 I
#ifdef _DEBUG6 m" m$ O. z+ s
#define new DEBUG_NEW( V4 D" p0 i# x- F: g% v; u% F
#undef THIS_FILE/ w3 q8 G: W8 p$ K, O: O
static char THIS_FILE[] = __FILE__; : h; H. S% |/ I#endif ' b' V! x! J1 w. K# X" w1 l9 l' H) I6 o. h% n
///////////////////////////////////////7 s5 A3 b, k* ?# B& j
//////////////////////////////////////0 h" I: s d# t' n v
// COpenGLWnd 2 E( b" K1 {# A) o I! f: n* `: F
IMPLEMENT_DYNCREATE(COpenGLWnd, CFrameWnd)4 H& C. g3 U# N. r
6 x2 |* p" u) p0 e8 d n. ^COpenGLWnd::COpenGLWnd()% i. \; S# K. j) h0 j; Q5 J
{ ; }) j: |' O& X# B* q8 n+ P* `m_pDC = NULL; 1 R7 E+ P2 s8 A5 F. Mm_hrc = 0; 9 C/ s& k$ _1 G) m: _8 I g& sLoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW + e; e9 _5 J9 ^4 A1 p8 ]; u! x| WS_CLIPCHILDREN | WS_CLIPSIBLINGS0 j' ], A2 V. O5 t' L
,NULL,NULL ); - F0 q" E9 l: k} & q. o2 }: x. H' Y; W* h ( s6 t% u+ l0 K! `% TCOpenGLWnd::~COpenGLWnd(), Y8 }3 U/ s+ H( P( V4 O, X- n. e
{& g9 j: {6 b: G3 C; w
}: {! f5 i1 A0 q4 d2 t
- C* c$ X4 R9 g
4 Q& m& Q3 A% `/ {4 Z! z
BEGIN_MESSAGE_MAP(COpenGLWnd, CFrameWnd) 0 m/ \, o% {+ b! V. n//{{AFX_MSG_MAP(COpenGLWnd)+ ~ B x% G" n* I* g
ON_WM_CREATE()2 A4 Q- e2 [; J, B
ON_WM_SIZE() 0 i. _5 `% X4 BON_WM_DESTROY() 4 z/ E% N* x: Z8 m8 MON_WM_ERASEBKGND()4 @' I" q9 ?) }
ON_WM_PAINT(); ^$ q% D+ M: \ W! |
//}}AFX_MSG_MAP; b4 F# F( ~+ _% }8 B
END_MESSAGE_MAP()# a8 W, Q9 T( M& l/ w
$ \% [: S0 M9 V" Y! A/ z$ K* }! {' j7 y1 H+ `
# M) `. s V- @ w/ \1 v
BOOL COpenGLWnd:reCreateWindow(CREATESTRUCT& cs) * b6 k, J7 k" q. m2 H0 e
{ : m, A5 l1 ~6 m- Y) _% D& M// TOD Add your specialized9 |( f" p) S. z9 }* f+ V2 s
code here and/or call the base class: v: [* X/ k. k1 g2 E
cs.lpszClass = AfxRegisterWndClass( CS_DBLCLKS | / `% V1 g$ @' x* R2 q* _- ICS_HREDRAW |! g [- D. e# [% H. X+ u9 ^
CS_VREDRAW |' B4 K6 Z# I* {; r: h3 R. k) ?
CS_SAVEBITS |. q9 `8 o1 s$ D1 X. s; N$ j; h
CS_NOCLOSE |* O2 ]) C6 K6 u+ Z4 m: \
&&&&&&&&&&&&&&&&&&&CS_OWNDC ) p: i; ]7 l1 ^,AfxGetApp( )-6 R3 l/ A5 r0 m q$ {
& LoadStandardCursor(IDC_ARROW), 0 ,$ Z' f' W1 L z0 p
AfxGetApp( )- &LoadStandardIcon(IDI_APPLICATION));. X2 O8 K- c5 u- V5 I4 l% b% b
return CFrameWnd:reCreateWindow(cs);8 o* v& l: f6 C3 w& \
}: U5 j; C3 S2 p3 G/ o' t+ P0 D$ J
5 S8 C5 w1 F1 N4 V F 0 o% d0 d( x! v7 d. Aint COpenGLWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) ) C6 R4 Z8 Q$ t0 k% M0 E
{ ! E) ?7 ?2 [1 _2 ^ Iif (CFrameWnd::OnCreate(lpCreateStruct) == -1)6 Y- p6 g1 ~: M+ s8 h. Q t
return -1; 8 \6 G& r @! f* r, e. b# v7 n# d0 U$ D
&&&&int pixelformat; ! y. V$ v4 j T4 D) _1 ]6 n7 l( b 8 h2 N: G( ^2 E) u&&&&m_pDC = new CClientDC(this);//在客户区作图 ' T3 L' r$ F7 b8 RASSERT(m_pDC != NULL); ( }7 K$ ~8 ^- d% C+ G/ P! y ! `! x& G# k- R4 i5 f# Lstatic PIXELFORMATDESCRIPTOR pfd =+ a% J5 N5 @2 a9 J
{ % _# h# M/ r* B&&&&&&&&sizeof(PIXELFORMATDESCRIPTOR),&&//固定值 7 [2 ~/ D7 H& r! [! `&&&&&&&&1,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//固定值" ?+ @$ k! x! h! u
&&&&&&&&FD_DRAW_TO_WINDOW |&&&&&&&&&&&&// support window. U& Y% i# {* ]& \$ h. j$ l$ F3 h
&&&&&&&&FD_SUPPORT_OPENGL |&&&&&&&&&&&&// support OpenGL1 f: t$ u9 l6 v
&&&&&&&&FD_TYPE_RGBA,&&&&&&&&&&&&&&&&&&// RGBA模式,不用调色板 ; Y+ t) G+ X9 }4 E&&&&&&&&16,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//程序在16位色彩下运行0 t8 i: |. C! y9 \( x/ y; i
&&&&&&&&0, 0, 0, 0, 0, 0,&&&&&&&&&&&&&&&// color bits ignored0 W2 ^" D. d# U
&&&&&&&&0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// no alpha buffer7 R# E2 F) L2 Y5 H
&&&&&&&&0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// shift bit ignored0 {* ?+ O& I8 m* h4 i7 L
&&&&&&&&0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// no accumulation buffer ; f1 v: [" A0 y&&&&&&&&0, 0, 0, 0,&&&&&&&&&&&&&&&&&&&&&// accum bits ignored. Y2 g1 m8 {( ^7 f9 A P b+ v
&&&&&&&&32,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// 32-bit z-buffer " b0 e" i2 j, f2 d&&&&&&&&0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// no stencil buffer 1 K: {. o7 G$ P' K9 }6 ^$ [$ C&&&&&&&&0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// no auxiliary buffer ' Q& E) f8 H5 N7 U4 l! _# Q&&&&&&&&FD_MAIN_PLANE,&&&&&&&&&&&&&&&&&// main layer/ N4 ]* @* B& ~- h: o- q
&&&&&&&&0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&// reserved) f/ J) ~" R2 j& K! y
&&&&&&&&0, 0, 0&&&&&&&&&&&&&&&&&&&&&&&&&// layer masks ignored' q% u' C# Y8 h5 g9 J2 l" u: D
&&&&};) |, U, P; g+ p
: I" M! W9 E# l" e