Node setup for sprites rendering

Return to Code Snippets

Node setup for sprites rendering

Postby vardis » Sat Jun 13, 2009 12:55 pm

Hi,

the code snippet below is intented to simplify sprite rendering by allowing you to use screen coordinates in calls to NodePath.setPos() and NodePath.setScale() instead of render[2d] and aspect2d coordinates.

The idea is to first call create_sprites_node_setup and use the returned nodepath as the parent to all your sprite nodes. Then you can use screen coordinates with your sprite nodes.

Code: Select all
from pandac.PandaModules import Vec3
from pandac.PandaModules import Point3
from pandac.PandaModules import TextureStage
from pandac.PandaModules import NodePath
from pandac.PandaModules import CardMaker
from direct.interval.LerpInterval import LerpPosInterval
import direct.directbase.DirectStart

def create_sprites_node_setup(screenWidth, screenHeight, parent = render2d):
   
   aspect_ratio = parent.getScale()[0]   
   
   screenOrigin = parent.attachNewNode('screen_origin')
   screenNode = screenOrigin.attachNewNode('screen_node')

   screenOrigin.setPos(-1.0/aspect_ratio, 0.0, 1.0)
   screenOrigin.setScale(2.0, 1.0, -2.0)

   screenNode.setPos(0, 0, 0)
   
   screenNode.setScale(1.0/(aspect_ratio*screenWidth), 1.0, 1.0/screenHeight)
   screenNode.setTexScale(TextureStage.getDefault(), 1.0, -1.0)
   
   # test some points   
#   points = [(0,0), (screenWidth, 0), (screenWidth, screenHeight), (screenWidth/2.0, screenHeight/2.0), (0, screenHeight)]
#   for pt in points:
#      print '%s -> %s' % (pt, str(parent.getRelativePoint(screenNode, Vec3(pt[0], 0, pt[1]))))
   
   return screenNode


def create_sprite(filename, x, z, sx, sz, transparent = 1):
   cm = CardMaker('spritesMaker')
   cm.setFrame(-0.5, 0.5, -0.5, 0.5)
   sprite = cm.generate()   

   tex = loader.loadTexture(filename)

   spriteNP = NodePath(sprite)   

   spriteNP.setTexture(tex)
   spriteNP.setPos(x, 0, z)
   spriteNP.setScale(sx, 1.0, sz)
   spriteNP.setTransparency(transparent)
   return spriteNP
      
   
# use it like this
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

sprites_root = create_sprites_node_setup(SCREEN_WIDTH, SCREEN_HEIGHT, aspect2d)
flower_sprite = create_sprite('flower.png', SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 128, 128, 1)
flower_sprite.reparentTo(sprites_root)

horizontalMove = LerpPosInterval(flower_sprite, 9.0, Point3(SCREEN_WIDTH, 0, SCREEN_HEIGHT / 2), Point3(0, 0, SCREEN_HEIGHT / 2))
horizontalMove.loop()
   
run()

As you can see the coordinates to LerpPosInterval are given in screen space.

In case you want to run the code, you can right click on the sprite image below and save it:
Image

It has simplified my sprite handling code which was initially mixed with coordinates converions. :)

Regards
vardis
 
Posts: 9
Joined: Mon Jan 05, 2009 4:18 pm
Location: Athens, Greece

Postby treeform » Tue Sep 08, 2009 8:42 pm

Yeah i also use a similar method. For 2d stuff i think you really got to do the pixel perfect normal screen space coordinates.
User avatar
treeform
 
Posts: 2106
Joined: Sat May 05, 2007 5:15 pm
Location: SF, CA

Postby snaptothegrid » Wed Sep 30, 2009 5:55 am

hey, just want to tell i used your script for start making a simple gui and really has helped a lot.

chek it here if you feel like.
http://www.panda3d.org/phpbb2/viewtopic.php?p=44860

I coudn't manage to create text inside the screen root node or inside the sprite nodes, is there any way you can do that? Thanks!
snaptothegrid
 
Posts: 133
Joined: Tue Jun 03, 2008 6:14 am
Location: Tokyo Japan

Postby nande » Thu Oct 21, 2010 7:21 pm

thanks!! this is really usefull, it should be on the sample applications and the doc.
User avatar
nande
 
Posts: 16
Joined: Thu Oct 21, 2010 7:17 pm

Postby rxra » Mon Jan 10, 2011 4:22 pm

snaptothegrid wrote:hey, just want to tell i used your script for start making a simple gui and really has helped a lot.

chek it here if you feel like.
http://www.panda3d.org/phpbb2/viewtopic.php?p=44860

I coudn't manage to create text inside the screen root node or inside the sprite nodes, is there any way you can do that? Thanks!


hello,

I have exaxtly the same problem as "snaptothegrid", I did not succeed to attach text node to the sprites root. Any idea ?
rxra
 
Posts: 22
Joined: Sat Nov 20, 2010 5:45 am
Location: Paris, France

Postby ns.hermione » Fri Jul 27, 2012 3:29 am

I draw cardmarker with original size of texture with a little code:

Code: Select all
def create_sprite(filename, x, z, screenWidth, screenHeight, transparent=1):   
    tex = loader.loadTexture(filename)   
    cm = CardMaker('spritesMaker')
    sprite = NodePath(cm.generate())   
    sprite.setTexture(tex)
   
    #Scale and position
    sx = float(tex.getXSize()) / screenWidth
    sz = float(tex.getYSize()) / screenHeight
    sprite.setScale(sx, 1.0, sz)
    sprite.setPos(x, 0.0, z)
    sprite.setTransparency(transparent)
    return sprite
ns.hermione
 
Posts: 59
Joined: Wed Jul 11, 2012 9:38 am


Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 0 guests