Multiple Subwindows Display List rendering problem [Python]

Hi. May I ask you to help me with the following problem. I wrote short application that contains two modules: .obj loader and viewer. I would like to display my .obj in two subwindows at once. Here is the code.
I tested my loader in single-windowed application and it works perfectly, when I call the displayList in render function. Unluckily it doesn’t work for subwindows. In RenderGeometry() function i try to render my displaylist for both subwindows.
I am sure the model is loaded well, python doesnt generate any warnings too. Please tell me if there’s any special routine for drawing displaylists in subwindows or possible bug in my or Opengl code? I would be very thankful for your help.

from OpenGL.GL		import *
from OpenGL.GLU		import *
from OpenGL.GLUT	import *
from staticOBJ		import *

class game(object):
	def __init__(self, posx, posy, resx, resy, window_label):
		self.posx, self.posy = posx,posy
		self.resx, self.resy = resx, resy
		self.window_label = window_label
		self.window = 1
		self.rightEye, self.leftEye = 1,1
		self.geometryList = []
#######################################################################################################
#INIT GLUT
		glutInit()
		glutInitWindowSize(self.resx, self.resy)
		glutInitWindowPosition(self.posx, self.posy)
		glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE)
		self.window = glutCreateWindow(self.window_label)
		glutDisplayFunc(self.Render)
######################################################################################################
#LOAD GEOMETRY
		self.AddGeometry("temp.obj")
######################################################################################################
#INIT SUBWINDOWS
		self.leftEye = glutCreateSubWindow(self.window,20,20,360,360)
		glutDisplayFunc(self.leftEyeRender)		
		self.rightEye = glutCreateSubWindow(self.window,420,20,360,360)
		glutDisplayFunc(self.rightEyeRender)
		glutIdleFunc(self.RenderAll)
		glutMainLoop()
######################################################################################################
#RENDER METHODS
	def leftEyeRender(self):
		glutSetWindow(self.leftEye)
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
		glMatrixMode(GL_PROJECTION)
		
		glMatrixMode(GL_MODELVIEW)		
		glClearColor(0.0,0.0,0.2,1.0)
		self.RenderGeometry()	
		glutSwapBuffers()
	def rightEyeRender(self):
		glutSetWindow(self.rightEye)
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
		glMatrixMode(GL_PROJECTION)
		
		glMatrixMode(GL_MODELVIEW)		
		glClearColor(0.0,0.0,0.2,1.0)
		self.RenderGeometry()	
		glutSwapBuffers()
	def Render(self):
		glutSetWindow(self.window)
		glClear(GL_COLOR_BUFFER_BIT)
		glClearColor(0.0,0.0,0.0,1.0)
		glutSwapBuffers()
	def RenderAll(self):
		self.Render()
		self.leftEyeRender()
		self.rightEyeRender()	
	def RenderGeometry(self):
		glColor3f(1.0,0.0,0.0)
		glCallList(self.geometryList[0].gl_list)
		#glutSolidCone(0.2,0.8,4,4)

#####################################################################################################
#GEOMETRY_METHODS

	def AddGeometry(self,filename):
		mesh = staticOBJ("temp.obj")
		self.geometryList.append(mesh)

And the loader:

from OpenGL.GL   import *
from OpenGL.GLU  import *
from OpenGL.GLUT import *

class face(object):
	def __init__(self):
		self.vertexData = []
		self.normalData = []
		self.textureData = []
	def AddVertex(self,new_value):
		self.vertexData.append(new_value)
	def AddNormal(self,new_value):
		self.normalData.append(new_value)
	def AddUV(self,new_value):
		self.textureData.append(new_value)
	
class staticOBJ:
	def __init__(self, filename):
		self.vertices = []
		self.normals = []
		self.texcoords = []
		self.facelist = []
