OpenGL (extended monitors) error

Hi guys,

As some of you already know I’m programming a 4 screens interactive experience. However, I ran into another problem…I can run perfectly both static and interactive contents within my screen res but when I try to place anything to other screens, I get this error:

panda 3d :display:gsg:glgsg(error): at 8190 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation:display:gsg:glgsg(error): at 8193 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation:display:gsg:glgsg(error): at 8190 of

Any thoughts on this?

I think it relates to opengl and I tried adding a config to the config.prg (gl-showcast if i remember correctly) but it’s still not working.

source in this post: [About the number of cores used)

Thanks in advance for any help you can give me

António

Assuming you’re using Panda3D 1.7.2, then line 8190 is within apply_texture(), which suggests that something is wrong with one of your textures. It might be a texture associated with an offscreen buffer, if you have such a thing.

“Invalid operation” could mean any number of things, but it might mean your texture or offscreen buffer has already been deleted, or is otherwise invalid somehow.

What do you mean you are doing when you “try to place anything to other screens”?

David

INCAVE = 0      # 0 = no, 1 = yes
# window PRCfile data   - index 0 is not in cave, 1 is in cave
PRC_ORIGIN = [["win-origin 0 50", "win-origin 400 50", "win-origin 800 50", "win-origin 800 400", "win-origin 1200 400"],
              ["win-origin -1024 -768", "win-origin 0 -768", "win-origin 1024 -768", "win-origin 100 100","win-origin 0 0"]]
PRC_SIZE = ["win-size 320 240", "win-size 1024 768"]
PRC_DEC = ["undecorated 0", "undecorated 1"]

changing the resolution values to place the content in the second screen…assumind that i’m running 1280x1024 monitors, anything bigger than that (i.e. 1500x100) should be placed in the second screen…as for the textures, I thought so myself but they work in my main window, shouldn’t it work in 2, 3, and 4 monitors?

Ah, the textures could indeed cause problems in the other windows, if each window has its own graphics context. It’s not supposed to cause problems, but this is a codepath that isn’t often used, so perhaps there is a bug somewhere. The fundamental problem is that if each window has its own graphics context, then the texture contents have to be re-uploaded to each one. But the default behavior is to flush the RAM image after the texture is uploaded the first time, which means that it is no longer available to re-upload it the second and later times.

One easy solution is to put the line:

keep-texture-ram 1

in your Config.prc file. This will tell Panda not to flush the RAM image after the texture is uploaded, so that it should be available to upload again for the next window.

A better solution would be to pass gsg = base.win.getGsg() to each call to base.openWindow(). This tells Panda to share the same graphics context (the GSG) among all of the windows, obviating the need to upload the texture multiple times.

Another solution would be to go with one continuous window instead of multiple windows. :slight_smile:

David

I’ll try that tomorrow first thing I get back to the university and I’ll get back at you David!

Thank you for the help, as usual :wink:

Hi again,

So, I just tried both adding keep-texture-ram 1 to config.prg and gsg to each open windows but I keep having the same error… --’

# Open four new windows and title them "left", "center", "right" and "back"
        self.wp.setTitle('left')
        self.w2 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        loadPrcFileData("", PRC_ORIGIN[INCAVE][1])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()  
        base.win.requestProperties(self.wp)
        self.wp.setTitle('center')
        self.w3 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        loadPrcFileData("", PRC_ORIGIN[INCAVE][2])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()      
        base.win.requestProperties(self.wp)
        self.wp.setTitle('right')
        self.w4 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        loadPrcFileData("", PRC_ORIGIN[INCAVE][3])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()      
        base.win.requestProperties(self.wp)
        self.wp.setTitle('back')
        self.w5 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        loadPrcFileData("", PRC_ORIGIN[INCAVE][4])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()      
        base.win.requestProperties(self.wp)

this was the code i already had, i added keep-texture-ram 1 and now I get this:

:display:gsg:glgsg(error): at 3200 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): at 3223 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): at 3225 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): at 3227 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): at 8190 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): at 8193 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): at 8190 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): at 8193 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation
:display:gsg:glgsg(error): GL texture creation failed for back_set_04 : invalid operation
:display:gsg:glgsg(error): Could not load back_set_04

