Create context without Display, and share it with a Display later. [SOLVED]

Started by Kirov Anatoly, April 28, 2015, 11:11:22

Previous topic - Next topic

Kirov Anatoly

Hello,

This is my first post here, and I hope I'm in the right place.

I've been trying to do the following:

1 Create Context 1 and load assets into it in a thread, without spawning a window.
2 Create Context 2, shared with context 1, and attach it to a Display.

I've found some solutions for 1, primarily a version where you create a PBuffer object and make it current.
I've not found a solution for both 1 and 2, and so I solved it like this:

By modifying the sealed parameter of lwjgl.jar, create a new class in package "org.lwjgl.opengl"
In this class, spawn the PBuffer as explained, create a shared context from the pbuffer, and
*and this is the terrible part*
create an anonymous DrawableGL instance without (additional) implementation, to wrap the new context.
Feed the anonymous Drawable instance to a display.create method.

This works, as far as I can tell, but it might as well break down at any time.
It's a horrible approach to this problem, I must be missing something!

Can anyone help me find a better way?

Thanks in advance.

Here's the code:

package org.lwjgl.opengl;

import org.lwjgl.LWJGLException;

public class SharedContextTest{
	public SharedContextTest() throws LWJGLException{
		//basic context settings
		PixelFormat pixelFormat = new PixelFormat();
		ContextAttribs contextAtrributes = new ContextAttribs(3, 3)
		.withForwardCompatible(true)
		.withProfileCore(true);
		
		//create context without spawning window
	    Pbuffer pbuffer = new Pbuffer(1, 1, pixelFormat, null, null, contextAtrributes);
	    
	    //create empty drawable to pass to Display later
	    DrawableGL drawable = new DrawableGL(){
	    	
	    };
	    
	    //prepare drawable for Display
	    drawable.context = pbuffer.createSharedContext();
		
	    //setup display
		org.lwjgl.opengl.Display.setFullscreen(false);
		org.lwjgl.opengl.Display.setDisplayMode(new DisplayMode(512,512));
		org.lwjgl.opengl.Display.setResizable(true);
		org.lwjgl.opengl.Display.create(pixelFormat, drawable, contextAtrributes);
		
		//test some draw code
		GL11.glClearColor(0, 1,0,1);
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
		GL11.glEnable(GL11.GL_SCISSOR_TEST);
		GL11.glScissor(0, 0, 100, 100);
		GL11.glClearColor(1, 0,0,1);
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
		GL11.glDisable(GL11.GL_SCISSOR_TEST);
		Display.update();
		
		//wait a second so you can see the draw code works
		try{
			Thread.sleep(1000);
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws LWJGLException{
		new SharedContextTest();
	}
}


EDIT: Please, any help is appreciated!

spasi

You can pass the Pbuffer instance to Display.create directly. Pbuffer is a drawable (extends DrawableGL), there is no need to create a new one.

spasi

Btw, if you're new to LWJGL, give LWJGL 3 a try. It's much simpler for stuff like this. In this specific case you don't even have to use a Pbuffer; just create a hidden window, do any loading, then show the window when the context is ready.

Kirov Anatoly

Thanks!

I also missed the fact that the Display.create makes a shareddrawable if you supply one, stupid me.

I'll look into LWJGL 3, but I thought it wasn't done yet?

Thanks again!

spasi

It depends on your definition of done. If you mean feature-parity with LWJGL 2.x, then this is what's missing currently:

- Window icons (on Windows/Linux)
- Many vendor-specific extensions
- OpenGL ES
- AWT integration (will not be added)
- The util package (will not be added)

If you don't need any of the above, LWJGL 3 is basically done. GLFW, OpenGL and OpenAL, the 3 bindings most users need, work perfectly fine right now. If you really need some extensions that are currently missing, let us know and they'll be given priority.