<>这是NENE的OPENGL的框架CB原代码,是黑屏的效果,最简单的。OPENGL我才开始学,很多不懂的,希望和大家交流,共同进步,我会把我的资料和大家共享的!</P># V, X5 L) D U1 h2 ?
<>首先在CB下建立一个CONSOLE的程序,然后把CONSOLE APPLICATION的勾去掉即可。然后再把以下的原代码粘贴上去就可以运行了!!</P>! N( C* j5 F: }+ u
<>//---------------------------------------------------------------------------</P>$ u2 P0 Q. f9 \% B: A1 a9 K1 `
<>#include <vcl.h>9 h; a" {6 [' S2 n
#include <windows.h> // Header file for windows: ~2 ^( a3 L' j8 \1 Y
#include <gl\gl.h> // Header file for the OpenGL32 library Q% i, k& G: e8 M# _# F4 r2 e
#include <gl\glu.h> // Header file for the GLu32 library v4 h _6 A) N) h#include <gl\glaux.h> // Header file for the GLaux library* S3 h ?, w0 y- y
#pragma hdrstop</P> ' g# `/ E% j9 \: d7 `<>//---------------------------------------------------------------------------0 ?) R: {0 x8 V. L% _
#pragma argsused</P>8 ~( o0 }, g* H" R( y6 O
<>HGLRC hRC = NULL; // Permanent rendering context3 m( q0 |% C% b& }: z/ o( f8 Q5 Z
HDC hDC = NULL; // Private GDI device context; {: \, W5 X9 L; \
HWND hWnd = NULL; // Holds our window handle. d' c/ B% M9 r5 x
HINSTANCE hInstance = NULL; // Holds the instance of the application</P># I& K/ J2 Z8 Y G# B# k' v7 _+ r
<>bool keys[256]; // Array used for the keyboard routine6 n0 ]# g& k4 N* w
bool active = true; // Window active flag set to true by default # T1 X% g/ i% Gbool fullscreen = true; // Fullscreen flag set to fullscreen mode by default</P>. Z# t, m A" x! b
<>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc</P> , c4 i! K& \1 S8 O- I# f<>GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window 7 L. J4 L4 z. K/ r3 N* H{* _, |% v U% b* H4 {
if (height == 0) // Prevent a divide by zero by 0 B- v* ^# x4 ]2 H. t: P9 R4 X { / k! \4 C8 j5 A height = 1; // Making height equal One ! K, A0 k" g3 W# [. U }</P>2 N( [* T0 }3 q( F
<> glViewport(0, 0, width, height); // Reset the current viewport</P>/ C" `) S; U4 F" `* [$ ~
<> glMatrixMode(GL_PROJECTION); // Select the projection matrix' K# b0 N6 ]6 Q& @
glLoadIdentity(); // Reset the projection matrix</P>' H! C9 ]. ^6 f0 I, o2 q% {( F; k
<> // Calculate the aspect ratio of the window . t' N& s1 w7 E2 z+ M; m8 i gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);</P> ' d2 L8 s% M. S5 Y+ g& Z<> glMatrixMode(GL_MODELVIEW); // Select the modelview matrix6 E% D5 J& w3 |/ t7 h
glLoadIdentity(); // Reset the modelview matrix % V3 t3 z( S+ Z' C" O$ i$ S/ r}</P>: q5 p9 e6 E- O) v( L
<>int InitGL(GLvoid) // All setup for OpenGL goes here 2 r4 P6 }; F9 B0 s9 X+ z0 k{ , {5 m. A9 ^( s0 c4 `$ e$ E, A9 S glShadeModel(GL_SMOOTH); // Enable smooth shading ) e. O$ J9 u+ t) l: V! O glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background, ?8 z+ \6 {8 L0 U3 F- Q
glClearDepth(1.0f); // Depth buffer setup * G% V) H5 q, [1 |) ^& D. ] glEnable(GL_DEPTH_TEST); // Enables depth testing ) [+ u( ]; x) c+ H glDepthFunc(GL_LEQUAL); // The type of depth testing to do+ u6 x7 Q- b- I/ Q+ P5 `* }
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations ! h! O2 B8 p$ o. c0 L& x return true; // Initialization went OK : A# J# c* t' w5 f$ j}</P> 4 J: A. Y1 K3 N& }1 G$ M<>int DrawGLScene(GLvoid) // Here's where we do all the drawing ) x4 Y8 o+ u4 J/ Z7 f0 L{ M) y" f$ @6 J) T6 c* X# U glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer # c* n2 x6 `$ P, p0 A; Z. v glLoadIdentity(); // Reset the current modelview matrix4 G' X/ G) E; D, r2 J
8 ~& N) z3 k5 K9 j return true; // Everything went OK & y) m" b4 A* V4 f}</P>8 f" s% R3 H) W
<>GLvoid KillGLWindow(GLvoid) // Properly kill the window& ?) B% \1 p4 C/ S b# R
{6 H3 B) o0 g/ J, T
if (fullscreen) // Are we in fullscreen mode? 9 B. l% y$ @4 B { ! W$ ?% K' v5 T8 T) d* x S- J ChangeDisplaySettings(NULL,0); // If so switch back to the desktop 6 z) v6 T4 C' P ShowCursor(true); // Show mouse pointer ! Q O" U" x4 [# {" @$ V) H3 c# [ }</P>, G1 G+ Z' f* A1 Y
<> if (hRC) // Do we have a rendering context?2 s8 z. ~1 ?, _
{+ _: H! V% v: j, y% m9 D: t* }
if (!wglMakeCurrent(NULL,NULL)) // Are we able to release the DC and RC contexts? 6 o* I" \# ^ U' Y. o& @+ `9 ` {, i7 f: s% P3 E/ Z, h& R
MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 9 [8 ~: P; ^" l8 y1 m }</P> 5 C; T0 `! g9 S7 Q& f3 v<> if (!wglDeleteContext(hRC)) // Are we able to delete the RC?( j: Y5 o+ M* e1 w" y, i6 j) Q
{ e9 l6 n: g. Y( F! Y; f/ L
MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);& m" j/ f4 T- K, J ?
}& z8 O8 P ~' ^* {
hRC = NULL; // Set RC to NULL7 x+ t* B; b- @# o, P& I' P
}</P> 2 n$ h8 j2 o* Y$ q<> if (hDC && !ReleaseDC(hWnd,hDC)) // Are we able to release the DC# G9 m9 G1 I' e' F5 E/ V w
{3 k: X5 `( w2 w& ?5 c* l" z; C D
MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 8 x3 ]) v! _) S; o hDC = NULL; // Set DC to NULL & S1 P" E' G: U0 R8 @# z }</P>4 M4 k3 ?: r2 J- P
<> if (hWnd && !DestroyWindow(hWnd)) // Are we able to destroy the window?/ r: H- N4 k0 W0 q
{ ) N, K0 q2 \& z1 x: S; o* B MessageBox(NULL,"Could not release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);; G$ r5 N: `5 U- |+ x% E9 I5 `
hWnd = NULL; // Set hWnd to NULL+ U& u5 X3 C1 @) x7 X) C# R- v
}</P> - b# H8 h5 q- H& N- V1 z$ j! E" e<> if (!UnregisterClass("OpenGL",hInstance)) // Are we able to unregister class / e/ M; ?5 e' ]. S+ M+ U { " g3 @. C$ f8 r7 I+ R. { MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); : F. ?+ I+ [ H7 v2 X+ c# d hInstance = NULL; // Set hInstance to NULL 2 A- s5 @' r' `, |- Z0 B$ w }! _3 k3 f! ^2 V& m: M0 L1 U% W
}</P>) D0 l. Q: f( U1 R5 C( H
<>/* This Code Creates Our OpenGL Window. Parameters Are: & r% R' p: V7 q: b1 F; g* r& E" j * title - Title To Appear At The Top Of The Window! U c+ E1 O% U1 k- Q8 D( Y+ d
* width - Width Of The GL Window Or Fullscreen Mode # K1 U% q# A. y& y/ `2 a8 y; c: n * height - Height Of The GL Window Or Fullscreen Mode ! W' L( ^( H3 i * bits - Number Of Bits To Use For Color (8/16/24/32)/ l) j) F2 [* g- D& c
* fullscreenflag - Use Fullscreen Mode (true) Or Windowed Mode (false)*/: m5 ^) j7 E. x
6 }4 u K; t9 H3 l, }+ B9 Rbool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)# S1 g" X6 T; v: N' G; N- `
{6 `3 d" u* H2 V( ~# }
GLuint PixelFormat; // Holds the results after searching for a match $ m7 s8 R* T/ _; J WNDCLASS wc; // Windows class structure 6 C; M# s2 U5 n& M% z3 w DWORD dwExStyle; // Window extended style p$ C/ M* m0 |, x2 a- r0 V' g
DWORD dwStyle; // Window style6 M4 o5 c. v3 Z; D/ k
RECT WindowRect; // Grabs rctangle upper left / lower right values # v1 U. ?* N# _; w# [ WindowRect.left = (long)0; // Set left value to 0 + M8 r0 ^' Y r* @* L* @ WindowRect.right = (long)width; // Set right value to requested width $ _% U! s) S: P WindowRect.top = (long)0; // Set top value to 05 _4 r3 Z" W9 o; ~$ q, h& o
WindowRect.bottom = (long)height; // Set bottom value to requested height</P> & q' r+ Q# b" g7 U( b$ Y# Z<> fullscreen = fullscreenflag; // Set the global fullscreen flag</P> ) G" q8 W9 }8 ^# [7 z<> hInstance = GetModuleHandle(NULL); // Grab an instance for our window 5 R) w4 \1 D' W wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on size, and own DC for window6 }2 r6 g7 n+ k8 r- H$ f0 z
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles messages ( v* e/ m6 X5 D, b/ d) { c wc.cbClsExtra = 0; // No extra window data / {) M. O4 W0 L. R wc.cbWndExtra = 0; // No extra window data' E' j7 i% `# f
wc.hInstance = hInstance; // Set the Instance " N+ ]$ M* t N( E0 J `; j wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon . k; Q& y( {5 [! S4 o; r" @ wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer + N4 B$ z" R8 m/ ?6 f5 ^ wc.hbrBackground = NULL; // No background required for GL3 O. H. C) N3 _
wc.lpszMenuName = NULL; // We don't want a menu! Y. w6 e9 W" `5 c! z3 ~
wc.lpszClassName = "OpenGL"; // Set the class name</P> ) L5 o5 u; g0 @$ B* U' ^<> if (!RegisterClass(&wc)) // Attempt to register the window class ! z% W q4 V+ ]+ s, z# T& G/ R { : r4 ^! }( M8 J; Q MessageBox(NULL,"Failed to register the window class.","Error",MB_OK|MB_ICONEXCLAMATION);</P> 3 J" C- T8 B6 d; a) _) l( Q! O; O- i<> return false; // Return false* y+ O$ f# i) f9 o& O
}# t' r* d6 W# u& u6 x4 Q5 d
9 s. [1 e& k/ b, l. f6 P if (fullscreen) // Attempt fullscreen mode?6 g, q8 u8 X o- s3 J
{ 0 t6 k, g$ i% u- R# t DEVMODE dmScreenSettings; // Device mode) I7 W2 j( D+ e# K! Y# S$ U! _/ o
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes sure memory's cleared 1 C) k' }) l' z7 e dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of the devmode structure ! }/ E. W. [2 Q! N) a' X; d3 Q% ]$ _+ ^ dmScreenSettings.dmPelsWidth = width; // Selected screen width & @. X" U2 U( i dmScreenSettings.dmPelsHeight = height; // Selected screen height. [: e, z* S0 E! D
dmScreenSettings.dmBitsPerPel = bits; // Selected bits per pixel | O! ], j) y. u# q. w dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;</P>% G' m! g4 k, t. W' ~1 ?) e
<> // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar. ) J, q+ f( y: Z! D* a, w- @ if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL), w" T' {4 r( ^2 ^. E
{ & {1 I* @1 R$ p5 Z* d! d' } // If the mode fails, offer two options. Quit or use windowed mode. # z0 m; m0 j8 ]6 R 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: d/ n- X2 ^& ~" l' B m8 z
{1 M, _. R+ `$ D; C
fullscreen = false; // Windowed mode selected. Fullscreen = false 8 t* k) l8 G" W: r8 L }6 p% O( p0 \! V6 s/ Y( ^
else- S4 K& L& _( \) D* r
{3 h+ p, ?2 v! M& z
// Pop up a message box letting user know the program is closing.; |0 q y. ^ h# z5 }3 V+ o7 s/ Y, @/ `
MessageBox(NULL,"rogram will now close.","ERROR",MB_OK|MB_ICONSTOP);% @; T' k) u) ]
return false; // Return false , v4 p' M+ }* Z% m* I6 [& x) S+ _- J# K4 r }" g: ^: U6 p8 n2 }
} i5 D3 f( o$ {+ D, J& C9 ~
}</P>+ s% K+ V; r+ {
<> if (fullscreen) // Are We Still In Fullscreen Mode?7 k4 _, x& R5 X0 x9 o
{( @$ `" H/ `4 V5 j
dwExStyle = WS_EX_APPWINDOW; // Window extended style 1 V9 c* `/ ] b, }- R2 c* T dwStyle = WS_POPUP; // Windows style 8 v6 T' h8 C- X- a! a0 D ShowCursor(false); // Hide mouse pointer9 k* _% R1 c' m& X& Y- ]* c
} ' U T2 h4 ^7 e5 K8 h7 F0 F$ t* e else: h) @& \0 b7 I! _) _
{ , W) o, S3 u" L/ s dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style7 d5 _8 c$ w; z+ z; q" p4 x
dwStyle = WS_OVERLAPPEDWINDOW; // Windows style + o7 Z% e/ x* g+ e! ~$ V5 ?" {0 F5 T$ x }</P> s/ a/ K Q5 n* R- Q5 d1 Y% k
<> AdjustWindowRectEx(&WindowRect,dwStyle,false,dwExStyle); // Adjust window to true requested size</P> 8 x% {5 U" i( g<P> // Create the window5 w: i7 Q1 W% Y$ n- c/ [0 S% D9 z
if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window $ O+ o" E, ~2 @ "OpenGL", // Class name , Z- R k% t( [1 I1 f0 p title, // Window title 5 g" c. W/ H. R) m ? dwStyle | // Defined window style 5 B0 w( `+ T. G8 O# M+ z; g" o WS_CLIPSIBLINGS | // Required window style 9 X6 W; H' v$ o+ a& } WS_CLIPCHILDREN, // Required window style 6 G2 q i; g- C. d 0, 0, // Window position0 Z) _* S I% E5 |5 R) u t
WindowRect.right-WindowRect.left, // Calculate window width % t3 {* Q0 L1 I/ ]% y+ c WindowRect.bottom-WindowRect.top, // Calculate window height7 Q+ c& x. b, G1 K& C8 z3 u1 e
NULL, // No parent window6 i. M" ~1 T8 q2 M& Y. l5 o2 X( f
NULL, // No menu9 g( j) _% o# ?% B' p
hInstance, // Instance/ G+ P/ Z, x3 c7 R, g. T5 l0 u: V; [
NULL))) // Dont pass anything to WM_CREATE0 Z3 S, p( a! x6 C
{ \9 l- X8 p. } y5 e" s# {9 | KillGLWindow(); // Reset the display , ?: Q3 \2 h' u1 Q MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION); 6 k1 j. d$ H& L) a% ?- N4 A0 d/ E3 p return false; // Return false8 m- v- ^: I/ ^6 ]! k# X$ P; v
}</P>) {9 s$ L3 Q" `4 P
<P> static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be 1 j: D' z8 z' _ {1 G w* q6 s l
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor6 r. z* o; }9 m3 k H, @
1, // Version number: ~5 p+ g3 g/ ?6 G$ H" W
PFD_DRAW_TO_WINDOW | // Format must support window . T% S- N0 S1 ^2 ~1 [9 L( Z8 b9 h( u; D! g/ m PFD_SUPPORT_OPENGL | // Format must support OpenGL7 e0 Z: T- Y% d" x1 L" S
PFD_DOUBLEBUFFER, // Must support double buffering # g* {" K% j4 K9 h& D% I6 S PFD_TYPE_RGBA, // Request an RGBA format$ \4 e' x, v2 Y7 S; ^+ M
bits, // Select our color depth) ], a V3 T, z% W7 n% o
0, 0, 0, 0, 0, 0, // Color bits ignored7 j) H( Q4 Z( |% {6 ]
0, // No alpha buffer6 r8 b$ h/ D4 `4 W* Q; j2 }
0, // Shift bit ignored9 s, p/ S: l* L$ ?* J; o+ `
0, // No accumulation buffer * v" n5 x( E; n# K 0, 0, 0, 0, // Accumulation bits ignored/ J" g |9 e" j8 @' E
16, // 16Bit Z-Buffer (Depth buffer) , T. q& S* c8 U9 g" _ 0, // No stencil buffer( k; V1 V& z( h6 b) M* ]* n5 @" |
0, // No auxiliary buffer3 [% r: `3 N* D1 z
PFD_MAIN_PLANE, // Main drawing layer; |$ n1 w$ y l* p
0, // Reserved3 d1 P1 b0 w: @3 Q; y6 [
0, 0, 0 // Layer masks ignored$ _ R# H L6 m; S
};- `0 J; B5 g) i8 V& {
+ ]9 f. C/ ^, \5 y% {5 G! `
if (!(hDC = GetDC(hWnd))) // Did we get a device context?- y$ @& {* h. S: S \; R a
{ 5 J' Y; b% H+ x2 M/ a) _" Y: ~8 _ KillGLWindow(); // Reset the display# H5 l4 y$ V4 `; x( G
MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION); " N( C9 J% \. [9 P! n return false; // Return false: }; P/ ^- ^! V3 e& ]+ W
}</P>, m! E( m# [) L: E
<P> if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did windows find a matching pixel format? 6 m# L+ y, u. I5 S2 O, u {3 o y/ D; k- I. J) y- N1 H
KillGLWindow(); // Reset the display; W4 Z. G# K+ a7 x s
MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION); 9 `; O g9 q) I3 |8 {. z6 g return false; // Return false$ z ]. [2 ]6 |$ H$ n* ?5 s
}</P>1 F8 A8 u( C$ S! p G
<P> if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are we able to set the pixel format? 0 B: G( [$ a: `$ y" F8 _" w {# [/ \. q1 }4 g
KillGLWindow(); // Reset the display& P* l) v/ Q% S8 c M) Z# s' r
MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION); # S. x) `# S+ p. G; _ return false; // Return false 9 L' o& J/ k/ W0 o7 a% R! A }</P> ! @, N$ s* B2 x<P> if (!(hRC = wglCreateContext(hDC))) // Are we able to get a rendering context? * ]& s0 e/ C: ~" V8 p9 |! C7 U { . d: x" \8 Q, \0 R/ y7 ^ KillGLWindow(); // Reset the display1 U* l5 j: D0 K
MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);+ F5 d$ }+ I3 e/ }
return false; // Return false ' x3 i5 i! U/ p }</P> 5 U( W7 x# C T! l; U/ V8 R; Z<P> if(!wglMakeCurrent(hDC,hRC)) // Try to activate the rendering context' \' x1 }" G. G7 @ f$ ~
{6 h$ Y, |0 H5 `, s
KillGLWindow(); // Reset the display6 w7 a& Q- m, Y
MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION); / R; T) n* o' s4 C# r' O return false; // Return false 1 u7 c( U1 [6 e1 V1 F- z }</P> " {' T0 n$ |0 W0 N4 C<P> ShowWindow(hWnd,SW_SHOW); // Show the window 9 | f/ \5 @9 E: k% e& d. c SetForegroundWindow(hWnd); // Slightly higher priority5 f$ K+ \- A Q8 J1 F1 s( l
SetFocus(hWnd); // Sets keyboard focus to the window : x. M9 u1 B8 X8 @ ReSizeGLScene(width, height); // Set up our perspective GL screen</P> 0 {* C8 ?6 d5 @. a4 Q, m<P> if (!InitGL()) // Initialize our newly created GL window) I- u( E1 I6 c7 C5 m5 l s) k7 ?
{ ( @2 m: D) O9 z- _7 D( d8 S; Z KillGLWindow(); // Reset the display% i1 ` Z' q/ e$ m( Y
MessageBox(NULL,"Initialization failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);' c7 S! v! y0 o
return false; // Return false # w1 H. q; e8 j0 o, a% Y8 h! {& N& T }</P> : v" W9 P" y T<P> return true; // Success # I2 H1 C, m" z}</P>" |9 x- Q8 U. n5 H2 u& i$ b
<P>LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window3 |6 T8 `5 p! j5 f. z. X
UINT uMsg, // Message for this window `2 s! G0 c7 }3 G
WPARAM wParam, // Additional message information: W* u. q$ n8 D
LPARAM lParam) // Additional message information3 N; [3 ^& p5 |9 s# u
{ " r2 ?* I$ Z D; U+ n6 a4 l switch (uMsg) // Check for windows messages ) K& l, Z' d; [" U { * Z9 {. x) S5 d3 L( c case WM_ACTIVATE: // Watch for window activate message2 m4 n% c9 {& }5 N; B5 s) E$ N% c
{ n" Y) U+ l- h5 W) K
if (!HIWORD(wParam)) // Check minimization state$ j' P; d! i9 D3 Q- ^
{. \$ @0 }3 p5 `- ~ L
active = true; // Program is active+ ?3 X; ^7 m' H& T
} ) n3 }7 P) w9 \. j7 Q* l! u k/ n% q else6 ^. {/ Q8 C( S( t" I& g1 X
{ - M# @7 y9 b9 L7 E; m7 L3 ~ active = false; // Program is no longer active 4 j2 _3 t5 E0 i" ~; X8 r }</P>; d, d& S5 h* u: W( S3 x9 ]# T
<P> return 0; // Return to the message loop; O+ ?9 m; f u7 b3 Q% ?
}</P> + m; h$ l7 ]0 M<P> case WM_SYSCOMMAND: // Intercept system commands0 q4 o( G/ o$ L# `& J; c
{ 3 K: ~* l/ Y( |* g switch (wParam) // Check system calls1 O1 M4 g) W: ^& |% |8 I
{4 |0 K# O) L r
case SC_SCREENSAVE: // Screensaver trying to start?5 Q7 S5 ~7 u& b7 N# N( x* K
case SC_MONITORPOWER: // Monitor trying to enter powersave?" ^# G5 v4 I( P( ^$ O L; |2 [9 W8 h F
return 0; // Prevent from happening q. E7 S+ W: i/ ]6 Z L& W( I l# g } % S( @- B( H: K/ |, M6 Y break; // Exit" Z* U1 d' r. t, ?
}</P>5 T# Y, E9 T: x8 ~& l% D
<P> case WM_CLOSE: // Did we receive a close message?5 U2 \3 I. h( T0 r
{ & d0 c0 O7 \1 J PostQuitMessage(0); // Send a quit message 2 N) Q0 W! H* `, h$ o" C return 0; // Jump back . O0 M7 m" g7 Y- p% ^ }</P>* J2 {/ U% G6 ~) k
<P> case WM_KEYDOWN: // Is a key being held down?& j- z# k/ P) T5 [
{ % A3 `6 r, E. G9 h: K9 F keys[wParam] = true; // If so, mark it as true. r# N% {7 g: |0 A! _% N! G' n1 i0 p
return 0; // Jump back 6 _7 Z) b7 _0 I/ u+ H }</P>6 |" l: p0 |) L8 m
<P> case WM_KEYUP: // Has a key been released?8 q6 x+ g5 J7 T9 b# n) k$ j% e
{! Q g0 I# r0 C: Y5 l$ n* L* U
keys[wParam] = false; // If so, mark it as false ' o8 W, H' P) W- E# {3 ]# m return 0; // Jump back , B" p# J4 B- j3 K }</P>- ^1 G% D9 D9 Y9 c4 E# b
<P> case WM_SIZE: // Resize the OpenGL window 0 }8 d% {: S/ g {* N" z8 G- [" e/ U2 Q
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord = Width, HiWord = Height $ n) |5 m i8 t8 r. m- N return 0; // Jump back 6 u1 |7 A& G4 M4 n7 Y& e) X }. G1 v+ o0 V1 n9 E
}</P>9 ^: ?7 P( P2 c/ c) z& L; y* O
<P> // Pass all unhandled messages to DefWindowProc ! {$ T2 _9 T" |0 D4 |2 B! } return DefWindowProc(hWnd,uMsg,wParam,lParam);( A! N1 o7 \$ r- T7 \
}</P> - L; P: h1 x2 B! `5 ^9 s<P>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) " Q# ~9 o! T ^+ L7 d# ?{: O/ z# ?3 |" x2 N6 [3 O( F
MSG msg; // Windows message structure/ O" a6 E) E% c1 X5 ~, @
bool done = false; // bool variable to exit loop</P>+ w5 v. L/ b+ O
<P> // Ask the user which screen mode they prefer ( @" y$ _9 p* S2 N1 k3 ?4 V) n& ~ if (MessageBox(NULL,"Would you like to run in fullscreen mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION) == IDNO): j) T% f. m, j8 D- \( {2 I$ u
{ , f3 ]5 q: M7 K6 i: p fullscreen = false; // Windowed mode" f2 K/ K: _& j) T1 _4 p( s7 \
}</P> . b" R* n2 p4 u* E0 s8 a3 ?4 k0 c4 `<P> // Create our OpenGL window( G$ S2 e* d- W9 p: H1 d5 |/ S
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))6 q4 x5 d/ [( Y* [+ L5 E3 O# `6 v
{ 7 H) w# E) L: [- t& p return 0; // Quit if window was not created! H6 h9 x* A6 c
}</P>: x" P- @. K+ {$ C
<P> while(!done) // Loop that runs while done = false6 [! D! j5 l1 K5 a
{' Y' P$ T" J* W# Q1 q9 ?
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is there a message waiting? ) _! M8 u* ^9 K# }! \ {) c, Y( O( l- @: ~! k) {
if (msg.message == WM_QUIT) // Have we received a quit message?; o; ` p% @- ~$ c, ]
{6 s: j, K7 J! E! D: V% n9 i* k
done = true; // If so done = true( l6 t2 {0 \1 s8 f6 n
} ' ]% k5 Z. }* F1 ? else // If not, deal with window messages + Z7 r9 S$ ^; g {+ G7 p7 a6 s( v7 i0 _
TranslateMessage(&msg); // Translate the message L2 c E" e1 r6 ~" d5 ]9 z DispatchMessage(&msg); // Dispatch the message8 Z, F; M. I j" v, ?% J, F3 q$ c j3 X
}0 f, t/ B0 ^' n% D& T9 K( C9 I
} 5 O- }/ j" y+ m4 E9 M" _% h else // If there are no messages! z: \# Z! W) n) s% K! y; ]1 P
{ , a8 k2 f3 I$ W" X // Draw the scene. Watch for ESC key and quit messages from DrawGLScene() G* P. F7 @7 O7 N" G2 z0 {0 L, u if (active) // Program active? : @/ G7 I7 e- C {4 O1 e1 N' y. k
if (keys[VK_ESCAPE]) // Was ESC pressed?1 `+ ]0 H: O7 D- R# y+ t
{ $ i' K/ K7 B! k8 v, ~3 d$ [0 X done = true; // ESC signalled a quit * |; }% O+ Q9 f6 ` } 1 i" f# I1 `- j1 O1 |6 B8 N else // Not time to quit, Update screen0 |% R$ u1 R$ w! B3 |8 D. i
{ ; C( w) c0 S" }% d. l/ a2 J DrawGLScene(); // Draw the scene 8 {! J+ Q: m, I0 T1 D SwapBuffers(hDC); // Swap buffers (Double buffering) 8 ^6 m) z9 g0 R; P1 N" ]2 b5 q. Q }' p. v4 U4 \; r% w7 _- c4 d
}</P> . k# w' e, |% C+ X<P> if (keys[VK_F1]) // Is F1 being pressed?# Z" `0 f4 P- g. r9 o1 [( t
{ / K7 _1 ~) Z/ ^5 w: }# [ keys[VK_F1] = false; // If so make key false 8 j# x3 n( U' G$ H1 F/ M KillGLWindow(); // Kill our current window- t8 z' n3 a; y+ H; y
fullscreen =! fullscreen; // Toggle fullscreen / windowed mode% _' M/ h& F* |- W4 c
// Recreate our OpenGL window ! P0 t3 o- ], H3 p7 R; B! y if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))6 c9 ~5 A* z4 u9 W. l' d
{7 u, ^9 y2 G! |4 s6 M
return 0; // Quit if window was not created& `- G/ c& N6 w O0 z/ F
} , F2 o1 I1 G+ ?! [ } 5 W2 @2 g; E- M. A% Q) ~3 O7 q/ q } " ~, l, ^/ o% X7 w! R( o }</P> H. l6 }3 i5 c! u5 J' C<P> // Shutdown $ R6 x% A1 w* E! i KillGLWindow(); // Kill the window 7 n1 B: B# Y/ F e1 Q return (msg.wParam); // Exit the program 0 O9 r+ f3 k% p. ^2 E3 F}* y2 @ t- P# b; Z7 v. R
//---------------------------------------------------------------------------</P>