<>这是NENE的OPENGL的框架CB原代码,是黑屏的效果,最简单的。OPENGL我才开始学,很多不懂的,希望和大家交流,共同进步,我会把我的资料和大家共享的!</P> 3 r U) | F: O& J |$ `<>首先在CB下建立一个CONSOLE的程序,然后把CONSOLE APPLICATION的勾去掉即可。然后再把以下的原代码粘贴上去就可以运行了!!</P> U [+ F* u3 j
<>//---------------------------------------------------------------------------</P> 5 ^( }% o$ p% h% |5 Y<>#include <vcl.h> 8 ?& Y% u& Y: }8 z0 w. _#include <windows.h> // Header file for windows , X. l0 d6 T; ]) s+ F#include <gl\gl.h> // Header file for the OpenGL32 library1 T, f5 L/ H2 E+ @3 A
#include <gl\glu.h> // Header file for the GLu32 library/ Z4 b' R/ o' D
#include <gl\glaux.h> // Header file for the GLaux library% Y4 L/ O$ W* Q- J9 n
#pragma hdrstop</P> . R5 u2 c8 E. d/ G<>//--------------------------------------------------------------------------- # J( @9 R& u1 B0 G1 R+ Q8 c D1 A) {#pragma argsused</P> * Z) j+ f* f) R* g<>HGLRC hRC = NULL; // Permanent rendering context 6 X4 r% X# Q7 w' A+ D: L1 GHDC hDC = NULL; // Private GDI device context ! w; @: ?/ b& q$ a( N8 s8 {1 qHWND hWnd = NULL; // Holds our window handle& Q3 n8 E' n' B# l" n6 p y" Z
HINSTANCE hInstance = NULL; // Holds the instance of the application</P>, ^* v% ]8 e2 V# @- C# {8 m' F
<>bool keys[256]; // Array used for the keyboard routine& Z5 s& z0 L! O: Q }% }
bool active = true; // Window active flag set to true by default" f: Q+ r7 I6 c( g
bool fullscreen = true; // Fullscreen flag set to fullscreen mode by default</P> 7 V W0 o" o7 |, O<>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc</P>& c! H E8 C, i/ L4 a k' X! N7 z
<>GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window 4 E7 W. E. ?( |* o8 ]{6 {: |) o6 ~# X+ I
if (height == 0) // Prevent a divide by zero by . s% X; ]7 w% ?( k! ^4 `% m& E {+ E' ]& `8 w2 x5 v
height = 1; // Making height equal One - E) N) s" U" F: ^% M }</P>- W. Z8 w: i% v
<> glViewport(0, 0, width, height); // Reset the current viewport</P>7 M3 D! M+ |. d$ A$ \
<> glMatrixMode(GL_PROJECTION); // Select the projection matrix 3 x8 z+ {" e- ~" D3 Z( z glLoadIdentity(); // Reset the projection matrix</P> Y$ F; W2 x2 J; v* D<> // Calculate the aspect ratio of the window7 o: \7 q" N' [, E; ?! J
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);</P>+ v% U9 j5 x, F
<> glMatrixMode(GL_MODELVIEW); // Select the modelview matrix ! G- G8 g' `9 o: N glLoadIdentity(); // Reset the modelview matrix- N i, e0 F9 k% _* z# H( I+ r \% d
}</P>- J, O1 Q3 P+ V6 d: k9 a, e
<>int InitGL(GLvoid) // All setup for OpenGL goes here 7 D/ D5 R! {0 C+ |{$ C6 Z% _/ r. V O% z9 Y
glShadeModel(GL_SMOOTH); // Enable smooth shading; ~8 h4 ~- ?- n/ g' h
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background . }# p2 ^7 p" v- J- o; D7 y9 F4 k glClearDepth(1.0f); // Depth buffer setup/ ?3 z+ S" o0 j7 H+ l3 \5 ~# y& L
glEnable(GL_DEPTH_TEST); // Enables depth testing q+ _, A5 b ~
glDepthFunc(GL_LEQUAL); // The type of depth testing to do . j; y- {$ z* j1 U1 m1 @ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations" l5 P7 E/ O5 e6 |& c1 A% O
return true; // Initialization went OK2 i' o/ U% K/ r& A
}</P> 2 d1 r# ~& r. W4 h- j" y9 a7 o<>int DrawGLScene(GLvoid) // Here's where we do all the drawing8 F! Q7 g6 M+ k: z9 w
{ / `" k' F. v; R$ Z" G glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer |1 Q& J4 d' ~ }3 H7 S glLoadIdentity(); // Reset the current modelview matrix & ~/ ]# I9 S2 ~7 y# ~+ ~ . q8 K6 j! j) k+ o8 B) y return true; // Everything went OK ; v5 y/ x9 N! ~3 E4 |}</P>5 G" t% a5 C- h s
<>GLvoid KillGLWindow(GLvoid) // Properly kill the window. \& _# T$ D" x$ m! \
{' U# f! [% `$ b2 O. P: u; h% q
if (fullscreen) // Are we in fullscreen mode?, P: Q8 U, J& _9 d
{" m1 y! C7 v: Q& C/ A, u4 w+ R
ChangeDisplaySettings(NULL,0); // If so switch back to the desktop9 ?$ M* m3 N) t
ShowCursor(true); // Show mouse pointer . G' t% E v3 B P% T* ~ }</P> 6 b4 D) B: c0 Z) ]# Z& a<> if (hRC) // Do we have a rendering context? 5 s1 m4 r# p3 l! Y2 P {4 F+ I a$ F) R' C$ J5 U
if (!wglMakeCurrent(NULL,NULL)) // Are we able to release the DC and RC contexts? " o5 C/ x' X3 {4 _; i, l2 i5 e& s, h { 1 r$ ^( ? M4 K* w3 e2 s g8 U MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);' z; K- z7 f& e6 z
}</P>! ^5 Y% R g) P; A2 i) { ]3 K
<> if (!wglDeleteContext(hRC)) // Are we able to delete the RC? 0 X+ a" `# u! c5 e4 f# @ { 0 [: R! I, t3 _. U$ U2 j1 v MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);( ?# |8 t. n9 k! p- b
} + O3 ~0 U$ e8 A6 z& A( s hRC = NULL; // Set RC to NULL 6 o) D/ y' b+ p( h$ w. i+ E }</P>, J3 Z1 J, L/ b. t0 z
<> if (hDC && !ReleaseDC(hWnd,hDC)) // Are we able to release the DC- }) \1 z% Q2 g
{5 H+ y3 K0 m# V/ P8 S7 Z" M
MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 0 F! M1 D3 l5 K3 U8 s: o hDC = NULL; // Set DC to NULL . i- c/ b, k, x. R# @4 M/ R }</P> + i3 m& H9 T$ u7 f( o& Q<> if (hWnd && !DestroyWindow(hWnd)) // Are we able to destroy the window? 0 \) o7 |5 p* u5 @1 | {" } r8 f, A7 G5 q* r* ?
MessageBox(NULL,"Could not release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); " f+ a" D8 O5 D, @/ ~ hWnd = NULL; // Set hWnd to NULL % E% M) m+ Y8 ?/ i, [ }</P>! j5 m$ l$ I+ q4 m8 l: d
<> if (!UnregisterClass("OpenGL",hInstance)) // Are we able to unregister class ' a7 o0 O: b& y7 [/ y9 y9 O( L {# ^2 H% k$ _* y; B
MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);: l F8 z6 p8 b [! X5 `' A) q
hInstance = NULL; // Set hInstance to NULL ; i0 V# c$ i, m4 l, `1 q8 H } 1 r0 B# u& S# q3 K}</P> 0 | U% Q+ i* x: Z* z<>/* This Code Creates Our OpenGL Window. Parameters Are:& V6 I: _$ {/ l
* title - Title To Appear At The Top Of The Window {/ r- B- ^3 E5 U4 |& C' w * width - Width Of The GL Window Or Fullscreen Mode - Z1 ^* l$ N6 t/ @4 `/ @ * height - Height Of The GL Window Or Fullscreen Mode0 ]/ O. o, e, B
* bits - Number Of Bits To Use For Color (8/16/24/32)) p' ?3 S- q- `; k
* fullscreenflag - Use Fullscreen Mode (true) Or Windowed Mode (false)*/: A! `8 Z/ u) g- f, S8 M
' u1 c: y" R: M; `- t% x
bool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) ]) Z$ G8 h* v" b8 O/ Y" n
{ * k; Q; k) {, Z* Q+ R0 K( J$ \ GLuint PixelFormat; // Holds the results after searching for a match " U" N9 v B) U* D3 W. X3 K WNDCLASS wc; // Windows class structure+ y) [5 x# \9 L! v2 B
DWORD dwExStyle; // Window extended style $ \; f9 A8 D. X! p; B! a- v DWORD dwStyle; // Window style 2 a7 c: I/ {, k% j( x7 ? RECT WindowRect; // Grabs rctangle upper left / lower right values4 z d% c( E( W7 Y1 x5 w0 C( H7 E
WindowRect.left = (long)0; // Set left value to 0 4 o6 V4 i" a6 l" S7 t WindowRect.right = (long)width; // Set right value to requested width/ U: x: m4 o. o9 N' D7 N! m
WindowRect.top = (long)0; // Set top value to 0 $ z j4 R7 Q* @6 ~+ A- b L WindowRect.bottom = (long)height; // Set bottom value to requested height</P> $ Q& D5 O+ Z, V<> fullscreen = fullscreenflag; // Set the global fullscreen flag</P>7 c- |/ N$ r( N: ?# V
<> hInstance = GetModuleHandle(NULL); // Grab an instance for our window M$ ` [/ s, a: ^3 b( D, e! J
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on size, and own DC for window ! w$ d9 v4 h: K0 T. s wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles messages 6 E9 {9 l, E, X( ~; ]0 G5 f wc.cbClsExtra = 0; // No extra window data 4 L3 s0 T. C8 J! k# \( A wc.cbWndExtra = 0; // No extra window data, T' d$ O9 B# q2 c' r+ d. ]
wc.hInstance = hInstance; // Set the Instance 4 ?( a9 @0 \$ u+ z wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon 7 x( q0 y" k9 A* _3 B wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer $ \& g5 i) G) U wc.hbrBackground = NULL; // No background required for GL , _) t2 i n+ G( y wc.lpszMenuName = NULL; // We don't want a menu ) ?8 @- C6 I( ~" U) Z wc.lpszClassName = "OpenGL"; // Set the class name</P> , I. z3 q8 q: q7 v" G0 g) P<> if (!RegisterClass(&wc)) // Attempt to register the window class3 n. U4 N2 C: ]/ r5 `. @
{ . z% R8 L1 G) H( C1 g4 s MessageBox(NULL,"Failed to register the window class.","Error",MB_OK|MB_ICONEXCLAMATION);</P> 7 o% p! `- _& k1 @, T<> return false; // Return false ) ?3 W7 L& I5 [# ` }# N0 @* \ i* m) U2 X% B
! _! [! r* i/ `* }, h" o3 H if (fullscreen) // Attempt fullscreen mode? + f% T& N2 h$ U) g: [ { $ v8 d! G2 H$ [6 H' | DEVMODE dmScreenSettings; // Device mode; q( Y1 I6 d8 `9 N7 p
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes sure memory's cleared2 O; O5 ]% `& a) d9 p
dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of the devmode structure $ _, E0 Q9 E) C: r2 W# K dmScreenSettings.dmPelsWidth = width; // Selected screen width # c) c, x3 h, [9 q5 T! i( Y0 z dmScreenSettings.dmPelsHeight = height; // Selected screen height " i) ]0 U; |% L dmScreenSettings.dmBitsPerPel = bits; // Selected bits per pixel' {2 ~4 L; N2 D& k- N2 N1 C F2 ~
dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;</P> 4 T0 s( X' U7 M: Y, `3 h<> // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar./ B& W0 o; g& {; \* @: a7 B/ F
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) 9 ^% D& H3 n: F {* I ~. n& L* ]" f
// If the mode fails, offer two options. Quit or use windowed mode.% E) a& w2 p+ i% ^+ j- K
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) ' j( @/ [3 E# t" E8 C {3 x7 X8 i; t6 o" D* q
fullscreen = false; // Windowed mode selected. Fullscreen = false $ g$ g1 V, [9 R9 h }1 X/ q1 B3 n0 j" `' k6 \: s
else% |5 z" \* \, A, U/ b3 P5 g
{1 [- n( z' M$ i C
// Pop up a message box letting user know the program is closing.- Y& Y3 W( X# m( H: f1 e
MessageBox(NULL,"rogram will now close.","ERROR",MB_OK|MB_ICONSTOP); ! z# O' z# |: {- D8 N' x return false; // Return false 5 I9 z7 f: Y& O; ]# ^6 V } 6 c& \& J" t. o5 p } # z* w. @6 ~' U4 y5 e7 j1 J }</P> ( j5 S4 y. l8 t: r$ `) Z3 l: R( {<> if (fullscreen) // Are We Still In Fullscreen Mode? ) e6 ]: }5 i/ G& D$ l {) h. b, j1 Y+ ^5 {; X4 F8 b8 t& I
dwExStyle = WS_EX_APPWINDOW; // Window extended style2 {8 I6 t& ~) O1 r- |" l! T2 k) U
dwStyle = WS_POPUP; // Windows style- f( m+ C- T% b7 x: T. D- p
ShowCursor(false); // Hide mouse pointer . [3 t$ c4 j7 V% ?" ^ } * E4 ]5 B3 d7 z' p else7 F/ F" i. Z; w/ q
{ ) ]& I8 a2 h( K) y" ?8 C" x dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style i3 C P# P6 h0 L' W dwStyle = WS_OVERLAPPEDWINDOW; // Windows style; X" T5 ^8 T6 V( N) W
}</P> 7 N! g) S( k8 }( z# x& y2 V<> AdjustWindowRectEx(&WindowRect,dwStyle,false,dwExStyle); // Adjust window to true requested size</P> $ g9 A: F1 D. b6 k' ^<P> // Create the window 7 L" {' e I2 w( `* |& L5 b4 a if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window0 b, ?" \' Y7 y& V1 C% k. M" u% c0 _
"OpenGL", // Class name W7 b2 S7 @+ p- K: Q' F6 \) P: c title, // Window title $ u( A @0 R* N; P, } dwStyle | // Defined window style, F) ], W" A, _0 r7 ?3 U
WS_CLIPSIBLINGS | // Required window style / G) S0 H' X/ c2 l) C/ a0 U WS_CLIPCHILDREN, // Required window style# C6 [! U( A- R7 q! D' x
0, 0, // Window position : x5 \6 m/ D" q, f' [3 L! K WindowRect.right-WindowRect.left, // Calculate window width2 A" h+ }8 ~6 Z+ h2 N
WindowRect.bottom-WindowRect.top, // Calculate window height ! {4 T y4 Q5 n) K NULL, // No parent window 7 g: D4 Q! R7 v# l/ V( Z$ t0 V NULL, // No menu # P$ Y- D( }) B! w7 `& X hInstance, // Instance( g, l0 ]% n8 o0 K. ~
NULL))) // Dont pass anything to WM_CREATE + u% \$ B2 s; L! y, c8 S7 ~ { Y* ]8 e* `; j5 ` KillGLWindow(); // Reset the display P. [2 @# D' ]! E6 S1 J' I
MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION); 3 c2 }* G M v% c& T2 D | return false; // Return false, I3 _6 q. \* m. [
}</P>- Y- _/ |0 ~; x8 S0 o1 @1 A3 {- h
<P> static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be- M G- b4 D9 }: e
{2 m( H3 H+ [$ R3 _6 ?
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor: n! M( E# H1 Q g! f) G
1, // Version number% R2 t, W- h$ X) }, L X1 k
PFD_DRAW_TO_WINDOW | // Format must support window , I. K. Q- E) m3 h! B' b3 S J8 i, W PFD_SUPPORT_OPENGL | // Format must support OpenGL v$ p( d5 ~. o% w& H4 ]' M
PFD_DOUBLEBUFFER, // Must support double buffering/ F0 ?- {' L2 v- S) Y; M" C! \
PFD_TYPE_RGBA, // Request an RGBA format4 \$ [' c' l; T
bits, // Select our color depth ( v2 [8 y+ |# M; Y: A2 i$ v 0, 0, 0, 0, 0, 0, // Color bits ignored' I/ \- s2 R$ g
0, // No alpha buffer 3 d6 y6 H# c" J+ t 0, // Shift bit ignored . l3 }7 q9 q) i! Z* i; P& {' s | 0, // No accumulation buffer- n1 _% }* F+ z0 [
0, 0, 0, 0, // Accumulation bits ignored$ }) s9 H0 n8 A7 G1 ^7 R
16, // 16Bit Z-Buffer (Depth buffer) , ~, V! l- D- E- ] 0, // No stencil buffer - N: v+ U' V3 m' \0 F 0, // No auxiliary buffer 9 V# k& Z2 d! \. x, |0 b3 y" d PFD_MAIN_PLANE, // Main drawing layer + i, y* ?9 J7 M$ y 0, // Reserved$ @2 s0 t" K* A' L) E
0, 0, 0 // Layer masks ignored " b3 ]3 Q+ G8 r0 ? };8 p7 P+ J3 q/ l5 D6 l
; S4 N1 L* U3 y if (!(hDC = GetDC(hWnd))) // Did we get a device context? : m: Z4 Y' i+ b { . j5 e# J- _6 W8 y$ D KillGLWindow(); // Reset the display0 Y! C6 o) L4 I0 z) p
MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION);" g6 D+ W; [* n3 _$ d; k) K
return false; // Return false/ N% r& C2 n1 @) Z
}</P> $ `) D( q3 L% q3 Y; Y6 y* W+ C<P> if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did windows find a matching pixel format?9 `, d+ F3 W) f7 n* g- ]4 o
{ * J# k% y* j/ g9 k0 x KillGLWindow(); // Reset the display 9 {& g% ~, G- M; {( V3 A MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION); 3 h# Q" }: l. @# Q$ i5 P return false; // Return false 1 `* b* p, _2 h% L6 h8 ?- E" r- } }</P> 2 ^( B4 j6 v3 A: `/ q3 |<P> if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are we able to set the pixel format?+ j' z2 k1 C3 H( f. O6 U8 t' r
{% O: Y9 E* D1 m- q" h+ J; r
KillGLWindow(); // Reset the display / V" ^) Y x! n) d" ?! W2 q5 j" { MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);9 S& s, i2 {$ A
return false; // Return false2 Y! c3 b# U! P/ U3 {
}</P> , J4 ?3 v& h+ ?0 R& c; f* s<P> if (!(hRC = wglCreateContext(hDC))) // Are we able to get a rendering context?2 O% k; j8 n" T; J
{ , T. z8 K; s$ w. w: `: K3 i KillGLWindow(); // Reset the display# u+ x) P' O0 F( Y i( C- S
MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION); ! ~4 V- X a0 n/ H: {/ E1 k return false; // Return false1 Y3 ?, t- k. ` m: c6 l
}</P> ( {% Q! a9 z3 \' H4 r9 x$ Y<P> if(!wglMakeCurrent(hDC,hRC)) // Try to activate the rendering context : a) U+ w- e- e- S3 z% O7 D- e6 i { 9 r* s' {+ k: d8 p! x2 q" L KillGLWindow(); // Reset the display0 g; H- e6 D0 s0 v# r
MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION); % |1 J* z1 Z3 z, q+ ^4 L+ g ^" M! f, h return false; // Return false6 S6 \; } h2 r$ A1 y6 v+ H
}</P> % J; W" t G3 k6 G* z0 i$ k<P> ShowWindow(hWnd,SW_SHOW); // Show the window6 F6 L3 R/ m. E, |8 [9 G
SetForegroundWindow(hWnd); // Slightly higher priority 5 S8 q4 J# m' Q: m; }5 e" S SetFocus(hWnd); // Sets keyboard focus to the window" P% @! L9 e7 L% d7 A2 G9 _( i$ J
ReSizeGLScene(width, height); // Set up our perspective GL screen</P> 5 B& S0 J( I1 {& ~<P> if (!InitGL()) // Initialize our newly created GL window 3 L- }: J$ c/ H. ~6 g/ N {/ R7 v$ t$ W- Y
KillGLWindow(); // Reset the display / Q" I w- [, F! p! H MessageBox(NULL,"Initialization failed.","ERROR",MB_OK|MB_ICONEXCLAMATION); ! G' ~+ g5 K+ Z6 q+ Z2 E) p return false; // Return false" ^9 m" [* F% b2 z
}</P> 9 @- d2 D2 A5 g( e2 [<P> return true; // Success7 L0 T% L& O$ u9 u# _ W0 _
}</P>8 R6 p! [3 H: @! R0 J- T, ^
<P>LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window* w0 W2 q4 w- Z0 t/ Q- k+ R+ x
UINT uMsg, // Message for this window" m! `) z* z& o: c; R, }1 D& w2 N, Q
WPARAM wParam, // Additional message information- `; {" N6 ^" B
LPARAM lParam) // Additional message information & a& B: A8 ~, k3 ~3 A6 _2 _: X{) z9 H* _1 X: c/ S( `/ j3 X5 W
switch (uMsg) // Check for windows messages ( K* l" R7 y$ a. l$ ] { ) b# J# f, H! Z) N2 Z6 z' [6 L# ? case WM_ACTIVATE: // Watch for window activate message3 d" I3 L2 ?% G# X5 _- m& W# E/ S
{3 S8 m0 R4 D @& d+ T
if (!HIWORD(wParam)) // Check minimization state ' K1 h: t1 l" a5 D { . ^; ~1 E/ Q; z9 X+ ?& R active = true; // Program is active" Y( ]6 s" ?; F7 H6 p: M& X
}- r( e8 h3 c" z5 X& q
else5 C% }4 w: B3 Z! T" h7 N
{6 W: {1 h6 Z ]3 A9 b6 N4 \$ y" B
active = false; // Program is no longer active4 n1 s/ r# \/ b. x+ W
}</P> % P% l0 v+ T$ p S; q<P> return 0; // Return to the message loop4 H0 A* n2 ]6 e h
}</P> , Q8 V ?; E f4 k7 A<P> case WM_SYSCOMMAND: // Intercept system commands - h% i) v. f# W { / ]1 \( P8 J; y' s$ @ switch (wParam) // Check system calls , [* p) O7 g9 a# o1 {. x {' l/ D$ z9 Q1 S8 Y9 f
case SC_SCREENSAVE: // Screensaver trying to start?$ | |6 ]8 k% ^) y# K
case SC_MONITORPOWER: // Monitor trying to enter powersave?% F* D' V8 d" v: D8 }8 w
return 0; // Prevent from happening- h$ T9 Z4 X, `. a, v9 u/ Q
}4 u* _7 T( T! H' D
break; // Exit S! C/ b5 f; e }</P> 0 N2 M* `" A6 x2 s* C<P> case WM_CLOSE: // Did we receive a close message? $ v7 c$ C( ^$ a& |5 P. O8 Z H { 7 y( n" t: J- w8 m PostQuitMessage(0); // Send a quit message ) ]% R& ? q4 Y return 0; // Jump back / T5 L1 X) a! j/ C# [/ a }</P> 4 P* I9 s+ [: i1 g0 w/ \<P> case WM_KEYDOWN: // Is a key being held down? 1 d$ {9 q* Q3 r$ \4 a { ! c$ m1 m1 f4 X& N7 r$ q$ C keys[wParam] = true; // If so, mark it as true& }3 |2 L2 i4 c
return 0; // Jump back/ h3 R) z! ]) [4 J: [+ x- e
}</P> : J- ?) d% ?: v6 r<P> case WM_KEYUP: // Has a key been released? ; ^+ h8 {4 g( u. N4 F& A( m {, y3 q0 ?9 R4 X; c) n. ?/ d: t
keys[wParam] = false; // If so, mark it as false . M$ B8 Z3 q; G I$ F& q. j return 0; // Jump back3 i3 L% O$ q* m6 a
}</P> ; T7 N- R8 Z# j& p<P> case WM_SIZE: // Resize the OpenGL window, V3 Z) h* i4 D
{, V' J! W+ t d& v2 S$ k3 k: X
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord = Width, HiWord = Height , D2 {' K" p' {6 i8 d( G5 c( } return 0; // Jump back" F1 F2 v; s2 S5 x/ ~
} 1 u+ C* D' r# |5 `' S( f% U( S }</P> 7 n) m2 n9 {' P<P> // Pass all unhandled messages to DefWindowProc 0 n- g' v1 c; c5 L, Y7 q3 z return DefWindowProc(hWnd,uMsg,wParam,lParam); : C9 m i F i- M+ D}</P> ' \; ^: R7 G+ V# }' s/ i4 B<P>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) & z' }9 V; G; [$ |( f7 c, n y{ 6 @4 t# E+ ~4 C* G MSG msg; // Windows message structure& t( J6 D- j, t' n: z: Q
bool done = false; // bool variable to exit loop</P> ; m' p( p9 @4 ? z9 t' c<P> // Ask the user which screen mode they prefer $ N C% k* w2 Y7 y2 ` if (MessageBox(NULL,"Would you like to run in fullscreen mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION) == IDNO) 7 u9 l% {7 d. { ^ x: U {/ X) b1 A( l! K2 {: W1 [6 A
fullscreen = false; // Windowed mode. Y2 G+ M" x0 k; ]
}</P>, p( g/ L* ?7 Q/ C3 `$ E
<P> // Create our OpenGL window ' z( i7 U4 ?8 y- ` if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))) D* W1 f7 K# y/ K2 H% c6 W
{ # t Y5 I- o& n6 w+ v return 0; // Quit if window was not created$ J, ]9 S# Q" I
}</P>; V: J7 A. M7 I
<P> while(!done) // Loop that runs while done = false ' e- W4 `& S' Q |0 G( @1 O {! R) S) i6 s* w/ Z2 H8 j! \( I3 @
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is there a message waiting? 6 {4 ~8 S% l: S" l) Z/ g, T { 1 F/ O% O, z5 y. K if (msg.message == WM_QUIT) // Have we received a quit message? : _% x9 X9 ]; F; s1 N! q6 }: {2 O { * C( j" e! }( q; w0 M* g done = true; // If so done = true - K8 T9 Q( U+ w- f/ h8 p. a2 w! ] } * A. k. P; i) L3 z+ N, C else // If not, deal with window messages' e2 B6 m+ X0 y1 q8 z
{2 d4 y6 B9 X: ~& @" |: n3 z
TranslateMessage(&msg); // Translate the message; a. u3 q8 R0 s* N# Q" [( e
DispatchMessage(&msg); // Dispatch the message: N- ^ j- c, t$ k; X, ~$ v* t
}' ^3 g3 @ o( w+ t
}% M3 M& I: y0 Z2 C6 _% k
else // If there are no messages$ | z x) N5 @ v
{ ( ~( P: y1 Y z( M9 C+ M# H# [ // Draw the scene. Watch for ESC key and quit messages from DrawGLScene()# ^) p* m, W5 y/ S& v1 S
if (active) // Program active? " r7 {# C3 s! M2 ^. e {7 y/ C6 B) V n! N$ Y
if (keys[VK_ESCAPE]) // Was ESC pressed? 1 u( D& G! v S7 a+ |9 S' \+ b! a { + r( M ~. h8 U+ K# r7 S done = true; // ESC signalled a quit ; G7 [1 Q/ J6 Z! W, K4 ]& n2 W' u }0 a. G# G% x0 V) ]" S
else // Not time to quit, Update screen ~" E _" G0 w( ^! Q2 F, K3 D! C
{, O! E" M+ [+ w
DrawGLScene(); // Draw the scene: T# d- @) ~( R; ]% v
SwapBuffers(hDC); // Swap buffers (Double buffering)# ?! z! ^2 B0 r# v2 `" l
} 8 k1 b m8 x8 f9 [+ e1 j. b# W5 I }</P> * U4 w7 t* f2 y2 S6 c- m8 U! n<P> if (keys[VK_F1]) // Is F1 being pressed?2 B) P) d4 K5 _4 @
{ " u8 O( |; l n# u6 Z, o8 c8 G keys[VK_F1] = false; // If so make key false $ M/ Y$ D- Z) o0 e3 q2 A% S; E KillGLWindow(); // Kill our current window- j( t. @5 |5 s3 [7 X
fullscreen =! fullscreen; // Toggle fullscreen / windowed mode/ V; ]/ }. K6 u% d( Q
// Recreate our OpenGL window 7 A: \; ]9 s Q2 v# ] b if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))4 Q0 T8 ~5 ^# Z# j y8 H: l4 Q4 O
{: L- c; b4 {6 [, S: A' z( g- S
return 0; // Quit if window was not created / C! Z$ \# b2 ~6 Q! o3 W# o }$ f0 }' ]( p2 B
} # M6 g2 X( A$ n }1 \# N2 Q) H7 U. C
}</P> & ~! M& P8 ]% t5 |( K! ^! f K<P> // Shutdown/ B, l( P' {0 I# T( `) V. {3 N2 J
KillGLWindow(); // Kill the window W( }4 n) O) m
return (msg.wParam); // Exit the program6 x. q; h% h* E
}1 Z- u, M7 m% v! c1 t
//---------------------------------------------------------------------------</P>