This shows how to print texturemapped outline fonts. Press the L key for lighting.
The BuildFont3D procedure is the same as in lesson 14. Here it is used to print the "Wingdings" symbol font.
You can get the "Lights.bmp" from the "lesson15.zip" here:
nehe.gamedev.net/data/lessons/vc/lesson15.zip
Last edited on 20 Feb 2007.
Code: Select all
;NeHe's Texturemapped Outline Font Tutorial (Lesson 15)
;http://nehe.gamedev.net
;Credits: Nico Gruener, Dreglor, traumatic
;Author: hagibaba
;Date: 10 Jan 2007
;Note: up-to-date with PB v4.02 (Windows)
;Note: requires a bitmap in path "Data/Lights.bmp"
;Section for standard constants, structures, macros and declarations
XIncludeFile #PB_Compiler_Home+"Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi" ;include the gl.h constants
;wingdi.h constants
#ANTIALIASED_QUALITY=4 ;for CreateFont_()
#WGL_FONT_POLYGONS=1 ;for wglUseFontOutlines_()
#DM_BITSPERPEL=$40000
#DM_PELSWIDTH=$80000
#DM_PELSHEIGHT=$100000
;winuser.h constants
#CDS_FULLSCREEN=4
#DISP_CHANGE_SUCCESSFUL=0
#SC_MONITORPOWER=$F170
Structure POINTFLOAT ;wingdi.h structure
x.f : y.f
EndStructure
Structure GLYPHMETRICSFLOAT ;wingdi.h structure
gmfBlackBoxX.f
gmfBlackBoxY.f
gmfptGlyphOrigin.POINTFLOAT
gmfCellIncX.f
gmfCellIncY.f
EndStructure
Structure AUX_RGBImageRec ;glaux.h structure
sizeX.l : sizeY.l
Data.l
EndStructure
Procedure.w LoWord(value.l) ;windef.h macro
ProcedureReturn (value & $FFFF)
EndProcedure
Procedure.w HiWord(value.l) ;windef.h macro
ProcedureReturn ((value >> 16) & $FFFF)
EndProcedure
;glaux.lib symbols
!public ___ftoll
!___ftoll dw 0
!public __imp__wsprintfA
!__imp__wsprintfA dw 0
Import "glaux.lib"
CompilerIf #PB_Compiler_Unicode
auxDIBImageLoad.l(filename.s) As "_auxDIBImageLoadW@4" ;loads a 24-bit Windows DIB
CompilerElse
auxDIBImageLoad.l(filename.s) As "_auxDIBImageLoadA@4" ;loads a 24-bit Windows DIB
CompilerEndIf
EndImport
Import "glu32.lib"
gluPerspective(fovy.d,aspect.d,zNear.d,zFar.d) ;sets up a perspective projection matrix
EndImport
Import "opengl32.lib"
glClearDepth(depth.d) ;specifies the clear value for the depth buffer
EndImport
;Start of Lesson 15
Global hDC.l ;Private GDI Device Context
Global hRC.l ;Permanent Rendering Context
Global hWnd.l ;Holds Our Window Handle
Global hInstance.l ;Holds The Instance Of The Application
Global Dim keys.b(256) ;Array Used For The Keyboard Routine
Global active.b=#True ;Window Active Flag Set To TRUE By Default
Global fullscreen.b=#True ;Fullscreen Flag Set To Fullscreen Mode By Default
Global Dim texture.l(1) ;One Texture Map
Global base.l ;Base Display List For The Font Set
Global rot.f ;Used To Rotate The Text
Global Dim gmf.GLYPHMETRICSFLOAT(256) ;Buffer For Font Storage
Global light.b=#True ;Lighting ON/OFF
Global lp.b ;L Pressed? Note: added L key code to toggle lighting
Declare.l WndProc(hWnd.l,uMsg.l,wParam.l,lParam.l) ;Declaration For WndProc
Procedure BuildFont(name.s,bold.l,italic.b,symbol.l,depth.f,blocky.f) ;Build Our Outline Font
Protected font.l ;Windows Font ID
Protected oldfont.l ;Used For Good House Keeping
If bold : bold=#FW_BOLD : Else : bold=#FW_NORMAL : EndIf ;font weight
If symbol : symbol=#SYMBOL_CHARSET : Else : symbol=#ANSI_CHARSET : EndIf ;character set
If blocky : blocky=0.1 : Else : blocky=0.0 : EndIf ;blocky font shape
base=glGenLists_(256) ;Storage For 256 Characters
;CreateFont_(Height, Width, Angle Of Escapement, Orientation Angle, Weight, Italic, Underline, Strikeout, Character Set, Output Precision, Clipping Precision, Output Quality, Family And Pitch, Name)
font=CreateFont_(0,0,0,0,bold,italic,#False,#False,symbol,#OUT_TT_PRECIS,#CLIP_DEFAULT_PRECIS,#ANTIALIASED_QUALITY,#FF_DONTCARE | #DEFAULT_PITCH,name)
oldfont=SelectObject_(hDC,font) ;Selects The Font We Created
;wglUseFontOutlines_(DC, Starting Character, Number Of Display Lists, Starting Display List, Deviation From True Outlines, Font Thickness, Use Polygons, Buffer To Receive Data)
wglUseFontOutlines_(hDC,0,255,base,blocky,depth,#WGL_FONT_POLYGONS,gmf(0))
SelectObject_(hDC,oldfont) ;reselect the old font again
DeleteObject_(font) ;Delete The Font
EndProcedure
Procedure KillFont() ;Delete The Font List
glDeleteLists_(base,256) ;Delete All 256 Characters
EndProcedure
Procedure glPrint(text.s) ;Custom GL "Print" Routine
If text="" ;If There's No Text
ProcedureReturn #False ;Do Nothing
EndIf
glPushAttrib_(#GL_LIST_BIT) ;Pushes The Display List Bits
glListBase_(base) ;Sets The Base Character to 0
glCallLists_(Len(text),#GL_UNSIGNED_BYTE,text) ;Draws The Display List Text
glPopAttrib_() ;Pops The Display List Bits
EndProcedure
Procedure.l LoadBMP(Filename.s) ;Loads A Bitmap Image
Protected File.l=#Null ;File Handle
If Filename="" ;Make Sure A Filename Was Given
ProcedureReturn #Null ;If Not Return NULL
EndIf
File=ReadFile(#PB_Any,Filename) ;Check To See If The File Exists
If File ;Does The File Exist?
CloseFile(File) ;Close The Handle
ProcedureReturn auxDIBImageLoad(Filename) ;Load The Bitmap And Return A Pointer
EndIf
ProcedureReturn #Null ;If Load Failed Return NULL
EndProcedure
Procedure.l LoadGLTextures() ;Load Bitmaps And Convert To Textures
Protected Status.l=#False ;Status Indicator
Protected Dim *TextureImage.AUX_RGBImageRec(1) ;Create Storage Space For The Texture
;Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
*TextureImage(0)=LoadBMP("Data/Lights.bmp")
If *TextureImage(0)
Status=#True ;Set The Status To TRUE
glGenTextures_(1,@texture(0)) ;Create The Texture
glBindTexture_(#GL_TEXTURE_2D,texture(0))
glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_MAG_FILTER,#GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_MIN_FILTER,#GL_LINEAR_MIPMAP_NEAREST)
gluBuild2DMipmaps_(#GL_TEXTURE_2D,3,*TextureImage(0)\sizeX,*TextureImage(0)\sizeY,#GL_RGB,#GL_UNSIGNED_BYTE,*TextureImage(0)\Data)
;Note: GL_OBJECT_LINEAR did not work on my PC, GL_EYE_LINEAR/GL_SPHERE_MAP did
glTexGeni_(#GL_S,#GL_TEXTURE_GEN_MODE,#GL_EYE_LINEAR) ;X Texturing Contour Anchored To The Object
glTexGeni_(#GL_T,#GL_TEXTURE_GEN_MODE,#GL_EYE_LINEAR) ;Y Texturing Contour Anchored To The Object
glEnable_(#GL_TEXTURE_GEN_S) ;Auto Texture Generation
glEnable_(#GL_TEXTURE_GEN_T) ;Auto Texture Generation
EndIf
If *TextureImage(0) ;If Texture Exists
If *TextureImage(0)\Data ;If Texture Image Exists
;FreeMemory(*TextureImage(0)\Data) ;Free The Texture Image Memory
EndIf
;FreeMemory(*TextureImage(0)) ;Free The Image Structure
EndIf
ProcedureReturn Status ;Return The Status
EndProcedure
Procedure ReSizeGLScene(width.l,height.l) ;Resize And Initialize The GL Window
If height=0 : height=1 : EndIf ;Prevent A Divide By Zero Error
glViewport_(0,0,width,height) ;Reset The Current Viewport
glMatrixMode_(#GL_PROJECTION) ;Select The Projection Matrix
glLoadIdentity_() ;Reset The Projection Matrix
gluPerspective(45.0,Abs(width/height),0.1,100.0) ;Calculate The Aspect Ratio Of The Window
glMatrixMode_(#GL_MODELVIEW) ;Select The Modelview Matrix
glLoadIdentity_() ;Reset The Modelview Matrix
EndProcedure
Procedure.l InitGL() ;All Setup For OpenGL Goes Here
If LoadGLTextures()=0 ;Jump To Texture Loading Routine
ProcedureReturn #False ;If Texture Didn't Load Return FALSE
EndIf
;BuildFont(name,bold,italic,symbol,depth,blocky)
BuildFont("Wingdings",1,0,1,0.2,1) ;Build The Outline Font
glShadeModel_(#GL_SMOOTH) ;Enable Smooth Shading
glClearColor_(0.0,0.0,0.0,0.5) ;Black Background
glClearDepth(1.0) ;Depth Buffer Setup
glEnable_(#GL_DEPTH_TEST) ;Enables Depth Testing
glDepthFunc_(#GL_LEQUAL) ;The Type Of Depth Testing To Do
glHint_(#GL_PERSPECTIVE_CORRECTION_HINT,#GL_NICEST) ;Really Nice Perspective Calculations
glEnable_(#GL_LIGHT0) ;Quick And Dirty Lighting (Assumes Light0 Is Set Up)
glEnable_(#GL_LIGHTING) ;Enable Lighting
glEnable_(#GL_TEXTURE_2D) ;Enable Texture Mapping
glBindTexture_(#GL_TEXTURE_2D,texture(0)) ;Select The Texture
ProcedureReturn #True ;Initialization Went OK
EndProcedure
Procedure.l DrawGLScene() ;Here's Where We Do All The Drawing
glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT) ;Clear Screen And Depth Buffer
glLoadIdentity_() ;Reset The View
glTranslatef_(1.1*Cos(rot/16.0),0.8*Sin(rot/20.0),-3.0)
glRotatef_(rot,1.0,0.0,0.0) ;Rotate On The X Axis
glRotatef_(rot*1.2,0.0,1.0,0.0) ;Rotate On The Y Axis
glRotatef_(rot*1.4,0.0,0.0,1.0) ;Rotate On The Z Axis
glTranslatef_(-0.35,-0.35,0.1) ;Center On X, Y, Z Axis
glPrint("N") ;Draw A Skull And Crossbones Symbol
rot+0.05 ;Increase The Rotation Variable
ProcedureReturn #True ;Keep Going
EndProcedure
Procedure KillGLWindow() ;Properly Kill The Window
If fullscreen ;Are We In Fullscreen Mode?
ChangeDisplaySettings_(#Null,0) ;If So Switch Back To The Desktop
ShowCursor_(#True) ;Show Mouse Pointer
EndIf
If hRC ;Do We Have A Rendering Context?
If wglMakeCurrent_(#Null,#Null)=0 ;Are We Able To Release The DC And RC Contexts?
MessageBox_(#Null,"Release Of DC And RC Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
EndIf
If wglDeleteContext_(hRC)=0 ;Are We Able To Delete The RC?
MessageBox_(#Null,"Release Rendering Context Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
EndIf
hRC=#Null ;Set RC To NULL
EndIf
If hDC And ReleaseDC_(hWnd,hDC)=0 ;Are We Able To Release The DC
MessageBox_(#Null,"Release Device Context Failed.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
hDC=#Null ;Set DC To NULL
EndIf
If hWnd And DestroyWindow_(hWnd)=0 ;Are We Able To Destroy The Window?
MessageBox_(#Null,"Could Not Release hWnd.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
hWnd=#Null ;Set hWnd To NULL
EndIf
If UnregisterClass_("OpenGL",hInstance)=0 ;Are We Able To Unregister Class
MessageBox_(#Null,"Could Not Unregister Class.","SHUTDOWN ERROR",#MB_OK | #MB_ICONINFORMATION)
hInstance=#Null ;Set hInstance To NULL
EndIf
KillFont() ;Destroy The Outline Font
EndProcedure
;This Code Creates Our OpenGL Window. Parameters Are:
;title - Title To Appear At The Top Of The Window
;width - Width Of The GL Window Or Fullscreen Mode
;height - Height Of The GL Window Or Fullscreen Mode
;bits - Number Of Bits To Use For Color (8/16/24/32)
;fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)
Procedure.b CreateGLWindow(title.s,width.l,height.l,bits.l,fullscreenflag.b)
Protected PixelFormat.l ;Holds The Results After Searching For A Match
Protected wc.WNDCLASS ;Windows Class Structure
Protected dwExStyle.l ;Window Extended Style
Protected dwStyle.l ;Window Style
Protected WindowRect.RECT ;Grabs Rectangle Upper Left / Lower Right Values
Protected wpos.POINT ;Window position
WindowRect\left=0 ;Set Left Value To 0
WindowRect\right=width ;Set Right Value To Requested Width
WindowRect\top=0 ;Set Top Value To 0
WindowRect\bottom=height ;Set Bottom Value To Requested Height
fullscreen=fullscreenflag ;Set The Global Fullscreen Flag
hInstance=GetModuleHandle_(#Null) ;Grab An Instance For Our Window
wc\style=#CS_HREDRAW | #CS_VREDRAW | #CS_OWNDC ;Redraw On Size, And Own DC For Window
wc\lpfnWndProc=@WndProc() ;WndProc Handles Messages
wc\cbClsExtra=0 ;No Extra Window Data
wc\cbWndExtra=0 ;No Extra Window Data
wc\hInstance=hInstance ;Set The Instance
wc\hIcon=LoadIcon_(#Null,#IDI_WINLOGO) ;Load The Default Icon
wc\hCursor=LoadCursor_(#Null,#IDC_ARROW) ;Load The Arrow Pointer
wc\hbrBackground=#Null ;No Background Required For GL
wc\lpszMenuName=#Null ;We Don't Want A Menu
wc\lpszClassName=@"OpenGL" ;Set The Class Name
If RegisterClass_(wc)=0 ;Attempt To Register The Window Class
MessageBox_(#Null,"Failed To Register The Window Class.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
If fullscreen ;Attempt Fullscreen Mode?
Protected dmScreenSettings.DEVMODE ;Device Mode
dmScreenSettings\dmSize=SizeOf(DEVMODE) ;Size Of The Devmode Structure
dmScreenSettings\dmFields=#DM_BITSPERPEL | #DM_PELSWIDTH | #DM_PELSHEIGHT ;bit flags to specify the members of DEVMODE that were initialized
dmScreenSettings\dmBitsPerPel=bits ;Selected Bits Per Pixel
dmScreenSettings\dmPelsWidth=width ;Selected Screen Width in pixels
dmScreenSettings\dmPelsHeight=height ;Selected Screen Height in pixels
;Try To Set Selected Mode And Get Results. Note: CDS_FULLSCREEN Gets Rid Of Start Bar
If ChangeDisplaySettings_(dmScreenSettings,#CDS_FULLSCREEN)<>#DISP_CHANGE_SUCCESSFUL
;If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode
If MessageBox_(#Null,"The Requested Fullscreen Mode Is Not Supported By"+Chr(10)+"Your Video Card. Use Windowed Mode Instead?","NeHe GL",#MB_YESNO | #MB_ICONEXCLAMATION)=#IDYES
fullscreen=#False ;Windowed Mode Selected. Fullscreen = FALSE
Else
;Pop Up A Message Box Letting User Know The Program Is Closing
MessageBox_(#Null,"Program Will Now Close.","ERROR",#MB_OK | #MB_ICONSTOP)
ProcedureReturn #False
EndIf
EndIf
EndIf
If fullscreen ;Are We Still In Fullscreen Mode?
dwExStyle=#WS_EX_APPWINDOW ;Window Extended Style
dwStyle=#WS_POPUP ;Windows Style
ShowCursor_(#False) ;Hide Mouse Pointer
Else
dwExStyle=#WS_EX_APPWINDOW | #WS_EX_WINDOWEDGE ;Window Extended Style
dwStyle=#WS_OVERLAPPEDWINDOW ;Windows Style
EndIf
AdjustWindowRectEx_(WindowRect,dwStyle,#False,dwExStyle) ;Adjust Window To True Requested Size
If fullscreen=0 ;if not fullscreen mode calculate screen centered window
wpos\x=(GetSystemMetrics_(#SM_CXSCREEN)/2)-((WindowRect\right-WindowRect\left)/2)
wpos\y=(GetSystemMetrics_(#SM_CYSCREEN)/2)-((WindowRect\bottom-WindowRect\top)/2)
EndIf
;CreateWindowEx_(Extended Window Style, Class Name, Window Title, Window Style, Window X Position, Window Y Position, Width, Height, No Parent Window, No Menu, Instance, No Creation Data)
hWnd=CreateWindowEx_(dwExStyle,"OpenGL",title,dwStyle | #WS_CLIPSIBLINGS | #WS_CLIPCHILDREN,wpos\x,wpos\y,WindowRect\right-WindowRect\left,WindowRect\bottom-WindowRect\top,#Null,#Null,hInstance,#Null)
If hWnd=0
KillGLWindow() ;Reset The Display
MessageBox_(#Null,"Window Creation Error.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
Protected pfd.PIXELFORMATDESCRIPTOR ;pfd Tells Windows How We Want Things To Be
pfd\nSize=SizeOf(PIXELFORMATDESCRIPTOR) ;Size Of This Structure
pfd\nVersion=1 ;Version Number
pfd\dwFlags=#PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW ;Format Must Support Window, OpenGL, Double Buffering
pfd\iPixelType=#PFD_TYPE_RGBA ;Request An RGBA Format
pfd\cColorBits=bits ;Select Our Color Depth
pfd\cRedBits=0 ;Color Bits Ignored
pfd\cRedShift=0
pfd\cGreenBits=0
pfd\cGreenShift=0
pfd\cBlueBits=0
pfd\cBlueShift=0
pfd\cAlphaBits=0 ;No Alpha Buffer
pfd\cAlphaShift=0 ;Shift Bit Ignored
pfd\cAccumBits=0 ;No Accumulation Buffer
pfd\cAccumRedBits=0 ;Accumulation Bits Ignored
pfd\cAccumGreenBits=0
pfd\cAccumBlueBits=0
pfd\cAccumAlphaBits=0
pfd\cDepthBits=16 ;16Bit Z-Buffer (Depth Buffer)
pfd\cStencilBits=0 ;No Stencil Buffer
pfd\cAuxBuffers=0 ;No Auxiliary Buffer
pfd\iLayerType=#PFD_MAIN_PLANE ;Main Drawing Layer
pfd\bReserved=0 ;Reserved
pfd\dwLayerMask=0 ;Layer Masks Ignored
pfd\dwVisibleMask=0
pfd\dwDamageMask=0
hDC=GetDC_(hWnd)
If hDC=0 ;Did We Get A Device Context?
KillGLWindow() ;Reset The Display
MessageBox_(#Null,"Can't Create A GL Device Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
PixelFormat=ChoosePixelFormat_(hDC,pfd)
If PixelFormat=0 ;Did Windows Find A Matching Pixel Format?
KillGLWindow() ;Reset The Display
MessageBox_(#Null,"Can't Find A Suitable PixelFormat.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
If SetPixelFormat_(hDC,PixelFormat,pfd)=0 ;Are We Able To Set The Pixel Format?
KillGLWindow() ;Reset The Display
MessageBox_(#Null,"Can't Set The PixelFormat.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
hRC=wglCreateContext_(hDC)
If hRC=0 ;Are We Able To Get A Rendering Context?
KillGLWindow() ;Reset The Display
MessageBox_(#Null,"Can't Create A GL Rendering Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
If wglMakeCurrent_(hDC,hRC)=0 ;Try To Activate The Rendering Context
KillGLWindow() ;Reset The Display
MessageBox_(#Null,"Can't Activate The GL Rendering Context.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
ShowWindow_(hWnd,#SW_SHOW) ;Show The Window
SetForegroundWindow_(hWnd) ;Slightly Higher Priority
SetFocus_(hWnd) ;Sets Keyboard Focus To The Window
ReSizeGLScene(width,height) ;Set Up Our Perspective GL Screen
If InitGL()=0 ;Initialize Our Newly Created GL Window
KillGLWindow() ;Reset The Display
MessageBox_(#Null,"Initialization Failed.","ERROR",#MB_OK | #MB_ICONEXCLAMATION)
ProcedureReturn #False
EndIf
ProcedureReturn #True ;Success
EndProcedure
Procedure.l WndProc(hWnd.l,uMsg.l,wParam.l,lParam.l)
Select uMsg ;Check For Windows Messages
Case #WM_ACTIVATE ;Watch For Window Activate Message
If HiWord(wParam)=0 ;Check Minimization State
active=#True ;Program Is Active
Else
active=#False ;Program Is No Longer Active
EndIf
ProcedureReturn 0 ;Return To The Message Loop
Case #WM_SYSCOMMAND ;Intercept System Commands
Select wParam ;Check System Calls
Case #SC_SCREENSAVE ;Screensaver Trying To Start?
ProcedureReturn 0 ;Prevent From Happening
Case #SC_MONITORPOWER ;Monitor Trying To Enter Powersave?
ProcedureReturn 0 ;Prevent From Happening
EndSelect
Case #WM_CLOSE ;Did We Receive A Close Message?
PostQuitMessage_(0) ;Send A Quit Message
ProcedureReturn 0 ;Jump Back
Case #WM_KEYDOWN ;Is A Key Being Held Down?
keys(wParam)=#True ;If So, Mark It As TRUE
ProcedureReturn 0 ;Jump Back
Case #WM_KEYUP ;Has A Key Been Released?
keys(wParam)=#False ;If So, Mark It As FALSE
ProcedureReturn 0 ;Jump Back
Case #WM_SIZE ;Resize The OpenGL Window
ReSizeGLScene(LoWord(lParam),HiWord(lParam)) ;LoWord=Width, HiWord=Height
ProcedureReturn 0 ;Jump Back
EndSelect
;Pass All Unhandled Messages To DefWindowProc
ProcedureReturn DefWindowProc_(hWnd,uMsg,wParam,lParam)
EndProcedure
Procedure.l WinMain() ;Main Program
Protected msg.MSG ;Windows Message Structure
Protected done.b ;Bool Variable To Exit Loop
;Ask The User Which Screen Mode They Prefer
If MessageBox_(#Null,"Would You Like To Run In Fullscreen Mode?","Start FullScreen?",#MB_YESNO | #MB_ICONQUESTION)=#IDNO
fullscreen=#False ;Windowed Mode
EndIf
If CreateGLWindow("NeHe's Texturemapped Outline Font Tutorial",640,480,16,fullscreen)=0 ;Create The Window
ProcedureReturn 0 ;Quit If Window Was Not Created
EndIf
While done=#False ;Loop That Runs While done=FALSE
If PeekMessage_(msg,#Null,0,0,#PM_REMOVE) ;Is There A Message Waiting?
If msg\message=#WM_QUIT ;Have We Received A Quit Message?
done=#True ;If So done=TRUE
Else ;If Not, Deal With Window Messages
TranslateMessage_(msg) ;Translate The Message
DispatchMessage_(msg) ;Dispatch The Message
EndIf
Else ;If There Are No Messages
;Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
If (active And DrawGLScene()=0) Or keys(#VK_ESCAPE) ;Active? Was There A Quit Received?
done=#True ;ESC or DrawGLScene Signalled A Quit
Else ;Not Time To Quit, Update Screen
Delay(1)
SwapBuffers_(hDC) ;Swap Buffers (Double Buffering)
If keys(#VK_L) And lp=0 ;L Key Being Pressed Not Held?
lp=#True ;lp Becomes TRUE
light=~light & 1 ;Toggle Light TRUE/FALSE
If light=0 ;If Not Light
glDisable_(#GL_LIGHTING) ;Disable Lighting
Else ;Otherwise
glEnable_(#GL_LIGHTING) ;Enable Lighting
EndIf
EndIf
If keys(#VK_L)=0 ;Has L Key Been Released?
lp=#False ;If So, lp Becomes FALSE
EndIf
EndIf
If keys(#VK_F1) ;Is F1 Being Pressed?
keys(#VK_F1)=#False ;If So Make Key FALSE
KillGLWindow() ;Kill Our Current Window
fullscreen=~fullscreen & 1 ;Toggle Fullscreen / Windowed Mode
;Recreate Our OpenGL Window
If CreateGLWindow("NeHe's Texturemapped Outline Font Tutorial",640,480,16,fullscreen)=0
ProcedureReturn 0 ;Quit If Window Was Not Created
EndIf
EndIf
EndIf
Wend
;Shutdown
KillGLWindow() ;Kill The Window
End ;Exit The Program
EndProcedure
WinMain() ;run the main program