weird thing is, the puppet window works on secondary display

I told David but forgot to mention here, the other weird thing is that when I eliminate gsg = base.win.getGsg() from my code it actually works in external screens with a considerable loss of performance though…anyone knows other solution to this?

I’m really trying to avoid switching to a single screen since our next playtesting is too close !

Thanks guys

I everyone, long time no see (been really buse with project --’)…anyway, I’m still struggling with the external monitors but I think the program lies within my code…I tested an example code to check if i can load to 4 screens and it works fine with this setup:

# set up the camera
        self.camBase = render.attachNewNode('camBase')  # control camera x,y ; ground collider attached
        self.camHigh = self.camBase.attachNewNode('camBase')  # control camera Z
        self.right = self.camBase.attachNewNode('right')
        self.right.setPos(1, 0, 0)
        self.forward = self.camBase.attachNewNode('forward')
        self.forward.setPos(0, 1, 0)
            
            
        # Open three new windows and title them "left", "center", and "right"  
        loadPrcFileData("", PRC_ORIGIN[INCAVE][0])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()
        self.wp.setTitle('left')
        self.w2 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        base.win.requestProperties(self.wp)
        
        loadPrcFileData("", PRC_ORIGIN[INCAVE][1])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()  
        self.wp.setTitle('center')
        self.w3 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        base.win.requestProperties(self.wp)
        
        loadPrcFileData("", PRC_ORIGIN[INCAVE][2])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()      
        self.wp.setTitle('right')
        self.w4 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        base.win.requestProperties(self.wp)
        
        # Retitle the main window as the "puppet" 
        loadPrcFileData("", PRC_ORIGIN[INCAVE][3])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        self.wp = WindowProperties.getDefault()
        self.wp.setTitle('puppet')
        self.wp.setUndecorated(0)
        base.win.requestProperties(self.wp)
        
        # position the cameras    
        base.camList[0].setHpr(0, 0, 0)             # puppet
        base.camList[0].reparentTo(self.camHigh)
        base.camList[1].setHpr(40, 0, 0)            # left
        base.camList[1].reparentTo(self.camHigh)
        base.camList[2].setHpr(0, 0, 0)             # center
        base.camList[2].reparentTo(self.camHigh)
        base.camList[3].setHpr(-40, 0, 0)           # right
        base.camList[3].reparentTo(self.camHigh)
        
        # setup the left, center, and right cameras to render the desired node
        base.camList[0].node().setScene(render)       # puppet
        base.camList[1].node().setScene(render)       # left
        base.camList[2].node().setScene(render)       # center
        base.camList[3].node().setScene(render)       # right

However, I used render2d and I think the problem might be there…any ideas? My code is as follows:

def screenSet(self):
        base.setBackgroundColor(1,1,1)
        #sets up the camera nodes
        self.camBase = render.attachNewNode('camBase')  # control camera x,y ; ground collider attached
        self.camHigh = self.camBase.attachNewNode('camHigh')  # control camera Z
        self.right = self.camBase.attachNewNode('right')
        self.right.setPos(1, 0, 0)
        self.backward = self.camBase.attachNewNode('backward')
        self.backward.setPos(0, 1, 0)
        # position the camera node
        #self.camBase.setPosHpr(171.411,19.1365,158.941,  -191,0,0)
        ##self.camBase.setPosHpr(0,0,0, 0,0,0)

        ##self.renders2d={}
        # Retitle the main window as the "puppet" 
        loadPrcFileData("", PRC_ORIGIN[INCAVE][0])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()
        self.wp.setTitle('front')
        base.win.requestProperties(self.wp)

        # Open four new windows and title them "left", "center", "right" and "back"
        
        self.wp.setTitle('right')
        self.w2 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        loadPrcFileData("", PRC_ORIGIN[INCAVE][1])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()      
        base.win.requestProperties(self.wp)
        self.renders2d[BLUE]=NodePath('centerRender2d')
        self.renders2d[BLUE]=base.render2d
        centerCamera2d=base.makeCamera2d(self.w2)
        centerCamera2d.reparentTo(self.renders2d[BLUE])

        self.wp.setTitle('back')
        self.w3 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        loadPrcFileData("", PRC_ORIGIN[INCAVE][2])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()      
        base.win.requestProperties(self.wp)
        self.renders2d[RED]=NodePath('rightRender2d')
        rightCamera2d=base.makeCamera2d(self.w3)
        rightCamera2d.reparentTo(self.renders2d[RED])

        self.wp.setTitle('left')
        self.w4 = base.openWindow(gsg=base.win.getGsg(), props=self.wp)
        loadPrcFileData("", PRC_ORIGIN[INCAVE][3])
        loadPrcFileData("", PRC_SIZE[INCAVE])
        loadPrcFileData("", PRC_DEC[INCAVE])
        self.wp = WindowProperties.getDefault()      
        base.win.requestProperties(self.wp)
        self.renders2d[GREEN]=NodePath('leftRender2d')
        backCamera2d=base.makeCamera2d(self.w4)
        backCamera2d.reparentTo(self.renders2d[GREEN])

