PDA

View Full Version : Question about textured polys as background (color bleeding)



Snatcher
February 11th, 2011, 06:25
I need some help figuring out why there is some bleeding or banding in my textures using KallistiOS directly. I previously used SDL and everything worked fine with BMP as my source for images, but unfortunately it was too slow for my needs and I decided to switch my drawing layer to using the PVR directly.

I ended up using PNG, here is the code I am using to test these functions:



if(png_load_texture(filename, &image->tex, PNG_MASK_ALPHA, &image->tw, &image->th) == -1)
{
free(image);
fprintf(stderr, "Could not load %s\n", filename);
return(NULL);
}

...

pvr_poly_cxt_t cxt;
pvr_poly_hdr_t hdr;
pvr_vertex_t vert;


pvr_poly_cxt_txr(&cxt, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB1555, image->tw, image->th, image->tex, 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 = image->x;
vert.y = image->y;
vert.z = image->layer;
vert.u = 0.0;
vert.v = 0.0;
pvr_prim(&vert, sizeof(vert));

vert.x = image->x + image->w;
vert.y = image->y;
vert.z = image->layer;
vert.u = 1.0;
vert.v = 0.0;
pvr_prim(&vert, sizeof(vert));

vert.x = image->x;
vert.y = image->y + image->h;
vert.z = image->layer;
vert.u = 0.0;
vert.v = 1.0;
pvr_prim(&vert, sizeof(vert));

vert.x = image->x + image->w;
vert.y = image->y + image->h;
vert.z = image->layer;
vert.u = 1.0;
vert.v = 1.0;
vert.flags = PVR_CMD_VERTEX_EOL;
pvr_prim(&vert, sizeof(vert));
}



Quite typical as you can see. I am using 320x240 and PM_RGB565, and loading a png that is 512x256, but only 320x240 pixels have my actual image, the rest have alpha. I am drawing a polygon that is 512x256 located at 0, 0 with the code above and the texture I am using is not showing properly.. that is, it has some banding, bleeding or form of distortion. As stated above, when using SDL it displays perfectly. I am wondering if I am doing something wrong or expecting the wrong thing. I simply want pixel perfect rendering of the texture to the screen. I am using either VGA or RGB via an XRGB-3 for display, so I know that the problem is somewhere in my code or expectations.

