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
Bookmarks