##################################################################################################
#PARSING OBJ FILE
		for line in open(filename, "r"):
			if line.startswith('#'): continue
			values = line.split()
			if not values: continue
			if values[0] == 'v':
				values.pop(0)
				v = [0] * 3
				for i in range(len(values)):
					v[i] = float(values[i])
				self.vertices.append(v)
			elif values[0] == 'vn':
				values.pop(0)
				v = [0] * 3
				for i in range(len(values)):
					v[i] = float(values[i])
				self.normals.append(v)
			elif values[0] == 'vt':
				values.pop(0)
				v = [0] * 3
				for i in range(len(values)):
					v[i] = float(values[i])
				self.texcoords.append(v)
			elif values[0] == 'f':
				tempface = face()
				values.pop(0)
				for i in range(len(values)):
					a = values[i].split('/')
					tempface.AddVertex(int(a[0]))
					tempface.AddNormal(int(a[2]))
					tempface.AddUV(int(a[1]))
				self.facelist.append(tempface)
#####################################################################################################
#CREATING GLLIST
		self.gl_list = glGenLists(1)
		glNewList(self.gl_list, GL_COMPILE)
		glFrontFace(GL_CCW)		
		glBegin(GL_QUADS)		
		for facenumber in range(0,len(self.facelist)):
			for vertexnumber in range(0,len(self.facelist[facenumber].vertexData)):
				vindex = self.facelist[facenumber].vertexData[vertexnumber] -1			
				nindex = self.facelist[facenumber].normalData[vertexnumber] -1
				tindex = self.facelist[facenumber].textureData[vertexnumber] -1
				glNormal3f(self.normals[nindex][0],self.normals[nindex][1],self.normals[nindex][2])				
				glTexCoord2f(self.texcoords[tindex][0], self.texcoords[tindex][1])
				glVertex3f(self.vertices[vindex][0],self.vertices[vindex][1],self.vertices[vindex][2])
		glEnd()
		glEndList()
		glShadeModel(GL_SMOOTH)

All right, I resolved the problem myself. It is not mentioned in the documentation so let me tell you how to do this, if somebody had the same problem.
glLists are not shared between windows contexts so it needs to be initialized for every subwindow every time. Heres the code:


self.leftEye = glutCreateSubWindow(self.window,20,20,360,360)
glutDisplayFunc(self.leftEyeRender)
self.gl_list = glGenLists(1)

...

self.rightEye = glutCreateSubWindow(self.window,20,20,360,360)
glutDisplayFunc(self.rightEyeRender)
self.gl_list = glGenLists(1)


And now you can call glCallList for both windows.

It is possible to share lists (and other GL objects, but - oddly - not (IIRC) VAOs), but it’s platform specific: wglShareLists on Windows, for example.

Youre probably right;) I am the linux user so i wont even try;) Nevertheless I found the solution finally - opengl for python is unfortunately very poorly documented.

[QUOTE=lucasgeras;1283185]
glLists are not shared between windows contexts so it needs to be initialized for every subwindow every time. [/QUOTE]
If you’re using FreeGLUT, you can use


glutSetOption(GLUT_RENDERING_CONTEXT, GLUT_USE_CURRENT_CONTEXT)

This makes subsequent calls to glutCreateWindow() or glutCreateSubWindow() associate the current context with the window rather than creating a new context.

Note that this isn’t the same as creating a new context which shares data (display lists, textures, etc) with an existing context. It causes the windows to share the context itself, which means sharing everything. If your sub-windows have different state, you’ll need to initialise that state at the beginning of the display callback (in particular, you can’t set the projection matrix in the resize callback if the sub-windows might have different sizes).

If you want more flexibility that GLUT provides, use a more general GUI toolkit such as GTK, Qt or wxWidgets. GLUT was created to allow simple programs (primarily the example programs in the red book) to be created with a bare minimum of setup code.

According to the wiki, vertex array objects, framebuffer objects, transform feedback objects and program pipeline objects can’t be shared. Other object types can be shared.

But that requires using something other than GLUT for context management.