Maximum Texture Size
Maximum Texture Size
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
edit: just tried it and it doesn't work on an image that is 992x504 so how can i fix this / work around it
-
- Posts: 388
- Joined: Tue Aug 12, 2008 12:46 am
Re: Maximum Texture Size
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.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
PSHN - Playstation Hacking Network
PSX/PS1 - HACK - Game Shark
PS2 - HACK - Swap
PSP - HACK - Pandora
PS3 - ?
PSX/PS1 - HACK - Game Shark
PS2 - HACK - Swap
PSP - HACK - Pandora
PS3 - ?
-
- Posts: 91
- Joined: Sun Feb 22, 2009 8:32 am
- Location: Melbourne Australia ZOMG
i read somewhere the maximum size was 512x512 px
Code: Select all
int main(){
SetupCallbacks();
makeNiceGame();
sceKernelExitGame();
}
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
http://www.sprites-inc.co.uk/files/EXE/ ... Falzer.png
You can split the image in seperate parts.
BTW:
Why can't that image be tiled?
Code: Select all
|--------|--------|
| | |
| 1 | 2 |
| | |
|--------+--------|
| | |
| 3 | 4 |
| | |
|--------|--------|
Why can't that image be tiled?
Code: Select all
int main(){
SetupCallbacks();
makeNiceGame();
sceKernelExitGame();
}
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();
}
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(vector<Image *>::iterator it = tiles.begin();
it != tiles.end();
it++)
{
if((*it) != NULL)
{
(*it)->moveTo(loc);
loc.x += (*it)->getWidth();
// cout << "Loc: " << loc.toString() << endl;
if(++fnum_w >= frames_wide )
{
fnum_w = 0;
if(++fnum_h >= frames_high)
break;
loc.x = start.x;
loc.y += (*it)->getHeight();
}
}
}
Did you swizzle the images? (Enormous speedup)
How big is the gap between the parts?
How big is the gap between the parts?
Code: Select all
int main(){
SetupCallbacks();
makeNiceGame();
sceKernelExitGame();
}
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
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
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
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
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
this is Room::moveTo
ex:
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(controls.held() & PSP_CTRL_RIGHT)
{
if(InsidePolygon(points.data(),points.size(),Location(next.x+speedx,next.y)) )
next.x += speedx;
}
if(controls.held() & PSP_CTRL_LEFT)
{
if(InsidePolygon(points.data(),points.size(),Location(next.x-speedx,next.y)))
next.x -= speedx;
}
if(controls.held() & PSP_CTRL_UP)
{
if(InsidePolygon(points.data(),points.size(),Location(next.x,next.y-speedy)))
next.y -=speedy;
}
if(controls.held() & PSP_CTRL_DOWN)
{
if(InsidePolygon(points.data(),points.size(),Location(next.x,next.y+speedy)))
next.y += speedy;
}
lan_walk->update();
if(next.x != lan_loc.x || next.y != lan_loc.y)
{
lan_loc = next;
// lan_hp.moveTo((480.0f/2.0f)-lan_loc.x,(272.0f/2.0f)-lan_loc.y);
lan_hp.moveTo(240.0f-lan_loc.x,136-lan_loc.y);
}
Code: Select all
void Room::update()
{
Location loc = start;
uint fnum_w = 0, fnum_h = 0;
for(vector<Image *>::iterator it = tiles.begin();
it != tiles.end();
it++)
{
if((*it) != NULL)
{
(*it)->moveTo(loc);
cout << "Loc: " << loc.toString() << endl;
loc.x += (*it)->getWidth();
if(++fnum_w >= frames_wide )
{
fnum_w = 0;
if(++fnum_h >= frames_high)
break;
loc.x = start.x;
loc.y += (*it)->getHeight();
}
}
}
}
void Room::moveTo(Location loc)
{
if(loc.x != start.x || loc.y != start.y)
{
start = loc;
cout << "Room::moveTo " << start.toString() << endl;
update();
}
}
void Room::moveTo(float x, float y)
{
moveTo(Location(x,y));
}
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 =(
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 =(
-
- Posts: 18
- Joined: Thu Aug 13, 2009 11:42 pm
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.
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.
inside polygon uses floats and here is the function
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
Code: Select all
bool InsidePolygon(Location* polygon, int N, Location p, int bound)
{
//cross points count of x
int __count = 0;
//neighbour bound vertices
Location p1, p2;
//left vertex
p1 = polygon[0];
//check all rays
for(int i = 1; i <= N; ++i)
{
//point is an vertex
if(p == p1) return bound;
//right vertex
p2 = polygon[i % N];
//ray is outside of our interests
if(p.y < MIN(p1.y, p2.y) || p.y > MAX(p1.y, p2.y))
{
//next ray left point
p1 = p2; continue;
}
//ray is crossing over by the algorithm (common part of)
if(p.y > MIN(p1.y, p2.y) && p.y < MAX(p1.y, p2.y))
{
//x is before of ray
if(p.x <= MAX(p1.x, p2.x))
{
//overlies on a horizontal ray
if(p1.y == p2.y && p.x >= MIN(p1.x, p2.x)) return bound;
//ray is vertical
if(p1.x == p2.x)
{
//overlies on a ray
if(p1.x == p.x) return bound;
//before ray
else ++__count;
}
//cross point on the left side
else
{
//cross point of x
double xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
//overlies on a ray
if(fabs(p.x - xinters) < __DBL_EPSILON__) return bound;
//before ray
if(p.x < xinters) ++__count;
}
}
}
//special case when ray is crossing through the vertex
else
{
//p crossing over p2
if(p.y == p2.y && p.x <= p2.x)
{
//next vertex
const Location& p3 = polygon[(i+1) % N];
//p.y lies between p1.y & p3.y
if(p.y >= MIN(p1.y, p3.y) && p.y <= MAX(p1.y, p3.y))
{
++__count;
}
else
{
__count += 2;
}
}
}
//next ray left point
p1 = p2;
}
bool INSIDE = true;
bool OUTSIDE = false;
//EVEN
if(__count % 2 == 0) return(OUTSIDE);
//ODD
else return(INSIDE);
}
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.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
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.
Code: Select all
//cross point of x
double xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
//overlies on a ray
if(fabs(p.x - xinters) < __DBL_EPSILON__) return bound;
oops i was trying another function and i posted it before i did find replace all fixed itJ.F. wrote:Looks like double precision to me.Code: Select all
//cross point of x double xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x; //overlies on a ray if(fabs(p.x - xinters) < __DBL_EPSILON__) return bound;
loading lots of images and unloading sometimes. this seems to complicatedThe 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
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::loadImageFilePNG(VirtualFile * fp, PixelFormat pixelFormat , bool swizzle, bool in_vram, DrawingCanvas * canvas)
{
if(fp == NULL || !is_png(fp))
return NULL;
Image * rimg = new Image(canvas);
rimg->image = (Image::ImageData *) malloc(sizeof(Image::ImageData));
if(rimg->image == NULL)
{
rimg->Delete();
return NULL;
}
Image::ImageData * image = rimg->image;
memset(image,0,sizeof(Image::ImageData));
image->pixelFormat = pixelFormat;
image->in_vram = in_vram;
png_structp png_ptr;
png_infop info_ptr;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
if(png_ptr == NULL)
{
rimg->Delete();
return NULL;
}
info_ptr = png_create_info_struct(png_ptr);
if(info_ptr == NULL)
{
rimg->Delete();
png_destroy_read_struct(&png_ptr, NULL, NULL);
return NULL;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
rimg->Delete();
return NULL;
}
png_set_read_fn(png_ptr,fp,(png_rw_ptr)ImageUtil_PNG_ReadFn);
// png_init_io(png_ptr, fp);
// png_set_sig_bytes(png_ptr, 8);
if(pixelWidths[pixelFormat] <= 8)
{
png_read_png(png_ptr,info_ptr,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_BGR, NULL );
}
else
{
png_read_png( png_ptr, info_ptr,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_BGR, NULL );
}
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 (!info_ptr->num_palette && pixelWidths[pixelFormat] <= 8)
{
pixelFormat = GU_PSM_8888;
image->pixelFormat = pixelFormat;
image->in_vram = false;
}
else
{
image->pixelFormat = pixelFormat;
image->in_vram = in_vram;
}
image->width = width;
image->height = height;
image->swizzled = false;
if(image->width > 512)
image->textureWidth = image->width;
else
image->textureWidth = getNextPower2(image->width);
if(image->height > 512)
image->textureHeight = image->height;
else
image->textureHeight = getNextPower2(image->height);
image->size = (image->textureWidth * image->textureHeight * pixelWidths[image->pixelFormat]) >> 3;
if(image->in_vram)
image->data = (uint *)valloc(image->size);
else
image->data = (uint *)memalign(16,image->size);
if(image->data == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
rimg->Delete();
return NULL;
}
if(pixelWidths[pixelFormat] <= 8)
{
image->palette = Image::CreatePalette(MIN(info_ptr->num_palette, 1 << paletteSizes[pixelFormat]), in_vram, GU_PSM_8888);
if(image->palette == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
rimg->Delete();
return NULL;
}
info_ptr->num_palette = MIN(info_ptr->num_palette, image->palette->nentries);
for(int i = 0; i < info_ptr->num_palette; i++)
{
int r = info_ptr->palette[i].red;
int g = info_ptr->palette[i].green;
int b = info_ptr->palette[i].blue;
int a = 0xff;
}
sceKernelDcacheWritebackInvalidateRange(image->palette->data,image->palette->size);
}
u32 *p_dest4 = (u32*)image->data;
u16 *p_dest2 = (u16*)image->data;
u8 *p_dest1 = (u8*)image->data;
u32 x, y;
int color_per_entry = 8 / depth;
int color_offset, pixel_value = 0;
int mask = (1 << depth) - 1;
for ( y = 0; y < height; ++y )
{
const png_byte * pRow = pRowTable[y];
for ( x = 0; x < width; ++x )
{
switch ( color_type )
{
case PNG_COLOR_TYPE_GRAY:
r = g = b = *pRow++;
if ( r == 0 && g == 0 && b == 0 )
a = 0x00;
else
a = 0xff;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
r = g = b = *pRow++;
if ( r == 0 && g == 0 && b == 0 )
a = 0x00;
else
a = 0xff;
pRow++;
break;
case PNG_COLOR_TYPE_RGB:
b = *pRow++;
g = *pRow++;
r = *pRow++;
a = 0xff;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
b = *pRow++;
g = *pRow++;
r = *pRow++;
a = *pRow++;
break;
case PNG_COLOR_TYPE_PALETTE:
color_offset = x % color_per_entry;
pixel_value = (*pRow >> (8 - depth * (color_offset + 1))) & mask;
if (x % color_per_entry == color_per_entry - 1)
pRow++;
if (image->palette)
{
r = (((u32*)image->palette->data)[pixel_value]) & 0xff;
g = ((((u32*)image->palette->data)[pixel_value]) >> 8) & 0xff;
b = ((((u32*)image->palette->data)[pixel_value]) >> 16) & 0xff;
a = ((((u32*)image->palette->data)[pixel_value]) >> 24) & 0xff;
}
else
{
b = info_ptr->palette[pixel_value].blue;
g = info_ptr->palette[pixel_value].green;
r = info_ptr->palette[pixel_value].red;
a = 0xff;
}
break;
}
if (pixelFormat == GU_PSM_8888)
p_dest4[x] = RGBA(r,g,b,a);
else if (pixelFormat == GU_PSM_5650)
p_dest2[x] = RGB16(r,g,b);
else if (pixelFormat == GU_PSM_5551)
p_dest2[x] = RGBA15(r,g,b,a);
else if (pixelFormat == GU_PSM_4444)
p_dest2[x] = RGBA12(r,g,b,a);
else if (pixelFormat == GU_PSM_T8)
p_dest1[x] = pixel_value;
else if (pixelFormat == GU_PSM_T4)
{
p_dest1[x >> 1] &= ~(15 << ((x & 1) << 2));
p_dest1[x >> 1] |= (pixel_value & 15) << ((x & 1) << 2);
}
}
p_dest1 += ( image->textureWidth * pixelWidths[pixelFormat]) >> 3;
p_dest2 += ( image->textureWidth );
p_dest4 += ( image->textureWidth );
}
sceKernelDcacheWritebackInvalidateRange(image->data,image->size);
rimg->setStart(Location(0,0));
rimg->setEnd(Location(image->width,image->height));
// TODO swizzle images and convert pixel formats
if(wantedPixelFormat != pixelFormat)
rimg = ImageUtil::convertImageTo(rimg,in_vram,wantedPixelFormat);
if(swizzle)
rimg->swizzle();
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return rimg;
}