Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: Native PNG Loader with no 3rd party requirements

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Native PNG Loader with no 3rd party requirements

    EDIT: Updated code and screen caps for reference

    Ok, we have all seen the posts of want for a simple native PNG loader that supports FPC and doesn't require a ton o'crap along with it. So, I got off my duff and wrote one. It still has a few minor issues (see the screen shot below) regarding colors (green is off for some reason) but it works and should be a good starting point.

    The code is based on previous works from zgl, BX, several C/C++ libraries, and hours spent reading the spec (talk about long winded ways to explain things like CRC32)...

    This code ONLY LOADS PNG's from file or from a TStream, no saving (sorry WILL). It only requires classes (for stream support) and paszlib (for decompression).

    Download at: http://www.eonclash.com/gl/uPNGSupport.pas

    Here is how I'm testing it with OpenGL:

    Loading a PNG file from disk:
    Code:
     png := TRawPNG.Create(loadFileName);
     Writeln(loadFileName, ': ', png.LoadErrorMessage);
     WriteLn('Chunk Info:');
     for i := 0 to png.NumChunks-1 do
      WriteLn(' ', png.ChunkName[i], ' of size ', png.ChunkAt[i]^.Length);
     WriteLn('tEXt: ', png.tEXt);
    Converting the PNG to an OpenGL texture:
    Code:
     glShadeModel(GL_SMOOTH);
     glGenTextures(1, @FGLImage);
     glBindTexture(GL_TEXTURE_2D, FGLImage);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, png.Width, png.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, png.Data );
    Displaying the loaded PNG in OpenGL:
    Code:
     glEnable(GL_TEXTURE_2D);
     glEnable(GL_BLEND);
     glDisable(GL_DEPTH_TEST);
      glLoadIdentity();
      glTranslatef(1.5,0.0,-6.0);//1.5
      if(png.BackgroundColor.C > 0)then
       glColor4f(png.BackgroundColor.R/255, png.BackgroundColor.G/255, png.BackgroundColor.B/255, png.BackgroundColor.A/255)
      else
       glColor4f(1.0, 1.0, 1.0, 1.0);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glBindTexture(GL_TEXTURE_2D, FGLImage);
      glRotatef(-rotation, 0.0, 1.0, 0.0);
     	glBegin(GL_QUADS);
       glTexCoord2f(0.0, 1.0);
       glVertex3f(-1.0, 1.0, 0.0);
       glTexCoord2f(1.0, 1.0);
       glVertex3f( 1.0, 1.0, 0.0);
       glTexCoord2f(1.0, 0.0);
       glVertex3f( 1.0,-1.0, 0.0);
       glTexCoord2f(0.0, 0.0);
       glVertex3f(-1.0,-1.0, 0.0);
     	glEnd();
     glEnable(GL_DEPTH_TEST);
     glDisable(GL_BLEND);
     glDisable(GL_TEXTURE_2D);
    And here is a screenshot (with a triangle displayed using glColor3f). You will notice that the square's colors just don't quite add up, they should be white (top left), blue (top right), green (bottom left), red (bottom right) of the same intensity as the triangle ... Any ideas I'd love to hear them. I still have to implement Gama Correction in the loading algo, and thats on the plans just isn't quite complete and need to implement the rest of the Chunk Types, but it loads any PNG I've thrown at it thus far. (NOW FIXED)



    - Jeremy

  2. #2

    Re: Native PNG Loader with no 3rd party requirements

    Ok, so, I feel sheepish... Bit of looking at my own GL code and realized I did the binding wrong

    Here is the proper GL init stuff:
    Code:
     glGenTextures(1, @FGLImage); // THIS WAS WRONG, it was pointed at png.data :(
     glBindTexture(GL_TEXTURE_2D, FGLImage);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, png.Width, png.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, png.Data );
    Here is another screenshot showing the fixed gamma and color space:


    - Jeremy

  3. #3

    Re: Native PNG Loader with no 3rd party requirements

    I tried this unit with Next3D. Took some jpg, scaled it down to 512x1024 and saved as PNG using Gimp and max compression. Result was correct image when it comes to colors but it only loaded correctly 5% of the top part line by line and it drew it upside down. Rest 95% of the image was the same as last read line.

    I tried with my original engine code (freepascal's unit) first which drew it without problems.

    Edit: Now.. explained the format bit wrong. Later i added pixel wide corners and some text by hand using MsPaint and saved it in PNG again. That is different format than what gimp used and caused the above explained behavior.

    But now i re-saved the same image with Gimp max compression and the loader give access violation. I commented out everything else so it's certainly in the png unit. It pops cpu window so i can't debug exactly where.

  4. #4

    Re: Native PNG Loader with no 3rd party requirements

    @User137: Can you post the image file that your using to break things? I'd like to have it to work with

    @Anyone Interested: Updated one more time, just a few minor tweaks. Here is the current list of supported chunks:

    • IHDR - PNG Header
    • PLTE - Color Palette Chunk
    • IDAT - Image Data Chunk
    • gAMA - Gamma Correction Chunk
    • tEXt - Text Chunk
    • zTXt - Text Chunk
    • iTXt - Text Chunk
    • bKGD - Background Color Chunk
    • tRNS - Transparency Chunk, updated for proper support now


    Download and links in first post have been updated.

    - Jeremy

  5. #5

    Re: Native PNG Loader with no 3rd party requirements

    Well, found my issue with the coloring.... Guess it helps if you setup the proper color before you render your image. I had the color setup wrong, now using the background color provided or white (as a default) everything works great.

    Code should be:
    Code:
     glEnable(GL_TEXTURE_2D);
     glEnable(GL_BLEND);
     glDisable(GL_DEPTH_TEST);
      glLoadIdentity();
      glTranslatef(0.1,0.0,-6.0);//1.5
      if(png.BackgroundColor.C > 0)then
       glColor4f(png.BackgroundColor.R/255, png.BackgroundColor.G/255, png.BackgroundColor.B/255, png.BackgroundColor.A/255)
      else
       glColor4f(1.0, 1.0, 1.0, 1.0);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glBindTexture(GL_TEXTURE_2D, FGLImage);
      glRotatef(-rotation, 0.0, 1.0, 0.0);
     	glBegin(GL_QUADS);
       glTexCoord2f(0.0, 1.0);
       glVertex3f(-1.0, 1.0, 0.0);
       glTexCoord2f(1.0, 1.0);
       glVertex3f( 1.0, 1.0, 0.0);
       glTexCoord2f(1.0, 0.0);
       glVertex3f( 1.0,-1.0, 0.0);
       glTexCoord2f(0.0, 0.0);
       glVertex3f(-1.0,-1.0, 0.0);
     	glEnd();
     glEnable(GL_DEPTH_TEST);
     glDisable(GL_BLEND);
     glDisable(GL_TEXTURE_2D);
    - Jeremy

  6. #6

    Re: Native PNG Loader with no 3rd party requirements

    Nice one, i thought i was stuck on using an .dll or .so file with using png.
    Can i use your code with code that is under the mozilla public license?
    http://3das.noeska.com - create adventure games without programming

  7. #7

    Re: Native PNG Loader with no 3rd party requirements

    I'm not sticking no stinkin licenses on this, so as far as I care use it as you wish . But, to quote, "Beware of bugs in my code; I have only proved it correct, not tried it." The only thing you can't do is take away my right to publish it anyone and everywhere LOL

    I think this is something we as a community need, and its definitely been a stumbling block for me for long enough .

    What I would love to see, and what I plan on building myself as I get time, is a support unit like this for other formats as well. Would be nice to have ones for TGA, BMP, and SVG. Though I can't imagine that SVG could be put into a single stand alone simple to use unit.

    - Jeremy

  8. #8

    Re: Native PNG Loader with no 3rd party requirements

    on the svg matter take a look at my gl vector graphics project:
    http://www.pascalgamedevelopment.com...p?topic=5916.0
    but that does not read physical svg files (yet)
    http://3das.noeska.com - create adventure games without programming

  9. #9

    Re: Native PNG Loader with no 3rd party requirements

    Testing this kind now: http://next3d.webs.com/test1.png

    It didn't crash but dimensions are 1024x512 so opposite than previous. Didn't try your new version yet...

    Edit: Now run that with new version but it didn't make difference. This is how it looks in program:
    http://i32.tinypic.com/ibe5bt.jpg

  10. #10
    Co-Founder / PGD Elder WILL's Avatar
    Join Date
    Apr 2003
    Location
    Canada
    Posts
    6,107
    Blog Entries
    25

    Re: Native PNG Loader with no 3rd party requirements

    Quote Originally Posted by jdarling
    This code ONLY LOADS PNG's from file or from a TStream, no saving (sorry WILL). It only requires classes (for stream support) and paszlib (for decompression).
    Well if you have the decoding working for the decompression to load it into memory, would it not be a simple task to encode it back for saving? Maybe when I get back from vacation, I could take a look at your code for decompression and play with it. That is if it's exposed and not in a separate API.
    Jason McMillen
    Pascal Game Development
    Co-Founder





Page 1 of 3 123 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
  •