TextNode in multiple windows

I seem to have a problem trying to display a text node in multiple windows:

When a make a new window :

   myRender = NodePath("New window")
    win2 = base.openWindow(scene = myRender, props = props, type = 'onscreen', keepCamera = False,        
                    makeCamera = True, requireWindow = True)
    self.seriesFont = loader.loadFont("fonts/SnellRoundhand.ttc")
    self.seriesText1 = TextNode("Text1")
    self.seriesText2 = TextNode("Text2")
    self.seriesText1NodePath = myRender.attachNewNode(self.seriesText1.generate())

    self.seriesText2NodePath = myRender.attachNewNode(self.seriesText2.generate())

Any ideas?

Thank you

You tell us there is a problem, but you do not tell us what the problem is. Could you describe what you’re seeing, versus what you expected to see?

It is either I am doing something wrong to show Text1 and Text2 in the new window or there is a gap in my understading on how the same TextNodes can be placed in the multiple windows.

One thing is definitely missing in your code: nowhere do you set the actual text to be rendered :slight_smile: . You need to call TextNode.setText() if you want to see your text.

And do you really want your text to be placed in the new scene as a 3D object? If not, then giving both TextNodePaths a different Y-value will not make any difference; they will still have the same position on screen. More importantly, your second window will need its own 2D layer, similar to render2D and aspect2d, as explained here, to which you can then copy your TextNodePaths from base.aspect2d, using TextNodePath.copyTo().

Forgive me if I misunderstood what you’re trying to do exactly, because it isn’t all that clear to me - the more info you give, the better we can help you :wink: .

Also, using code tags would be nice:

#My code here

Thank you for your help on this.

Basically I think what I need is to know how to switch the default ‘render’ or ‘render2d’ to become attached to the second window (and subsequent new windows) so the TextNode can be rendered also in the second window with a different value.

I am already able to render my procedural model in each window with no problem but for some reason I can’t seem to do the same for the TextNodes as all of them are rendered in the first window only.


The default render2d is set up for the first window. If you want to make the same render2d also apply to the second window, you can do this:

dr = win2.makeDisplayRegion()

If you want to create a separate 2-D scene graph for your second window, you’ll have to use base.makeCamera2d.

I did added what you suggested and I still get the text rendered in the first window.

It seems that base.render or base.render2d is still pointing to the first window even though the code you suggested has been added:

        props = WindowProperties.getDefault()
        renderingTo = NodePath('myRender2d')
        win2 = base.openWindow(scene = renderingTo, props = props, type = 'onscreen', keepCamera = False,           makeCamera = True, requireWindow = True)
        base.setBackgroundColor( 1, 1, 1, 1, win2 )
        dr = win2.makeDisplayRegion()

Not sure why? - the models rendered fine in separate windows but the it comes to the following text:

        self.seriesText1 = OnscreenText(text="my text",
                       style=1, fg=(0,0,0,1), 
                       pos=(-.9,-0.33-.30), scale = .05, font = self.seriesFont)

still renders in the first window

Could you describe in a bit more detail what exactly you’re trying to do?

The code you showed doesn’t seem to make a lot of sense, as it first assigns base.cam2d to the display region, but then overrides that setting immediately by setting it to base.cam. If you remove the last setCamera line, it should display render2d in both windows.

Ok, this is the code:


    renderingTo = NodePath('myRender2d')    
    win2 = base.openWindow(scene = renderingTo, props = props, type = 'onscreen', keepCamera = False, makeCamera = True, requireWindow = True)
    base.setBackgroundColor( r=1, g=1, b=1, a=0, win=win2 )

    dr = win2.makeDisplayRegion()

    test = OnscreenText(text="Hello world",
                   style=1, fg=(0,0,0,1), parent = renderingTo, 
                   pos=(-.9,-0.33-.30), scale = .05, font = self.seriesFont)


I removed what you suggested, still the text is now showing in either window

Thanks for your help

I don’t think it’s possible to make one and the same TextNode show a different text depending on what window it is rendered to… A different TextNode for each window will be needed I think.
Which brings us to the next point:

Unless I’m missing something, that doesn’t seem to be the case; according to the API:

That’s the default render2d being mentioned, right? And the following code sample seems to support that, as it shows the same TextNode in both windows (at least for me, it does):

from panda3d.core import *
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):

        # open a second window with its own camera
        props = WindowProperties.getDefault()
        props.setTitle("Second Window")
        my_scene = NodePath("my_scene")
        win2 = self.openWindow(props=props, type='onscreen', keepCamera=False,
                                scene=my_scene, makeCamera=True, requireWindow=True)
        dr = win2.makeDisplayRegion()

        text = TextNode("my_text")
        text.setText("This is my text")
        self.text_np = self.aspect2d.attachNewNode(text)
        self.text_np.setPos(-.5, 0., -.3)

app = MyApp()

On my own desktop PC, replacing “dr.setCamera(self.makeCamera2d(win2))” with “dr.setCamera(self.cam2d)” in the above code gives the following OpenGL error and makes the Python interpreter crash (happens also on my crappy old laptop, but that’s no longer surprising):

:display:gsg:glgsg(error): GL_INVALID_OPERATION error generated. Not a valid sam
pler name.

Hmm, yes, makeCamera2d does seem to create under render2d, and for some reason it doesn’t take a scene= parameter to override this like makeCamera does. However, all you have to do is reparent the return value to a new scene graph of your choosing.

All it does, though, is create a new display region, camera and lens, and reparents the camera to render2d.

Hmm, the sampler error seems a bit worrying, though it’s probably unrelated to the matter of using a 2d camera.

I actually got that error after adding “loadPrcFileData(’’, ‘gl-debug true’)” to the top of that code sample; before that (and without “scene=my_scene” in the self.openWindow call), the code was spamming the following error message in the command console (closing the second window stops the error messages):

:display:gsg:glgsg(error): at 2954 of c:\buildslave\sdk-windows-i386\build\panda
\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): An OpenGL error (invalid operation) has occurred.  Se
t gl-debug #t in your PRC file to display more information.

Although there is no crash while those messages are spamming, the second window doesn’t show the TextNode (or anything else parented to either aspect2d or render2d).

And now I found out that without any renderable NodePaths parented to either aspect2d or render2d, there is no error/crash (a TextNode without text or any empty NodePath causes no problems, while attaching e.g. the smiley model does).

Maybe you could file a separate bug report on this with the full log of “notify-level-glgsg debug” and “gl-debug true”; it doesn’t seem related to the matter of TextNode in multiple windows.

Done; and my apologies for going off-topic.