Page 3 of 4 FirstFirst 1234 LastLast
Results 21 to 30 of 37

Thread: Prometheus News

  1. #21
    PGD Staff code_glitch's Avatar
    Join Date
    Oct 2009
    Location
    UK (England, the bigger bit)
    Posts
    933
    Blog Entries
    45
    Well, the rewrite is coming along nicely - the Linux branch of the new modular system is 'stable' and needs zero third party dependencies with support for TGA and PNG (no auto-detection yet but on its way), I've kicked off the Win32 branch today, the new units out so far are:

    PM_Colour - The colour type, used for defining colours
    PM_TileSets - Allows you to manage tilesets
    PM_Image - Allows you to load, draw, rotate, resize, colourize... Images.
    PM_Debug - Using DebugWriteln nd DebugWrite can easily switch to writing to screen, log file or nothing at all with a simple boolean flip
    PM_X11Window - Direct access to the X11 management system for windows on the Linux desktop
    PM_Window - Access to window management accross all platforms (routes your commands to the appropriate PM_X11Window or PM_Win32Window units at compile time)
    PM_Utils - The usual StrToInt, StrToReal etc plus support for clearing some basic arrays with a simple EmptyIntArray(@YourIntArrayVariable); as well as a timer system writen from the sysutils unit.
    PM_Event - Handles mouse, keyboard, window manager and other such events
    PM_Maps - Access to maps drawing them, loading them from TMX files (CSV/XML encoding) etc.

    Under development:
    PM_Win32Window and PM_Window
    PM_Event
    PM_Image
    PM_Maps
    PM_DataFiles
    PM_Network

    So thats all for now, still hard at work
    I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.

  2. #22
    Hi Ben

    I have done some simple image type detection in my xeEngine that I am writing for The Probe...

    here is that part of the code if you want to try it (seems to work for me):

    Code:
    type
      TImageType = (itUnknown,itBMP,itPNG,itTGA);
    
    function  GetImageTypeFromStream(Stream: TStream): TImageType;
    type
      TTGAHeader = packed record   // Header type for TGA images
        FileType     : Byte;
        ColorMapType : Byte;
        ImageType    : Byte;
        ColorMapSpec : Array[0..4] of Byte;
        OrigX  : Array [0..1] of Byte;
        OrigY  : Array [0..1] of Byte;
        Width  : Array [0..1] of Byte;
        Height : Array [0..1] of Byte;
        BPP    : Byte;
        ImageInfo : Byte;
      end;
    
    const
      cBMPSig = $4d42;
      cPNGSig: array[0..7] of Byte = (137, 80, 78, 71, 13, 10, 26, 10);
    var
      BMPSig   : Word;
      PNGSig   : array[0..7] of Byte;
      TGAHeader: TTGAHeader;
      i        : Integer;
      OldPos   : Int64;
      Image    : AnsiString;
    begin
      Result := itUnknown;
    
      OldPos := Stream.Position;
      try
        // check for BMP
        Stream.Read(BMPSig, SizeOf(BMPSig));
        if BMPSig = cBMPSig then
        begin
          Result := itBMP;
          Exit;
        end;
    
        //check for PNG
        Result := itPNG;
        Stream.Seek(OldPos,soFromBeginning);
        Stream.Read(PNGSig,SizeOf(PNGSig));
        for i := 0 to 7 do
        begin
          if PNGSig[i] <> cPNGSig[i] then
          begin
            Result := itUnknown;
            Break;
          end;
        end;
    
        if Result = itPNG then Exit;
    
        Result := itUnknown;
    
        //check for TGA
        Stream.Seek(OldPos,soFromBeginning);
        Stream.Read(TGAHeader,SizeOf(TGAHeader));
    
        // Only support 24, 32 bit images
        if (TGAHeader.ImageType <> 2) and    { TGA_RGB }
           (TGAHeader.ImageType <> 10) then  { Compressed RGB }
        begin
          Exit;
        end;
    
        // Don't support colormapped files
        if TGAHeader.ColorMapType <> 0 then
        begin
          Exit;
        end;
    
        Result := itTGA;
      finally
        Stream.Seek(OldPos,soFromBeginning);
      end;
    end;
    Using it:
    Code:
    function  TImageBuffer32.LoadFromStream(Stream: TStream): Boolean;
    var
      ImgType: TImageType;
    begin
      Result := False;
    
      ImgType := GetImageTypeFromStream(Stream);
    
      case ImgType of
        itBMP : Result :=  LoadBMPFromStream(Stream,Self);
        itPNG : Result :=  LoadPNGFromStream(Stream,Self);
        itTGA : Result :=  LoadTGAFromStream(Stream,Self);
      else
      end;
    end;
    cheers,
    Paul

  3. #23
    PGD Staff code_glitch's Avatar
    Join Date
    Oct 2009
    Location
    UK (England, the bigger bit)
    Posts
    933
    Blog Entries
    45
    Neat stuff paul, I take it the xe Engine treats you nicely then? The only problem in no auto detection YET is that a while back I wrote a separate unit that identifies the file type based on the first few bytes ord numbers. I just need to find a nice way of implementing it. I'm thinking I could just commission a PM_FileTypes unit and make something like

    Code:
    var
       ft: ANSIString;
    
    begin
       ft := GetFileType('SomeRandomFile');
       if ft = 'PNG' then // and so on...
    I've just had so much stuff to do recently I've barely had any time to implement it All the stuff mentioned above is stuff I have already played with, although there are some problems in Net as much of the code has never been tried by me, and DataFiles runs so fast on the CPU it thrashes the hard drive cache and thus gets killed for memory violation; due to accessing a file while it is being updated by the OS, so timings need to be updated as well as some synchronization procedures. But good progress all round.
    I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.

  4. #24
    PGD Staff code_glitch's Avatar
    Join Date
    Oct 2009
    Location
    UK (England, the bigger bit)
    Posts
    933
    Blog Entries
    45
    A tad more news in the unwind of code leading up to exam week - the PM_DataFiles unit is in its first implementation although at the moment it is quite limited - a maximum of 255 characters for the Name of a record and 4k (4096 bytes) for the actual value Although in its second revision this should be rectified.

    The framework for detecting file types in undergoing final tests but will be quite limited out of the box - only mp3, wav, ogg, png, jpeg and tga detection although more could be added by modifying the constants line in PM_FileTypes, all courtesy of keeping the weight of prometheus down.

    In other news, it has been found that the UPX utility can squeeze prometheus into a poultry <100k for a default compilation - no DLLs etc required so this is quite a bit lower than previous iterations.

    Also, looking out for a jpeg/bmp loader as well as a PM_DataFS unit that can store multiple files inside a Prometheus Data Storage file (.PDFS) as a sort of filesystem - such as raw proemtheus images and since each record eats up 4k at the moment, I'm implementing a basic compression system for all that white space too

    So lots of stuff going on, hopefully rolling out at the end of the weekend or in early next week.

    Just a few teaser stats on the data file system: loading a 21mb data file of 5200 records takes you a cool 51ms on a 1.3ghz dual core machine with an ageing stock, mechanical HDD... Thats around 375mb/s for those that were counting

    PM_PDSF_Benchmark.jpg
    Last edited by code_glitch; 25-11-2011 at 09:36 PM.
    I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.

  5. #25
    Hey Ben,
    here is my BMP loading code I wrote for my xeEngine:

    Code:
    unit unit_bmp_loader;
    {$ifdef fpc}
    {$mode Delphi}
    {$endif}
    {$H+}
    
    interface
    
    uses
      Classes,
      unit_ImageBuffer32;
    
    function  LoadBMPFromStream(Stream: TStream;  Buffer: TImageBuffer32): Boolean;
    function  LoadBMPFromFile(FileName: String; Buffer: TImageBuffer32): Boolean;
    
    implementation
    
    uses
      SysUtils;
    
    type
      //File information header
      //provides general information about the file
      TBITMAPFILEHEADER = packed record
        bfType      : Word;
        bfSize      : LongWord;
        bfReserved1 : Word;
        bfReserved2 : Word;
        bfOffBits   : LongWord;
      end;
    
      //Bitmap information header
      //provides information specific to the image data
      TBITMAPINFOHEADER = packed record
        biSize          : LongWord;
        biWidth         : LongInt;
        biHeight        : LongInt;
        biPlanes        : Word;
        biBitCount      : Word;
        biCompression   : LongWord;
        biSizeImage     : LongWord;
        biXPelsPerMeter : LongInt;
        biYPelsPerMeter : LongInt;
        biClrUsed       : LongWord;
        biClrImportant  : LongWord;
      end;
    
      //Colour palette
      TRGBQUAD = packed record
        rgbBlue     : Byte;
        rgbGreen    : Byte;
        rgbRed      : Byte;
        rgbReserved : Byte;
      end;
    
      PBitmapPixel = ^TBitmapPixel;
      TBitmapPixel = packed record
        b,g,r: Byte;
      end;
    
    function  LoadBMPFromStream(Stream: TStream;  Buffer: TImageBuffer32): Boolean;
      var
        FileHeader    : TBITMAPFILEHEADER;
        InfoHeader    : TBITMAPINFOHEADER;
        Palette       : array of TRGBQUAD;
        BitmapLength  : LongWord;
        PaletteLength : LongWord;
        ReadBytes     : LongWord;
        Width,Height  : Integer;
        BitmapPixels  : PBitmapPixel;
        BitmapAddr    : PBitmapPixel;
        BufferRow     : PRGBAArray;
        x,y           : LongWord;
        OldPos        : Int64;
    begin
      OldPos := Stream.Position;
    
      // Get header information
      Stream.Read(FileHeader, SizeOf(FileHeader));
    
      if FileHeader.bfType <> $4d42 then
      // not a BMP file!
      begin
        // reset position
        Stream.Seek(OldPos,soFromBeginning);
    
        Exit;
      end;
    
      Stream.Read(InfoHeader, SizeOf(InfoHeader));
    
      if InfoHeader.biBitCount <> 24 then
      // only supports 24 bit bitmaps!
        Exit;
    
      // Get palette
      PaletteLength := InfoHeader.biClrUsed;
    
      if PaletteLength > 0 then
      begin
        SetLength(Palette, PaletteLength);
        ReadBytes := Stream.Read(Palette,PaletteLength);
        if (ReadBytes <> PaletteLength) then
        begin
      //  MessageBox(0, PChar('Error reading palette'), PChar('BMP Loader'), MB_OK);
          Exit;
        end;
      end;
    
      Width  := InfoHeader.biWidth;
      Height := InfoHeader.biHeight;
    
      Buffer.SetSize(Width,Height);
    
      BitmapLength := InfoHeader.biSizeImage;
    
      if BitmapLength = 0 then
        BitmapLength := Width * Height * (InfoHeader.biBitCount Div 8);
    
      // Get the actual pixel data
      GetMem(BitmapPixels, BitmapLength);
      try
        ReadBytes := Stream.Read(BitmapPixels^, BitmapLength);
        if (ReadBytes <> BitmapLength) then
        begin
      //    MessageBox(0, PChar('Error reading bitmap data'), PChar('BMP Unit'), MB_OK);
          Exit;
        end;
    
        BitmapAddr := BitmapPixels;
        // copy bitmap pixels to buffer pixels
        for y := 0 to Height - 1 do
        begin
          BufferRow := Buffer.ScanLine[(Height - 1) - y];
          for x := 0 to Width - 1 do
          begin
            BufferRow^[x].r := BitmapAddr^.r;
            BufferRow^[x].g := BitmapAddr^.g;
            BufferRow^[x].b := BitmapAddr^.b;
            BufferRow^[x].a := 255;
            Inc(BitmapAddr);
          end;
        end;
      finally
        FreeMem(BitmapPixels)
      end;
    end;
    
    function  LoadBMPFromFile(Filename: String;  Buffer: TImageBuffer32): Boolean;
    var
      BMPFile : TFileStream;
    begin
      Result := False;
    
      if not FileExists(FileName) then Exit;
    
      BMPFile := TFileStream.Create(FileName,fmOpenRead or fmShareDenyWrite);
      try
        Result := LoadBMPFromStream(BMPFile,Buffer);
      finally
        BMPFile.Free;
      end;
    end;
    
    end.
    cheers,
    Paul

  6. #26
    And here is my image buffer I use for all my textures and image loading:

    Code:
    unit unit_ImageBuffer32;
    {$ifdef fpc}
    {$mode Delphi}
    {$endif}
    {$H+}
    
    interface
    
    uses
      Classes;
    
    type
      PRGBA = ^TRGBA;
      TRGBA = packed record
        case Integer of
          0 : (r,g,b,a: Byte);
          1 : (Value: LongWord);
      end;
    
      PRGBAArray = ^TRGBAArray;
      TRGBAArray = array[0..(MaxInt div SizeOf(TRGBA)) - 1] of TRGBA;
    
      TImageBuffer32 = class
      private
        FWidth  : Word;
        FHeight : Word;
        FPixels : array of TRGBA;
    
        function  GetScanLine(y: Word): Pointer;
        function  GetBit(Index: Integer): TRGBA;
        procedure SetBit(Index: Integer; Color: TRGBA);
      public
        constructor Create;
        destructor  Destroy; override;
    
        procedure SetSize(aWidth,aHeight: Word);
        procedure SetBitRGBA(Index: Integer; r,g,b,a: Byte);
        function  GetPixels: Pointer;
    
        function  LoadFromStream(Stream: TStream): Boolean;
        function  LoadFromFile(FileName: String): Boolean;
        function  LoadBMPFromFile(FileName: String): Boolean;
        function  LoadPNGFromFile(FileName: String): Boolean;
        function  LoadTGAFromFile(FileName: String): Boolean;
    
        property Width : Word read FWidth;
        property Height: Word read FHeight;
        property ScanLine[y: Word]: Pointer  read GetScanLine;
        property Bits[Index: Integer]: TRGBA read GetBit write SetBit;
      end;
    
    implementation
    
    uses
      SysUtils,
      unit_bmp_loader,
      unit_tga_loader,
      unit_png_loader;
    
    type
      TImageType = (itUnknown,itBMP,itPNG,itTGA);
    
    function  GetImageTypeFromStream(Stream: TStream): TImageType;
    type
      TTGAHeader = packed record   // Header type for TGA images
        FileType     : Byte;
        ColorMapType : Byte;
        ImageType    : Byte;
        ColorMapSpec : Array[0..4] of Byte;
        OrigX  : Array [0..1] of Byte;
        OrigY  : Array [0..1] of Byte;
        Width  : Array [0..1] of Byte;
        Height : Array [0..1] of Byte;
        BPP    : Byte;
        ImageInfo : Byte;
      end;
    
    const
      cBMPSig = $4d42;
      cPNGSig: array[0..7] of Byte = (137, 80, 78, 71, 13, 10, 26, 10);
    var
      BMPSig   : Word;
      PNGSig   : array[0..7] of Byte;
      TGAHeader: TTGAHeader;
      i        : Integer;
      OldPos   : Int64;
      Image    : AnsiString;
    begin
      Result := itUnknown;
    
      OldPos := Stream.Position;
      try
        // check for BMP
        Stream.Read(BMPSig, SizeOf(BMPSig));
        if BMPSig = cBMPSig then
        begin
          Result := itBMP;
          Exit;
        end;
    
        //check for PNG
        Result := itPNG;
        Stream.Seek(OldPos,soFromBeginning);
        Stream.Read(PNGSig,SizeOf(PNGSig));
        for i := 0 to 7 do
        begin
          if PNGSig[i] <> cPNGSig[i] then
          begin
            Result := itUnknown;
            Break;
          end;
        end;
    
        if Result = itPNG then Exit;
    
        Result := itUnknown;
    
        //check for TGA
        Stream.Seek(OldPos,soFromBeginning);
        Stream.Read(TGAHeader,SizeOf(TGAHeader));
    
        // Only support 24, 32 bit images
        if (TGAHeader.ImageType <> 2) and    { TGA_RGB }
           (TGAHeader.ImageType <> 10) then  { Compressed RGB }
        begin
          Exit;
        end;
    
        // Don't support colormapped files
        if TGAHeader.ColorMapType <> 0 then
        begin
          Exit;
        end;
    
        Result := itTGA;
    {    SetLength(Image,Stream.Size);
        Stream.Read(PAnsiChar(Image)^,Stream.Size);
        if Pos('TRUEVISION-XFILE',Image) > 0 then
        begin
          Result := itTGA;
          Exit;
        end;}
      finally
        Stream.Seek(OldPos,soFromBeginning);
      end;
    end;
    
    function  NewRGBA(r,g,b,a: Byte): TRGBA;
    begin
      Result.r := r;
      Result.g := g;
      Result.b := b;
      Result.a := a;
    end;
    
    constructor TImageBuffer32.Create;
    begin
      inherited Create;
    
      SetSize(0,0);
    end;
    
    destructor  TImageBuffer32.Destroy;
    begin
      SetSize(0,0);
    
      inherited Destroy;
    end;
    
    procedure TImageBuffer32.SetSize(aWidth,aHeight: Word);
    var
      i: Integer;
    begin
      FWidth  := aWidth;
      FHeight := aHeight;
    
      SetLength(FPixels,FWidth * FHeight);
    
      for i := 0 to FWidth * FHeight - 1 do
        FPixels[i].Value := 0;
    end;
    
    function  TImageBuffer32.GetScanLine(y: Word): Pointer;
    begin
      Result := @FPixels[y * FWidth];
    end;
    
    function  TImageBuffer32.GetBit(Index: Integer): TRGBA;
    begin
      Result := FPixels[Index];
    end;
    
    procedure TImageBuffer32.SetBit(Index: Integer; color: TRGBA);
    begin
      FPixels[Index] := color;
    end;
    
    procedure TImageBuffer32.SetBitRGBA(Index: Integer; r,g,b,a: Byte);
    begin
      FPixels[Index].r := r;
      FPixels[Index].g := g;
      FPixels[Index].b := b;
      FPixels[Index].a := a;
    end;
    
    function  TImageBuffer32.GetPixels: Pointer;
    begin
      Result := nil;
    
      if Length(FPixels) = 0 then Exit;
    
      Result := @FPixels[0];
    end;
    
    function  TImageBuffer32.LoadFromStream(Stream: TStream): Boolean;
    var
      ImgType: TImageType;
    begin
      Result := False;
    
      ImgType := GetImageTypeFromStream(Stream);
    
      case ImgType of
        itBMP : Result :=  LoadBMPFromStream(Stream,Self);
        itPNG : Result :=  LoadPNGFromStream(Stream,Self);
        itTGA : Result :=  LoadTGAFromStream(Stream,Self);
      else
      end;
    end;
    
    function  TImageBuffer32.LoadFromFile(FileName: String): Boolean;
    var
      Ext: String;
    begin
      Result := False;
    
      if not FileExists(FileName) then Exit;
    
      Ext := LowerCase(ExtractFileExt(FileName));
    
      if      Ext = '.bmp' then Result := unit_bmp_loader.LoadBMPFromFile(FileName,Self)
      else if Ext = '.tga' then Result := unit_tga_loader.LoadTGAFromFile(FileName,Self)
      else if Ext = '.png' then Result := unit_png_loader.LoadPNGFromFile(FileName,Self);
    end;
    
    function  TImageBuffer32.LoadBMPFromFile(FileName: String): Boolean;
    begin
      Result := False;
    
      if not FileExists(FileName) then Exit;
    
      Result := unit_bmp_loader.LoadBMPFromFile(FileName,Self);
    end;
    
    function  TImageBuffer32.LoadPNGFromFile(FileName: String): Boolean;
    begin
      Result := False;
    
      if not FileExists(FileName) then Exit;
    
      Result := unit_png_loader.LoadPNGFromFile(FileName,Self);
    end;
    
    function  TImageBuffer32.LoadTGAFromFile(FileName: String): Boolean;
    begin
      Result := False;
    
      if not FileExists(FileName) then Exit;
    
      Result := unit_tga_loader.LoadTGAFromFile(FileName,Self);
    end;
    
    end.
    cheers,
    Paul

  7. #27
    PGD Staff code_glitch's Avatar
    Join Date
    Oct 2009
    Location
    UK (England, the bigger bit)
    Posts
    933
    Blog Entries
    45
    Hmm... Indeed that PMB code is very nice indeed, you aren't putting a license on it are you? I hate having to reverse engineer techniques to write my own loaders although it does look simple. I'm thinking JPEG won't be as nice, maybe I should drop support for the low-quality support... I mean, who wants dithering like photos on their apps?!

    Cheers for that, got a few hours train ride today so I'll work some more then by the looks of it
    I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.

  8. #28
    No, I'm not putting a license on it...and I finally got the BMP loading code working after looking at a bunch of online code myself. I'm giving back to the community since it gives to me, so use it how you wish

    I came up with the image buffer class myself after I tried using some Graphics32 PNG loading code initially and wanted to replace some other classes...

    I ended up using BeRo's PNG loader instead but kept the image buffer as it was rather useful for the textures and loaders to hook into

    cheers,
    Paul
    Last edited by paul_nicholls; 26-11-2011 at 09:03 AM.

  9. #29
    PGD Staff code_glitch's Avatar
    Join Date
    Oct 2009
    Location
    UK (England, the bigger bit)
    Posts
    933
    Blog Entries
    45
    Just another check-in. At this point a lot of stuff works and some does not. Focus is now for XML/TMX support and audio support based on openal. The PNG loader is being looked into after the Ludum Dare entry started producing weird behavior on X11 based systems but not WINAPI based systems - although this is most likely down to bad memory optimization and x11 management.

    As a result the entire OpenGL code is being scrutinized and most likely binned for a new system based on FBOs and PBOs for extendability and switchable render targets - perhaps a 'render to disk' option or multiple monitor/window option will arise as a result.

    The X11 event management code is being overhauled yet again for better integration as well as for mouse support - Mac OS X will have to put up with the 'Generic' window handler AKA SDL while linux users benefit from native X11 code and WIN32 users benefit from native WINAPI code that I hope will be released within the next few weeks.

    So, what this means for users:
    -Faster performance (up to 35% better frame rates and memory management)
    -More OSes without touching a single line of code - Mac, Windows, Linux and possible flash (this one is.... complicated )
    -Audio is on its way
    -Using prometheus for proper rendering as well as potentially in multi-monitor setups and support for a 'virtual monitor' which will be elaborated on at a later date!
    I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.

  10. #30
    I'm curious, how would you handle Flash? Would you use FlashPascal or something different?
    Freeze Development | Elysion Game Framework | Twitter: @Stoney_FD
    Check out my new book: Irrlicht 1.7.1 Realtime 3D Engine Beginner's Guide (It's C++ flavored though)

    Programmer: A device for converting coffein into software.

Page 3 of 4 FirstFirst 1234 LastLast

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •