DirectLabel image pixel to pixel

Hello,

Please advise how to show image pixel to pixel in DirectLabel.

I mean if I have TIF with LZW copression, how to show this image in DirectLabel with 1:1 scale. In this case each pixel from TIF file will be shown on the screen without scaling.

Thank you very much,
Konst

Use the command:


egg-texture-cards -p 240,240 -o myImage.egg myTex1.tif myTex2.tif ...

In the above, replace 240 with one-half the height of your target window resolution. That is, use “-p 240,240” if your target resolution is 640x480, “-p 300,300” if you use 800x600, or “-p 512,512” if you use 1280x1024, etc.

Then apply your label with code like this:

model = loader.loadModel('myImage.egg')
myTex1 = model.find('**/myTex1')
label = DirectLabel(image = myTex1)

David

THANK YOU VERY MUCH, DAVID

Hi, David. Could you explain the reasoning behind the -p option a bit more? Specifically, why you should set it to half of the screen height?

I’m trying to create DirectEntry fields with a specific background image (a rectangle). I’ve been playing around with egg-texture-cards and other methods of getting the image in the game without scaling, but I’m having a bit of trouble. Thanks!

-Ogel

It is a strange concept, I’ll be the first to admit.

The idea is that -p specifies the pixel size required to fill up the default polygon, which has a frame of (-0.5, 0.5, -0.5, 0.5) (this is what the egg-texture-cards -h explanation says as well).

Since aspect2d has a frame of (-1.333, 1.333, -1, 1)–that is, the X coordinates of aspect2d range from -1.333, and the Y coordinates range from -1 to 1–it follows that the default polygon is half as high as the screen height. (The total screen height is 2 units tall, while the default polygon from egg-texture cards is only 1 unit tall.)

So, if your screen size is 640x480 pixels, and you specify:

egg-texture-cards -p 240,240 my_texture.png

you are saying that if your texture is 240 pixels high, it should be given a polygon 1.0 units tall (that is, it will fill up the default polygon, which is 1.0 units tall), and by coincidence this is exactly half of the screen height–so it will take up 240 pixels onscreen.

If your texture is 480 pixels high, it will be given a polygon 2.0 units tall (twice the default polygon), and will exactly fill the screen height, taking up 480 pixels onscreen.

So, the bottom line: the reason you should set -p to half the screen height is because aspect2d has a height of 2.0 but egg-texture-cards bases the -p parameter on a standard polygon of height 1.0.

David

Thanks for that explanation - I’m new to 2D/interface stuff with Panda.

I’m trying to create a login screen (1024x768) that provides a number of text entry fields. I have small rectangular images (61x23 and 168x23) that I want to use for these fields. So I want the text to fit in these fields and for the background images to remain unstretched/unscaled.

I’ve tried a few things (such as the recommendation above), but I keep getting really massive text centered (not left-justified) over a small image. I think I can use ‘image_scale’ to make the image bigger and then shrink the whole thing with ‘scale’, but that seems like overkill.

Is there a simple solution for this? I’ve posted some of my test code below. It’s basically a mess because I keep trying different things, but maybe it will shed light on what I’m doing wrong. Thanks for your help!


    def __init__(self):
        """Initializes DirectGUI components"""
        
        self.fieldList = []   # store references to each input field
        
        # All other DirectGUI objects will connect to baseFrame, the background:
        self.baseFrame = DirectFrame(image='LoginInfoScreen.jpg', relief = None)
        self.baseFrame.setSx(1.333)  # correct the scale for "full screen"
        
        # Entry fields for login information
        model = loader.loadModel('entry_field_maps.egg')
        myTex = model.find('**/DialogueBoxLong')
        self.firstName = DirectEntry(self.baseFrame,
                                     relief = None,
                                     cursorKeys = 1,
                                     initialText = "First",
                                     image = myTex,
                                     enableEdit = 1)

        self.fieldList.append(self.firstName)
                                     
        # Listen for debug keys
        self.accept('p', self.printTransforms)
    # end __init__
  • Ogel

