Loading an Image with PVR

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
EnigmaticCoder
DCEmu Crazy Poster
DCEmu Crazy Poster
Posts: 36
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Tue Nov 03, 2009 6:02 pm
Has thanked: 0
Been thanked: 0

Loading an Image with PVR

Post by EnigmaticCoder »

I've been using pvr to load my images. This aspect of the game has been working fine up until the time I started using big images (1024 X 512). Firstly, I'd like to know if my drawImage function is correct. In the function, the images had to be the same width and height previously, but I changed that. I don't know if that's the problem or not. Here's the function:

Code: Select all

void drawImage(const pvr_ptr_t &image, float x, float y, float layer, float width, float height)
{
    size_t size = 2;
    size_t size2 = 2;
    for (size = 2; size < width; size *= 2);
    for (size2 = 2; size2 < height; size2 *= 2);

    pvr_poly_cxt_t cxt;
    pvr_poly_hdr_t hdr;
    pvr_vertex_t vert;

    //pvr_poly_cxt_txr(&cxt, PVR_LIST_PT_POLY, PVR_TXRFMT_ARGB1555, size, size2, image, PVR_FILTER_NONE);
    pvr_poly_cxt_txr(&cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB4444, size, size2, image, PVR_FILTER_NONE);
    pvr_poly_compile(&hdr, &cxt);
    pvr_prim(&hdr, sizeof(hdr));

    vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);    
    vert.oargb = 0;
    vert.flags = PVR_CMD_VERTEX;
    
    vert.x = x;
    vert.y = y;
    vert.z = layer;
    vert.u = 0.0;
    vert.v = 0.0;
    pvr_prim(&vert, sizeof(vert));
    
    vert.x = x + width;
    vert.y = y;
    vert.z = layer;
    vert.u = width / size;
    vert.v = 0.0;
    pvr_prim(&vert, sizeof(vert));
    
    vert.x = x;
    vert.y = y + height;
    vert.z = layer;
    vert.u = 0.0;
    vert.v = height / size2;
    pvr_prim(&vert, sizeof(vert));
    
    vert.x = x + width;
    vert.y = y + height;
    vert.z = layer;
    vert.u = width / size;
    vert.v = height / size2;
    vert.flags = PVR_CMD_VERTEX_EOL;
    pvr_prim(&vert, sizeof(vert));
}
I wanted to make sure that I wasn't using too much memory, so I printed pvr_mem_available(). It returned with 168.

Code: Select all

void initTitleScreen(pvr_ptr_t &titleScreenImage, pvr_ptr_t &cursorImage)
{
	loadImage(&titleScreenImage, IMAGE_PATH_TITLE_SCREEN,
		IMAGE_WIDTH_TITLE_SCREEN, IMAGE_HEIGHT_TITLE_SCREEN);

	if(!titleScreenImage)
		exit(EXIT_FAILURE);

	loadImage(&cursorImage, IMAGE_PATH_CURSOR,
		IMAGE_WIDTH_CURSOR, IMAGE_HEIGHT_CURSOR);

	if(!cursorImage)
		exit(EXIT_FAILURE);

	dbglog(DBG_DEBUG, "%i\n", pvr_mem_available());
}
The problem is that after my game runs and returns to the title screen, the cursor has a bunch of garbage next to it (it's a 32 x 32 image). What are the potential causes of garbage being shown? Is anything wrong with my functions?
BlackAura
DC Developer
DC Developer
Posts: 9951
Joined: Sun Dec 30, 2001 9:02 am
Has thanked: 0
Been thanked: 1 time

Re: Loading an Image with PVR

Post by BlackAura »

The image drawing function looks OK. Unless there's some subtle bug there that I'm not seeing, it should work just fine.

As far as I remember, pvr_mem_available returns the number of bytes available. A value of 168 would suggest that you've basically run out of video memory somehow.

The DC has 8MB of video memory. That memory doesn't just contain textures. It also has to contain two complete framebuffers (one containing the current frame, which is being rendered into, and the other containing the previous frame, which is being displayed on-screen), and two complete frame descriptions containing vertex buffers and the like (one containing the current frame, which the PVR is reading from, and one containing the next frame, which your program is writing to). That chews up something like 3MB of VRAM before you've even started to draw something, leaving you with somewhat less than 5MB of texture memory available.

A single 1024x512 texture, at 16bpp, uses 1MB of texture memory all by itself. Just five of those would leave you with no video memory left at all. Since the screen is only 640x480, a 1024x512 texture is probably overkill anyway. You might try using some of that wasted space to store smaller textures, or using smaller textures and stitching them together - a 512x512 texture and a 128x512 texture together could contain a 640x480 image, while using only 640KB of VRAM instead of 1MB. Depending on the actual image you're using, a 512-wide texture stretched to 640 wide will probably look just fine anyway, and would use only 512KB.

Image corruption would probably suggest that the video memory allocated for the texture in question has been overwritten with something else. It depends on how your image loading works, but it's possible that another texture was partially loaded over the top of the corrupted one.
EnigmaticCoder
DCEmu Crazy Poster
DCEmu Crazy Poster
Posts: 36
Joined: Tue Nov 03, 2009 6:02 pm
Has thanked: 0
Been thanked: 0

Re: Loading an Image with PVR

Post by EnigmaticCoder »

You're very knowledgeable about this stuff!

Anyways, I was following your advice, changing all my dimensions to 512 x 512, and then I found the bug. I set the cursor's width to 640! Thanks for your help!
Post Reply