Maximum Texture Size

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Maximum Texture Size

Post by coolkehon »

what is the maximum size of a texture that the gu will accept. I plan on loading a lvl map background that will probably over a 1000x600 pixels and maybe more that will be bigger and i want to know if the gu will be able to handle this

edit: just tried it and it doesn't work on an image that is 992x504 so how can i fix this / work around it
Dariusc123456
Posts: 388
Joined: Tue Aug 12, 2008 12:46 am

Re: Maximum Texture Size

Post by Dariusc123456 »

coolkehon wrote:what is the maximum size of a texture that the gu will accept. I plan on loading a lvl map background that will probably over a 1000x600 pixels and maybe more that will be bigger and i want to know if the gu will be able to handle this

edit: just tried it and it doesn't work on an image that is 992x504 so how can i fix this / work around it
idk if this will help out or not but have you try to bring it down to 480x272? I know this is a stupid answer, but it might work.
PSHN - Playstation Hacking Network
PSX/PS1 - HACK - Game Shark
PS2 - HACK - Swap
PSP - HACK - Pandora
PS3 - ?
slasher2661996
Posts: 91
Joined: Sun Feb 22, 2009 8:32 am
Location: Melbourne Australia ZOMG

Post by slasher2661996 »

don't load a massive image like that, load tiles of the big image
jojojoris
Posts: 255
Joined: Sun Mar 30, 2008 4:06 am

Post by jojojoris »

i read somewhere the maximum size was 512x512 px

Code: Select all

int main(){
     SetupCallbacks();
     makeNiceGame();
     sceKernelExitGame();
}
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

i can't bring the image down to 480x272. the image is not a tile and cannot be tiled. so how can i load this big image. here is a link to the copy of it i just cut out the bottom part and used it. i'll place the objects on there later

http://www.sprites-inc.co.uk/files/EXE/ ... Falzer.png
jojojoris
Posts: 255
Joined: Sun Mar 30, 2008 4:06 am

Post by jojojoris »

You can split the image in seperate parts.

Code: Select all

|--------|--------|
|        |        |
|    1   |    2   |
|        |        |
|--------+--------|
|        |        |
|    3   |    4   |
|        |        |
|--------|--------|
BTW:
Why can't that image be tiled?

Code: Select all

int main(){
     SetupCallbacks();
     makeNiceGame();
     sceKernelExitGame();
}
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

i was just going to edit and say i did that with imagemagick. but how do i display those correctly.
jojojoris
Posts: 255
Joined: Sun Mar 30, 2008 4:06 am

Post by jojojoris »

Simply draw those images at the rght place.

Code: Select all

Image1.x=0;
Image1.y=0;

Image2.x=totalwidth/2;
Image2.y=0;

Image3.x=0;
Image3.y=totalheight/2;

Image4.x=totalwidth/2;
Image4.y=totalheight/2;

drawImage(Image1);
drawImage(Image2);
drawImage(Image3);
drawImage(Image4);

Code: Select all

int main(){
     SetupCallbacks();
     makeNiceGame();
     sceKernelExitGame();
}
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

here is the function i was using but it is slow and leaves a gap in the images

Code: Select all

	Location loc = start;
	uint fnum_w = 0, fnum_h = 0;
	for&#40;vector<Image *>&#58;&#58;iterator it = tiles.begin&#40;&#41;;
		it != tiles.end&#40;&#41;;
		it++&#41;
	&#123;
		if&#40;&#40;*it&#41; != NULL&#41;
		&#123;
			&#40;*it&#41;->moveTo&#40;loc&#41;;
			loc.x += &#40;*it&#41;->getWidth&#40;&#41;;
//			cout << "Loc&#58; " << loc.toString&#40;&#41; << endl;
			if&#40;++fnum_w >= frames_wide &#41;
			&#123;
				fnum_w = 0;
				if&#40;++fnum_h >= frames_high&#41;
					break;
				loc.x = start.x;
				loc.y += &#40;*it&#41;->getHeight&#40;&#41;;
			&#125;
			
		&#125;
	&#125;
jojojoris
Posts: 255
Joined: Sun Mar 30, 2008 4:06 am

Post by jojojoris »

Did you swizzle the images? (Enormous speedup)

How big is the gap between the parts?

Code: Select all

int main&#40;&#41;&#123;
     SetupCallbacks&#40;&#41;;
     makeNiceGame&#40;&#41;;
     sceKernelExitGame&#40;&#41;;
