<>这是NENE的OPENGL的框架CB原代码,是黑屏的效果,最简单的。OPENGL我才开始学,很多不懂的,希望和大家交流,共同进步,我会把我的资料和大家共享的!</P> * m+ N. p- @. c- s<>首先在CB下建立一个CONSOLE的程序,然后把CONSOLE APPLICATION的勾去掉即可。然后再把以下的原代码粘贴上去就可以运行了!!</P>1 b. h1 G) G" K) S: q0 ?% B
<>//---------------------------------------------------------------------------</P>8 K. O+ R. c0 L# C) c1 W4 A# C
<>#include <vcl.h>% w+ ?% q) R7 i8 _; u
#include <windows.h> // Header file for windows- B# x0 b# c" S2 o" z. W
#include <gl\gl.h> // Header file for the OpenGL32 library * u) m% I# m' d, s7 X#include <gl\glu.h> // Header file for the GLu32 library' W1 h* Z/ p% H0 n) U
#include <gl\glaux.h> // Header file for the GLaux library , b q4 v" z6 ?#pragma hdrstop</P>' L; F# S: M* q% w# W
<>//--------------------------------------------------------------------------- ' A& e4 U0 w* W#pragma argsused</P>% Z6 q! L/ c+ I6 T6 P) t, y
<>HGLRC hRC = NULL; // Permanent rendering context3 Q- Q* h/ v1 [, o7 h! L8 I+ \' |
HDC hDC = NULL; // Private GDI device context6 R# r6 f) d- m* L* X
HWND hWnd = NULL; // Holds our window handle! c* O8 \2 G2 u$ P& I
HINSTANCE hInstance = NULL; // Holds the instance of the application</P>! c* s+ z5 d, h/ R$ y; a
<>bool keys[256]; // Array used for the keyboard routine . c) Q: {# a: o0 e+ G$ ybool active = true; // Window active flag set to true by default0 B& r% J/ S( \- K
bool fullscreen = true; // Fullscreen flag set to fullscreen mode by default</P> 6 K6 A! r- \) j! s& d<>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc</P> / I) d; R/ v4 _2 f' O5 F% E2 F1 X<>GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window . `8 U5 o' j: x. b; D& B4 F1 a{# D1 ?% G8 n h" Z; z) _3 N/ ~
if (height == 0) // Prevent a divide by zero by7 t" P9 L4 Z$ d# Q5 [
{ ! P; n: D3 j4 Q3 }7 H height = 1; // Making height equal One0 T5 ~2 l& q w$ S# w) c& |
}</P> , E* f9 d1 B" p y( z<> glViewport(0, 0, width, height); // Reset the current viewport</P> ) f, N& P1 c- E" F<> glMatrixMode(GL_PROJECTION); // Select the projection matrix ' Q; \8 I# F8 ~' J& R glLoadIdentity(); // Reset the projection matrix</P>0 \8 c. {3 M0 x, E+ X) A
<> // Calculate the aspect ratio of the window , v4 n! s+ S. Q) t+ X gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);</P>8 o; e) B+ {+ a( v6 }* s
<> glMatrixMode(GL_MODELVIEW); // Select the modelview matrix2 P R% [0 X( O( d
glLoadIdentity(); // Reset the modelview matrix% B6 ^/ E( G N3 m7 p2 z
}</P> , W6 Q8 }1 B" F0 H<>int InitGL(GLvoid) // All setup for OpenGL goes here $ r; R! L4 F" m' p) E) M{ % k: Y8 L k8 J4 t# S& {: I/ m glShadeModel(GL_SMOOTH); // Enable smooth shading9 ~+ b1 M- B$ U/ h) z! J* B0 S
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background 8 N- S+ T# h' M ^! H glClearDepth(1.0f); // Depth buffer setup 2 o3 K. a4 p8 f0 w3 B glEnable(GL_DEPTH_TEST); // Enables depth testing ! Z# j& [0 d8 r { E glDepthFunc(GL_LEQUAL); // The type of depth testing to do+ d7 h% B' O/ d& d
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations$ z2 S7 Y* s4 [
return true; // Initialization went OK 1 g# b% I* [5 w3 q' E# Q}</P>! s# ]; ?. u* i1 j! \# R0 g
<>int DrawGLScene(GLvoid) // Here's where we do all the drawing % r0 }2 n6 n! U9 k, g5 ]9 t+ _{# x2 k9 o$ l8 z
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer 9 R6 Y7 {9 Q8 N" [ _% O3 a$ w glLoadIdentity(); // Reset the current modelview matrix9 z; ?/ d- ^2 [+ n
' j6 h* J! g, ?
return true; // Everything went OK5 ~ G4 y! p1 t% {- |
}</P> 7 E5 G; x& O$ f4 N<>GLvoid KillGLWindow(GLvoid) // Properly kill the window 6 Q! C+ A1 I$ s" p6 t3 C( Z{# g/ b: J+ f$ e M0 F1 d4 t
if (fullscreen) // Are we in fullscreen mode? ( ~5 ^8 b0 \1 h { + a2 n6 N/ }8 ]/ S- ]" J4 T ChangeDisplaySettings(NULL,0); // If so switch back to the desktop' Y- q$ \3 Z3 [, l9 v+ t
ShowCursor(true); // Show mouse pointer * G2 ]2 B+ L* F% g7 ?4 u' R0 t }</P>1 M! N0 l& |5 S6 |* D g
<> if (hRC) // Do we have a rendering context?3 p ?8 `* G, M4 l- X
{" _9 y2 V2 k" `! f( t
if (!wglMakeCurrent(NULL,NULL)) // Are we able to release the DC and RC contexts?/ c- m) h/ K5 A4 H* r/ R- x
{% ?- E3 ~* t8 L+ N( R( O1 ]
MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);& \* J4 \4 @6 t' j6 @
}</P> & { [: x) i6 T9 [4 b<> if (!wglDeleteContext(hRC)) // Are we able to delete the RC?* x- }! G" U7 U% j9 s7 Y
{ q" ^5 n& v: M8 s
MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); , I# @5 ^6 g- H2 n7 ?. c! c } , x' \7 j: E$ ?' A hRC = NULL; // Set RC to NULL% U" `' u2 A4 a5 _( ^" d
}</P> 6 A' g' k& A% y2 ^: @, v+ P<> if (hDC && !ReleaseDC(hWnd,hDC)) // Are we able to release the DC8 i: B# p' m6 g5 z- n
{ * z+ i' s" C t; ?/ |7 m MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);9 X, o. D: {/ H; \4 a7 H
hDC = NULL; // Set DC to NULL ) i% G4 \+ T. T3 F& ~+ q3 k }</P>/ H9 m A/ `* T* P9 j& D$ @/ C3 j" M/ O
<> if (hWnd && !DestroyWindow(hWnd)) // Are we able to destroy the window?) ?8 r5 [2 x0 t& M( G4 W
{! x$ H$ Y/ n5 d: I
MessageBox(NULL,"Could not release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);$ H& o: m, T: b U6 B C3 k# y
hWnd = NULL; // Set hWnd to NULL7 F0 R/ j& s$ |( r. [3 Y3 l- n. Z
}</P>7 m9 X* l4 R6 Q) i8 [( t9 w
<> if (!UnregisterClass("OpenGL",hInstance)) // Are we able to unregister class : c) J$ H6 q; Q& b+ h. Y {5 @' v! D; V( D( B! n. j) `7 a7 d
MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 7 w) ]4 o, W3 r9 t: o* X' D hInstance = NULL; // Set hInstance to NULL; V" p8 i; s- T; o! m
} 3 Q( p8 [, Q. W2 ?) N' T}</P>& u' P, ]0 k# l* [' S
<>/* This Code Creates Our OpenGL Window. Parameters Are:: c I! x# f# r! g8 n/ z1 h S, r
* title - Title To Appear At The Top Of The Window ' @, o, c- k& b1 Q/ e% v4 Z- k, T * width - Width Of The GL Window Or Fullscreen Mode 0 M) n4 y! M8 Q$ H) K * height - Height Of The GL Window Or Fullscreen Mode3 u7 x8 w' F! }4 C* F5 R3 [) D7 L
* bits - Number Of Bits To Use For Color (8/16/24/32) & T# Y# {8 m5 R * fullscreenflag - Use Fullscreen Mode (true) Or Windowed Mode (false)*/) \ @& w" S k$ p) f# K- ^
* g" M" @' v+ }* F* e* C: h
bool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)9 O: O2 m& q8 I" z" @, i6 l
{ ' R8 B' f4 P$ A5 i GLuint PixelFormat; // Holds the results after searching for a match / H" o _' l6 w7 J( s% D9 @ WNDCLASS wc; // Windows class structure . T- Y2 n4 L. r- t+ h DWORD dwExStyle; // Window extended style 3 H( U$ ?- @. C, J9 l/ u DWORD dwStyle; // Window style @4 A; R) A3 ~- z1 |; l6 P2 {- m
RECT WindowRect; // Grabs rctangle upper left / lower right values i, t7 u" `1 O4 [
WindowRect.left = (long)0; // Set left value to 0 3 [: B* J) h9 ]3 x5 e, w* N; f WindowRect.right = (long)width; // Set right value to requested width $ N' N; `0 G" a6 T3 @6 s- g6 F WindowRect.top = (long)0; // Set top value to 0/ M9 g/ i$ ]9 i' a- e% o; E
WindowRect.bottom = (long)height; // Set bottom value to requested height</P> * X/ `, ]7 {, w( q<> fullscreen = fullscreenflag; // Set the global fullscreen flag</P> 3 I( @& A/ L" @3 a/ b- r<> hInstance = GetModuleHandle(NULL); // Grab an instance for our window$ F( R) A$ ?9 q* n: f
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on size, and own DC for window Y( L3 w. O8 a! E
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles messages ; ~) ]) Z [) G: m' i wc.cbClsExtra = 0; // No extra window data7 L/ j% ^- U7 ]) Z
wc.cbWndExtra = 0; // No extra window data : F7 V6 o. e. ? wc.hInstance = hInstance; // Set the Instance( Q. P- t6 \; ~) ], F; B# x( i
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon+ h- M5 ?0 {$ d- W' V
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer. q. ~/ }7 [/ ]- s3 Y; p
wc.hbrBackground = NULL; // No background required for GL 9 t' V1 B/ @8 b wc.lpszMenuName = NULL; // We don't want a menu D3 V5 H0 P7 E/ a5 W- p
wc.lpszClassName = "OpenGL"; // Set the class name</P>! B7 C" Y9 u& i, S& v: ^
<> if (!RegisterClass(&wc)) // Attempt to register the window class $ m; c7 O$ w4 M5 ` { 9 Y3 }" Q. f6 k MessageBox(NULL,"Failed to register the window class.","Error",MB_OK|MB_ICONEXCLAMATION);</P> 2 s* j7 S* S" _* w3 e3 X k9 v<> return false; // Return false 5 k1 l( Q) w+ R& }$ Z/ g }5 d; \: w' J9 q- h; ]1 c; j
8 x5 i9 q; v* L* o if (fullscreen) // Attempt fullscreen mode? . z; k3 |5 Z) ]2 J/ X! _' |, B" ~ {) P, V1 K" Q2 a% r! S9 H1 G \
DEVMODE dmScreenSettings; // Device mode4 t: n+ q9 l A* E/ o* m
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes sure memory's cleared& k1 P; g6 I$ f
dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of the devmode structure2 r2 k2 e, d; A# P5 s
dmScreenSettings.dmPelsWidth = width; // Selected screen width% @ t& [( a: q
dmScreenSettings.dmPelsHeight = height; // Selected screen height* F# ~; x% `7 G. \
dmScreenSettings.dmBitsPerPel = bits; // Selected bits per pixel * V/ s' L0 i! O& U1 S dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;</P>2 d0 y4 _; K+ b; ^1 l" F
<> // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar.# g6 \2 x! j$ f& Y9 Q" \+ W
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) / x, @8 b' s' y( J) [$ @0 C- b { & N, j: ?. o% M // If the mode fails, offer two options. Quit or use windowed mode. % L# X! [. O! x1 p, L 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) - K" @, z: U. G( P, p {0 m0 `0 D, c) k: a8 T, K% f9 s
fullscreen = false; // Windowed mode selected. Fullscreen = false * V0 u7 e1 Z ^& ~3 d2 h }" R) j* |1 c% ]; e% Y2 L: U
else ! Q: P: Y7 i; v' E6 R8 h" B {8 ~9 ?0 b+ W; i% @! S
// Pop up a message box letting user know the program is closing.( y$ l0 y0 l) K- ]6 y
MessageBox(NULL,"rogram will now close.","ERROR",MB_OK|MB_ICONSTOP); / Y7 Z( @5 A1 m: |* a& Q return false; // Return false+ s9 O0 Z- t& V
}! m+ _# {* E ^8 y( ]& S
}4 S( j1 q7 v. r, L& |
}</P> 6 J# o9 o: v3 m6 E9 r1 F R' V<> if (fullscreen) // Are We Still In Fullscreen Mode? B+ H, H' x8 A
{- w& m9 N [' S; W' R6 B
dwExStyle = WS_EX_APPWINDOW; // Window extended style+ s: V# z d( u* x1 V+ {3 B* e
dwStyle = WS_POPUP; // Windows style 8 y. q2 t5 |9 W$ K; }5 t ShowCursor(false); // Hide mouse pointer2 r" Z$ l& R3 f0 L3 o
} $ c: E7 U6 Y( E0 p4 j6 L, d$ z1 s else 3 O* d5 n( j6 g: o& ^ { 4 L2 |5 f0 [, w# i | dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style% g$ w! X# o( e+ g* n
dwStyle = WS_OVERLAPPEDWINDOW; // Windows style( t0 Q b' z$ \. ~+ Y; p- [
}</P>; V$ O2 p3 B. q( {0 X$ p) X
<> AdjustWindowRectEx(&WindowRect,dwStyle,false,dwExStyle); // Adjust window to true requested size</P>6 E# q5 x$ C2 T4 t! P1 X$ z
<P> // Create the window* n8 _! B' N! x( A% P* a
if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window/ m7 P3 i6 e) @3 V: ?; x
"OpenGL", // Class name7 f8 g8 p* H' P/ a1 W1 I4 B. `8 q: _
title, // Window title g: _ g. l+ M( ]: X! U
dwStyle | // Defined window style 6 I p ~& J3 @/ B4 x) p WS_CLIPSIBLINGS | // Required window style8 p( Q. \) `$ f, @0 X
WS_CLIPCHILDREN, // Required window style : T, q# G: G& U 0, 0, // Window position 0 }6 F$ h, P, | WindowRect.right-WindowRect.left, // Calculate window width! F- t8 w" j, W. `/ x
WindowRect.bottom-WindowRect.top, // Calculate window height / a1 e4 ^& u( |/ q f) `& A, |7 p8 F NULL, // No parent window) X; u! M2 U9 H+ V- R" C3 f
NULL, // No menu " y, v' H& P& v8 r hInstance, // Instance 1 T, |- Q$ h0 D NULL))) // Dont pass anything to WM_CREATE3 q+ W8 s8 z; A& n' z& T( r1 S
{/ t) ?- m, ~* b
KillGLWindow(); // Reset the display # _, J* N- M C2 \6 O$ `+ v* g MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION); ' F1 b, J- j8 W k return false; // Return false + P, T6 U6 [, z) X- q4 ^ }</P> . \0 k3 G# M2 ]2 J0 D- e: {<P> static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be/ a0 _8 H) `# N4 S$ e0 V4 g9 X" O# X
{ 9 r: E5 J- M) V8 y+ n3 y( _ sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor! \, R! u+ ^& J' ]: ~4 I
1, // Version number" F! v; @6 R7 X0 X: v$ y
PFD_DRAW_TO_WINDOW | // Format must support window2 h) c% M* `+ ~& t2 a- [4 l
PFD_SUPPORT_OPENGL | // Format must support OpenGL 5 ^* n& I" c( b# q& E, q PFD_DOUBLEBUFFER, // Must support double buffering8 H. ~0 p9 h2 w! S% J. K
PFD_TYPE_RGBA, // Request an RGBA format Y/ j0 z/ z7 @9 W+ n* J5 g
bits, // Select our color depth + A m$ r n* N$ B 0, 0, 0, 0, 0, 0, // Color bits ignored' G9 s" w( T2 O9 W8 c- S. k
0, // No alpha buffer + f' P* `; t( u0 Y 0, // Shift bit ignored - G g7 r1 d/ H/ b, B0 A& i- ?& o 0, // No accumulation buffer 6 ~: a, P8 E+ m3 ^* j 0, 0, 0, 0, // Accumulation bits ignored2 _ f! Z% ^- r7 ~9 z
16, // 16Bit Z-Buffer (Depth buffer) n' c% r* y$ E, M! _2 n
0, // No stencil buffer- ^! K' J$ D8 k3 J) I( i6 y
0, // No auxiliary buffer ^* e, o8 V" f2 o6 F5 s3 N3 q3 z
PFD_MAIN_PLANE, // Main drawing layer6 W c3 o) u* T, |+ [
0, // Reserved% t; x7 L" C7 m: M( D5 U
0, 0, 0 // Layer masks ignored 5 ]; K% n7 ~* E( w4 q9 O }; . l( _" s" a C , g3 I4 ]$ A- ?/ H, G: @ if (!(hDC = GetDC(hWnd))) // Did we get a device context?9 e, L/ z. U1 Y
{. r% f4 t6 n2 S7 a" d, @4 a
KillGLWindow(); // Reset the display, t/ O6 }$ t8 h" h
MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION);9 e$ \7 X; X. ~( b5 ?
return false; // Return false( S: r$ ^) Y5 d6 F
}</P> 3 W. M# X, C4 {! c- v4 R7 A<P> if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did windows find a matching pixel format?. A m. G/ u7 B' Q7 {. g
{, R0 A' `" F8 r' D1 X" V
KillGLWindow(); // Reset the display 7 [1 p) Y7 O# _- G& J# @ MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);/ T& X6 C0 p- i0 G8 Q1 X
return false; // Return false 0 d6 z6 i" O' R( v }</P> ! Y7 j0 n" S! ]& _- S% |) w% Q<P> if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are we able to set the pixel format?& ?% s" v _0 A0 O. a. g; Z% ~2 o
{( ~, f \" r* P& }% A B3 l
KillGLWindow(); // Reset the display9 d+ e5 r5 \1 |; ~* Q3 [' @
MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION); , J5 q3 L2 M, f) g* P/ H2 S return false; // Return false ' j ]. l2 S( J: o- ~ }</P>' O2 r" |4 h X8 W+ N) G
<P> if (!(hRC = wglCreateContext(hDC))) // Are we able to get a rendering context? 2 y9 x7 Q; n/ B$ B6 W% ^$ C( n4 c {3 ]* Q$ q9 o* \& q% e% V$ @# l
KillGLWindow(); // Reset the display , F: c" q/ |" k2 ?/ p# }- l MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);0 N* o/ T, K; V; C7 r- Y
return false; // Return false `1 j5 _% o! Z, p- }
}</P>1 Z- q" _; r- \! `0 d& y
<P> if(!wglMakeCurrent(hDC,hRC)) // Try to activate the rendering context 1 k& G6 a5 S' E { ( I3 `% i5 v- P* K8 T# N7 G5 T2 H KillGLWindow(); // Reset the display o) G0 c/ j1 K: w1 l7 f
MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);/ I* M6 k0 X1 L2 t0 m8 R/ d
return false; // Return false3 w3 d3 A; S0 C
}</P> # Q0 d" ~2 b @<P> ShowWindow(hWnd,SW_SHOW); // Show the window# z- }) B; I3 `1 }/ N" C8 I( P
SetForegroundWindow(hWnd); // Slightly higher priority . r! m/ r/ }5 `9 R6 f8 O& ^ SetFocus(hWnd); // Sets keyboard focus to the window : n2 C% b" G& I' l. H9 q ReSizeGLScene(width, height); // Set up our perspective GL screen</P> # D1 \. Y5 |4 ?% X! m& q+ v+ ^. W2 Q<P> if (!InitGL()) // Initialize our newly created GL window3 Z7 g \+ v9 U. m7 Y" y
{ . ], |+ i1 S7 \) Z: P& f# c' M% w KillGLWindow(); // Reset the display $ N, G9 D; B1 l MessageBox(NULL,"Initialization failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);0 y0 s# i4 o9 P4 S
return false; // Return false - B8 M7 y8 `7 ] }</P>( t3 _: C% s6 |+ k; w; K
<P> return true; // Success . z8 s6 o. x0 B; D/ {$ l& C}</P>3 Z5 u2 p8 E8 V7 O( j
<P>LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window: S. L' Z, u8 L3 q5 K( ^+ y
UINT uMsg, // Message for this window , U* l) v# u( B1 g R* q WPARAM wParam, // Additional message information " c, s% F% y( a- J, e LPARAM lParam) // Additional message information : V! U7 v: p) E+ {! }{# Z# M2 v8 X; z! I7 U' L/ K% }
switch (uMsg) // Check for windows messages 8 z9 l% O3 O( L { # K4 |6 f. \9 [4 {. l+ W6 S$ H. K5 [ case WM_ACTIVATE: // Watch for window activate message 6 B5 m; P' y, j {) q5 q- z! c8 P" m
if (!HIWORD(wParam)) // Check minimization state& R$ v) ^$ e p; e! l+ O
{ % q0 X6 \; f |( N0 u active = true; // Program is active, ?6 n9 ^) C T( R8 k! d1 U
} ! h; C) q3 F9 Q; C& r/ I* h2 B else, d/ r" c- ]0 i* `. E* c: w2 u
{6 O. b. j+ x D& R$ K* _
active = false; // Program is no longer active * v* J0 C! k4 R9 ?) B. Y7 { }</P>0 K2 p: q5 X$ m2 ?
<P> return 0; // Return to the message loop% `6 b5 F1 h+ P$ V
}</P> # z8 p! m; A! N' _4 X2 N<P> case WM_SYSCOMMAND: // Intercept system commands 9 n6 q$ t" b- `8 d% ?8 J. K3 w7 l { 3 g) z* X; Z, G& i8 _( S! J# s switch (wParam) // Check system calls 6 w0 _$ n! H8 h5 T, z/ X {; \8 ]! Y% J, V
case SC_SCREENSAVE: // Screensaver trying to start? 6 i2 J3 ^# ]5 g case SC_MONITORPOWER: // Monitor trying to enter powersave? 0 Q$ d8 p2 }3 I4 \: g return 0; // Prevent from happening 6 W _( }7 A$ x: J }' E5 v* z, U' l- C& q
break; // Exit% E9 z( E4 S" Z7 u# x7 m; f8 m$ T
}</P>, p; g, y1 K" r3 H& z# b
<P> case WM_CLOSE: // Did we receive a close message? _: N1 S6 F& _5 `
{ 0 |( D6 D6 u% v' e h9 V5 w0 k PostQuitMessage(0); // Send a quit message3 e- M8 u7 b/ I- K+ {9 b
return 0; // Jump back 9 l- s6 }% u$ Z) x }</P>/ I$ t, B# d$ Z h
<P> case WM_KEYDOWN: // Is a key being held down? 5 F+ C* ~" K2 ^; ?; _& s {" F3 `! p9 J* l# e
keys[wParam] = true; // If so, mark it as true * U: S2 `0 a2 M( f: k8 A return 0; // Jump back7 ~$ j) G) ~$ E }7 f! j$ \ W
}</P>6 D4 V7 L+ D' a/ a
<P> case WM_KEYUP: // Has a key been released? 5 Z8 b9 P" U4 B: K& y+ K1 j1 ~ W {3 z; S) D3 S$ q8 A: c H& T/ x/ k
keys[wParam] = false; // If so, mark it as false , v* k4 ] Q" g& {1 k return 0; // Jump back ) D, Z. p1 }* j# a }</P> " v5 R* g- ^( W3 d9 L<P> case WM_SIZE: // Resize the OpenGL window/ C. |" T, h% w) r0 O
{) u& |# Q) s2 m0 P2 T6 w
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord = Width, HiWord = Height4 A3 [# N; z2 d& g& Q0 ]1 U* L
return 0; // Jump back ; l C' d( R5 F* h8 A( r }$ M+ ?9 v, b$ z- d d- _
}</P> - p8 Q }7 C7 A<P> // Pass all unhandled messages to DefWindowProc+ W* j8 q) v4 x" H0 ]% |) d
return DefWindowProc(hWnd,uMsg,wParam,lParam); 2 o8 C A9 V$ W$ m}</P>, [$ _1 a; t B% ]
<P>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) ! [: N8 }0 X+ p$ m{ u9 _4 l& u( t MSG msg; // Windows message structure 8 e( v7 H0 b8 q% H! P bool done = false; // bool variable to exit loop</P>% n% v0 C3 S! {! P
<P> // Ask the user which screen mode they prefer0 \! ~ Z2 a3 i% V' ~
if (MessageBox(NULL,"Would you like to run in fullscreen mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION) == IDNO)! o( I6 ~1 I* ` c+ O$ S: v
{' p6 b% e. o! G8 M
fullscreen = false; // Windowed mode+ k6 ]7 g( |8 S7 x
}</P> " C" s6 l8 W( q8 \) U<P> // Create our OpenGL window4 A) K" x. s% H' n
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)) , |5 C# M! b8 l/ a* h { 9 o2 `/ r) v# }/ ], ~: q return 0; // Quit if window was not created " \2 r. R7 _3 m: e$ W+ z8 {( H+ F }</P> : x+ j3 @/ E- R& K! S/ f9 I<P> while(!done) // Loop that runs while done = false6 `3 z$ m9 j' [$ I) G; ?3 L a
{) l, e' b$ d/ v& R" R' n
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is there a message waiting? % ~" [7 [. o9 K2 V { 1 b$ @! P* _% W) Z9 ^7 j if (msg.message == WM_QUIT) // Have we received a quit message?/ I" p1 g; V q% }
{. J# k9 T$ @- Q2 j" [- z
done = true; // If so done = true& h4 }2 N; Q9 o1 j+ q
}! s+ \$ K' h. B
else // If not, deal with window messages & J7 U/ T- N# a! H" K { . z' @2 r1 L: ]9 R" X0 C3 A) R0 O" ^ TranslateMessage(&msg); // Translate the message3 ?4 k1 r* ]: i1 t+ f* ]* U& h
DispatchMessage(&msg); // Dispatch the message 8 g6 s- J7 R$ A }; Y2 A7 g5 Q) z' R
}) d) }: z1 X* P Z
else // If there are no messages ; o% k$ f# m9 e* g. j {4 U6 N/ b1 _* w0 e% N
// Draw the scene. Watch for ESC key and quit messages from DrawGLScene() + q! x8 P/ M( e+ N0 F8 c& f2 ] if (active) // Program active? 9 L6 v3 S3 ]/ `% m$ w { " s, @; k4 F: ?4 O. Z- \ if (keys[VK_ESCAPE]) // Was ESC pressed? U' Z( ?% y' Z3 C
{- b1 I; u# h$ i# d
done = true; // ESC signalled a quit 1 O* o7 \) |$ d/ m+ K: W+ E } , h. P# P0 P. ^' Y( H0 l' @% } else // Not time to quit, Update screen ' Z/ p/ w! q; L0 g2 r { 6 G$ R ?" D8 O9 o2 F8 d5 ] DrawGLScene(); // Draw the scene + b1 a; b+ y. G! p, k) T SwapBuffers(hDC); // Swap buffers (Double buffering) & M) p" @" A. B! f( F6 U% P }$ e- j4 M' c. A8 G6 ~3 }( J& z
}</P> 6 R( R5 U# @; w' o2 y* `) D<P> if (keys[VK_F1]) // Is F1 being pressed?; T/ b+ r' R& y) U
{: b3 r/ g8 M! G# b4 d+ X
keys[VK_F1] = false; // If so make key false 6 ]# J. R9 d1 z" i; W( J- l KillGLWindow(); // Kill our current window: [3 }7 @& ^9 M1 o+ u1 I! k
fullscreen =! fullscreen; // Toggle fullscreen / windowed mode; Z/ x( y {5 S- D- t& ^
// Recreate our OpenGL window , k6 p6 b# a9 h7 b' ? if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)) 0 K# f. B2 s& \- `2 z { ' j9 I2 N$ g2 o* { s" N, R1 p return 0; // Quit if window was not created7 |( b/ V. r6 i& y G: `* N
} 2 `0 Q0 S$ k: o- x, n% b& h0 F } % z+ h' ]1 P5 o0 L$ N; Z7 W }, p( N5 }, I2 a
}</P>, D- Y1 T# J% r' J0 i6 |
<P> // Shutdown# S- C+ H$ s3 X6 |/ j
KillGLWindow(); // Kill the window 4 z. u* s, C( H% F8 Y* n" a, |: A& b9 E return (msg.wParam); // Exit the program $ g, {1 d9 F. n5 o, U _} 7 L* ~! l' `4 u1 c7 x. B4 t& q1 F: T//---------------------------------------------------------------------------</P>