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:
Converting the PNG to an OpenGL texture: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);
Displaying the loaded PNG in OpenGL: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 );
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 triangleCode: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);... 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


... 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)
Reply With Quote


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.

