Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: OpenGL Texture Manager

  1. #1

    OpenGL Texture Manager

    System: Windows XP SP2, Pentium D 805 2,66 GHz, GeForce 7600 GS, 2 GB RAM
    Compiler/IDE: Delphi 2007
    API: JEDI-SDL, OpenGL
    ---
    Hi everyone!

    I want to make a texture manager for my first 3D engine. I heard there are different ways of doing this. Well, I previously did a texture manager, but it was crappy and I want something optimized and well-working for this project. Can you suggest me how I should build the manager?

  2. #2

    OpenGL Texture Manager

    Here's how I did mine. I have a global gTextureManager class which returns handles to textures, you get the handle by the filename and when you don't need the texture anymore you tell that to the manager and it decreases the usage counter for that texture.

    When the texture's usage counter is 0 it means that this texture can be replaced by another. Textures used for the same purpose usually are the same size and glTexSubImage is used to replace the data in the graphics card's memory.

    Another way to do it would be to use massive texture sizes, ie. allocate as big texture as possible and then start fitting the actual textures in that, a sort of texture atlas. This would reduce the number of state changes when binding textures. But you'd probably need several textures and handling all the reallocation can be tricky and the texture classes should handle all bindings themselves, no more calling glBindTexture directly with a handle and setting the texture coordinates would be tricky too (would have to alter the texture matrix). I might try something like this next.
    If you develop an idiot proof system, the nature develops better idiots.

  3. #3

    OpenGL Texture Manager

    Hmm, pretty interesting approach. I guess a singleton-based texture manager would be a good choice, too. The manager I have in mind loads textures from a file/stream, uses TThreadList to store the texture object. The texture object is just a simple class (something like that):
    Code:
    type
      TTexture = class(TObject)
      private
        { Private declarations }
        FName: String;
        FID: Cardinal;
      public
        { Public declarations }
        constructor Create(const ATexName: String; const ATexId: Cardinal);
    
        property TexName: String read FName;
        property ID: Cardinal read FID;
      end;
    What do you think of this idea?

  4. #4

    OpenGL Texture Manager

    This is how it's defined on my latest engine:

    Code:
     TTexture = record
        name: string[12];
        sizeX, sizeY, values: word; // values 3 or 4
        index,format: cardinal; // GL_RGB or GL_RGBA
        Data: PByteArray; // size = sizeX*sizeY*values
      end;
      PTexture = ^TTexture;
    
      TTextureLoadOptions = set of (toMipMap, toAlphaColor,
        toKeepData, toAbsoluteSize, toColorKey);
    
      TTextureSet = class
        texture: array of TTexture;
        count, TextureQuality: integer;
        Options: TTextureLoadOptions;
        TransparentColor: TRGBTriple;
      private
        count2: integer;
        function Pow2Limit(var w,h: word; var sx,sy: single): boolean;
        procedure SetCount(n: integer);
      public
        constructor Create;
        destructor Destroy; override;
    // AddTexture creates new item, makes call to LoadTextureData which makes extension check and loads any format that is identified
        function AddTexture(name,filename: string; transparency: boolean = false): integer;
        procedure Clear;
        procedure Disable;
        procedure Enable;
        function IndexOf(name: string): integer;
        function LoadBMPDataFile(tex: PTexture; filename: string): boolean;
        function LoadBMPData(tex: PTexture; bmp: TBitmap): boolean;
        function LoadPNGData(tex: PTexture; filename: string): boolean;
        function LoadJPGData(tex: PTexture; filename: string): boolean;
        function LoadTextureData(tex: PTexture; filename: string): boolean;
        procedure RemoveTexture(n: integer);
        procedure ReloadTexture(n: integer; filename: string; transparency: boolean);
        procedure Restore(tex: PTexture);
        procedure SetTex(n: integer);
      end;
    Also because glBindTexture calls should be minimized as much as possible, this one is used every time (except forced when making displaylists):
    Code:
    implementation
    
    var lastTex: cardinal;
    
    procedure nxSetTex(t: cardinal; force: boolean);
    begin
      if (t<>lastTex) or force then begin
        glBindTexture(GL_TEXTURE_2D,t); 
        lastTex:=t;
      end;
    end;
    Last edited by SilverWarior; 07-05-2019 at 09:25 PM. Reason: Fixed CODE tags

  5. #5

    OpenGL Texture Manager

    That's almost the same I' was thinking about. I don't understand the last snippet, though. Can you explain it further to me, please?

  6. #6

    OpenGL Texture Manager

    It simply skips glBindTexture call if it is already bound, therefore making program run much faster if same ID was been tried to set many times in a row. Only way to change binding is another glBindTexture call, no other method can unbind it.

  7. #7

    OpenGL Texture Manager

    I suppose this method is not a member of any class and is called within SetTex method. Am I right?

  8. #8

    OpenGL Texture Manager

    Quote Originally Posted by Brainer
    I suppose this method is not a member of any class and is called within SetTex method. Am I right?
    Right

    TTextureSet.SetTex makes call to nxSetTex

    Also, why there is private SetCount procedure and Count2 variable, is because i made setlength calls to power of 2 only. This reduce amount of times array is resized and likely makes program faster.

  9. #9

    OpenGL Texture Manager

    Pretty clever idea! Still, I heard that using a singleton is the best option. What do you think?

  10. #10

    OpenGL Texture Manager

    If you mean, each texture should be object... it's matter of taste maybe. I like mix of object oriented and procedural Every bit of procedural gives a little more efficiency to program but little more headache to programmer if done too much.

Page 1 of 2 12 LastLast

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
  •