Sharing textures over multiple GLCanvases

As the title suggests I want to be able to render with the same texture on two different GLCanvases.

I’m building a toolkit (tilemap editor) which would need one GLCanvas to draw the main surface and one to draw the tileset. The reason for keeping those separate is that it makes resizing easier (JSplitPane) and tracking mouse clicks when selecting tiles from the tileset and then when placing them on the actual tilemap.

I’ve come up with a solution where I store my textures in a Map<GLAutoDrawable, Map<String,Texture>> where I can keep one set of textures per GLAutoDrawable and then access the textures by a string.

Although this works it feels wrong.

Any input is welcome.

You can share the textures between the two contexts of the GLCanvases. GLCanvas has another constructor that takes a GLContext as an argument. If this is non-null, the new GLCanvas will share textures with that context.

How would I go about and do that? I’ve been trying a few different setups but I can’t seem to figure this out.

My initialization looks like this:



// Creating Tile Canvas and adding it to
// split pane  (subclass of GLCanvas)
GLProfile glP = GLProfile.getDefault();
GLCapabilities glC = new GLCapabilities(glP);
		
tileCanvas = new TileCanvas(glC);
splitPane_1.setLeftComponent(tileCanvas);

// Creating tile selector (subclass of GLCanvas)
this.tileSelector = new TileSelector(glC, tileCanvas.getContext());
splitPane_1.setRightComponent(this.tileSelector);

The only thing that gets it rendering both scenes is if I create another Texture for the TileCanvas and bind it during its rendering.

If TileCanvas and TileSelector are types you defined, I’m assuming that they extend GLCanvas or GLJPanel. You need to make sure that the TileSelector constructor that takes a GLContext is properly passing it to its super constructor.

If you’re using GLJPanel, strange things might be going on and I’m not sure if context sharing is actually supported. This is because the GLJPanel uses a PBuffer underneath the hood and the PBuffer is recreated every time the GLJPanel changes size. Since GLCanvas is a heavy weight component it does not have this problem since its context stays the same.

In your case, if you’re using the GLJPanel as the super type for TileCanvas and TileSelector, when the split pane is first show, everything resizes and the pbuffers are probably recreated, so the GLContext initially used is different.

To fix that, you can explicitly create a 1x1 GLPBuffer and use it as the shared context to both your canvas and selector panels. That way, even if they internally recreate their own contexts, both will be sharing with the global 1x1 pbuffer you set up first. Using a pbuffer in this case is also nice because it always has a context, unlike with a GLCanvas which doesn’t always get one until it’s visible.

As a final note, I don’t think it’s the best practice to subclass GLCanvas. Instead you should use GLEventListeners to draw when necessary.