Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: Multiple Subwindows Display List rendering problem [Python]

  1. #1
    Newbie Newbie
    Join Date
    Jul 2016
    Posts
    3

    Unhappy 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.

    Code :
    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:

    Code :
    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)

  2. #2
    Newbie Newbie
    Join Date
    Jul 2016
    Posts
    3

    Solution

    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:
    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.

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,789
    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.

  4. #4
    Newbie Newbie
    Join Date
    Jul 2016
    Posts
    3
    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.

  5. #5
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,008
    Quote Originally Posted by lucasgeras View Post
    glLists are not shared between windows contexts so it needs to be initialized for every subwindow every time.
    If you're using FreeGLUT, you can use
    Code :
    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.

  6. #6
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,008
    Quote Originally Posted by mhagain View Post
    It is possible to share lists (and other GL objects, but - oddly - not (IIRC) VAOs)
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •