From b38772ffdbcc6bf2189d0e14a9828f911ea44a7d Mon Sep 17 00:00:00 2001 From: tobigun Date: Sat, 21 Mar 2009 19:25:18 +0000 Subject: new branch for whiteshark's service and hook based (party) plugins git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@1643 b956fd51-792f-4845-bead-9b4dfca2ff2c --- .../src/lib/freetype/demo/engine-test.bdsproj | 175 +++++++++++ .../src/lib/freetype/demo/engine-test.dpr | 336 +++++++++++++++++++++ .../src/lib/freetype/demo/engine-test.lpi | 173 +++++++++++ .../src/lib/freetype/demo/nehe/UFreeType.pas | 326 ++++++++++++++++++++ .../src/lib/freetype/demo/nehe/lesson43.bdsproj | 175 +++++++++++ .../src/lib/freetype/demo/nehe/lesson43.dpr | 289 ++++++++++++++++++ .../src/lib/freetype/demo/nehe/readme.txt | 9 + .../src/lib/freetype/demo/switches.inc | 1 + 8 files changed, 1484 insertions(+) create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/engine-test.bdsproj create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/engine-test.dpr create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/engine-test.lpi create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/nehe/UFreeType.pas create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.bdsproj create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.dpr create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/nehe/readme.txt create mode 100644 ServiceBasedPlugins/src/lib/freetype/demo/switches.inc (limited to 'ServiceBasedPlugins/src/lib/freetype/demo') diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.bdsproj b/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.bdsproj new file mode 100644 index 00000000..9547f18f --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.bdsproj @@ -0,0 +1,175 @@ + + + + + + + + + + + + engine-test.dpr + + + 7.0 + + + 8 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + True + True + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; + + False + + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + False + False + False + True + True + True + True + True + True + + + + 0 + 0 + False + 1 + False + False + False + 16384 + 1048576 + 4194304 + + + + + + + + ..\..\JEDI-SDL\SDL\Pas + vclx;vcl;rtl;vclactnband + + + False + + + + + + False + + + True + False + + + + $00000000 + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1031 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.dpr b/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.dpr new file mode 100644 index 00000000..80177735 --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.dpr @@ -0,0 +1,336 @@ +program engine_test; +(* + * 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', + glext in '../../JEDI-SDL/OpenGL/Pas/glext.pas', + glu in '../../JEDI-SDL/OpenGL/Pas/glu.pas', + {$IFNDEF FPC} + ctypes in '../../ctypes/ctypes.pas', + {$ENDIF} + FreeType in '../freetype.pas', + UFont in '../../../base/UFont.pas', + math, + sysutils; + +const + // screen width, height, and bit depth + SCREEN_WIDTH = 640; + SCREEN_HEIGHT = 480; + SCREEN_BPP = 16; + + //FONT_FILE = 'Test.ttf'; + //FONT_FILE = 'C:/Windows/Fonts/Arial.ttf'; + //FONT_FILE = 'C:/Windows/Fonts/SimSun.ttf'; + //FONT_FILE = 'eurostarregularextended.ttf'; + FONT_FILE = 'FreeSans.ttf'; + +var + OurFont: TScalableFont; + // 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 + OurFont.Free; + + // 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; +begin + // Protect against a divide by zero + if ( height = 0 ) then + height := 1; + + // 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 + //gluOrtho2D(0, width, 0, height); + gluOrtho2D(0, 800, 0, 600); + + // 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( 1, 1, 1.0, 1.0 ); + //glClearColor( 0.3, 0.7, 1.0, 1.0 ); + glClearColor( 0.0, 0.0, 0.0, 1.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 ); + + //OurFont := TFTScalableFont.Create(FONT_FILE, 64); + //OurFont := TFTFont.Create(FONT_FILE, 128); + OurFont := TFTScalableOutlineFont.Create(FONT_FILE, 64, 0.05); + //OurFont.UseKerning := false; + TFTScalableOutlineFont(OurFont).SetOutlineColor(1, 0, 0); + //OurFont := TOutlineFont.Create(FONT_FILE, 32, 2); + //OurFont.LineSpacing := OurFont.LineSpacing * 0.5; + + Result := true; +end; + +var + NextTime: cardinal; + Counter: integer; + +type + TVector4d = array[0..3] of GLdouble; + +function NewVector4d(a, b, c, d: GLdouble): TVector4d; +begin + Result[0] := a; + Result[1] := b; + Result[2] := c; + Result[3] := d; +end; + +(* Here goes our drawing code *) +function drawGLScene(): boolean; +var + msg: WideString; + bounds: TBoundsDbl; +begin + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer + + //msg := 'Here'#13'there'#13'be'#13#13'newlines'#13'.'; + //msg := 'Here'#13'newlines'; + msg := 'Active FreeType Text - ' + FloatToStr(cnt1); + //msg := 'Hören'#13'其自诞生至今'#13'спецификация'; + + // Red text + glLoadIdentity(); + glTranslatef(cnt2, 240, 0); + if (cnt2 > 800) then + cnt2 := 0; + glTranslatef(30, 40, 0); + //glTranslatef(320, 240, 0); + //glRotatef(cnt1, 0, 0, 1); + //glScalef(1, 0.8 + 0.3*cos(cnt1/5), 1); + + OurFont.Style := [Italic, {Underline,} Reflect]; + //OurFont.GlyphSpacing := 10; + //OurFont.SetOutlineColor(0.5, 0.5, 0.5); + //OurFont.ReflectionSpacing := -4; + //OurFont.UseKerning := false; + OurFont.Height := 64;//cnt2; + //OurFont.Reset; + //OurFont.Aspect := 2; + + glColor3f(1, 1, 0); + bounds := OurFont.BBox(msg); + //glRectf(bounds.Left, OurFont.Ascender, bounds.Right, OurFont.Ascender-OurFont.Height); + + glColor3f(1, 1, 1); + //OurFont.ReflectionSpacing := 0; + OurFont.Print(msg); + + cnt1 := cnt1 + 0.051; // Increase The First Counter + cnt2 := cnt2 + 0.005; // Increase The First Counter + + SDL_GL_SwapBuffers( ); + + Inc(Counter); + + if (NextTime < SDL_GetTicks()) then + begin + NextTime := SDL_GetTicks() + 2000; + writeln('FPS: ' + floattostr(Counter / 2.0)); + Counter := 0; + end; + + 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 or SDL_INIT_TIMER ) < 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. diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.lpi b/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.lpi new file mode 100644 index 00000000..6cbfe1eb --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/engine-test.lpi @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/nehe/UFreeType.pas b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/UFreeType.pas new file mode 100644 index 00000000..c1243aae --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/UFreeType.pas @@ -0,0 +1,326 @@ +unit UFreeType; + +{$IFDEF FPC} + {$mode delphi}{$H+} +{$ENDIF} + +interface + +uses + FreeType, + gl, + glu, + classes, + sysutils; + +type + // This holds all of the information related to any + // freetype font that we want to create. + TFontData = class + h: single; ///< Holds the height of the font. + textures: array of GLuint; ///< Holds the texture id's + list_base: GLuint; ///< Holds the first display list id + + // The init function will create a font of + // of the height h from the file fname. + constructor Create(const fname: string; h: cardinal); + + // Free all the resources assosiated with the font. + destructor Destroy(); override; + end; + + TFreeType = class + public + // The flagship function of the library - this thing will print + // out text at window coordinates x,y, using the font ft_font. + // The current modelview matrix will also be applied to the text. + class procedure print(ft_font: TFontData; x, y: single; const str: string); + end; + + +implementation + + +// This function gets the first power of 2 >= the +// int that we pass it. +function next_p2 ( a: integer ): integer; inline; +begin + Result := 1; + while (Result < a) do + Result := Result shl 1; +end; + +type + PAGLuint = ^AGLuint; + AGLuint = array[0..High(Word)] of GLuint; + +// Create a display list coresponding to the given character. +procedure make_dlist ( face: FT_Face; ch: byte; list_base: GLuint; tex_base: PAGLuint ); +var + i, j: integer; + width, height: integer; + glyph: FT_Glyph; + bitmap_glyph: FT_BitmapGlyph; + bitmap: PFT_Bitmap; + expanded_data: array of GLubyte; + x, y: single; +begin + // The first thing we do is get FreeType to render our character + // into a bitmap. This actually requires a couple of FreeType commands: + + // Load the Glyph for our character. + if (FT_Load_Glyph( face, FT_Get_Char_Index( face, ch ), FT_LOAD_DEFAULT ) <> 0) then + raise Exception.create('FT_Load_Glyph failed'); + + // Move the face's glyph into a Glyph object. + if (FT_Get_Glyph( face^.glyph, glyph ) <> 0) then + raise Exception.create('FT_Get_Glyph failed'); + + // Convert the glyph to a bitmap. + FT_Glyph_To_Bitmap( glyph, ft_render_mode_normal, nil, 1 ); + bitmap_glyph := FT_BitmapGlyph(glyph); + + // This reference will make accessing the bitmap easier + bitmap := @bitmap_glyph^.bitmap; + + // Use our helper function to get the widths of + // the bitmap data that we will need in order to create + // our texture. + width := next_p2( bitmap.width ); + height := next_p2( bitmap.rows ); + + // Allocate memory for the texture data. + SetLength(expanded_data, 2 * width * height); + + // Here we fill in the data for the expanded bitmap. + // Notice that we are using two channel bitmap (one for + // luminocity and one for alpha), but we assign + // both luminocity and alpha to the value that we + // find in the FreeType bitmap. + // We use the ?: operator so that value which we use + // will be 0 if we are in the padding zone, and whatever + // is the the Freetype bitmap otherwise. + for j := 0 to height-1 do + begin + for i := 0 to width-1 do + begin + if ((i >= bitmap.width) or (j >= bitmap.rows)) then + expanded_data[2*(i+j*width)] := 0 + else + expanded_data[2*(i+j*width)] := byte(bitmap.buffer[i + bitmap.width*j]); + expanded_data[2*(i+j*width)+1] := expanded_data[2*(i+j*width)]; + end; + end; + + + // Now we just setup some texture paramaters. + glBindTexture( GL_TEXTURE_2D, tex_base[integer(ch)]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + + // Here we actually create the texture itself, notice + // that we are using GL_LUMINANCE_ALPHA to indicate that + // we are using 2 channel data. + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, + 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @expanded_data[0] ); + + //With the texture created, we don't need to expanded data anymore + SetLength(expanded_data, 0); + + //So now we can create the display list + glNewList(list_base+ch, GL_COMPILE); + + glBindTexture(GL_TEXTURE_2D, tex_base[ch]); + + glPushMatrix(); + + //first we need to move over a little so that + //the character has the right amount of space + //between it and the one before it. + glTranslatef(bitmap_glyph^.left, 0, 0); + + //Now we move down a little in the case that the + //bitmap extends past the bottom of the line + //(this is only true for characters like 'g' or 'y'. + glTranslatef(0, bitmap_glyph^.top - bitmap.rows, 0); + + //Now we need to account for the fact that many of + //our textures are filled with empty padding space. + //We figure what portion of the texture is used by + //the actual character and store that information in + //the x and y variables, then when we draw the + //quad, we will only reference the parts of the texture + //that we contain the character itself. + x := bitmap.width / width; + y := bitmap.rows / height; + + //Here we draw the texturemaped quads. + //The bitmap that we got from FreeType was not + //oriented quite like we would like it to be, + //so we need to link the texture to the quad + //so that the result will be properly aligned. + glBegin(GL_QUADS); + glTexCoord2d(0, 0); glVertex2f(0, bitmap.rows); + glTexCoord2d(0, y); glVertex2f(0, 0); + glTexCoord2d(x, y); glVertex2f(bitmap.width, 0); + glTexCoord2d(x, 0); glVertex2f(bitmap.width, bitmap.rows); + glEnd(); + + glPopMatrix(); + glTranslatef(face^.glyph^.advance.x shr 6, 0, 0); + + //increment the raster position as if we were a bitmap font. + //(only needed if you want to calculate text length) + //glBitmap(0,0,0,0,face->glyph->advance.x >> 6,0,NULL); + + //Finnish the display list + glEndList(); +end; + + +constructor TFontData.Create(const fname: string; h: cardinal); +var + library_: FT_Library; + //The object in which Freetype holds information on a given + //font is called a "face". + face: FT_Face; + i: byte; +begin + //Allocate some memory to store the texture ids. + SetLength(textures, 128); + + Self.h := h; + + //Create and initilize a freetype font library. + if (FT_Init_FreeType( library_ ) <> 0) then + raise Exception.create('FT_Init_FreeType failed'); + + //This is where we load in the font information from the file. + //Of all the places where the code might die, this is the most likely, + //as FT_New_Face will die if the font file does not exist or is somehow broken. + if (FT_New_Face( library_, PChar(fname), 0, face ) <> 0) then + raise Exception.create('FT_New_Face failed (there is probably a problem with your font file)'); + + //For some twisted reason, Freetype measures font size + //in terms of 1/64ths of pixels. Thus, to make a font + //h pixels high, we need to request a size of h*64. + //(h shl 6 is just a prettier way of writting h*64) + FT_Set_Char_Size( face, h shl 6, h shl 6, 96, 96); + + //Here we ask opengl to allocate resources for + //all the textures and displays lists which we + //are about to create. + list_base := glGenLists(128); + glGenTextures( 128, @textures[0] ); + + //This is where we actually create each of the fonts display lists. + for i := 0 to 127 do + make_dlist(face, i, list_base, @textures[0]); + + //We don't need the face information now that the display + //lists have been created, so we free the assosiated resources. + FT_Done_Face(face); + + //Ditto for the library. + FT_Done_FreeType(library_); +end; + +destructor TFontData.Destroy(); +begin + glDeleteLists(list_base, 128); + glDeleteTextures(128, @textures[0]); + SetLength(textures, 0); +end; + +/// A fairly straight forward function that pushes +/// a projection matrix that will make object world +/// coordinates identical to window coordinates. +procedure pushScreenCoordinateMatrix(); inline; +var + viewport: array [0..3] of GLint; +begin + glPushAttrib(GL_TRANSFORM_BIT); + glGetIntegerv(GL_VIEWPORT, @viewport); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(viewport[0], viewport[2], viewport[1], viewport[3]); + glPopAttrib(); +end; + +/// Pops the projection matrix without changing the current +/// MatrixMode. +procedure pop_projection_matrix(); inline; +begin + glPushAttrib(GL_TRANSFORM_BIT); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); +end; + +///Much like Nehe's glPrint function, but modified to work +///with freetype fonts. +class procedure TFreeType.print(ft_font: TFontData; x, y: single; const str: string); +var + font: GLuint; + h: single; + i: cardinal; + lines: TStringList; + modelview_matrix: array[0..15] of single; +begin + // We want a coordinate system where things coresponding to window pixels. + pushScreenCoordinateMatrix(); + + font := ft_font.list_base; + h := ft_font.h / 0.63; //We make the height about 1.5* that of + + lines := TStringList.Create(); + ExtractStrings([#13], [], PChar(str), lines); + + glPushAttrib(GL_LIST_BIT or GL_CURRENT_BIT or GL_ENABLE_BIT or GL_TRANSFORM_BIT); + glMatrixMode(GL_MODELVIEW); + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glListBase(font); + + glGetFloatv(GL_MODELVIEW_MATRIX, @modelview_matrix); + + //This is where the text display actually happens. + //For each line of text we reset the modelview matrix + //so that the line's text will start in the correct position. + //Notice that we need to reset the matrix, rather than just translating + //down by h. This is because when each character is + //draw it modifies the current matrix so that the next character + //will be drawn immediatly after it. + for i := 0 to lines.Count-1 do + begin + glPushMatrix(); + glLoadIdentity(); + glTranslatef(x, y - h*i, 0); + glMultMatrixf(@modelview_matrix); + + // The commented out raster position stuff can be useful if you need to + // know the length of the text that you are creating. + // If you decide to use it make sure to also uncomment the glBitmap command + // in make_dlist(). + //glRasterPos2f(0,0); + glCallLists(Length(lines[i]), GL_UNSIGNED_BYTE, PChar(lines[i])); + //float rpos[4]; + //glGetFloatv(GL_CURRENT_RASTER_POSITION ,rpos); + //float len=x-rpos[0]; + + glPopMatrix(); + end; + + glPopAttrib(); + + pop_projection_matrix(); + + lines.Free(); +end; + +end. diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.bdsproj b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.bdsproj new file mode 100644 index 00000000..9d3851c4 --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.bdsproj @@ -0,0 +1,175 @@ + + + + + + + + + + + + lesson43.dpr + + + 7.0 + + + 8 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + True + True + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; + + False + + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + False + False + False + True + True + True + True + True + True + + + + 0 + 0 + False + 1 + False + False + False + 16384 + 1048576 + 4194304 + + + + + + + + ../../../JEDI-SDL/SDL/Pas + + + + False + + + + + + False + + + True + False + + + + $00000000 + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1031 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.dpr b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.dpr new file mode 100644 index 00000000..fe296fb5 --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/lesson43.dpr @@ -0,0 +1,289 @@ +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. diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/nehe/readme.txt b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/readme.txt new file mode 100644 index 00000000..1186ef0e --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/nehe/readme.txt @@ -0,0 +1,9 @@ +Pascal conversion of the NeHe tutorial lesson 43 (Tutorial on using FreeType Fonts in OpenGL) +http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=43 + +Put the following DLLs into this directory: +- libfreetype-6.dll +- SDL.dll +- zlib1.dll + +and copy a TrueType font to this directory and rename it into "Test.ttf". diff --git a/ServiceBasedPlugins/src/lib/freetype/demo/switches.inc b/ServiceBasedPlugins/src/lib/freetype/demo/switches.inc new file mode 100644 index 00000000..0a940004 --- /dev/null +++ b/ServiceBasedPlugins/src/lib/freetype/demo/switches.inc @@ -0,0 +1 @@ +{$DEFINE FREETYPE_DEMO} -- cgit v1.2.3