I made a small test to draw a splash screen for my game using this code:
from direct.gui.DirectGui import *
splashScreen = DirectLabel(image="splash.png", scale=(1.333,1,1))
The splash.png image is 800x600 and so is the game screen. The problem i have is that the screen is rendered too much blured compared to the original image (like if a gimp Blur filter was applied to it).
Increasing the image resolution will reduce the problem but i would prefer if there was some trick to disable this Blur effect. Any idea how this can be done?
Interesting! My hunch would be that you are getting an unexpected distortion applied to your image card (“blurred” almost always means that the texture card doesn’t match the original texture size). Are you sure you’re running at 800x600? How do you guarantee this size?
The only thing i changed from the original Config.prc is the full screen flag, so im running the game in 800x600. The splash screen image is also 800x600 but in the test demo above it gets rendered as a square with gray borders at the left and right. Thats why i have to scale it by (1.333,1,1).
This is the original splash screen image:
And this is the image in game from a screenshot taken with Fraps:
If you zoom into the star icon or the gray lines that mark disabled buttons you will see that a very strong bluring was applied. Any idea how this hapened?
The issue is that the non-uniform scaling you’ve used is slightly off of the aspect ratio. Scaling by 1.333 is not quite right, because the aspect ratio for 800x600 is actually 1.3333333333333… So scaling by 1.333 makes the texture cover 799.79999999999995 pixels, not 800. Since the original images is 800 pixels wide, the render engine has to interpolate between pixels, and you get a slight blurring.
There are a couple of ways to solve this problem, but in this specific instance the most elegant way is probably to create your label as a child of the render2d tree, instead of the default aspect2d:
splashScreen = DirectLabel(parent=render2d, image="splash.png")
The render2d tree is exactly like aspect2d, except the coordinates are defined so that (-1,1) are the screen-edge to screen-edge bounds. So in that space, you get an image of correct ratio without scaling. If you need your object in the aspect2d tree, you can follow the command above with splashScreen.wrtReparentTo(aspect2d).
I hope that helps! Definitely post again if you have any more questions.
Best of luck,
Thanks for the feedback. This is what i tried, with and without reparenting:
from direct.gui.DirectGui import *
splashScreen = DirectLabel(parent=render2d, image="StartMenux1.png")
I didn’t notice any change. The image is still being blured.
Since you are interested in helping could you try this code in your computer with the first image (the non-blured one) i linked above to see if it happens the same thing to you?
This is the configuration file im using. Like i said i only changed to fullscreen.
### Panda3D Configuration File - User-Editable Portion ###
# Uncomment one of the following lines to choose whether you should
# run using OpenGL or DirectX rendering.
# These control the placement and size of the default rendering window.
win-origin 50 50
win-size 800 600
# Uncomment this line if you want to run Panda fullscreen instead of
# in a window.
# If you don't object to running OpenGL in software leave the keyword
# "software" in the following line, otherwise remove it to force
# hardware only.
framebuffer-mode rgba double-buffer depth hardware
# These control the amount of output Panda gives for some various
# categories. The severity levels, in order, are "spam", "debug",
# "info", "warning", and "fatal"; the default is "info". Uncomment
# one (or define a new one for the particular category you wish to
# change) to control this output.
# These specify where model files may be loaded from. You probably
# want to set this to a sensible path for yourself. $THIS_PRC_DIR is
# a special variable that indicates the same directory as this
# particular Config.prc file.
# This enable the automatic creation of a TK window when running
# Enable/disable performance profiling tool and frame-rate meter
# Enable audio using the FMod audio library by default:
# The new version of panda supports hardware vertex animation, but it's not quite ready
remember the power of 2…
i’m thorwing in my thought. dont know it this aplly do buttons and such… but could it be that the graficcard (or whatever else) is rescaleing the image to a texture of the size of power of 2?
if thats the case you might load a 800x600 image but it would be scaled to a 512x512 which again would look blured due to texture filters makeing up for the lower resolution.
just my 2 cents… since i dont think that 0,3% scaleing error would mess things up like this.
try a 512x512 textures or try 4 of them. lots of older games are using lots of small 128x128 textures to build the menue background. 512x512 should be ok for todays hardware.
That worked!! It’s still a bit blurred after rescaling from 800x600 to 1024x1024 but thats not pandas fault. Gimp does a much better job at rescaling than graphics cards aparently. I should have noticed that the airblade demo used 1024x1024 splash screens.
“512x512 should be ok for todays hardware.”
Do you think that a 1024 size textures may not run on some old hardware? I will use 512 just for sure.
well depends on the tatgeting hardware. if you have “really” old hardware like voodoo series you might be better off with 265 or even 128er tiles…
i think the texture limit of my geforce4ti is at 4096
512 should be fine as long as you don’t own a card from the early last century.
just put a line into the readme telling :" if you have a very old graficcard and cant see any menu,… " or something like this.
bdw… you could avoid scaleing if you just take you 800x600 image and add a black border on the right and bottom to make it 1024x1024 (same with 512er tiles). (in case that the user is forced to play in 800x600… more would blur your menue again)
I don’t know how DirectLabel treats the image. If the blur is all over the image, it maybe the texture filtering result.
Have you ever tried directly texturize a fullscreen card (parented to render2d) with your image (800x600) ?
The default when you firstly texturize the card is no filtering, so your splash screen image will remain as the original image.
Wow, this seems complicated!
Oversampling the image will work, I’m sure. But I’m afraid about doing that in our project: we’re already getting close to upwards of 100 megs of texture data lying around in memory, and I’d like to avoid unnecessarily large textures where at all possible.
Is there any way to force Panda to direct-throughput my image with no scaling? As in, I give it an X-and Y-pixel coordinate, and it just slams it down? It’s unfortunate that in this case, the 3D-acceleration system actually seems to be getting in the way of the simple 2D graphics
If, and only if, you have a recent graphics card that supports non-power-of-2 textures, you can turn off Panda’s default texture rescaling by putting the following in your Config.prc file:
Then you can load your 800x600 texture and display it exactly as an 800x600 texture.
If that doesn’t work, you could alternatively use:
which would implicity upscale the texture for you, instead of the default behavior of downscaling it, so that it will at least have the same quality level it started with. Of course, it will consume more texture memory in this mode.
The most-likely-to-succeed-on-any-hardware alternative has already been suggested: put your texture in the lower-left 800x600 corner of a 1024x1024 texture, and make your UV’s range from (0,0) in the lower left to (800/1024, 600/1024) in the upper right–instead of (1, 1) in the upper right.
Note that 3-D hardware has historically supported only power-of-2 textures, because it is much easier to apply 3-d manipulations to textures of this nature. Even the more recent cards that relax this limitation still don’t support the full range of 3-D operations on these non-power-of-2 textures. Furthermore, OpenGL specifically states that it is not “pixel accurate”: that is, the OpenGL spec makes no promises that your texture will ever be displayed pixel-for-pixel the way that you painted it. In practice, it can be, of course, but the point is that OpenGL allows the graphics cards manufacturers to be sloppy.
Short answer: 3-D ain’t 2-D. They’re converging, more and more rapidly, but there’s still a broad gulf between things that are easy in 2-D and things that are easy in 3-D.
Excellent; thank you for the clarification!
In our specific instance, the texture was too dark; I had previously incorrectly assumed that it was darkened by blurring (the text has a noisy background, so blur would bring it towards neutral gray). But I realized later that the DirectFrames we’re using to display images default to a frameColor of (.8,.8,.8,1). Resetting them to white cleaned up the images enough to be seen without eye-strain; I think the tiny amount of blurring left will probably be acceptable, and if it isn’t, I’ll try up-sampling and see how it impacts performance.
Thank you for the help!