program lesson43; (* * This code was created by Jeff Molofee '99 * (ported to Linux/SDL by Ti Leggett '01) * * If you've found this code useful, please let me know. * * Visit Jeff at http://nehe.gamedev.net/ * * or for port-specific comments, questions, bugreports etc. * email to leggett@eecs.tulane.edu *) {$IFDEF FPC} {$mode delphi}{$H+} {$ENDIF} {$APPTYPE Console} uses moduleloader in '../../../JEDI-SDL/SDL/Pas/moduleloader.pas', SDL in '../../../JEDI-SDL/SDL/Pas/sdl.pas', gl in '../../../JEDI-SDL/OpenGL/Pas/gl.pas', glu in '../../../JEDI-SDL/OpenGL/Pas/glu.pas', ctypes in '../../../ctypes/ctypes.pas', FreeType in '../../freetype.pas', UFreeType in 'UFreeType.pas', math, sysutils; const // screen width, height, and bit depth SCREEN_WIDTH = 640; SCREEN_HEIGHT = 480; SCREEN_BPP = 16; var our_font: TFontData; // This is our SDL surface surface: PSDL_Surface; cnt1, cnt2: GLfloat; (* function to release/destroy our resources and restoring the old desktop *) procedure Quit(returnCode: integer); begin // clean up the window SDL_Quit( ); // and exit appropriately Halt( returnCode ); end; (* function to reset our viewport after a window resize *) function resizeWindow(width: integer; height: integer): boolean; var // Height / width ration ratio: GLfloat; begin // Protect against a divide by zero if ( height = 0 ) then height := 1; ratio := width / height; // Setup our viewport. glViewport( 0, 0, GLsizei(width), GLsizei(height) ); // change to the projection matrix and set our viewing volume. glMatrixMode( GL_PROJECTION ); glLoadIdentity( ); // Set our perspective gluPerspective( 45.0, ratio, 0.1, 100.0 ); // Make sure we're chaning the model view and not the projection glMatrixMode( GL_MODELVIEW ); // Reset The View glLoadIdentity( ); Result := true; end; (* function to handle key press events *) procedure handleKeyPress(keysym: PSDL_keysym); begin case ( keysym^.sym ) of SDLK_ESCAPE: begin // ESC key was pressed Quit( 0 ); end; SDLK_F1: begin // F1 key was pressed // this toggles fullscreen mode SDL_WM_ToggleFullScreen( surface ); end; end; end; (* general OpenGL initialization function *) function initGL(): boolean; begin // Enable smooth shading glShadeModel( GL_SMOOTH ); // Set the background black glClearColor( 0.0, 0.0, 0.0, 0.0 ); // Depth buffer setup glClearDepth( 1.0 ); // Enables Depth Testing glEnable( GL_DEPTH_TEST ); // The Type Of Depth Test To Do glDepthFunc( GL_LEQUAL ); // Really Nice Perspective Calculations glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); our_font := TFontData.Create('Test.ttf', 16); Result := true; end; (* Here goes our drawing code *) function drawGLScene(): boolean; begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer glLoadIdentity(); // Reset The Current Modelview Matrix glTranslatef(0.0, 0.0, -1.0); // Move One Unit Into The Screen // Blue Text glColor3ub(0, 0, $ff); // Position The WGL Text On The Screen glRasterPos2f(-0.40, 0.35); // Here We Print Some Text Using Our FreeType Font // The only really important command is the actual print() call, // but for the sake of making the results a bit more interesting // I have put in some code to rotate and scale the text. // Red text glColor3ub($ff, 0, 0); glPushMatrix(); glLoadIdentity(); glRotatef(cnt1, 0, 0,1); glScalef(1, 0.8 + 0.3*cos(cnt1/5) ,1); glTranslatef(-180, 0, 0); TFreeType.print(our_font, 320, 240, 'Active FreeType Text - ' + FloatToStr(cnt1)); glPopMatrix(); //Uncomment this to test out print's ability to handle newlines. //TFreeType.print(our_font, 320, 200, 'Here'#13'there'#13'be'#13#13'newlines'#13'.'); cnt1 := cnt1 + 0.051; // Increase The First Counter cnt2 := cnt2 + 0.005; // Increase The First Counter SDL_GL_SwapBuffers( ); Result := true; end; var // Flags to pass to SDL_SetVideoMode videoFlags: integer; // main loop variable done: boolean = false; // used to collect events event: TSDL_Event; // this holds some info about our display videoInfo: PSDL_VideoInfo; // whether or not the window is active isActive: boolean = true; begin // initialize SDL if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) then begin writeln( ErrOutput, 'Video initialization failed: ' + SDL_GetError() ); Quit( 1 ); end; // Fetch the video info videoInfo := SDL_GetVideoInfo( ); if ( videoInfo = nil ) then begin writeln( ErrOutput, 'Video query failed: ' + SDL_GetError() ); Quit( 1 ); end; SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // Enable double buffering // the flags to pass to SDL_SetVideoMode videoFlags := SDL_OPENGL; // Enable OpenGL in SDL videoFlags := videoFlags or SDL_HWPALETTE; // Store the palette in hardware videoFlags := videoFlags or SDL_RESIZABLE; // Enable window resizing // This checks to see if surfaces can be stored in memory if ( videoInfo^.hw_available <> 0 ) then videoFlags := videoFlags or SDL_HWSURFACE else videoFlags := videoFlags or SDL_SWSURFACE; // This checks if hardware blits can be done if ( videoInfo^.blit_hw <> 0 ) then videoFlags := videoFlags or SDL_HWACCEL; // Sets up OpenGL double buffering SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // get a SDL surface surface := SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, videoFlags ); // Verify there is a surface if ( surface = nil ) then begin writeln( ErrOutput, 'Video mode set failed: ' + SDL_GetError() ); Quit( 1 ); end; // initialize OpenGL initGL(); // resize the initial window resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT ); // wait for events while ( not done ) do begin { handle the events in the queue } while ( SDL_PollEvent( @event ) <> 0 ) do begin case( event.type_ ) of SDL_ACTIVEEVENT: begin // Something's happend with our focus // If we are iconified, we shouldn't draw the screen if ( (event.active.state and SDL_APPACTIVE) <> 0 ) then begin if ( event.active.gain = 0 ) then isActive := false else isActive := true; end; end; SDL_VIDEORESIZE: begin // handle resize event {$IFDEF UNIX} surface := SDL_SetVideoMode( event.resize.w, event.resize.h, 16, videoFlags ); if ( surface = nil ) then begin writeln( ErrOutput, 'Could not get a surface after resize: ' + SDL_GetError( ) ); Quit( 1 ); end; {$ENDIF} resizeWindow( event.resize.w, event.resize.h ); end; SDL_KEYDOWN: begin // handle key presses handleKeyPress( @event.key.keysym ); end; SDL_QUITEV: begin // handle quit requests done := true; end; end; end; // draw the scene if ( isActive ) then drawGLScene( ); end; // clean ourselves up and exit Quit( 0 ); end.