<>这是NENE的OPENGL的框架CB原代码,是黑屏的效果,最简单的。OPENGL我才开始学,很多不懂的,希望和大家交流,共同进步,我会把我的资料和大家共享的!</P> e/ \3 m& S+ K
<>首先在CB下建立一个CONSOLE的程序,然后把CONSOLE APPLICATION的勾去掉即可。然后再把以下的原代码粘贴上去就可以运行了!!</P> " ]9 Q5 Y/ U/ u<>//---------------------------------------------------------------------------</P>, j; g" f/ B @, r; h9 U
<>#include <vcl.h>. {1 l, V, h1 ^2 C
#include <windows.h> // Header file for windows/ Q/ ?2 m3 V, e9 Z& s4 l+ b) W
#include <gl\gl.h> // Header file for the OpenGL32 library% w2 \4 G& ]8 K$ @
#include <gl\glu.h> // Header file for the GLu32 library " o: Y+ Y' y; w8 a1 U#include <gl\glaux.h> // Header file for the GLaux library8 ~; V9 V/ o) y0 X
#pragma hdrstop</P> $ f1 A$ k; L7 f' Z2 h, p<>//--------------------------------------------------------------------------- ! g3 w- J% R/ ^1 l r) Q#pragma argsused</P> . `* @7 w1 w) r5 N) j6 u2 u# e<>HGLRC hRC = NULL; // Permanent rendering context- w! n2 h$ L* F$ B7 ?& [
HDC hDC = NULL; // Private GDI device context ! Z6 h$ S; z* tHWND hWnd = NULL; // Holds our window handle5 d) @% k- |" C& Q' B* x$ Y1 ]! |' b! G
HINSTANCE hInstance = NULL; // Holds the instance of the application</P> ) C( Z' l- ?( a( T+ @9 v<>bool keys[256]; // Array used for the keyboard routine/ j/ R) `7 x' E B
bool active = true; // Window active flag set to true by default8 ?0 ~8 Q* U1 m* T
bool fullscreen = true; // Fullscreen flag set to fullscreen mode by default</P> : v0 b" P! h8 @0 E$ a<>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc</P>% g( B+ ?/ i# Y/ g0 a5 T# W
<>GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window, \7 O9 `" m- V7 \" d3 u6 W2 |, d
{( k: _1 T5 s* S* e4 U, X
if (height == 0) // Prevent a divide by zero by 3 e3 j0 N P' y8 P7 P { / `7 x1 `/ F- O( a height = 1; // Making height equal One( J( k9 j0 `; ^8 s# l
}</P>! W3 i! f& W. ^ v
<> glViewport(0, 0, width, height); // Reset the current viewport</P> # Z7 a& T* z3 j" x5 h, ~8 m<> glMatrixMode(GL_PROJECTION); // Select the projection matrix. o/ H$ O$ x K. m5 }
glLoadIdentity(); // Reset the projection matrix</P> + y" e4 r8 o$ u, @, e5 j9 T: j<> // Calculate the aspect ratio of the window7 g; P; p6 g- T, H( Z. G9 y! L# w4 P
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);</P> : { I% d) E; u<> glMatrixMode(GL_MODELVIEW); // Select the modelview matrix+ m' Z7 ]9 k- C! s) j
glLoadIdentity(); // Reset the modelview matrix4 C2 z* D/ B6 y' l: o
}</P> + t4 T; P: F3 M8 n<>int InitGL(GLvoid) // All setup for OpenGL goes here 7 n- D- X! K$ C& F" x- J* C{ ' K: A, H, p- ]7 Y9 d& l* o9 A glShadeModel(GL_SMOOTH); // Enable smooth shading & n. k7 j3 i+ l% g# f) M6 k/ R, C glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background $ t; }" D) i2 _0 z4 Y$ `# `1 F- k glClearDepth(1.0f); // Depth buffer setup 4 c! B5 \3 O. _" t, n glEnable(GL_DEPTH_TEST); // Enables depth testing # W& g/ R" @+ {9 Q glDepthFunc(GL_LEQUAL); // The type of depth testing to do ; p( \' x9 U4 M glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations9 a I j/ i1 r1 [9 E. D
return true; // Initialization went OK r1 E2 |1 s! ?: e6 S
}</P> S: o; W O4 r9 I: \% y<>int DrawGLScene(GLvoid) // Here's where we do all the drawing+ ]$ d! q3 s, n. w0 g
{- k& a5 l* u* l/ j8 c9 E q8 G, p. s
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer 6 c* |9 F, I7 F' L* e# Z7 S9 u glLoadIdentity(); // Reset the current modelview matrix ; W& q, }3 w3 G. [ \# p1 d ( K7 y- t1 L5 `( A9 c! M0 J# S return true; // Everything went OK " Y1 s# s8 n3 ]( y0 z}</P> % P0 ~8 v& v5 k8 N5 e: z. m<>GLvoid KillGLWindow(GLvoid) // Properly kill the window ( f" [( B) G( [& N2 ~{. ]* R$ r# |' m0 V& A' \0 p
if (fullscreen) // Are we in fullscreen mode? % C+ Z& V/ b& ]2 X {$ W7 J0 T8 C% ^# R3 A1 s7 P
ChangeDisplaySettings(NULL,0); // If so switch back to the desktop 1 u. R3 E/ r; e$ C5 Z- P ShowCursor(true); // Show mouse pointer. y7 e) c, @( Z/ i
}</P>6 s: p: ]; E( V' u) m! M
<> if (hRC) // Do we have a rendering context?" K1 G; R% J- _* n5 {. E5 Z! U
{# f" |% M, _5 R$ u
if (!wglMakeCurrent(NULL,NULL)) // Are we able to release the DC and RC contexts?' t& y; o( z( w H, D! k8 T
{ 0 [$ c7 E8 P' A1 u: q9 f MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); ) b: w. u& ]# u5 _2 Y }</P> _& \1 S5 I9 C& M( k: r, o
<> if (!wglDeleteContext(hRC)) // Are we able to delete the RC? + a. M8 l5 Z, ?( P( V {- R: w! z$ Z1 E; A6 a/ J, T7 c
MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);; B, D0 E/ `0 _ i+ a
} ; V }5 P( b: n, v7 i! [* a0 d hRC = NULL; // Set RC to NULL ! @; R5 b/ x! H) s }</P> ' z& u& [ W- k0 C<> if (hDC && !ReleaseDC(hWnd,hDC)) // Are we able to release the DC# x+ D# R/ H p( {: }
{ ; V. l, @4 F3 |/ ^& j MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); - V5 q8 K/ n% W4 J1 |& n ` hDC = NULL; // Set DC to NULL' D, x+ h. d9 R/ q1 K- Y+ \4 ]
}</P> " g5 {" Y2 Q, R" I$ m3 |+ \<> if (hWnd && !DestroyWindow(hWnd)) // Are we able to destroy the window? : F* d6 A' p8 E+ Q% T1 P5 \4 p {/ I" ]! D5 ? o" O* F+ L- h j
MessageBox(NULL,"Could not release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); & S8 E' y5 G) V+ _) ?- ? hWnd = NULL; // Set hWnd to NULL) \% ~+ `6 e! a& N7 P
}</P>9 ^% I1 K# m% ^! ^ {( R5 K2 ?
<> if (!UnregisterClass("OpenGL",hInstance)) // Are we able to unregister class1 D6 Z1 z6 Q1 F8 @* O
{ 4 j* w/ r7 D! x9 ~- y' c MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);0 s+ D$ L" T5 S- @0 s8 z. w) s6 [+ X
hInstance = NULL; // Set hInstance to NULL 6 m. ?7 r3 T! V C7 ?% ]( r( g }3 s1 C+ C. x) P. g
}</P>* \2 u; ^3 b1 _7 ^* F
<>/* This Code Creates Our OpenGL Window. Parameters Are: % {9 V+ {9 t8 Z3 u * title - Title To Appear At The Top Of The Window3 j$ ^2 A* @6 G. }% ~' f6 o% G f4 a/ |
* width - Width Of The GL Window Or Fullscreen Mode # ?9 o& ]( S5 ` * height - Height Of The GL Window Or Fullscreen Mode$ q1 A, P0 S6 l4 C# K
* bits - Number Of Bits To Use For Color (8/16/24/32)+ V$ D& T+ G& U6 b+ h
* fullscreenflag - Use Fullscreen Mode (true) Or Windowed Mode (false)*/7 p5 S. y7 ^& F# C' z, o5 d' w; Q
9 B* w5 W Y1 g+ g! s& ^3 O: Jbool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)+ Q) Q3 ?) h! h1 k' A* m' C
{" X7 G* D( {' i% ?3 i9 n* l
GLuint PixelFormat; // Holds the results after searching for a match. ^8 c" [/ F' o8 [
WNDCLASS wc; // Windows class structure / f$ n( _$ T1 e% U3 @' z7 O9 O DWORD dwExStyle; // Window extended style J+ Q+ y- t+ m0 [! ] DWORD dwStyle; // Window style ; x2 }# i& B/ q9 v1 a# a* r J RECT WindowRect; // Grabs rctangle upper left / lower right values- s; Z3 }( B4 m# L3 ?9 g+ o
WindowRect.left = (long)0; // Set left value to 0 ' A/ y/ n; a& @ WindowRect.right = (long)width; // Set right value to requested width8 Q% n1 d7 f- o2 Y. P3 k
WindowRect.top = (long)0; // Set top value to 0 3 `6 Z+ J l2 @2 V7 P: X/ D! U% } WindowRect.bottom = (long)height; // Set bottom value to requested height</P> * F! J9 T& f9 q- s<> fullscreen = fullscreenflag; // Set the global fullscreen flag</P> * `- F# b3 ]+ j% D<> hInstance = GetModuleHandle(NULL); // Grab an instance for our window% X: D# }( ^4 r/ k, S
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on size, and own DC for window 6 `( Q3 o7 i: T' G7 F( t7 Q wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles messages 8 T' X' }# l7 l# e7 V7 t% g! a" ^) V wc.cbClsExtra = 0; // No extra window data: p K! L1 d, A3 p- c
wc.cbWndExtra = 0; // No extra window data3 b8 t) N9 L9 [( y: T! z) I( P
wc.hInstance = hInstance; // Set the Instance& O" ~6 H0 @7 d& S
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon / I) V( L3 R1 ? L; [8 L m wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer! k6 t* b7 h9 L+ N/ Q
wc.hbrBackground = NULL; // No background required for GL , B+ I2 y* D! c wc.lpszMenuName = NULL; // We don't want a menu ( F/ L! b2 F% `. y wc.lpszClassName = "OpenGL"; // Set the class name</P> $ V$ K" Y& Z% ~! ?6 A( W* B<> if (!RegisterClass(&wc)) // Attempt to register the window class1 J: V6 E5 _1 e) L: C3 H. Q
{; s2 `3 O; P N N8 r2 `, y
MessageBox(NULL,"Failed to register the window class.","Error",MB_OK|MB_ICONEXCLAMATION);</P>" Q# b1 Z4 i& b! g+ g; L. _
<> return false; // Return false- j. r7 M2 D" h M& n
} 0 P) B. z& J0 M6 Z( G* ` e ) y p& o) A# `/ z: R if (fullscreen) // Attempt fullscreen mode?1 A! A6 p, W2 @
{ 4 ]2 z: X8 o; e) H! d9 H- X# b5 P3 w DEVMODE dmScreenSettings; // Device mode8 `8 l/ N3 l) W: I6 k
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes sure memory's cleared7 z: Y- s6 I& t7 y5 _% W' _
dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of the devmode structure6 s4 T' [# T: G
dmScreenSettings.dmPelsWidth = width; // Selected screen width! R8 h7 T) T7 h$ e- K* C
dmScreenSettings.dmPelsHeight = height; // Selected screen height b( K. E5 x' Q+ N
dmScreenSettings.dmBitsPerPel = bits; // Selected bits per pixel 9 s& f( N! d; S" Y8 h dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;</P> 0 e* g: p! s/ E<> // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar. 2 M+ i B w- B r; B2 s) o7 X, S0 I% s if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)! t. o5 {9 j* C1 U; N3 D
{0 B8 @" a% j# y% O
// If the mode fails, offer two options. Quit or use windowed mode.7 l5 r2 n2 t6 [5 t9 h0 @
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)9 I' p; x+ u- D; [
{ ' M0 e z$ b1 B: P3 N) }, k" n! G fullscreen = false; // Windowed mode selected. Fullscreen = false * L3 P, D8 d- f w- H! M' R }% l8 ^9 s' t5 x1 k( W! D
else + J) L+ D( o: p. O$ A: Z { ' B- L+ c3 v7 {- A7 n0 ~; X // Pop up a message box letting user know the program is closing.( M# x8 K# V( e% C/ ^8 g2 K" B
MessageBox(NULL,"rogram will now close.","ERROR",MB_OK|MB_ICONSTOP);. U4 O! r* B2 q5 }
return false; // Return false6 O0 N+ ?; v4 y! B! R
} 9 n, M9 S( c. m( L+ t/ ~ }+ ^/ r( u# y5 i- I9 W/ |
}</P> ! _( T6 }* {, z/ c! m3 G<> if (fullscreen) // Are We Still In Fullscreen Mode? $ p: l- j3 y" x- I8 b {9 K3 C. U" _+ C5 O; X1 V
dwExStyle = WS_EX_APPWINDOW; // Window extended style! E5 g' n) _1 @+ f* I4 b9 H$ y
dwStyle = WS_POPUP; // Windows style3 B, ~! Z& H1 |9 J2 ^
ShowCursor(false); // Hide mouse pointer% d, S6 V3 f1 R- k0 l ?
} 3 K6 g& Z3 ^2 k' u. N1 l1 L else% t8 Z( Z, z0 t0 j9 A( P* q
{! @9 y8 c- C$ \: X
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style& N5 k$ R- t3 K! E! x
dwStyle = WS_OVERLAPPEDWINDOW; // Windows style J3 E0 k2 i1 v: i, ]: g }</P> 1 H/ z; d. ]8 x# f' s: Q6 f# ~ p<> AdjustWindowRectEx(&WindowRect,dwStyle,false,dwExStyle); // Adjust window to true requested size</P> ~; H( h+ ?1 E, Y% E& g' g! ?<P> // Create the window ' E v# K) C. B1 z5 n _9 e( h if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window 7 b: b# v; @/ v4 Z "OpenGL", // Class name ) Q. r7 F$ H" J7 A* X. z# p title, // Window title0 [5 _2 h( n9 Y9 n9 O. {
dwStyle | // Defined window style8 S9 G7 K( M- L
WS_CLIPSIBLINGS | // Required window style # l5 S3 K1 _" f4 o Y$ Y WS_CLIPCHILDREN, // Required window style . @7 v1 r) p, x. ` O. l 0, 0, // Window position , R# G' ~+ ^1 j. x1 E1 J) r WindowRect.right-WindowRect.left, // Calculate window width e' c5 N0 I' n4 p% Q
WindowRect.bottom-WindowRect.top, // Calculate window height. O& R$ \, u( A& S2 \. g
NULL, // No parent window) b) N1 e# R4 V1 v& C2 t
NULL, // No menu3 M0 n% | z3 H s
hInstance, // Instance' J+ _8 Z3 q, h I
NULL))) // Dont pass anything to WM_CREATE5 e6 i; y! G- |% A+ h
{ 3 O9 I, Q! V7 K9 K KillGLWindow(); // Reset the display - N" l. D2 B6 y MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION); 3 L2 s$ {. K/ n: T$ { return false; // Return false 3 v5 j& Z* ^9 {, C- V3 d9 Y8 F' O }</P> 3 n/ q# _- o- a& K8 U" x<P> static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be 0 I) R" l7 U# A2 b2 T {" W+ r7 A3 [1 [3 i$ S9 e
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor . b3 O2 I: l T6 U6 K 1, // Version number 7 b+ d1 n% I. c3 q* G+ v; D PFD_DRAW_TO_WINDOW | // Format must support window . s- J+ ]# R1 @. F3 F; T% z7 o) Y PFD_SUPPORT_OPENGL | // Format must support OpenGL # o" m ?" p) @1 |$ @( n PFD_DOUBLEBUFFER, // Must support double buffering0 V# s; r5 P& \6 l% q$ ?
PFD_TYPE_RGBA, // Request an RGBA format5 @* M: E. j% \/ B8 c6 k% B+ ^
bits, // Select our color depth & @( j+ M# d8 ?, e8 I 0, 0, 0, 0, 0, 0, // Color bits ignored# u k Y8 h7 \$ M! l% ^. M' j
0, // No alpha buffer$ O# E/ s9 z; _. J1 H
0, // Shift bit ignored " y1 J( [+ p7 I9 ~, X. i 0, // No accumulation buffer 1 C j% g3 P) E7 R( t5 s% i 0, 0, 0, 0, // Accumulation bits ignored2 H8 a. s+ l% j* F( }
16, // 16Bit Z-Buffer (Depth buffer)4 O5 Q/ b' [* `/ I# [; L! j' K4 g Z
0, // No stencil buffer ; F* J0 p6 E6 U& K' t$ j0 K 0, // No auxiliary buffer0 N1 s3 t3 |5 q, e' E) a
PFD_MAIN_PLANE, // Main drawing layer& O! t2 _; M: m6 B4 B. D
0, // Reserved . a8 `; M2 @+ e- F 0, 0, 0 // Layer masks ignored: z) T7 p1 O* Y0 l
}; ( Q" U. h% v' T& e. q ) @2 O- K* k( h" Z: x
if (!(hDC = GetDC(hWnd))) // Did we get a device context? " P1 U a+ f0 o' } {% \7 P# L: x5 H# A e" v4 [
KillGLWindow(); // Reset the display3 _5 V: I; c$ E9 ?
MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION); u1 G3 {6 F$ \( p- d# Q return false; // Return false D/ i% Q7 R @; T9 t }</P>' O8 W1 c. D d/ J. I: r/ p
<P> if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did windows find a matching pixel format?6 P1 \$ D' c) x7 C7 ~- N# f" k
{0 b6 B0 a5 P$ O/ u
KillGLWindow(); // Reset the display F* t2 K) r$ P
MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION); ; t1 }4 |& L$ B$ p% R+ J return false; // Return false5 j: h$ }* M; r5 q! Q2 b
}</P>1 g& i) _! c% M: w& M- g) n% W& {
<P> if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are we able to set the pixel format?: G0 y5 r: x! y, l% h I6 L
{ . h& {! a8 Q& R# s8 Y KillGLWindow(); // Reset the display: n9 X9 D5 q+ C4 U
MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION); 0 K4 d: S4 e' }/ C return false; // Return false: Y5 C+ @, [, s8 ?* v7 ?4 F: |
}</P> * l9 L1 D9 j5 V<P> if (!(hRC = wglCreateContext(hDC))) // Are we able to get a rendering context? 5 j' m6 R# V% }+ H/ n7 V { * w8 m, p* Z. ^$ t+ ? KillGLWindow(); // Reset the display 5 O m3 \* P ] G8 n/ B MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);( y0 Q+ K6 J: y6 H& D* i: }
return false; // Return false . e6 T" z+ d, U" ]$ _ }</P> * z* [4 _& w$ k; y<P> if(!wglMakeCurrent(hDC,hRC)) // Try to activate the rendering context+ O2 }% J! r: g9 a% p! v
{ / Y' l5 o" z7 J KillGLWindow(); // Reset the display f+ X- ^3 i* Y' q
MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION); # W& M& n9 A' t+ d; m- B1 ^" k* { return false; // Return false ( l. M- o( y4 p8 x }</P>1 W% E4 L4 @ f. h8 f& e9 e
<P> ShowWindow(hWnd,SW_SHOW); // Show the window$ _2 L: n2 d. C" J8 C) H L O
SetForegroundWindow(hWnd); // Slightly higher priority 5 p6 {1 \" t1 Z" { SetFocus(hWnd); // Sets keyboard focus to the window 2 O; e* y6 E( [2 E- m: P' x+ Q |" G ReSizeGLScene(width, height); // Set up our perspective GL screen</P> ! R# {* Q1 |- e! f<P> if (!InitGL()) // Initialize our newly created GL window3 t. @0 g6 m/ K) }0 G4 C. ~" g2 }; h
{' z" F! q& I0 |* N1 h6 h& q: w
KillGLWindow(); // Reset the display ( |4 d5 k- }* y$ U4 J8 A. H1 w# R MessageBox(NULL,"Initialization failed.","ERROR",MB_OK|MB_ICONEXCLAMATION); . }& W) a0 x# `( B* M8 L6 X return false; // Return false ) E) f9 b4 X& ]1 q. q }</P> & n) C9 w; a5 Y) |4 y<P> return true; // Success% x( A7 y. |% I2 B: ?* `: I
}</P>, \6 ~0 r+ H# X: @
<P>LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window( v# R4 y) b7 D# g
UINT uMsg, // Message for this window , z# j; m Q6 e4 s# D e WPARAM wParam, // Additional message information" t/ @8 N0 n! b
LPARAM lParam) // Additional message information % J9 w: c2 u: ]{6 y4 S, r G3 c. F) W) Y
switch (uMsg) // Check for windows messages% m1 r" ^: M+ `4 ~0 T
{3 P0 \1 v5 \; g+ g- N L! A2 S7 ? r/ @
case WM_ACTIVATE: // Watch for window activate message8 O+ F9 A! \. |+ _5 J4 f9 V: A
{ & g- y% `9 N( |8 H if (!HIWORD(wParam)) // Check minimization state+ j( ^1 b0 l- _6 }7 S. Q$ h
{, B% ^6 b, h! ~8 O' f
active = true; // Program is active ( r2 @2 T5 o) S/ d. w* O5 L( l } / y% D- C3 N! f1 p$ j! I: j5 i2 B. I7 G else2 I( V j! A T& d2 b
{ 2 }; z, V8 O5 F' f9 _' f active = false; // Program is no longer active : b% ^6 l0 K7 o H6 J, V, I }</P>4 I6 f% P0 u6 |3 a
<P> return 0; // Return to the message loop) {9 P6 s' h. t0 |0 o/ K+ c
}</P> - q0 |. W) M( k5 P: H8 l! x, s; r! D; e<P> case WM_SYSCOMMAND: // Intercept system commands8 T R3 J8 C9 N: n6 ~* Y$ m: T$ h
{ + N+ Q0 ^$ c' U+ l0 w) }* Z switch (wParam) // Check system calls , m: [; r6 o& O, F& Q { 2 R5 z) q* w0 |; @+ G. P& q case SC_SCREENSAVE: // Screensaver trying to start? / L! ]% c/ w4 g8 i- C case SC_MONITORPOWER: // Monitor trying to enter powersave? - Y; F# ~8 t8 h! [/ S1 d$ l+ m$ g, T return 0; // Prevent from happening) M5 L7 {, L$ m6 E, P2 c
}/ Q- V( P" U8 {1 u' j
break; // Exit r5 e2 C2 o5 i. @7 Y, ~' P
}</P>- {( r+ x3 P" i( n
<P> case WM_CLOSE: // Did we receive a close message? . z! y" l" @- g/ \9 } { ; H# ]) K4 Z% b( N/ v0 y: u PostQuitMessage(0); // Send a quit message ; d7 |$ e4 v0 ^ W- t6 v( Y0 t" E. ^ return 0; // Jump back 4 Z+ q. t/ I5 S9 ?& `: d }</P> $ w) \' p+ ?' |% ]. y) d. w1 D- a<P> case WM_KEYDOWN: // Is a key being held down? ; G ^9 |2 P2 l& f" _# l) _ {' y1 B0 G9 g& Y% u0 I
keys[wParam] = true; // If so, mark it as true , u3 \; T0 p7 m f" F return 0; // Jump back ' x9 J8 d( e: y) g; R2 F }</P>. `- [6 y7 d0 \" ]5 @* g6 l' W
<P> case WM_KEYUP: // Has a key been released? ! _1 q* Q3 Q- D7 d3 T { ! U5 a4 Z$ @9 A' s keys[wParam] = false; // If so, mark it as false + o/ e* D0 t( m1 C- ~* n return 0; // Jump back8 l3 ]8 m! m( L2 B( H- z# ]# J7 a9 l
}</P>6 T5 c2 _ L' s4 k3 S5 Z
<P> case WM_SIZE: // Resize the OpenGL window) J" \8 Z, j. [4 S1 T1 o" D) G
{. X2 a# u- y4 w: H0 d4 t. b
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord = Width, HiWord = Height9 r2 {) b% Q3 R) B9 R
return 0; // Jump back ; x7 T1 |, R1 r5 j9 R3 j }2 a- o. i' v1 d2 y, N. F
}</P>, T$ C0 r/ m R2 i- g5 f. Y! x
<P> // Pass all unhandled messages to DefWindowProc3 ^; A y. ]1 h/ \4 n+ \
return DefWindowProc(hWnd,uMsg,wParam,lParam); 3 J G) T' }5 G: h0 R; j}</P> # u2 \ r o( v! g. u) l<P>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)5 _6 o; B9 o3 ~5 t9 P1 U# B
{ / x+ j, F3 I' J) J8 q; p MSG msg; // Windows message structure 1 a- N. L' r, T9 u( q5 y bool done = false; // bool variable to exit loop</P> ' g2 v* [+ @; v B& E8 f3 {3 Y<P> // Ask the user which screen mode they prefer $ l+ o* p; F3 G$ v$ \+ W9 A( \/ {3 K if (MessageBox(NULL,"Would you like to run in fullscreen mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION) == IDNO)+ K# v, e8 D4 ` i7 n7 ^3 ^; U
{+ d. y) X* D/ A) e- g( j- I
fullscreen = false; // Windowed mode : C# m. Y, l/ T }</P>. x7 V# N3 [9 T5 z
<P> // Create our OpenGL window# z8 z# v. X2 H6 f9 Y1 H; J' z* K
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)) , Y5 t+ b# }9 v {" z# ]3 q; O8 k7 m8 Z
return 0; // Quit if window was not created # S' i0 g% t n, i: o( ?0 ` }</P> , K2 @, @1 [) w! C<P> while(!done) // Loop that runs while done = false F6 c4 y6 M2 R4 R" ~0 [ {8 L7 D" c7 m) P, D* V W3 P' `
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is there a message waiting?( O* W' A+ q! ?* D
{ 5 O. x' U: |5 o if (msg.message == WM_QUIT) // Have we received a quit message?* L) L- @% B3 r5 Q7 u% ^/ N
{ ' h# ^; `# J; N# Y done = true; // If so done = true . i' w3 |" v5 a% |4 C O } - `. Y2 l1 p# U3 i else // If not, deal with window messages/ }# X+ u/ e) b# F- ^% q& X
{ & U3 S+ ^3 _% @: [9 r TranslateMessage(&msg); // Translate the message0 a& U0 P0 w E8 c' ^. {4 F
DispatchMessage(&msg); // Dispatch the message9 s9 @ w6 }4 r( S1 N9 p$ j
} $ {) S) q3 Z( R# `# \ } ' g5 \9 v0 H3 I else // If there are no messages * g1 x7 O. Z7 p, |6 z9 z' S { 0 v v& e9 O1 M5 V // Draw the scene. Watch for ESC key and quit messages from DrawGLScene() A' n' Y7 s( a/ w: |( ^0 o9 n if (active) // Program active? # K* w; w6 J7 K9 O) R( d {! }# S9 W b! F5 E6 A% {
if (keys[VK_ESCAPE]) // Was ESC pressed?" t! G3 s& C. X" s, f
{ 3 o9 X. t) g# o) M9 n1 z done = true; // ESC signalled a quit 3 o' |% A' c! N } ) K1 x7 r- O. x else // Not time to quit, Update screen + m% O- N+ P" g1 r- I {% v3 C* M" U& b7 s7 x4 c
DrawGLScene(); // Draw the scene * }# a$ d+ @8 q& m% Z% D% ? SwapBuffers(hDC); // Swap buffers (Double buffering)' }8 r* q5 S2 Y8 M" L
}5 v/ G+ r& n+ ? u
}</P> ( I: T5 m9 U4 j, A7 G<P> if (keys[VK_F1]) // Is F1 being pressed?* K, Q- h! F" c. q
{) Q$ ^0 X) n: D4 \$ F
keys[VK_F1] = false; // If so make key false8 @( e. p' c( x) z3 n( N
KillGLWindow(); // Kill our current window3 d6 T+ k/ l8 j. Y6 B: d7 s
fullscreen =! fullscreen; // Toggle fullscreen / windowed mode ( \# o8 u! \. p F% Y // Recreate our OpenGL window/ {- G! g' r6 @% t1 }
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)) 4 \/ r( v/ ?2 [4 `/ ^& u/ M { 5 o" r# I; g) D, z8 ?( J" k return 0; // Quit if window was not created" m0 ]9 r; k- L- A4 T
}% c6 o' G2 z- G: e u1 a
}5 |$ Y' c6 H/ u6 ~ }' N
}6 c" R" s8 |: E! E7 V9 p; ^* d1 m2 v
}</P> 2 B8 g8 M, J+ u( k8 Q* u0 J<P> // Shutdown % @' L2 e7 s# z+ ] KillGLWindow(); // Kill the window / G0 r3 S, H% W, H) W9 }; I7 d8 A return (msg.wParam); // Exit the program ( _0 |+ C) }8 I, j, Q0 d} . l6 {; y0 A- ~% I) S# F1 N$ Q//---------------------------------------------------------------------------</P>