1. Well if you don't mind not using libpng you can use this: http://members.gamedev.net/lode/project ... icopng.cpp.Kasumi wrote: Honestly, I'm looking to write functions to do three things:
1. Loading pngs.
2. Blitting small Xpixel by Ypixel areas of the png to the screen. (Tiles) (Fast, so I could draw thousands of tiles each frame)
3. Blitting small Xpixel by Ypixel areas of the png to the screen with Alpha Channel. (Sprites)
Text would be nice, but could be accomplished with #3. I do wish there was a magic solution, but I suppose I'm all for learning. The genesis deadline isn't getting further away, though. :
It is a single function which loads most any PNG file. The pixels it gives you will ALWAYS be 32-bit RGBA. Use is simple:
Code: Select all
std::vector<unsigned char> outPixels; // A vector to store the loaded pixels
unsigned long outWidth, outHeight; // Somewhere to store width and height of loaded image
const unsigned char* buffer; // The actual image data encoded as PNG from file, network etc
size_t imageSize // The size of the image data
decodePNG(outPixels, outWidth, outHeight, (const unsigned char*) buffer, imageSize, true);Code: Select all
/**
* Render an image onto the screen.
*
* @param float x X position to render to.
* @param float y Y position to render to.
* @param const ImageClip* clip Src blitting region.
*/
void Image::draw(float x, float y, const ImageClip* clip) {
unsigned int w, h;
int offsetX, offsetY;
if (clip != NULL) {
w = (clip->width == 0) ? this->segments[0].width : clip->width;
h = (clip->height == 0) ? this->segments[0].height : clip->height;
offsetX = clip->x;
offsetY = clip->y;
} else {
w = this->segments[0].width;
h = this->segments[0].height;
offsetX = 0;
offsetY = 0;
}
//printf("[%d] pos: (%f, %f) \noffset: (%d, %d)\ndimensions: (%d, %d)\n", this->segments.size(), x, y, offsetX, offsetY, w, h);
// Enable 2D textures
sceGuEnable(GU_TEXTURE_2D);
sceGuTexMode(GU_PSM_8888, 0, 0, this->isSwizzled());
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
sceGuTexScale(1.0f, 1.0f);
sceGuTexOffset(0.0f, 0.0f);
// Apply texture
sceGuTexImage(0, this->segments[0].p2Width, this->segments[0].p2Height, this->segments[0].width, &this->segments[0].pixels[0]);
Vertex2 image[2] = {
{ // Top-Left point
(offsetX / (float)this->segments[0].p2Width), (offsetY / (float)this->segments[0].p2Height),
x, y, 0.0f
},
{ // Bottom-Right point
((offsetX + w) / (float)this->segments[0].p2Width), ((offsetY + h) / (float)this->segments[0].p2Height),
x + w, y + h, 0.0f
}
};
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
Vertex2* finalImage = (Vertex2*) sceGuGetMemory(sizeof(Vertex2) * 2);
memcpy(finalImage, image, sizeof(Vertex2) * 2);
// Draw the quad
sceGumDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF, 2, 0, finalImage);
// Disable again
sceGuDisable(GU_TEXTURE_2D);
}
Code: Select all
ImageClip clip = {32, 32, 64, 64};
Image myImage;
myImage.loadFile("blabla.png");
myImage.draw(100, 24, &clip);