Ok - I’ve worked a little more on the code and here’s what I have now:


def __init__(self):
    """Initializes DirectGUI components"""
        
    self.fieldList = []   # store references to each input field
        
    # All other DirectGUI objects will connect to baseFrame, the background:
    self.baseFrame = DirectFrame(image = 'LoginInfoScreen.jpg',
                                 relief = None)
    self.baseFrame.setSx(1.333)
        
    # Entry fields for login information
    model = loader.loadModel('entry_field_maps.egg')
    # Shrink the input fields to an appropriate size
    textScale = 0.038
    # ...but rescale the field backgrounds to their normal size
    geomScale = 1/textScale
        
    self.firstName = DirectEntry(self.baseFrame,
                                 relief = None,
                                 text_fg = (255,255,255,1),
                                 geom = model,
                                 geom_scale =
                                     (geomScale, geomScale, geomScale),
                                 geom_pos = (4.1, 0.5, 0),
                                 cursorKeys = 1,
                                 initialText = "First",
                                 enableEdit = 1,
                                 scale = textScale)

    self.fieldList.append(self.firstName)
                                     
    # Listen for debug keys
    self.accept('p', self.printTransforms)
# end __init__

I’m still curious about a few things:

  1. Previously, our artists were creating square versions of our backgrounds (which we intend to be 1024x768) and then we’d strectch them (as shown above). I’ve been able to use the texture-card method to remove the setSx(1.333) call. However, doing so makes the image a bit blurry. Is there a better way to paint background images without blurring? Our artists don’t want to paint backgrounds and then condense them.

  2. I was using geom_pos to adjust the DirectEntry’s background image. I couldn’t get text_align to work. I’m basically finding the numbers for geom_pos through trial and error. Is there a better way to create DirectEntrys without all of this hard coding?

Thanks for any help!

  • Ogel

I think I see the problem. The piece you’re looking for here is text_scale. Unfortunately, text_scale doesn’t work for a DirectEntry, because of an unrelated bug.

Normally, when I create a DirectGui widget of some kind with a pre-painted background and a text label, I will use a text_scale of something like 0.07, and thereby avoid scaling the overall widget. This works for every kind of widget but DirectEntry. I guess until we fix that bug, the workaround is to make the image bigger and then shrink the whole thing, as you suggest–sorry about that!

self.baseFrame = DirectFrame(image='LoginInfoScreen.jpg', relief = None)
        self.baseFrame.setSx(1.333)  # correct the scale for "full screen" 

Incidentally, I’d recommend simply setting the parent of DirectFrame to render2d (for instance, with the keyword parameter parent=render2d) rather than setting its scale to 1.333. render2d is the original, unscaled parent of the 2-d scene graph, and it covers the full screen in the range -1, 1. aspect2d, the default parent of all of your DirectGui objects, is a child of render2d and has a 1/1.333 scale applied to it.

The advice to use half the screen height for the parameter to -p–that is, to specify -p 384,384 in your case–only makes sense if you are planning to attach the frame to aspect2d, where the X and Y dimensions are the same in both directions (and both based on Y). If you are attaching your card directly to render2d, use -p 512,384 instead, because you want to get the card the right shape in both dimensions. Or, avoid the -p option altogether and create a frame that fills the screen explicitly, with -g -1,1,-1,1.

It is true that text_align doesn’t work with the DirectEntry–it only does left-justified text.

Are you running your code interactively? If you have a handle to your DirectEntry, you can do entry.component(‘geom0’) to get the copy of the geom in the focus state (or entry.component(‘geom1’) to get the copy in the non-focus state). Then you can move these interactively and see the change immediately, the response time is very quick, and when you get it placed you can look up the transform and put it in your code. Alternatively, you could do something like entry.component(‘geom1’).place() to pop up the Tk panel to let you place it interactively.

David