http://farm6.static.flickr.com/5254/5435688864_dafea51e14_z.jpg (http://www.flickr.com/photos/artemiourbina/5435688864/)
20110211_004.jpg (http://www.flickr.com/photos/artemiourbina/5435688864/)
Close-up photo from LCD displayed via SDL

http://farm6.static.flickr.com/5176/5435687722_c38847f4df_z.jpg (http://www.flickr.com/photos/artemiourbina/5435687722/)
20110211_003.jpg (http://www.flickr.com/photos/artemiourbina/5435687722/)
Same are close up on same LCD and scaler, using the above code

Thanks for your help.

BlueCrab
February 11th, 2011, 15:12
Well, I know this probably won't have the least bit of an effect, on the output, but you should probably be using the Punchthru list for the polygon, rather than the translucent list for it. When you have a one-bit alpha, you're wasting processing time to use the translucent list, which does full alpha blending.

Also, I'm somewhat confused by what you're trying to do with it... I see that image->tw and image->th are the width and height of the texture itself, but what are image->w and image->h? Are they supposed to be the width/height of the result? Are you absolutely sure they're exactly the same as image->tw and image->th (since if they differ, that would explain the bleeding of the image, quite possibly). I really can't say that much more without seeing more code to demonstrate the problem (perhaps with something I could actually compile and run to try out different things to see if the problem goes away).

One thing I have to ask, was that picture taken via a VGA box or RGB/SCART? If it was via RGB, I might have an idea of how you might be able to fix it, but if it was via a VGA box, that idea would be out the window...

Snatcher
February 11th, 2011, 16:06
Thanks for thr reply BlueCrab, here is my code in a tar.gz including Makefile and png, I removed all other stuff that wasn't needed and I get the same result.

http://www.megaupload.com/?d=2VG46VIP

Indeed, tw and w are the same.

I am using both the RGB out right now, with an XRGB-3 upscaler and the VGA box; Indeed this only happens when I use the RGB cable. Of course this doesn't happen when I use the RGB cable with the same code using SDL.

BlueCrab
February 11th, 2011, 18:01
Aha! So, I'm pretty sure I know what's wrong if its only happening with the RGB Cable. When using any output other than VGA, KOS sets up a deflicker filter on the PVR. The filter is only in effect when the 3D hardware is active, and only for what it draws (so hence why you never saw it with SDL). Try putting this line of code right after you init the PVR (before you do any other drawing related calls):


PVR_SET(PVR_SCALER_CFG, 0x400);
That should turn off the deflicker filter, which will hopefully deal with the non-sharp lines you have. I haven't tested it with the exact code you're using, but I believe it should work.

EDIT: Actually, it looks like for some reason the link you provided to your code isn't right (or something's up with megaupload), as I keep getting "The file you are trying to access is temporarily unavailable. Please try again later." when I try.

Snatcher
February 12th, 2011, 18:00
That fixed it indeed. Does this have any side effects? Anything I should reset the PVR at some time? during my app I will change resolution to 480i at some points, I am guessing I will need to do the same after that again?

I am also guessing that pvr_wait_ready is what I need instead of vid_waitvbl. I will be rendering some textures full screen this way and alternating them each frame.

Thanks for your help.

BlueCrab
February 12th, 2011, 19:56
Well, the deflicker filter is there to reduce any flickering effects from using an interlaced video mode. On most modern TVs, its probably unnecessary, but I've never really looked at how things look without it. Any time you reset the PVR, you must run that line of code again, and you probably need to do so every time you change the resolution.

Also, yes, pvr_wait_ready() is what you should be using instead of vid_waitvbl().

Snatcher
February 13th, 2011, 04:15
A few more questions if you don't mind BlueCrab...

I attach code again, hopefully this time the download will work for you.


http://www.mediafire.com/?u7d28rxph4p38u7

When in VGA mode, there are some pixels that are lighter every other line.. as in a grid. This wasn't noticeable with the black background pattern.. but with the attached png one in the romdisk of this example, a solid color, it is very noticeable. Again, this doesn't happen when I use SDL.

And my other uestion is that, when using RGB with this same code, I get a white background evn though I set pvr_set_bg_color(0.0f, 0.0f, 0.0f), any ideas why this happens? Again, this doesn't happen when using SDL.

Sorry about being a pain here =P

Best Regards and thanks for all your help.

BlueCrab
February 13th, 2011, 04:43
The first problem there is that the PVR also has a dithering feature that KOS by default turns on. Its not really a problem in 640x480 mode, but it can cause the artifacts you're seeing in 320x240 mode. (Note, that I don't believe Sega officially "supported" 320x240 mode on the Dreamcast; hence why you see all kinds of odd artifacts with 320x240 that you wouldn't be able to see in 640x480)

To turn off the dithering, its another PVR register set (KOS sets this to 0x00000009 by default):

PVR_SET(PVR_FB_CFG_2, 0x00000001);

As for the other thing, I'm not entirely sure what you're talking about with regard to the background color? Are you saying you're getting a white background with that code if you comment out the call to the DrawImage() function? I can say that I'm certainly not getting a white background when I do that on my end, so I'm thinking maybe I'm just misunderstanding what you're asking...

Also, its always nice to have new developers (that are serious about doing stuff, anyway) around, so its not really a pain.

Random sidenote, but at some point I should throw together some information about the PVR registers and put it up somewhere, since there's so little documentation about it that's useful...

Snatcher
February 13th, 2011, 05:28
PVR_SET(PVR_FB_CFG_2, 0x00000001);


Worked like a charm, thanks!



As for the other thing, I'm not entirely sure what you're talking about with regard to the background color? Are you saying you're getting a white background with that code if you comment out the call to the DrawImage() function? I can say that I'm certainly not getting a white background when I do that on my end, so I'm thinking maybe I'm just misunderstanding what you're asking...


Indeed, I expressed myself in the wrong terms. I mean the area "outside" the screen, the one that is filled with white and black "stripes" when sending data via serial for instance. When viewing the video signal either via VGA or RGB, I get that white "overscan" around the image (I can only use RGB though the linedoubler). UPDATE: This stopped happening right now for me... strange, I was getting it all the time. UPDATE 2: AHA! It happens when I set the
PVR_SET(PVR_SCALER_CFG, 0x400); and not the PVR_SET(PVR_FB_CFG_2, 0x00000001);
since I am setting both now it doesn't appear. I hope it won't show it's ugly face around any more...




Also, its always nice to have new developers (that are serious about doing stuff, anyway) around, so its not really a pain.


Thanks man, it is not much of an app.. but I am betting it will be useful for the community that is interested in retrogaming on LCD and VGA displays, for evaluating upscalers and TV processors when handling 320x240 and 480i as well. At least more so than the Sega Genesis version since it is easier to get homebrew running of a DC.

Thanks again

BlueCrab
February 13th, 2011, 18:27
That border area is set by the serial loader, its really the luck of the draw what color it'll end up in the end. The PVR code doesn't touch it at all. You can do this to change the color back to black (the arguments are the red, green, and blue components, from 0-255):

vid_border_color(0, 0, 0);

Snatcher
February 13th, 2011, 22:19
Thanks =)

Just finished my port up to the way it was with SDL (and on the Genesis), also added Purupuru and VMU LCD support in the process. Will be beta testing the features within the upscaler community, and later I plan to release the source code in case anyone can benefit from that. Ended up using Parallax for txf fonts, the rest is pure KOS.

Of course you are mentioned in the Credits section of the small project. I still expect to add some extra features, but in case I have doubts I will be posting here sooner. Otherwise I will post the links to the code and cdi images here later on.

Thanks for everything.

BlueCrab
February 14th, 2011, 00:14
Heh, glad to hear that you got everything working. Be sure to link to it when all is done.

Snatcher
February 19th, 2011, 07:23
Here's a link to the page for the software:

http://junkerhq.net/xrgb/index.php/240p_test_suite

Links to a CDI image and the source code are available there as well.