Thank you so much in advance

Hi,

I can’t read that code and tell you precisely everything that will happen when you run it–that’s not the way my brain (or anyone else’s brain) works. I also can’t guess what “the problem” might be that you’re having with it.

But if you’re having a problem, perhaps I can help you diagnose it, and suggest a way to track it down further or correct it, if I know precisely what the nature of the problem is and what you expect to happen instead. :slight_smile:

Can you tell us more about what’s going wrong?

David

it stills remain the same problem…

panda 3d :display:gsg:glgsg(error): at 8190 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation:display:gsg:glgsg(error): at 8193 of c:\buildslave\release_sdk_win32\build\panda3d\panda\src\glstuff\glGraphicsStateGuardian_src.cxx : invalid operation:display:gsg:glgsg(error): at 8190 …

basically i have a vars file with 2 cases, either i’m inside the four screens setup and I want the content to be reproduced there (in this case, 4x 1024x768 windows to be displayed in fullscreen) or 4 smaller windows for when I’m coding at the computer, no problem there.

What i need is just to be able to load content to the external screens but in the interactive game, i always get wingsg error, I programmed a second world, just to display video to the 4 screens, and I was having the same error but I removed the wingsg and it works fine but I can’t do that in this situation :angry:

to make it simple: i want to be able to double click my .bat file and play the game right away…at this point, I have to drag all the windows manually

So I think I understand you are saying that when you run this code on your desktop, it works fine; but when you run similar code on the production machine, it fails with these gsg errors.

That doesn’t sound like a problem with code to me–it’s more likely caused by a difference in the graphics drivers on your desktop and the ones on the production machine. As I said earlier, when you open multiple windows, some graphics drivers handle it well, and others do not.

So I think the best way to solve your problem is to render to a single window, with multiple DisplayRegions, instead. That works on almost any graphics driver.

The code doesn’t have to require a lot of changing. Basically instead of calling base.openWindow() repeatedly, you will call base.makeCamera() repeatedly. Each time you call makeCamera you will pass a different value for displayRegion, for instance:

        self.camBase = render.attachNewNode('camBase')  # control camera x,y ; ground collider attached
        self.camHigh = self.camBase.attachNewNode('camBase')  # control camera Z
        self.right = self.camBase.attachNewNode('right')
        self.right.setPos(1, 0, 0)
        self.forward = self.camBase.attachNewNode('forward')
        self.forward.setPos(0, 1, 0)

        # Turn off the default camera.
        base.camNode.getDisplayRegion(0).setActive(0)
        del base.camList[0]

        # Make four new cameras in the four corners of the window.
        
        # Lower-left corner.
        base.makeCamera(base.win, displayRegion = (0.0, 0.5, 0.0, 0.5))

        # Lower-right corner.
        base.makeCamera(base.win, displayRegion = (0.5, 1.0, 0.0, 0.5))

        # Upper-left corner.
        base.makeCamera(base.win, displayRegion = (0.0, 0.5, 0.5, 1.0))

        # Upper-right corner.
        base.makeCamera(base.win, displayRegion = (0.5, 1.0, 0.5, 1.0))
       
        # position the cameras   
        base.camList[0].setHpr(0, 0, 0)             # puppet
        base.camList[0].reparentTo(self.camHigh)
        base.camList[1].setHpr(40, 0, 0)            # left
        base.camList[1].reparentTo(self.camHigh)
        base.camList[2].setHpr(0, 0, 0)             # center
        base.camList[2].reparentTo(self.camHigh)
        base.camList[3].setHpr(-40, 0, 0)           # right
        base.camList[3].reparentTo(self.camHigh)
        

