<>这是NENE的OPENGL的框架CB原代码,是黑屏的效果,最简单的。OPENGL我才开始学,很多不懂的,希望和大家交流,共同进步,我会把我的资料和大家共享的!</P> ! s, m$ z/ S+ c9 l<>首先在CB下建立一个CONSOLE的程序,然后把CONSOLE APPLICATION的勾去掉即可。然后再把以下的原代码粘贴上去就可以运行了!!</P> & i, @' l' c) |3 n2 l9 b<>//---------------------------------------------------------------------------</P> O6 z! ?5 f' v1 J4 |0 x; q<>#include <vcl.h>4 A m8 U1 ]' T, _1 ~2 p; T3 a
#include <windows.h> // Header file for windows9 ? d4 Y" X% n$ }, j, l
#include <gl\gl.h> // Header file for the OpenGL32 library " f7 y! z* F# _/ \#include <gl\glu.h> // Header file for the GLu32 library : |9 D& A3 q- q#include <gl\glaux.h> // Header file for the GLaux library # |' u7 [3 l, S9 Y; d#pragma hdrstop</P>+ y' X8 {. H6 h# w4 @1 `
<>//--------------------------------------------------------------------------- ) u( n9 O* ?2 v' w1 D; a9 C#pragma argsused</P>. c) d; W' a9 @7 N$ [1 j1 N/ n
<>HGLRC hRC = NULL; // Permanent rendering context9 L: q/ L9 n% g$ r. J
HDC hDC = NULL; // Private GDI device context ( V- I9 g* P. Z- T7 ]5 MHWND hWnd = NULL; // Holds our window handle . z( j0 D. r; e5 M. O9 l* `HINSTANCE hInstance = NULL; // Holds the instance of the application</P> B: P9 }6 t" p9 F<>bool keys[256]; // Array used for the keyboard routine$ y8 t A: X- Q3 L# w8 g# P
bool active = true; // Window active flag set to true by default 4 J; \) j4 W2 q5 Cbool fullscreen = true; // Fullscreen flag set to fullscreen mode by default</P>/ d% }9 z& Z& b, ~" h
<>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc</P> 8 W! `( p+ u8 I<>GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window- _. V. l) \1 c" H+ A F6 K% f
{ 0 f+ L' j) F2 M# f$ t* f1 L if (height == 0) // Prevent a divide by zero by5 n. _9 C0 X7 P N, v+ Y
{, b" }6 d1 [& V: C
height = 1; // Making height equal One & {% d9 M6 S' F4 r7 V; W+ ` }</P> ! R) ?; [: f) Q) ^2 Q& ~6 _3 W1 L<> glViewport(0, 0, width, height); // Reset the current viewport</P> ' @7 |% j* Z7 e<> glMatrixMode(GL_PROJECTION); // Select the projection matrix ; c( X0 `2 J c0 z+ R+ ~* j glLoadIdentity(); // Reset the projection matrix</P> 8 D6 ^) t4 Y$ e8 \. t1 d<> // Calculate the aspect ratio of the window $ N H, c& n5 x; _5 [! X" P gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);</P> - M, y- _4 ]3 K6 [) r) x<> glMatrixMode(GL_MODELVIEW); // Select the modelview matrix0 [ M! a! I1 E3 g8 [) }
glLoadIdentity(); // Reset the modelview matrix . E+ |3 w" J, T0 z) @7 h}</P> r0 I* H4 s0 U; ~% Z# {
<>int InitGL(GLvoid) // All setup for OpenGL goes here % h$ u- h- _: i7 G{! Q% Z& F5 |' d' N; Z4 u2 o
glShadeModel(GL_SMOOTH); // Enable smooth shading! `5 q1 @9 B/ m0 I. V
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background" ? {4 H7 D% B, S ~+ Z
glClearDepth(1.0f); // Depth buffer setup' Y0 G2 @; K; k- Y+ b6 u; e) }8 @
glEnable(GL_DEPTH_TEST); // Enables depth testing , \# l# N( V% z8 |! g& g4 F glDepthFunc(GL_LEQUAL); // The type of depth testing to do ) ~1 s( ?/ L+ I/ @5 z glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations6 j v; i' z$ W' k; l j, _
return true; // Initialization went OK4 [6 F6 S& S2 z7 V Y
}</P>' w9 Q( o! |4 h7 J' _- K P7 t
<>int DrawGLScene(GLvoid) // Here's where we do all the drawing! j/ M- H9 n8 q' ^ u9 l B
{ + X4 }5 L9 R" F/ J8 s glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer3 N$ e! r" _! L/ G! x
glLoadIdentity(); // Reset the current modelview matrix ) O1 l" [8 G% p( b2 v- b. P3 B 2 _" a9 c; k& |6 X% r' r return true; // Everything went OK , S* O" G- Z9 {( ]% s}</P> ( ]' P- [, Q$ R, [+ S<>GLvoid KillGLWindow(GLvoid) // Properly kill the window ' ^3 `3 D* r5 l' b Q' C7 `" q{ , o3 k/ m6 r* u: g% S2 Q if (fullscreen) // Are we in fullscreen mode? 8 I6 Y. C% X+ c- p { : i3 G5 U6 c( C* g9 d$ B ChangeDisplaySettings(NULL,0); // If so switch back to the desktop7 E7 x0 ? {7 I3 U" w
ShowCursor(true); // Show mouse pointer+ j! D8 `. W# y8 E! h d5 B* ?. T- |" [
}</P> / M( O9 ^; |. A/ r4 p<> if (hRC) // Do we have a rendering context? * w5 Z' c- b- C9 M4 M W { ) B! d5 u& Q) _$ S4 `# _ if (!wglMakeCurrent(NULL,NULL)) // Are we able to release the DC and RC contexts? ( Y, x- o$ c8 l Y1 z1 S { 9 X# r* B0 A& z {' M! K0 J MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);6 R6 \% Y: T* O, a/ w o; E
}</P> # G& W. I9 i5 O0 S6 Q6 ]<> if (!wglDeleteContext(hRC)) // Are we able to delete the RC?7 P1 ? E8 z0 _6 |. n( ?
{ 0 T7 r# M0 }/ L% m7 Q MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);* l( O5 T' H6 S% ]6 y9 S
}2 p$ p0 k( R8 P9 p5 ^6 p
hRC = NULL; // Set RC to NULL, o; i. ~5 x0 c
}</P>* _5 M! ?4 ]; K) _
<> if (hDC && !ReleaseDC(hWnd,hDC)) // Are we able to release the DC 7 W0 {3 q {( Y ?( a$ m A { 2 w& Z: G6 B! H( x MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);' Q4 A/ l! i% S1 g8 b; { }
hDC = NULL; // Set DC to NULL# ~4 t9 v! M5 n# g7 @4 J
}</P> ; N ^8 Q* O$ G, @, S<> if (hWnd && !DestroyWindow(hWnd)) // Are we able to destroy the window?% [) d1 a3 t4 V. r+ E- ~6 n
{" E& o0 o# X: f& E1 g% Q& }0 t
MessageBox(NULL,"Could not release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);. Q- B" p' L; Z: E: c$ c" y2 d
hWnd = NULL; // Set hWnd to NULL ) b, ?# z( f4 W" @) `1 H }</P>% f0 R& I" `. R& U2 C
<> if (!UnregisterClass("OpenGL",hInstance)) // Are we able to unregister class9 u, m+ v" x- ]8 H$ q( Y, w: x
{2 G* L/ y0 @0 ]2 m+ e3 \
MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);( h- s3 g, ?% l" m) o, T7 i+ N4 Q
hInstance = NULL; // Set hInstance to NULL2 A# Y, w" {& p: v f' a
}2 k" w; D& j. o r+ ^' Y, r4 ^, o
}</P>0 F, S9 `/ W" y- X$ S) F
<>/* This Code Creates Our OpenGL Window. Parameters Are: $ O! ?- g, t4 i * title - Title To Appear At The Top Of The Window 6 \, S$ b) E. ]$ L. ^ * width - Width Of The GL Window Or Fullscreen Mode% ?5 c# A1 R$ m: z
* height - Height Of The GL Window Or Fullscreen Mode! }+ A* b4 r& X* X) F- x
* bits - Number Of Bits To Use For Color (8/16/24/32) 0 }) A6 g8 W) G# M * fullscreenflag - Use Fullscreen Mode (true) Or Windowed Mode (false)*/- |. s: \1 X5 r6 F
- m8 S' H: h2 ~( C; D3 f
bool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) : f0 a }5 E x{ . x: s/ H" R ]4 E GLuint PixelFormat; // Holds the results after searching for a match % _8 u S0 t8 o WNDCLASS wc; // Windows class structure + a9 j: E5 G( a8 o DWORD dwExStyle; // Window extended style ! W8 q! {' F) y9 I% n$ n7 Y6 a DWORD dwStyle; // Window style" W& u6 C `9 g; \0 q
RECT WindowRect; // Grabs rctangle upper left / lower right values/ d6 p' `* ]8 V7 q
WindowRect.left = (long)0; // Set left value to 09 V! D) v$ B8 Q9 U" O- ], O: {* V
WindowRect.right = (long)width; // Set right value to requested width m' t1 O8 r! k A
WindowRect.top = (long)0; // Set top value to 0 , q6 ^1 c8 W5 h WindowRect.bottom = (long)height; // Set bottom value to requested height</P> ; O) U3 q* I2 z3 e% y" @% B<> fullscreen = fullscreenflag; // Set the global fullscreen flag</P>1 V7 A4 f( `3 w
<> hInstance = GetModuleHandle(NULL); // Grab an instance for our window1 e! o2 L, n" [2 q- t5 f) Z2 @1 S
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on size, and own DC for window! r6 p- h# A; D# }
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles messages $ E' L4 F* \; W) N" j wc.cbClsExtra = 0; // No extra window data - h; Z: z! |- w, _$ Y6 J( x% I& W wc.cbWndExtra = 0; // No extra window data * {! {0 `7 W/ ^0 M+ D wc.hInstance = hInstance; // Set the Instance 0 s, [9 k6 ?( F) w4 n3 W+ \ d wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon9 Q6 b! s3 N1 m
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer# y" i- V" x( G- u) ]( k
wc.hbrBackground = NULL; // No background required for GL7 h4 |2 H- _ b( J% A; j
wc.lpszMenuName = NULL; // We don't want a menu0 j I3 X) [$ n# X9 f C
wc.lpszClassName = "OpenGL"; // Set the class name</P>! K! s, G. V- x2 l, W
<> if (!RegisterClass(&wc)) // Attempt to register the window class , ] X+ E. G( N& x5 @4 d { / @4 g7 G/ w* [+ Y6 G# ]# X( t MessageBox(NULL,"Failed to register the window class.","Error",MB_OK|MB_ICONEXCLAMATION);</P>. {' ?: x! U6 O0 i
<> return false; // Return false0 J1 D+ p, T. P5 K ^' g* l. |# {
}" T6 k b8 d! k! }" l% }0 S
/ N# e% o+ W$ e! y. g if (fullscreen) // Attempt fullscreen mode?; ~# x9 }+ C f3 Q+ f. |' G9 O
{ $ g) y U4 {$ e! _. c) m DEVMODE dmScreenSettings; // Device mode ) z& D8 }& V) x$ q; X4 ^7 p3 O memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes sure memory's cleared ( v8 x. G8 l/ z1 i0 y+ U4 l dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of the devmode structure n* `0 |6 B# N" R* U% Q6 A dmScreenSettings.dmPelsWidth = width; // Selected screen width4 ^. s8 q) d8 n' w* M- s
dmScreenSettings.dmPelsHeight = height; // Selected screen height 0 Q1 j; ^3 a* n6 Z F dmScreenSettings.dmBitsPerPel = bits; // Selected bits per pixel, J8 L& r' | a& p3 E0 `
dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;</P>- B; j; N8 t6 U! y- h4 F
<> // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar. / G9 z; f# @% M3 Z& ? if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) 4 c6 J3 |5 u6 m/ h+ c6 h { 1 C4 r3 s3 N; n // If the mode fails, offer two options. Quit or use windowed mode.4 T i, @* R! w
if (MessageBox(NULL,"The requested fullscreen mode is not supported by\nyour video card. Use windowed mode instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION) == IDYES) B, ^2 i3 G! I {( `. ]4 {0 {( v; Z: p0 k* j
fullscreen = false; // Windowed mode selected. Fullscreen = false 5 a$ T; @% G' N/ }4 } }% J$ ]+ U7 g, O+ b
else6 R9 F7 N5 v _3 I9 [2 w( E
{ " ^8 k! L! g$ ?! h: M // Pop up a message box letting user know the program is closing.8 L6 N) C2 h5 b( @+ w8 F5 K
MessageBox(NULL,"rogram will now close.","ERROR",MB_OK|MB_ICONSTOP);) |+ l- B1 l/ K$ b
return false; // Return false & x! d+ k$ W& m }, Q! b; L9 l( U
} 3 N# L$ m9 t0 b c" ^% [% A& k }</P>1 v4 @9 y+ S$ m Y. E% h* a5 ~
<> if (fullscreen) // Are We Still In Fullscreen Mode?- z/ D3 p5 k: X
{ 4 h X. Y6 {' u& K% h/ G dwExStyle = WS_EX_APPWINDOW; // Window extended style: M9 i0 E) d. b) w
dwStyle = WS_POPUP; // Windows style , V7 ]4 l; [. q3 f2 Z ShowCursor(false); // Hide mouse pointer / E8 ?5 |; t7 ?* o6 g9 \ }! l6 S7 h2 c! p+ q6 i+ g0 ?
else9 N8 J7 m- s- r; H- [
{ o& N6 y+ c, O dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style1 |; s$ z4 q6 N% O$ j) E
dwStyle = WS_OVERLAPPEDWINDOW; // Windows style 3 l& A9 F3 U0 ]$ _2 W& e }</P> & o) d! o* z& @6 f! C/ E Q<> AdjustWindowRectEx(&WindowRect,dwStyle,false,dwExStyle); // Adjust window to true requested size</P>! B; h2 s( l9 @+ \7 T# b2 H: I
<P> // Create the window % x# V4 Z; w6 t6 J% _) F if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window , ]- Q, \2 R2 O9 t2 Y "OpenGL", // Class name , B' l5 G" {+ V. u& Q, F2 B title, // Window title , O/ u# U: r2 J1 o( o# r6 d Z9 F dwStyle | // Defined window style1 P1 `2 W8 F5 U+ o2 Z5 K9 g9 K
WS_CLIPSIBLINGS | // Required window style % }$ ?1 E7 {3 S) R/ X WS_CLIPCHILDREN, // Required window style1 k$ {) Q$ E5 x
0, 0, // Window position4 p( P3 d! M" k8 C
WindowRect.right-WindowRect.left, // Calculate window width4 P+ a6 Z! p n* D" y% ^6 d
WindowRect.bottom-WindowRect.top, // Calculate window height - U% Q- I+ t2 b: e, {' A; q* y" h NULL, // No parent window % O) x- s0 y0 a2 k: o) A% K6 p$ F( V NULL, // No menu1 i& X' w4 j- N; c( g+ f
hInstance, // Instance : G g: A5 M6 ]% m3 i7 u( m, ~4 J6 } NULL))) // Dont pass anything to WM_CREATE9 J. u3 p: m! ?+ }
{' W8 ^/ }# p" D
KillGLWindow(); // Reset the display5 e; D7 q. \* M p9 d3 S: R
MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION); 5 i) v% ~ j' k: \1 E% ~ return false; // Return false! b# o+ V' E1 ~! i! M
}</P> $ e/ c; Z+ v/ M<P> static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be / ]2 a4 n$ b& q1 c( W3 P {3 ~. _; B0 r6 |/ J7 ?# _
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor 0 m3 |% E8 r% |2 P( W2 R4 h 1, // Version number4 `& V' Y8 ]6 n% ]. f( X
PFD_DRAW_TO_WINDOW | // Format must support window & F: a9 A, {( y9 A PFD_SUPPORT_OPENGL | // Format must support OpenGL2 c- P6 ~9 p" h F, k3 |8 L( W
PFD_DOUBLEBUFFER, // Must support double buffering8 n* k2 g1 m g, Z$ P/ ^
PFD_TYPE_RGBA, // Request an RGBA format . U% ^$ t, c; k9 K9 t/ @3 M bits, // Select our color depth( `6 i5 h6 E1 L9 E
0, 0, 0, 0, 0, 0, // Color bits ignored4 r1 n2 i3 W4 H
0, // No alpha buffer2 S- W: s: l$ z& U5 w
0, // Shift bit ignored# W. `: {4 \6 {1 F& M; e+ F
0, // No accumulation buffer - M3 X0 t* @$ F! C 0, 0, 0, 0, // Accumulation bits ignored 4 P% F/ v- W7 f+ g5 T) y+ k 16, // 16Bit Z-Buffer (Depth buffer)/ m: c t+ _: c, o: v6 l. g5 l
0, // No stencil buffer3 ^: n. `& _/ |/ b0 p0 \2 S2 S
0, // No auxiliary buffer % f8 g+ r; T$ g3 W PFD_MAIN_PLANE, // Main drawing layer: l( u7 g! w& m! N3 V
0, // Reserved 3 l# Y) w1 t0 l M 0, 0, 0 // Layer masks ignored4 Z8 k, g3 a$ e' k0 l8 K; w* X
}; 3 J7 o }5 P8 W }/ T " I b* g% p. w/ z if (!(hDC = GetDC(hWnd))) // Did we get a device context?5 Q9 Y! T. ?( Y' }7 M) c7 r
{3 K1 G' J& `2 d- O
KillGLWindow(); // Reset the display 0 n9 X/ W5 j" |0 _; H MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION);& Q) s6 @$ _8 M" X2 r' Z
return false; // Return false$ u$ Z% `( s. f! H0 c+ {' P
}</P> 4 n6 p' x* n. U1 J3 d: S# z<P> if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did windows find a matching pixel format?: ~( A- x' c: c b! F: E
{ " L5 t6 {8 Q) [2 a$ r KillGLWindow(); // Reset the display: I2 j9 z6 M- V7 h4 o* Z
MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);8 ~5 l! j( B$ S# M. T6 O! y. g) R9 E
return false; // Return false3 b; k" q! ^0 J Z) D8 R. x% x
}</P> ; B% ?. G; ^1 w' V9 N7 {; D<P> if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are we able to set the pixel format?; O5 g' x4 h$ j% M+ `
{6 N( l3 g# T8 m- k) z P
KillGLWindow(); // Reset the display ( w! i* u8 o6 _$ ^) t8 S MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);; V! O4 ?. n3 |6 o0 L3 @
return false; // Return false C/ f% @/ ^, C! a" u }</P>9 d' K9 {* d1 E- n' H6 O/ k
<P> if (!(hRC = wglCreateContext(hDC))) // Are we able to get a rendering context? & v v6 b0 H8 A3 F- y {4 H9 |) M% i0 J7 t
KillGLWindow(); // Reset the display ! d& l$ o; c& P' N$ [ MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);, p6 j3 d) e6 f
return false; // Return false 9 E; |' ~- V" n# ~" D: y }</P>8 r. t* t" R( f( S) b# \3 F
<P> if(!wglMakeCurrent(hDC,hRC)) // Try to activate the rendering context + r2 H2 z% O$ u. a4 g( Q { C8 o1 P0 C+ C
KillGLWindow(); // Reset the display) v# _. S. F0 c$ r0 N
MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION); 8 U p4 z H& E j9 r5 y2 I return false; // Return false , I% X0 S7 S2 V5 L! r }</P> 1 c- j0 e! a8 r n) m0 ^<P> ShowWindow(hWnd,SW_SHOW); // Show the window " ]' d' T3 ?" ?7 m, [( U SetForegroundWindow(hWnd); // Slightly higher priority" c1 _/ F7 v+ b7 M
SetFocus(hWnd); // Sets keyboard focus to the window8 ?( q$ Y+ D' d9 t" h3 X
ReSizeGLScene(width, height); // Set up our perspective GL screen</P> [- I1 c+ Z5 l8 E2 Q; |7 c5 W; M; |
<P> if (!InitGL()) // Initialize our newly created GL window / W/ z& ~9 I/ w { % d8 v0 w9 t/ e2 G8 J( } KillGLWindow(); // Reset the display ! B. b! V. o Z/ e MessageBox(NULL,"Initialization failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);6 k0 y* h! D- r% K4 [
return false; // Return false) g8 [" n- y6 Y. C, G5 @8 Z
}</P> & ?" B* K! A- T<P> return true; // Success# \/ Q) `7 R A4 t' l
}</P> 4 A0 r9 Y$ H( G" z6 D" \<P>LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window% B' ]0 r4 C: b# G1 V& d/ O
UINT uMsg, // Message for this window ; B1 b! ?& |; X( D0 _6 r) V# | WPARAM wParam, // Additional message information' Q: g2 ?7 e9 R: M c
LPARAM lParam) // Additional message information 1 p( U( u0 p) X{. E# i( `% ^0 \) w4 I+ g
switch (uMsg) // Check for windows messages, P9 s; B6 X3 Y/ o
{ 4 f. c6 M7 s3 q6 B) }2 i case WM_ACTIVATE: // Watch for window activate message2 }+ x2 h4 H# c+ k: ^
{ * W0 L5 w8 }$ o7 Q9 ^ if (!HIWORD(wParam)) // Check minimization state/ Y" ~* v$ r! L+ i/ K% V
{9 C; ~, F/ r+ y5 P3 k2 M
active = true; // Program is active f @% \/ u- c* E
}) { U- H% p/ L: R- g
else- s; D% G+ K- j7 v. q0 y# S
{ ) V3 v Z ~! a. @' n active = false; // Program is no longer active ; q+ }! W! _$ t& P4 z& E }</P> 7 S: q0 d" @# P0 J<P> return 0; // Return to the message loop5 @( T0 K5 M0 M& y# V' B+ [9 d
}</P>1 \3 `% l0 q4 g
<P> case WM_SYSCOMMAND: // Intercept system commands - }' U7 N/ |$ J4 C+ x4 z {% N( G+ o% i) {1 K
switch (wParam) // Check system calls/ q5 d/ Z+ O# a) v/ c5 l
{0 J2 f: Z" w; k' _$ H2 f
case SC_SCREENSAVE: // Screensaver trying to start?( h0 Z) A. j1 ?0 E
case SC_MONITORPOWER: // Monitor trying to enter powersave?" j* f2 M$ h2 }! c
return 0; // Prevent from happening: x; { ]* N+ w7 Y
}' E# `, a. C9 K# q" p# q6 T
break; // Exit3 O- c* ]& D9 r& R& {0 L
}</P> 2 O/ ]' q+ Y- L7 H( a<P> case WM_CLOSE: // Did we receive a close message?/ e0 p7 A2 p2 ?3 s* G
{9 q. e- t; ?1 h( X, v
PostQuitMessage(0); // Send a quit message7 e: @4 {0 v. ^1 K
return 0; // Jump back % t" Y: a! o ^9 a. H. n }</P>! N) O" W. |' h2 X: c* K
<P> case WM_KEYDOWN: // Is a key being held down? & _1 N- R1 [6 @ { 2 S1 h+ g( u$ W1 O+ |& C keys[wParam] = true; // If so, mark it as true B( d- r4 i, ` F& ` F/ d# D$ }
return 0; // Jump back& O9 B8 f! D$ P) C+ S
}</P>& o1 ^, T# X* r" @2 f
<P> case WM_KEYUP: // Has a key been released?8 J. \' o3 _5 Z6 k
{2 X9 H9 [8 y0 z2 L
keys[wParam] = false; // If so, mark it as false F8 P0 U6 z* J8 N& B) `
return 0; // Jump back + {7 u1 A+ d$ i$ ?+ O- o1 a }</P>6 e" p1 C- g& n- E) }: \$ m& P
<P> case WM_SIZE: // Resize the OpenGL window1 u% Z- J* ?+ Z, Y8 u
{: W$ q5 \% S3 k5 h# p
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord = Width, HiWord = Height 5 j. z9 `. |1 h& \# a return 0; // Jump back , F; y9 M& B' i7 n! d }' o' i% c } 3 `8 a5 y# D. y6 E2 [* O' Z }</P># {, t2 h. ~0 ?1 c- A; ]: s
<P> // Pass all unhandled messages to DefWindowProc ( K1 m( I% \9 d return DefWindowProc(hWnd,uMsg,wParam,lParam); 6 k, p5 K8 |2 U. Q6 \}</P> + H, ~0 [- ~7 z. E Y( `<P>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) ' E% Y, s) c3 q& W9 F6 c{ 2 |4 a- Q8 o& @ MSG msg; // Windows message structure $ Q- G) [ {" } j, R) `# H' V: G bool done = false; // bool variable to exit loop</P> / P! s. X2 d: r- j {# Z<P> // Ask the user which screen mode they prefer2 \/ x( X$ |" W" f8 s, \ E6 P: A, s
if (MessageBox(NULL,"Would you like to run in fullscreen mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION) == IDNO) * e! j; H+ O" }$ \- u {, B$ `. y, K8 c9 {: n* a' D
fullscreen = false; // Windowed mode( t# K* ? V1 C1 N q
}</P> 8 o( D9 C+ c3 Z- l# n<P> // Create our OpenGL window$ R5 a u% H7 A- d$ o& r+ J% l
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)) 1 w1 C7 }" L$ E7 f8 p0 w- { { - f- `0 L' m. t: u% l `; V& m5 X return 0; // Quit if window was not created( {/ S% ` d% Z$ [# `3 l
}</P> 2 `4 G) e8 H3 O' `* Y) B<P> while(!done) // Loop that runs while done = false6 F+ V- H0 l! L/ l
{; z9 Q1 C' ^) |1 O$ o' a4 M5 i
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is there a message waiting? ' E. n' Z( b" W4 }# m9 W { 4 P l* D' }4 N* J if (msg.message == WM_QUIT) // Have we received a quit message?$ A3 w; R' w+ b: L( X
{5 {( W3 s! H5 u. W" f
done = true; // If so done = true1 A* r5 b( A' ]$ u5 C
} ' i( b& ?! X, |+ b, {( [ else // If not, deal with window messages 9 k2 {' h6 I1 {- k. C6 O: g6 e& z& \ { / K/ e9 ~2 R8 O2 n; ^ TranslateMessage(&msg); // Translate the message2 M" O7 ?1 U$ Z, z: h9 J6 U
DispatchMessage(&msg); // Dispatch the message1 I0 o( A; @0 [# }$ M
}0 `+ H" C1 `: [2 X
} 1 d6 h7 f* r- B; _: T+ X else // If there are no messages 8 k* h+ z8 F7 T5 X/ n7 v) _ { ; |/ Z8 |! g* T1 A // Draw the scene. Watch for ESC key and quit messages from DrawGLScene(): L' x$ V9 a: d6 i/ c
if (active) // Program active?% `" F2 d0 Q- N" h9 V
{ 0 {" \! u. O0 g& d if (keys[VK_ESCAPE]) // Was ESC pressed?8 d& l: q( Y: r! T: J/ U
{7 P8 ?2 q1 W+ E1 |/ [9 ~
done = true; // ESC signalled a quit+ x. v1 @) L$ v3 _/ P' F" Q
}/ m6 z3 r6 {/ T/ P' m
else // Not time to quit, Update screen1 h! H: u8 _5 i/ \% \
{ * S- k0 }# c$ _- J DrawGLScene(); // Draw the scene + ]- G5 |% H' ?" A: b; Z SwapBuffers(hDC); // Swap buffers (Double buffering) ) p5 m# e2 J# R7 L7 { } 3 G7 t& Q3 c0 q! X9 E3 m( J# ` }</P> 8 Q4 {% V9 y% m: j( _9 m- Z% C<P> if (keys[VK_F1]) // Is F1 being pressed? % a& V4 k7 ^' r/ n {& t# @/ L) S! O# s6 q& h
keys[VK_F1] = false; // If so make key false; |% Q; a% z. l% Z
KillGLWindow(); // Kill our current window ) s$ K& E$ O3 ?7 h1 y fullscreen =! fullscreen; // Toggle fullscreen / windowed mode y7 j$ Y3 q1 u' p2 Y // Recreate our OpenGL window 6 A; t$ |& V. i5 P* s if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))+ W9 X; \0 f: b0 Y
{ . {# `2 }+ L/ o1 U. A& {3 l* O. P return 0; // Quit if window was not created . n% G3 {) _6 J( _7 { } t% t5 g8 T K9 K. \0 k6 [
}$ Z) q! c6 M3 p8 q2 `1 T
}" C) n! G! A9 L+ p$ c7 p
}</P>0 l' c l/ y7 p
<P> // Shutdown 9 n4 ?6 O+ X. u. b4 M) c KillGLWindow(); // Kill the window 3 c8 o: h! C) y, V* Z6 u return (msg.wParam); // Exit the program ! t' @9 q a& X} 5 @2 P& z5 r; x//---------------------------------------------------------------------------</P>