<>这是NENE的OPENGL的框架CB原代码,是黑屏的效果,最简单的。OPENGL我才开始学,很多不懂的,希望和大家交流,共同进步,我会把我的资料和大家共享的!</P>0 f! i+ k, E/ v8 @" }4 \) ^
<>首先在CB下建立一个CONSOLE的程序,然后把CONSOLE APPLICATION的勾去掉即可。然后再把以下的原代码粘贴上去就可以运行了!!</P>* w( Q7 v5 s L' T
<>//---------------------------------------------------------------------------</P> 6 ?, v1 R) g+ L) K<>#include <vcl.h> 4 x& l+ N5 g# I* }% K' ^#include <windows.h> // Header file for windows3 G0 S1 r- b% u4 |
#include <gl\gl.h> // Header file for the OpenGL32 library0 ?3 V( t& u7 k, j" ]6 Q3 U
#include <gl\glu.h> // Header file for the GLu32 library) C2 f7 f2 J! y n3 [' e3 w" b
#include <gl\glaux.h> // Header file for the GLaux library ; @4 v4 a/ F8 ~) _9 `, j#pragma hdrstop</P> ' w4 V, I- R7 X7 s# H! ~<>//--------------------------------------------------------------------------- ! q" Y- v- |: C) e#pragma argsused</P> & U( D4 F1 I# H Z: b6 @$ p; w<>HGLRC hRC = NULL; // Permanent rendering context 6 Q% S# J& k% R2 |HDC hDC = NULL; // Private GDI device context / K/ k5 Z2 b% J" A3 DHWND hWnd = NULL; // Holds our window handle+ L& q0 ~+ e, v5 {( s. n0 C
HINSTANCE hInstance = NULL; // Holds the instance of the application</P>, e4 [0 D Q0 h* ?5 t l
<>bool keys[256]; // Array used for the keyboard routine2 w6 P, ?( s0 ^6 U3 Q
bool active = true; // Window active flag set to true by default ' g( ]! s4 [7 u$ sbool fullscreen = true; // Fullscreen flag set to fullscreen mode by default</P>+ |4 S+ n. z6 N a
<>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc</P>( K G: V' t, d {0 l5 U
<>GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize and initialize the GL window7 }* p1 N' s# E
{ 0 N) c& M. m. E" | if (height == 0) // Prevent a divide by zero by ! Z$ i0 x) E e3 i: g; B1 ?$ P) ]: U {7 \& e, z A# r2 c0 {
height = 1; // Making height equal One* n6 K2 X: R& R. O% r1 A
}</P>$ ]9 W2 q6 I& k5 H8 ]
<> glViewport(0, 0, width, height); // Reset the current viewport</P>/ T5 T( s, K- t! s) j6 a
<> glMatrixMode(GL_PROJECTION); // Select the projection matrix2 W( q; s' b) x. h% H2 H" v
glLoadIdentity(); // Reset the projection matrix</P>! p7 T3 ?4 W' W
<> // Calculate the aspect ratio of the window" d3 o9 a* B8 s) O& Z6 t/ p& E! ?) q& _
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);</P>9 }1 {7 A+ H* X+ z. ?
<> glMatrixMode(GL_MODELVIEW); // Select the modelview matrix* ^# F% s2 Q8 k( X- S0 j
glLoadIdentity(); // Reset the modelview matrix ! d2 a0 @. B" G) H2 T}</P> $ C7 S: }: l- O- e& _<>int InitGL(GLvoid) // All setup for OpenGL goes here& F0 r+ P( d1 |& `
{3 q3 [6 f1 r. a/ Z7 E9 h _* I
glShadeModel(GL_SMOOTH); // Enable smooth shading 2 m9 D* f) |! o- t: p glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background. L- ^' x& ?" n. q% k( f; [
glClearDepth(1.0f); // Depth buffer setup& o# b; K) D, h5 r
glEnable(GL_DEPTH_TEST); // Enables depth testing7 E9 R0 G$ P& q! R( p
glDepthFunc(GL_LEQUAL); // The type of depth testing to do 6 g* r4 o4 {7 a glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations + W, g* T" z$ t! [: `& T return true; // Initialization went OK# u, T# V$ i0 h/ u# ^7 f
}</P>, o- ]# x, l( c6 E: d9 `! S0 u5 K
<>int DrawGLScene(GLvoid) // Here's where we do all the drawing 4 i, ^: }6 E5 |* v+ c! z! |{8 C6 J' f9 R$ Z4 M5 C
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer# y- a. S H( p
glLoadIdentity(); // Reset the current modelview matrix - w. h8 B0 T) G0 ^+ c 6 P0 K6 Y! y) T5 Z% @5 N6 A return true; // Everything went OK 9 U4 P0 M; t, h5 }}</P>$ i2 C; H' V, f' w" d/ k9 L2 g! V% @
<>GLvoid KillGLWindow(GLvoid) // Properly kill the window 0 W' B W5 l/ v0 V) _2 Z& {& v{ " W3 H* a' E) K) @. D+ O7 [4 g if (fullscreen) // Are we in fullscreen mode?7 G# c* W5 E# x6 @3 y+ p1 G
{ 3 W3 U: o0 R) }# i4 V, M: P P ChangeDisplaySettings(NULL,0); // If so switch back to the desktop 4 T5 b$ E& Q4 }, n3 G" a ShowCursor(true); // Show mouse pointer7 g" |8 ^ g2 B% F
}</P> # _* `. P0 ]& d. D<> if (hRC) // Do we have a rendering context? : [! |1 s4 {4 U1 J4 ^( z {, r% d7 M- M @: O+ M2 I3 X
if (!wglMakeCurrent(NULL,NULL)) // Are we able to release the DC and RC contexts? 7 `& c$ l( z5 M$ X { . u/ W& N( {2 c/ M+ ? MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); # `( b2 t: [: S0 O. P }</P> 9 A8 a4 V" Q2 z<> if (!wglDeleteContext(hRC)) // Are we able to delete the RC?+ D# @2 \4 A" x3 Z
{ ! J# U$ ? m2 j3 h; \% H1 h5 ?8 f MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); " H3 }' D3 m M' |1 q" a } 2 Y0 O. y1 t. u& u+ U8 k hRC = NULL; // Set RC to NULL 2 d) M$ n0 X8 U# K; v }</P> ! Q6 X* l( h5 Y7 y<> if (hDC && !ReleaseDC(hWnd,hDC)) // Are we able to release the DC5 G8 o2 Q+ h( |7 F* h$ @
{9 N3 `- s8 u1 z
MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); 2 d9 |$ G8 k7 G: t9 S. h' ^6 K hDC = NULL; // Set DC to NULL8 Q0 j1 X0 M t Y3 ~2 H
}</P> * ]5 s( K8 p1 s, P3 s6 c) K; K<> if (hWnd && !DestroyWindow(hWnd)) // Are we able to destroy the window? 0 I6 d$ I+ Q% V) V* m* w$ D { ' o' q% U, f& \* J% n1 S6 m9 i) y) h MessageBox(NULL,"Could not release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); U& O4 ]) T4 f, `; j& t( A0 Q! h9 _9 n hWnd = NULL; // Set hWnd to NULL9 Z- C; X4 k! }$ w) n0 h
}</P>& c# d# h$ C+ ?7 N/ g0 B+ ^; _
<> if (!UnregisterClass("OpenGL",hInstance)) // Are we able to unregister class ( B' a4 @0 l' t* q) O3 a4 ~ {. W# s* Y' P9 B4 Y0 _6 m
MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);$ v% b4 h5 G6 X" s
hInstance = NULL; // Set hInstance to NULL : U( ]' K* _- U! r6 n7 U2 \ } ! I* W- F. I7 ]- [' C, c5 q}</P> & _# I c+ g$ k<>/* This Code Creates Our OpenGL Window. Parameters Are:0 `* p: V( e& d/ k" O! O
* title - Title To Appear At The Top Of The Window# d( `, k' H+ `9 E' t
* width - Width Of The GL Window Or Fullscreen Mode( {. Q" Y4 C. S) {
* height - Height Of The GL Window Or Fullscreen Mode 7 ^% H% u" v. M' R * bits - Number Of Bits To Use For Color (8/16/24/32)0 x2 L% z2 @* q$ M1 E% R
* fullscreenflag - Use Fullscreen Mode (true) Or Windowed Mode (false)*/; t8 {9 V% Z* p2 d O
6 ^% L& {$ z! L4 b% `. Dbool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) ) N0 M) J1 y7 G! q k8 M! ~{ $ p! ?9 Q; I5 v3 v$ Z: U GLuint PixelFormat; // Holds the results after searching for a match( |3 \; K. p1 ^ [# W" i
WNDCLASS wc; // Windows class structure 9 s& t! P4 P x' U+ R DWORD dwExStyle; // Window extended style6 ] o' t' }2 T U# p
DWORD dwStyle; // Window style 2 ?" F) _9 A* k" a+ E RECT WindowRect; // Grabs rctangle upper left / lower right values ; M/ A/ o; H3 V. D WindowRect.left = (long)0; // Set left value to 04 V& U) N" s6 s; n, J4 }7 ~
WindowRect.right = (long)width; // Set right value to requested width. D3 f$ X& t# ?1 b
WindowRect.top = (long)0; // Set top value to 0 r1 R% @ A3 \ WindowRect.bottom = (long)height; // Set bottom value to requested height</P> 8 a/ B* x' n7 J) l0 Q' t<> fullscreen = fullscreenflag; // Set the global fullscreen flag</P>7 g4 J/ |( W/ e8 Z1 k, x% L
<> hInstance = GetModuleHandle(NULL); // Grab an instance for our window) m) }, J7 \, p. f' D! }1 v
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on size, and own DC for window' ^1 X/ F* a2 x, a
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles messages , z' l' r9 I1 J8 H% B0 `+ x wc.cbClsExtra = 0; // No extra window data* r V+ C% F7 \
wc.cbWndExtra = 0; // No extra window data9 n$ N& e& K' M) T- \; s2 S
wc.hInstance = hInstance; // Set the Instance $ [$ x& | C# P- G, w wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon5 |. l1 i6 ?( R( w
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer! ~- f) [8 n/ e6 T. t
wc.hbrBackground = NULL; // No background required for GL 5 I) b% g; w% S$ ? wc.lpszMenuName = NULL; // We don't want a menu% J! ^* F. f7 [3 z$ L: @
wc.lpszClassName = "OpenGL"; // Set the class name</P>6 Y% K# H2 a# x; m
<> if (!RegisterClass(&wc)) // Attempt to register the window class {9 C* W. Q* U: I {5 @: Q) A3 p! C2 [! X
MessageBox(NULL,"Failed to register the window class.","Error",MB_OK|MB_ICONEXCLAMATION);</P> 6 o/ k0 [- g) @( V' U& W1 L3 T<> return false; // Return false 2 x! H5 _6 d8 B9 J- v* t" n: Z }* u. X; W" z% r+ X3 H
. w: j+ {* Z9 i! S+ I# z3 I- a+ l. G& L if (fullscreen) // Attempt fullscreen mode?/ c6 o' v- _" h+ P' m
{: D" b6 N1 I7 V' H
DEVMODE dmScreenSettings; // Device mode" s8 ~& K. ]6 B+ F) t/ ?5 ?1 i1 J
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes sure memory's cleared6 H2 F5 z+ Z7 ?% N& G7 W2 ~
dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of the devmode structure. T: m# d0 e% V) V _5 T" K6 [1 X
dmScreenSettings.dmPelsWidth = width; // Selected screen width0 d1 C2 ?) y1 Z: A7 ?
dmScreenSettings.dmPelsHeight = height; // Selected screen height$ c0 I" h8 k$ m) [$ C
dmScreenSettings.dmBitsPerPel = bits; // Selected bits per pixel% k; Q2 y; Y. } {
dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;</P> 0 c2 c) X( r$ p$ q" y<> // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar./ V$ O, `% |# `* @2 M% v
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) 6 p/ U$ Y% U8 ]2 b4 e+ \: P5 Q/ T' C. P { 9 C4 F4 R9 a6 H! Q& K/ z // If the mode fails, offer two options. Quit or use windowed mode. 4 l: m) e: U; l: q7 K: `/ t6 B 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)* Y* P) u0 g E( b
{& T' A; j1 I2 b1 b2 r8 c
fullscreen = false; // Windowed mode selected. Fullscreen = false- p6 l5 v; e$ V9 P! W6 y
} - h8 x/ O5 [+ Y5 V else ' b/ f1 i3 a1 V* \- ?' t/ g {' A: O/ ]) y' O$ [6 f' [5 P
// Pop up a message box letting user know the program is closing. + j$ O5 Q# {, {7 ` MessageBox(NULL,"rogram will now close.","ERROR",MB_OK|MB_ICONSTOP);: r& z; a6 C/ y& g$ N: D
return false; // Return false+ C" R% k! m7 Z2 |# }
} . G( M- p8 K( G9 C8 @ } - |; u$ e* ^$ W- P; y7 F9 ~$ U }</P>% K: ~' f$ c8 i( V
<> if (fullscreen) // Are We Still In Fullscreen Mode? $ U3 W* X f; S$ ^, u; D/ f {' p, m5 D# f/ S, U8 k
dwExStyle = WS_EX_APPWINDOW; // Window extended style / b, A, t' B5 j0 s6 l dwStyle = WS_POPUP; // Windows style% N, w f( |) y6 n% c3 H% o
ShowCursor(false); // Hide mouse pointer5 Q/ |( k+ E m0 t. f1 [+ C8 t
} 0 g$ M& G2 r' e- |2 u. ]& C else5 X8 ~- P. h. m( O$ Y" _* j6 |/ \
{- l( [! o: h d9 H: ?
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style . o( J+ W& ^, [7 G. D dwStyle = WS_OVERLAPPEDWINDOW; // Windows style& p5 Y& K: ?& j; r/ l* I; m" q6 ]
}</P> ' G! W& d1 P) V<> AdjustWindowRectEx(&WindowRect,dwStyle,false,dwExStyle); // Adjust window to true requested size</P>, _( a3 a1 K: ^5 E" _" q5 G4 V
<P> // Create the window$ [/ x6 H7 J1 @! Z* r" [5 h
if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window 8 h' D% w+ T! D) h3 C" ], _ "OpenGL", // Class name. q! o$ @2 r h# F$ [9 k8 m
title, // Window title # X7 H. o8 @, A( z5 W dwStyle | // Defined window style6 t2 x) {. k1 G' L
WS_CLIPSIBLINGS | // Required window style " R7 w4 k0 j" J0 k* W0 P, _1 e WS_CLIPCHILDREN, // Required window style ' K* c- Z1 T1 n7 h- N2 T4 T$ A 0, 0, // Window position 9 \" `% _; A& a3 { WindowRect.right-WindowRect.left, // Calculate window width % D2 v1 S6 J- W) v8 H/ R2 \ WindowRect.bottom-WindowRect.top, // Calculate window height U% ]( u' V6 a$ P+ ^
NULL, // No parent window5 L; y: m. [4 H3 P W' [9 r# f
NULL, // No menu + R' F& z/ `- _/ X# |- Q hInstance, // Instance - V2 q* [1 k8 F3 ^/ s; Y; L NULL))) // Dont pass anything to WM_CREATE e- P$ O& N; b9 J. G6 V { ; K: Z) W4 |# Q3 R KillGLWindow(); // Reset the display 4 R- @: D7 y% M6 y MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION);# j+ g, Z3 v! z' r0 {
return false; // Return false % N& U: U/ V( Y, M* f }</P> . x: p/ }6 f) @5 I<P> static PIXELFORMATDESCRIPTOR pfd = // pfd tells windows how we want things to be " G# A/ e/ c, C: f9 c {7 D) P3 Q" B9 M* a
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor+ t$ W I; c# s
1, // Version number 3 B" H0 Z' v( x3 Y PFD_DRAW_TO_WINDOW | // Format must support window, u% f& Z$ V i. V2 \
PFD_SUPPORT_OPENGL | // Format must support OpenGL 0 O6 T/ D0 n& I! ` PFD_DOUBLEBUFFER, // Must support double buffering 9 v2 e/ [% m- s3 a PFD_TYPE_RGBA, // Request an RGBA format; B' j) X7 u: f2 y+ ^4 k; }
bits, // Select our color depth 5 J& {! y; P6 B: v$ ?: l, ~: u, i 0, 0, 0, 0, 0, 0, // Color bits ignored / |5 e' r8 h9 \+ r 0, // No alpha buffer! D& ~; v1 J8 o/ f
0, // Shift bit ignored+ I" E. c" U( V9 m% K
0, // No accumulation buffer3 I& m- K% U5 p* T* b9 y1 A2 Q1 Q
0, 0, 0, 0, // Accumulation bits ignored , S' t" S! F; g: y( f. x 16, // 16Bit Z-Buffer (Depth buffer) ' E. p* V l) J 0, // No stencil buffer - _- c' Q8 R. b4 z* O4 u$ x 0, // No auxiliary buffer2 O4 _& o3 c* w7 l' T, B7 O
PFD_MAIN_PLANE, // Main drawing layer* z7 \9 _. F3 u6 |/ K* _' o1 @7 T' G
0, // Reserved 9 R* K$ l' e5 k ~% y1 E 0, 0, 0 // Layer masks ignored " o' k; G7 \# L, f# E9 F8 R: W, L };6 a" a/ ?; C+ m* c4 Z7 v
8 m. [$ W7 f; P- z' `: L if (!(hDC = GetDC(hWnd))) // Did we get a device context? ' W0 W8 Z2 }% R. E" l& Y* a# r/ ? {: G+ _- t) i5 p7 B2 \
KillGLWindow(); // Reset the display# h- @! x8 T; l. q, g( w5 m
MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION); 1 }" t1 H9 ~7 I% r return false; // Return false6 C |" P- e1 w- g
}</P> ) Z; q- M" D6 e$ s$ i<P> if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) // Did windows find a matching pixel format?' x, j+ `1 D: @! W& l
{0 T- L) A; H- ~7 B
KillGLWindow(); // Reset the display : s! V3 P4 z$ z5 c0 U/ u MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);: P( K) N8 p3 i
return false; // Return false0 e9 S2 K" B+ z0 \
}</P>1 P# J y- l* \' Y
<P> if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are we able to set the pixel format? * K/ J$ o1 \1 Q {4 c, H9 q( p6 j3 g9 j8 |
KillGLWindow(); // Reset the display. ?4 p3 t5 r+ ` w. G# P
MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION); % a4 f( N# z/ Z0 @5 \ return false; // Return false# [! M" r2 K% r* H+ Z
}</P>' G5 c+ Y. L9 _" f: }- w. C; W4 H
<P> if (!(hRC = wglCreateContext(hDC))) // Are we able to get a rendering context?! {. n4 o- |( {- Z
{4 N# g4 Z# ?/ r. X
KillGLWindow(); // Reset the display: e- c w j$ ^# p6 L8 t! s
MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);' ?" Y+ H$ W+ ^+ `2 q% \
return false; // Return false - p- b! n+ B. O, L- U; ` }</P>5 L- P) J" T; t% \ y7 A3 N# W
<P> if(!wglMakeCurrent(hDC,hRC)) // Try to activate the rendering context + t( g2 P. L1 H! T: M" m0 T { ' \; ^+ a7 `) B" p' q4 N; o KillGLWindow(); // Reset the display ' G! H6 _, o- |) \2 ^: m2 I MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);+ j6 ~) o/ f, O9 I7 {+ u8 G
return false; // Return false ! ?+ y- S4 g: P( e! ]6 C }</P> : F# ]! W) j# T6 c& ?<P> ShowWindow(hWnd,SW_SHOW); // Show the window# B3 y5 I# K* C# T- p% v
SetForegroundWindow(hWnd); // Slightly higher priority % F% h/ O, ^ L6 O/ D4 C$ x: N SetFocus(hWnd); // Sets keyboard focus to the window " |( M2 X6 X3 ]: M, `1 T1 i. _* [4 V4 V ReSizeGLScene(width, height); // Set up our perspective GL screen</P># `3 Q/ F3 {, O# g, w
<P> if (!InitGL()) // Initialize our newly created GL window " i! d$ M% P! B" ~, ` { 0 g4 t( J- R+ c3 x. L. ~7 S4 | KillGLWindow(); // Reset the display8 k/ c% r# G% C! j
MessageBox(NULL,"Initialization failed.","ERROR",MB_OK|MB_ICONEXCLAMATION); % {$ h: v$ {( p" e return false; // Return false 1 d% h' E: z g. t" D8 A- h }</P>: Y8 }2 J/ p3 ^0 G* x) Z6 b
<P> return true; // Success - s; B1 [; a6 D. C9 |$ `}</P> ) u, J$ S, u# F% N! j6 ]: r& n<P>LRESULT CALLBACK WndProc(HWND hWnd, // Handle for this window - @" b7 O* u+ g/ H UINT uMsg, // Message for this window ( r8 `6 R" J1 W& T4 R WPARAM wParam, // Additional message information; ]' V* x" I3 E
LPARAM lParam) // Additional message information * q D3 d x) q# z; i% a{ 1 C/ w1 d1 p, o' H# W switch (uMsg) // Check for windows messages ( ~% h$ e" {+ x' f" @ { 4 a, J; @' Q6 m4 _/ M* C case WM_ACTIVATE: // Watch for window activate message 4 l! _! a; }# V4 t- |. Y { # d8 w, Y7 j5 O' Y$ a7 m# D0 _) r if (!HIWORD(wParam)) // Check minimization state + f0 N5 ^: t0 F8 l& S {2 |5 b0 E3 k; ]- N6 r
active = true; // Program is active * v0 B. @+ |- t4 z }) d7 K5 ~0 e0 S
else 6 p7 O/ i, J/ B {$ C: L9 w5 k/ r$ @3 z8 c+ w$ |
active = false; // Program is no longer active6 J9 e% m# e8 G( ^( [/ I
}</P> $ l, P! D$ w. V6 b<P> return 0; // Return to the message loop% [$ x+ O. j7 b
}</P> 1 u# e3 h% e2 C, O% T<P> case WM_SYSCOMMAND: // Intercept system commands / J4 i7 o! _0 h( g {: ^! U1 O. S+ Q( S1 K8 u/ C& W+ K
switch (wParam) // Check system calls! ^3 R- @5 N. w4 t
{ 3 _/ K, o- o7 n1 b+ ~9 T" _ case SC_SCREENSAVE: // Screensaver trying to start?0 y: b6 d% Q& m# e
case SC_MONITORPOWER: // Monitor trying to enter powersave?6 p2 f, \* x, j
return 0; // Prevent from happening # m% K! w6 M) v } # [8 \" ^& k" ^* d5 E3 r break; // Exit5 H: H z+ G" t' m
}</P>' p; D5 S/ k, ~3 b r
<P> case WM_CLOSE: // Did we receive a close message?1 x$ T. y& f5 _& D' O0 E. m% Y* c
{* ^% y4 G x& z3 [9 h
PostQuitMessage(0); // Send a quit message& p! A0 b8 V0 W# i. J
return 0; // Jump back - N+ Q+ A4 g& J6 i" M) K" |' u$ y }</P># d; r' F+ v! g- \, v
<P> case WM_KEYDOWN: // Is a key being held down?6 [6 T7 o+ B$ d9 b( Z
{ 1 ?- ]) i, ]% E2 P) f' m keys[wParam] = true; // If so, mark it as true 2 l0 R9 Z9 a. N& B# P. X: U return 0; // Jump back" z. J" P8 p8 j5 n
}</P>6 g w' l' c+ q; h* d; V
<P> case WM_KEYUP: // Has a key been released? $ @ y1 B- ]* ? {9 b/ s( }0 U l0 B6 O! z
keys[wParam] = false; // If so, mark it as false9 g3 Y* A: P' H5 m( L% f0 M$ q
return 0; // Jump back, |$ z% b w7 q; Y: k1 a0 a+ r* y ]
}</P>4 b' ? z& X+ O& O+ t! M8 l
<P> case WM_SIZE: // Resize the OpenGL window 6 G: [" t8 l6 q. t2 y7 e2 C {$ N" K$ f9 T. {3 ^
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord = Width, HiWord = Height 7 r4 P. p# e9 j6 \8 k return 0; // Jump back& h; a3 e, f) g h% H# w: j5 l
} 4 P& j# e8 I- O: |. a& W$ y) r }</P>% i) D" l/ I7 ?) _
<P> // Pass all unhandled messages to DefWindowProc5 U* y [+ a, R# Q- X6 m6 A' n
return DefWindowProc(hWnd,uMsg,wParam,lParam);" y2 B$ ^3 {: {4 G
}</P>, N7 I5 T, O" z4 H0 i Z7 e8 C% l
<P>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); W; N- j8 V7 ?- C6 B, c9 `
{ 8 |/ f1 K- T4 Z ~1 S8 Y: s* E MSG msg; // Windows message structure # L4 I/ d P1 D6 h6 [/ L* b bool done = false; // bool variable to exit loop</P>+ U" k7 ^( G, S8 n8 P7 S/ W
<P> // Ask the user which screen mode they prefer8 `/ t3 l( }* d
if (MessageBox(NULL,"Would you like to run in fullscreen mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION) == IDNO)& L# {0 i- z# O% o9 E
{ & V* g6 {- i7 F" v' L% w: T' n' R fullscreen = false; // Windowed mode 9 [" U5 I1 b4 I9 b+ A/ z) _: ` }</P> z; \! N5 _4 b3 `/ x; M
<P> // Create our OpenGL window0 z" _! d4 k& W) `! X
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)) # k7 c) ]* N E) _ { 6 y1 x: ]6 `3 @4 S( B9 A return 0; // Quit if window was not created7 G6 v- S) B& }. k% V5 o
}</P> / U% c$ J4 {9 L1 Z7 z( N<P> while(!done) // Loop that runs while done = false - B) K+ c( b; n) L3 x {' c3 N0 j+ V+ ^1 s& B
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is there a message waiting? , M! p% ] B$ d) E {: h3 d2 O) S: F- Q
if (msg.message == WM_QUIT) // Have we received a quit message?7 X+ w0 M0 Q8 t, g0 a& R3 Q5 q
{ . z. u3 D: N# c: I6 a' B done = true; // If so done = true t6 T/ Z0 u+ i9 r3 W4 V) j } # i3 H0 g- t, [5 b) b else // If not, deal with window messages; \* S( `* J0 n. x$ @+ \
{ ) _. E, q8 E( q TranslateMessage(&msg); // Translate the message - J! Q' L' w. N& _5 s5 y DispatchMessage(&msg); // Dispatch the message 2 }) I1 H$ p! {) b! M }' L# g' I% ]- F* c
}/ Z% F/ _* m( N& b# c8 `/ h
else // If there are no messages6 H$ Y! q i& {5 i
{/ M+ w9 P, m0 }
// Draw the scene. Watch for ESC key and quit messages from DrawGLScene()8 C" V& v% \8 c) |' Y8 G; S" X5 j4 l
if (active) // Program active?. P" |1 P+ u1 Z' Q$ w+ L! b/ E
{ 3 S% Z; s2 r l! ?+ I4 m if (keys[VK_ESCAPE]) // Was ESC pressed?! k2 F& f( }6 e! x' \, G: w+ t
{- j A: q V4 s/ M2 v$ r
done = true; // ESC signalled a quit+ @/ Q2 C/ O1 w L8 m9 X3 i
}3 g9 U0 d; I% m+ h9 @0 C
else // Not time to quit, Update screen- f1 j9 j$ X* s3 o; w* S) L; c
{5 G4 L- R4 o1 Z+ T( I& v
DrawGLScene(); // Draw the scene# e5 V* K! n. Q: ]2 s- k# b3 M
SwapBuffers(hDC); // Swap buffers (Double buffering)5 G( [3 M3 B: I/ G3 C5 [: t
}7 Y+ b+ O: x/ A* v! ?; M
}</P> ! A: r& ~5 v4 M8 ^, r: @<P> if (keys[VK_F1]) // Is F1 being pressed? 6 c- |: R6 ~$ H {! ]7 R: a0 o' b C& ]
keys[VK_F1] = false; // If so make key false" O" U- P; J- N' R M8 u
KillGLWindow(); // Kill our current window( Z8 r2 O- l" k: _3 }8 J* m
fullscreen =! fullscreen; // Toggle fullscreen / windowed mode7 A9 u9 h- }( w) \5 T( U" y
// Recreate our OpenGL window' E9 H7 ]" }* }
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)) 1 a5 J8 i, E% u4 c$ ` { . k! t! T" G! l6 i0 f( R1 w return 0; // Quit if window was not created! ~" H/ }! O) G H$ Z% x4 l. e
} 7 P# z+ ~# U# x. w }( c: Y G7 u7 ~* d; P, V8 {
}+ B! U, `! A) @2 e+ U
}</P> 6 I2 Y5 x6 \& ^5 r<P> // Shutdown ( T& m3 s/ k; J( W6 x8 f KillGLWindow(); // Kill the window. }% }5 C: O/ y0 d w
return (msg.wParam); // Exit the program ' Y" `, N$ V3 V+ w5 P. `6 ~}. H4 {( G- {' X" l% e
//---------------------------------------------------------------------------</P>