David

Will try your suggestion :slight_smile:

Nonetheless, I’m running from my computer in both cases…either with a single screen or using 4 projectors but I’ll let you know later!

Thank you!

Really? Then I’m baffled, because I don’t see any significant difference between the working (first) case and the non-working (second) case. The different handling of render2d can’t have anything to do with the gsg failures.

David

Hi :smiley:

So I’ve been trying the single display region and it seems to be working fine

However, i’m a little bit confused about running this in 4x 1024x768 resolutions…do I have to define that (and make this fullscreen) or it should run automatically accordingly to the number of screens installed in the computer?

Thanks :slight_smile:

Panda knows nothing about the number of screens installed on your computer. It will subdivide the window into whatever DisplayRegions you specify.

In order to send the appropriate content to each projector, you will need to make your window fullscreen, and subdivide it into DisplayRegions such that each DisplayRegion corresponds to a projector. To do this, you will need to know the precise arrangement of projectors on your Windows desktop.

David

thank you David, I did understood you explanation with setting display regions however, I can’t figure out how exactly is it possible to fullsreen to the 4 screens (4096) this is what i did…

def screenSet(self):
        self.camBase = render.attachNewNode('camBase')  # control camera x,y ; ground collider attached 
        self.camHigh = self.camBase.attachNewNode('camBase')  # control camera Z 
        self.right = self.camBase.attachNewNode('right') 
        self.right.setPos(1, 0, 0) 
        self.forward = self.camBase.attachNewNode('forward') 
        self.forward.setPos(0, 1, 0) 

        loadPrcFileData("",LONG_SCREEN)
        # Turn off the default camera. 
        base.camNode.getDisplayRegion(0).setActive(0) 
        del base.camList[0] 

        # Make four new cameras in the four corners of the window. 
        
        # Lower-left corner. 
        base.makeCamera(base.win, displayRegion = (0.0, 0.25, 0.0, 1)) 

        # Lower-right corner. 
        base.makeCamera(base.win, displayRegion = (0.25, 0.5, 0.0, 1)) 

        # Upper-left corner. 
        base.makeCamera(base.win, displayRegion = (0.5, 0.75, 0, 1.0)) 

        # Upper-right corner. 
        base.makeCamera(base.win, displayRegion = (0.75, 1.0, 0, 1.0)) 
        
        # position the cameras    
        base.camList[0].setHpr(0, 0, 0)             # puppet 
        base.camList[0].reparentTo(self.camHigh) 
        base.camList[1].setHpr(-90, 0, 0)            # left 
        base.camList[1].reparentTo(self.camHigh) 
        base.camList[2].setHpr(90, 0, 0)             # center 
        base.camList[2].reparentTo(self.camHigh) 
        base.camList[3].setHpr(180, 0, 0)           # right 
        base.camList[3].reparentTo(self.camHigh) 

and on my VARS file I have

LONG_SCREEN="""win-size 4096 768
win-origin 0 0
undecorated 1"""

But no matter what, it just shows up in the first screen…

You do have to load the win-size etc. config settings before you input DirectStart or create a ShowBase instance. This means before there is a render or any of these other thing you are already referencing, so it means in your sample code it is already too late.

Normally people do this at the very beginning of the program file, before they do anything else (but after importing panda3d.core, of course).

David