&#125;
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

i just released the library so you can see where i've messed up (hopefully not) in the image rendering

here are some screenshots and i think it's because i'm drawing all of the images and they shouldn't be seen because of clipping but it's slowing it down

and i swizzled it and the speed went up but when moving it slows down again until i stop if i take out the vblank start it does 77 frames per second

ps: when i move i just update the image's location

Image
Image
Image

also there is something on this image although this one should be completly transparent it should have been in second image as well but it didn't show up for some reason in screenshot
Image
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

ok i changed the image because i was going to.
I changed the tile size to a power of 2 and now there aren't any gaps although i have no idea why having a power of 2 gets rid of gaps.
The images are all swizzled with each tile being 256x256.
The framerate is higher when stading still but when i start moving it drops below 60fps and there is also an issue with stray part of images being draw or the images being messed up

edit: how can i speed up the math because when i hide/don't render the image it is speeds up but when i do the math it is still slow. I believe its all that math that's happening which is a bunch of addition and maybe one or two divisions

here is how i move and update location

lan_hp is a Room

Code: Select all

		Location next = lan_loc;
		if&#40;controls.held&#40;&#41; & PSP_CTRL_RIGHT&#41;
		&#123;
			if&#40;InsidePolygon&#40;points.data&#40;&#41;,points.size&#40;&#41;,Location&#40;next.x+speedx,next.y&#41;&#41; &#41;
				next.x += speedx;
		&#125;
		if&#40;controls.held&#40;&#41; & PSP_CTRL_LEFT&#41;
		&#123;
			if&#40;InsidePolygon&#40;points.data&#40;&#41;,points.size&#40;&#41;,Location&#40;next.x-speedx,next.y&#41;&#41;&#41;
				next.x -= speedx;
		&#125;
		if&#40;controls.held&#40;&#41; & PSP_CTRL_UP&#41;
		&#123;
			if&#40;InsidePolygon&#40;points.data&#40;&#41;,points.size&#40;&#41;,Location&#40;next.x,next.y-speedy&#41;&#41;&#41;
				next.y -=speedy;
		&#125;
		if&#40;controls.held&#40;&#41; & PSP_CTRL_DOWN&#41;
		&#123;
			if&#40;InsidePolygon&#40;points.data&#40;&#41;,points.size&#40;&#41;,Location&#40;next.x,next.y+speedy&#41;&#41;&#41;
				next.y += speedy;
		&#125;
		
		lan_walk->update&#40;&#41;;
		if&#40;next.x != lan_loc.x || next.y != lan_loc.y&#41;
		&#123;
			lan_loc = next;
//			lan_hp.moveTo&#40;&#40;480.0f/2.0f&#41;-lan_loc.x,&#40;272.0f/2.0f&#41;-lan_loc.y&#41;;
			lan_hp.moveTo&#40;240.0f-lan_loc.x,136-lan_loc.y&#41;;
		&#125;
this is Room::moveTo

Code: Select all

void Room&#58;&#58;update&#40;&#41;
&#123;
	Location loc = start;
	uint fnum_w = 0, fnum_h = 0;
	for&#40;vector<Image *>&#58;&#58;iterator it = tiles.begin&#40;&#41;;
		it != tiles.end&#40;&#41;;
		it++&#41;
	&#123;
		if&#40;&#40;*it&#41; != NULL&#41;
		&#123;
			&#40;*it&#41;->moveTo&#40;loc&#41;;
			cout << "Loc&#58; " << loc.toString&#40;&#41; << endl;
			loc.x += &#40;*it&#41;->getWidth&#40;&#41;;
			if&#40;++fnum_w >= frames_wide &#41;
			&#123;
				fnum_w = 0;
				if&#40;++fnum_h >= frames_high&#41;
					break;
				loc.x = start.x;
				loc.y += &#40;*it&#41;->getHeight&#40;&#41;;
			&#125;
			
		&#125;
	&#125;
&#125;
void Room&#58;&#58;moveTo&#40;Location loc&#41;
&#123;
	if&#40;loc.x != start.x || loc.y != start.y&#41;
	&#123;
		start = loc;
		cout << "Room&#58;&#58;moveTo " << start.toString&#40;&#41; << endl;
		update&#40;&#41;;
	&#125;
&#125;
void Room&#58;&#58;moveTo&#40;float x, float y&#41;
&#123;
	moveTo&#40;Location&#40;x,y&#41;&#41;;
