How to rebind shared textures?


I am using seven GL rendering contexts spread across two forms (three contexts in the top form, four in the bottom). When my app starts, I create a separate rendering context to be used for sharing display lists and textures. For this context, I generate a set of display lists and textures using glGenLists and glGenTextures. Then when each rendering context on the two forms is initialised, I share the display lists and textures using glShareLists. This all works fine – I can then call any display list or display any texture I like in any rendering context.

The problem occurs when I try to rebind any texture in the shared set under certain circumstances. The first time I bind the texture to load the image and then display it in one context, everything works great. If I later rebind this same texture and display it in the same rendering context as for the first time the texture was displayed, it works fine. But if I run the app again, this time displaying the same texture in two rendering contexts, then rebinding the texture, the new image apparently isn’t loaded when I use glTexImage2D (after glBindTexture). Displaying the apparently rebound texture in the same two rendering contexts displays the old image in both contexts.

Also, if I display the texture in one rendering context but select a different rendering context prior to rebinding the texture, the same effect occurs (image isn’t updated). I figured this could be because I have to rebind the texture for the original rendering context in which it was first bound. So I tried initially binding all textures in the shared set for the shared rendering context and subsequently rebinding textures for this context. Result: same as before, the first image bound to the texture displays correctly, but it is still rendered after an attempt is made to rebind the texture.

I’ve simplified the test case down to a single shared texture with only two rendering contexts on a single form, plus the shared rendering context, and still no joy. In every case the texture rendering is not part of a display list.

Is there a simple solution to this problem? One thing I could try is to call glGenTextures every time I want to bind one texture, then delete it using glDeleteTextures and recreate it when I next want to bind it, but this doesn’t seem like the best solution.

Here is the code that displays the textures (Visual Basic code, using VB OpenGL API 1.2 (ANSI)). GlngTexName(1) is the single shared texture name.

Private Sub DrawTesture( )
wglMakeCurrent hDC, MlngGLRC(1) 'Select first form rendering context
glClear (clrColorBufferBit Or clrDepthBufferBit)

<< Load different image into array bytImage( ) >>

'Load texture image data
glBindTexture glTexture2D, GlngTexName(1)
glTexParameterf glTexture2D, tpnTextureWrapS, GL_CLAMP
glTexParameterf glTexture2D, tpnTextureWrapT, GL_CLAMP
glTexParameterf glTexture2D, tpnTextureMagFilter, GL_LINEAR
glTexParameterf glTexture2D, tpnTextureMinFilter, GL_LINEAR
glTexImage2D glTexture2D, 0, GL_RGBA, intImageWidth, intImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytImage(0, 0, 0)

For i = 1 To 2
wglMakeCurrent hDC, MlngGLRC(i) 'Select one of two form rendering contexts


  'Draw texture
  glBlendFunc sfSrcAlpha, dfOneMinusSrcAlpha              
  glColor4ub 255, 255, 255, 255
  glEnable glcTexture2D
  glBindTexture glTexture2D, GlngTexName(1)
  glTexEnvf tetTextureEnv, tenTextureEnvMode, tepDecal
  glBegin bmQuads
     glTexCoord2f 0, 0
     glVertex2f Gsng10cm * 3, Gsng10cm * 3		'Gsng10cm is a constant
     glTexCoord2f 1, 0
     glVertex2f Gsng10cm * 10, Gsng10cm * 3
     glTexCoord2f 1, 1
     glVertex2f Gsng10cm * 10, Gsng10cm * 10
     glTexCoord2f 0, 1
     glVertex2f Gsng10cm * 3, Gsng10cm * 10
  glDisable glcTexture2D


'Swap buffers to give clean transition (double buffered)
SwapBuffers hDC
End Sub

Thanks for any suggestions.

I ran into problems once, when using multiple rendering contexts, a context for each window. The only solution I found, and is a perfectly valid on according to docs I think, was to only have one rendering context for all windows. In wglMakeCurrent, you’ll always pass the only context you have but each window will pass it’s hdc. It has worked for me perfectly ever since, in at least 10 diferent OpenGL drivers. The only catch is that if you want to have different states set in different windows, you’ll have to store them in you app, and the set the window’s states when you change the hdc for the context. For example, when changing from a wireframe window to a solid window, change glPolygonMode(GL_LINE) to GL_FILL.

Thanks a lot for your reply.

I could try using a single rendering context for all windows, but the problem is that the seven different contexts (as they are now) are all visible and updated concurrently. With only two forms I only get two hDCs. Perhaps I will try having one hDC per window. But first I’m hoping that the idea of generating and deleting each texture on the fly will work, as this will be simpler.

Yes, generating and deleting one texture on the fly has worked, thankfully.