&#125;
ex:
Image
Image
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

why does the gu have these weird problems drawing those images because i see no reason there should be extra parts drawn. and if the image doesn't appear on the screen what does it matter if i draw it to the screen. that shouldn't slow it down any

edit: i made all the tiles the same size that was a power of 2 (256x256) and it fixed the problem with the gaps and the extra drawings but why is it that it has to be a power of two because it waste valuable ram =(
unsigned int
Posts: 18
Joined: Thu Aug 13, 2009 11:42 pm

Post by unsigned int »

I think the PSP only supports power of two textures. That is a limitation it shares with older graphics cards on the PC (e.g. there is an OpenGL extension ARB_texture_non_power_of_two from 2004 especially for supporting that).

You could further reduce the texture size to conserve memory.

If it slows down while moving, is it possible that you only do drawing when buttons get pressed? That would explain the speed difference. Not seeing the rest of the code I wonder if you maybe update the coordinates or draw the screen multiple times each frame instead of waiting for vsync.
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

i only update the coordinates and i posted the update code. Room::update is called which does the coordinates and then the gu is started and the canvas which holds all the images which holds all the coordinates draws the images based on whatever coordinates are set at that time.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Comment out the cout << lines and see what happens. :)
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

yeah their commented out

edit: it goes about 110 frames a second while not moving and 70 when moving. probably should have posted way earlier
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

How do textures 'waste space' if they have to be powers of two?

Jim
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Well, the main difference between standing still and moving appears to be InsidePolygon(). You might want to check that function. In particular, make sure you aren't doing any double-precision math anywhere. The PSP does that in software as it can only do single precision in hardware.
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

inside polygon uses floats and here is the function

Code: Select all

bool InsidePolygon&#40;Location* polygon, int N, Location p, int bound&#41;
&#123;
    //cross points count of x
    int __count = 0;

    //neighbour bound vertices
    Location p1, p2;

    //left vertex
    p1 = polygon&#91;0&#93;;

    //check all rays
    for&#40;int i = 1; i <= N; ++i&#41;
    &#123;
        //point is an vertex
        if&#40;p == p1&#41; return bound;

        //right vertex
        p2 = polygon&#91;i % N&#93;;

        //ray is outside of our interests
        if&#40;p.y < MIN&#40;p1.y, p2.y&#41; || p.y > MAX&#40;p1.y, p2.y&#41;&#41;
        &#123;
            //next ray left point
            p1 = p2; continue;
        &#125;

        //ray is crossing over by the algorithm &#40;common part of&#41;
        if&#40;p.y > MIN&#40;p1.y, p2.y&#41; && p.y < MAX&#40;p1.y, p2.y&#41;&#41;
        &#123;
            //x is before of ray
            if&#40;p.x <= MAX&#40;p1.x, p2.x&#41;&#41;
            &#123;
                //overlies on a horizontal ray
                if&#40;p1.y == p2.y && p.x >= MIN&#40;p1.x, p2.x&#41;&#41; return bound;

                //ray is vertical
                if&#40;p1.x == p2.x&#41;
                &#123;
                    //overlies on a ray
                    if&#40;p1.x == p.x&#41; return bound;
                    //before ray
                    else ++__count;
                &#125;

                //cross point on the left side
                else
                &#123;
                    //cross point of x
                    double xinters = &#40;p.y - p1.y&#41; * &#40;p2.x - p1.x&#41; / &#40;p2.y - p1.y&#41; + p1.x;

                    //overlies on a ray
                    if&#40;fabs&#40;p.x - xinters&#41; < __DBL_EPSILON__&#41; return bound;

                    //before ray
                    if&#40;p.x < xinters&#41; ++__count;
                &#125;
            &#125;
        &#125;
        //special case when ray is crossing through the vertex
        else
        &#123;
            //p crossing over p2
            if&#40;p.y == p2.y && p.x <= p2.x&#41;
            &#123;
                //next vertex
                const Location& p3 = polygon&#91;&#40;i+1&#41; % N&#93;;

                //p.y lies between p1.y & p3.y
                if&#40;p.y >= MIN&#40;p1.y, p3.y&#41; && p.y <= MAX&#40;p1.y, p3.y&#41;&#41;
                &#123;
                    ++__count;
                &#125;
                else
                &#123;
                    __count += 2;
                &#125;
            &#125;
        &#125;

        //next ray left point
        p1 = p2;
    &#125;

	bool INSIDE = true;
	bool OUTSIDE = false;
    //EVEN
    if&#40;__count % 2 == 0&#41; return&#40;OUTSIDE&#41;;
    //ODD
    else return&#40;INSIDE&#41;;
&#125;
and as for how it was space say the image size would have been 130x130 at the very least. that would mean that it's size would have to be 256x256 so i waste almost twice the space
User avatar
jbit
Site Admin
Posts: 293
Joined: Sat May 28, 2005 3:11 am
Location: København, Danmark
Contact:

Post by jbit »

coolkehon wrote:and as for how it was space say the image size would have been 130x130 at the very least. that would mean that it's size would have to be 256x256 so i waste almost twice the space
If you absolutely needed that size sprite then since this is 2d you'd just make the following textures: 128x128, 128x2, 2x128, and 2x2 then draw all four sprites at runtime. Most serious 2D engines will have an automated way to do this.
Working with systems requirements has always been a prerequisite of 2D art.
Last edited by jbit on Mon Aug 17, 2009 3:46 am, edited 1 time in total.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Code: Select all

                    //cross point of x
                    double xinters = &#40;p.y - p1.y&#41; * &#40;p2.x - p1.x&#41; / &#40;p2.y - p1.y&#41; + p1.x;

                    //overlies on a ray
                    if&#40;fabs&#40;p.x - xinters&#41; < __DBL_EPSILON__&#41; return bound;
Looks like double precision to me.
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

The other solution to the 'wasted' space problem is to use the blank area for other, smaller, graphics and use the texture coordinates to pick out the bits you want.

Jim
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

J.F. wrote:

Code: Select all

                    //cross point of x
                    double xinters = &#40;p.y - p1.y&#41; * &#40;p2.x - p1.x&#41; / &#40;p2.y - p1.y&#41; + p1.x;

                    //overlies on a ray
                    if&#40;fabs&#40;p.x - xinters&#41; < __DBL_EPSILON__&#41; return bound;
Looks like double precision to me.
oops i was trying another function and i posted it before i did find replace all fixed it
The other solution to the 'wasted' space problem is to use the blank area for other, smaller, graphics and use the texture coordinates to pick out the bits you want.

Jim
loading lots of images and unloading sometimes. this seems to complicated
coolkehon
Posts: 355
Joined: Mon Oct 20, 2008 5:44 am

Post by coolkehon »

the way i'm solving the texture problem is to resize the image file itself. is there another way i can solve this texture problem when loading and here is the function that loads a png. i tried always setting texture size to a power of two but that didn't work. why doesn't this work

Code: Select all

Image * ImageUtil&#58;&#58;loadImageFilePNG&#40;VirtualFile * fp, PixelFormat pixelFormat , bool swizzle, bool in_vram, DrawingCanvas * canvas&#41;
&#123;
	if&#40;fp == NULL || !is_png&#40;fp&#41;&#41; 
		return NULL;
	
	Image * rimg = new Image&#40;canvas&#41;;
	rimg->image = &#40;Image&#58;&#58;ImageData *&#41; malloc&#40;sizeof&#40;Image&#58;&#58;ImageData&#41;&#41;;
	if&#40;rimg->image == NULL&#41;
	&#123;
		rimg->Delete&#40;&#41;;
		return NULL;
	&#125;
	Image&#58;&#58;ImageData * image = rimg->image;
	memset&#40;image,0,sizeof&#40;Image&#58;&#58;ImageData&#41;&#41;;
	image->pixelFormat = pixelFormat;
	image->in_vram = in_vram;
	
	png_structp png_ptr;
	png_infop info_ptr;
	
	png_ptr = png_create_read_struct&#40;PNG_LIBPNG_VER_STRING,NULL,NULL,NULL&#41;;
	if&#40;png_ptr == NULL&#41;
	&#123;
		rimg->Delete&#40;&#41;;
		return NULL;
	&#125;
	info_ptr = png_create_info_struct&#40;png_ptr&#41;;
	if&#40;info_ptr == NULL&#41;
	&#123;
		rimg->Delete&#40;&#41;;
		png_destroy_read_struct&#40;&png_ptr, NULL, NULL&#41;;
		return NULL;
	&#125;
	if &#40;setjmp&#40;png_jmpbuf&#40;png_ptr&#41;&#41;&#41;
	&#123;
		png_destroy_read_struct&#40;&png_ptr, &info_ptr, NULL&#41;;
		rimg->Delete&#40;&#41;;
		return NULL;
	&#125;
	
	png_set_read_fn&#40;png_ptr,fp,&#40;png_rw_ptr&#41;ImageUtil_PNG_ReadFn&#41;;
//	png_init_io&#40;png_ptr, fp&#41;;
//	png_set_sig_bytes&#40;png_ptr, 8&#41;;
	
	if&#40;pixelWidths&#91;pixelFormat&#93; <= 8&#41;
	&#123;
		png_read_png&#40;png_ptr,info_ptr,
			PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_BGR, NULL &#41;;
	&#125;
	else
	&#123;
		png_read_png&#40; png_ptr, info_ptr, 
			PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_BGR, NULL &#41;;
	&#125;
	
	png_uint_32 width = info_ptr->width;
	png_uint_32 height = info_ptr->height;
	png_uint_32 depth = info_ptr->bit_depth;
	int color_type = info_ptr->color_type;
	
	png_byte **pRowTable = info_ptr->row_pointers;
	unsigned char r=0, g=0, b=0, a=0;
	int wantedPixelFormat = pixelFormat;
	if &#40;!info_ptr->num_palette && pixelWidths&#91;pixelFormat&#93; <= 8&#41;
	&#123;
		pixelFormat = GU_PSM_8888;
		image->pixelFormat = pixelFormat;
		image->in_vram = false;
	&#125;
	else
	&#123;
		image->pixelFormat = pixelFormat;
		image->in_vram = in_vram;
	&#125;
	image->width = width;
	image->height = height;
	image->swizzled = false;
	
	if&#40;image->width > 512&#41;
		image->textureWidth = image->width;
	else
		image->textureWidth = getNextPower2&#40;image->width&#41;;
	
	if&#40;image->height > 512&#41;
		image->textureHeight = image->height;
	else
		image->textureHeight = getNextPower2&#40;image->height&#41;;
	
	image->size = &#40;image->textureWidth * image->textureHeight * pixelWidths&#91;image->pixelFormat&#93;&#41; >> 3;
	if&#40;image->in_vram&#41;
		image->data = &#40;uint *&#41;valloc&#40;image->size&#41;;
	else
		image->data = &#40;uint *&#41;memalign&#40;16,image->size&#41;;
	
	if&#40;image->data == NULL&#41;
	&#123;
		png_destroy_read_struct&#40;&png_ptr, &info_ptr, NULL&#41;;
		rimg->Delete&#40;&#41;;
		return NULL;
	&#125;
	
	if&#40;pixelWidths&#91;pixelFormat&#93; <= 8&#41;
	&#123;
		image->palette = Image&#58;&#58;CreatePalette&#40;MIN&#40;info_ptr->num_palette, 1 << paletteSizes&#91;pixelFormat&#93;&#41;, in_vram, GU_PSM_8888&#41;;
		if&#40;image->palette == NULL&#41;
		&#123;
			png_destroy_read_struct&#40;&png_ptr, &info_ptr, NULL&#41;;
			rimg->Delete&#40;&#41;;
			return NULL;
		&#125;
		info_ptr->num_palette = MIN&#40;info_ptr->num_palette, image->palette->nentries&#41;;
		for&#40;int i = 0; i < info_ptr->num_palette; i++&#41;
		&#123;
			int r = info_ptr->palette&#91;i&#93;.red;
			int g = info_ptr->palette&#91;i&#93;.green;
			int b = info_ptr->palette&#91;i&#93;.blue;
			int a = 0xff;
		&#125;
		sceKernelDcacheWritebackInvalidateRange&#40;image->palette->data,image->palette->size&#41;;
	&#125;
	
	u32 *p_dest4 = &#40;u32*&#41;image->data;
	u16 *p_dest2 = &#40;u16*&#41;image->data;
	u8 *p_dest1 = &#40;u8*&#41;image->data;
	u32 x, y;
	int color_per_entry = 8 / depth;
	int color_offset, pixel_value = 0;
	int mask = &#40;1 << depth&#41; - 1;
	
	for &#40; y = 0; y < height; ++y &#41;
	&#123;
		const png_byte * pRow = pRowTable&#91;y&#93;;

		for &#40; x = 0; x < width; ++x &#41;
		&#123;
			switch &#40; color_type &#41;
			&#123;
				case PNG_COLOR_TYPE_GRAY&#58;
					r = g = b = *pRow++;
					if &#40; r == 0 && g == 0 && b == 0 &#41;
						a = 0x00;
					else
						a = 0xff;
					break;
				case PNG_COLOR_TYPE_GRAY_ALPHA&#58;
					r = g = b = *pRow++;
					if &#40; r == 0 && g == 0 && b == 0 &#41;
						a = 0x00;
					else
						a = 0xff;
					pRow++;
					break;
				case PNG_COLOR_TYPE_RGB&#58;
					b = *pRow++;
					g = *pRow++;
					r = *pRow++;
					a = 0xff;
					break;
				case PNG_COLOR_TYPE_RGB_ALPHA&#58;
					b = *pRow++;
					g = *pRow++;
					r = *pRow++;
					a = *pRow++;
					break;
			
				case PNG_COLOR_TYPE_PALETTE&#58;
					color_offset = x % color_per_entry;
					pixel_value = &#40;*pRow >> &#40;8 - depth * &#40;color_offset + 1&#41;&#41;&#41; & mask;
					
					if &#40;x % color_per_entry == color_per_entry - 1&#41;
						pRow++;
					if &#40;image->palette&#41;
					&#123;
						r = &#40;&#40;&#40;u32*&#41;image->palette->data&#41;&#91;pixel_value&#93;&#41; & 0xff;
						g = &#40;&#40;&#40;&#40;u32*&#41;image->palette->data&#41;&#91;pixel_value&#93;&#41; >> 8&#41; & 0xff;
						b = &#40;&#40;&#40;&#40;u32*&#41;image->palette->data&#41;&#91;pixel_value&#93;&#41; >> 16&#41; & 0xff;
						a = &#40;&#40;&#40;&#40;u32*&#41;image->palette->data&#41;&#91;pixel_value&#93;&#41; >> 24&#41; & 0xff;
					&#125;
					else	
					&#123;
						b = info_ptr->palette&#91;pixel_value&#93;.blue;
						g = info_ptr->palette&#91;pixel_value&#93;.green;
						r = info_ptr->palette&#91;pixel_value&#93;.red;
						a = 0xff;
					&#125;
					break;
			&#125;
			if &#40;pixelFormat == GU_PSM_8888&#41;
				p_dest4&#91;x&#93; = RGBA&#40;r,g,b,a&#41;;
			else if &#40;pixelFormat == GU_PSM_5650&#41;
				p_dest2&#91;x&#93; = RGB16&#40;r,g,b&#41;;
			else if &#40;pixelFormat == GU_PSM_5551&#41;
				p_dest2&#91;x&#93; = RGBA15&#40;r,g,b,a&#41;;
			else if &#40;pixelFormat == GU_PSM_4444&#41;
				p_dest2&#91;x&#93; = RGBA12&#40;r,g,b,a&#41;;
			else if &#40;pixelFormat == GU_PSM_T8&#41;
				p_dest1&#91;x&#93; = pixel_value;
			else if &#40;pixelFormat == GU_PSM_T4&#41;				
			&#123;
				p_dest1&#91;x >> 1&#93; &= ~&#40;15 << &#40;&#40;x & 1&#41; << 2&#41;&#41;;
				p_dest1&#91;x >> 1&#93; |= &#40;pixel_value & 15&#41; << &#40;&#40;x & 1&#41; << 2&#41;;
			&#125;
		&#125;

		p_dest1 += &#40; image->textureWidth * pixelWidths&#91;pixelFormat&#93;&#41; >> 3;
		p_dest2 += &#40; image->textureWidth &#41;;
		p_dest4 += &#40; image->textureWidth &#41;;
	&#125;
	
	sceKernelDcacheWritebackInvalidateRange&#40;image->data,image->size&#41;;
	rimg->setStart&#40;Location&#40;0,0&#41;&#41;;
	rimg->setEnd&#40;Location&#40;image->width,image->height&#41;&#41;;
//	TODO swizzle images and convert pixel formats
	if&#40;wantedPixelFormat != pixelFormat&#41;
		rimg = ImageUtil&#58;&#58;convertImageTo&#40;rimg,in_vram,wantedPixelFormat&#41;;
	if&#40;swizzle&#41;
		rimg->swizzle&#40;&#41;;
	png_destroy_read_struct&#40;&png_ptr, &info_ptr, NULL&#41;;
	return rimg;
&#125;
Post Reply