Login  Register

Re: Can JOGL be used without requiring GLAutoDrawable instances?

Posted by xghost on Jul 25, 2015; 1:25am
URL: https://forum.jogamp.org/Can-JOGL-be-used-without-requiring-GLAutoDrawable-instances-tp4034953p4034966.html

Sven Gothel wrote
You can do at least two things.

[1] Hiding JOGL details by wrapping the GL instance in an
implementation specific class, which implements a public interface.
This way, your users don't know the details .. but your implementation
has access to your inner states, at least JOGL's GL instance.
Hi Sven,

I agree. That's what I was doing, but in a separate RenderSystem class, which would internally implement the GLEventListener and simply expose a public method that would, in turn, cause the GLCanvas' display() method to be invoked (e.g. OpenGL4RenderSystem implements RenderSystem, GLEventListener // as a package private, only RenderSystem public, create impl using factory/manager). That part always seemed straightforward, though I may not have explained myself as well at first.

The part that I feel I've not found straightforward to address is that I do want the client/user to work with shaders directly, as shown in my code snippet at the bottom (part of a working test class). That snippet is not using JOGL, but something I like is that the user/client can work with the shader object, 'declare' shader inputs, build the shader, set values for inputs, and so on, while keeping the public interface fairly simple and binding-agnostic. This is what I'd expect the client to work with directly, even after the GL instance is hidden away in a renderer class that implements the GLEventListener, etc.

But notice that when the client asks the program to 'build()', if we expect that to happen immediately, instead of say, get queued as some sort of command (a complication I'd like to avoid), then it seems the GL instance would have to be exposed. I might be missing something, but it seems even the JOGL ShaderProgram class does this --although that's not a problem for JOGL itself.

After the client has provided the shader, it would simply send the 'current' shader program to the (not-yet-implemented) renderer class that I expect to work on in the near future.

There're a lot of things I like about JOGL, particularly the fact that it integrates nicely with current Java components and stuff, and that was what I first tried using before I tried playing/learning LWJGL3 for the sake of a comparison. I liked that LWJGL3 allowed me to create the public interface I wanted in my GpuShaderProgram interface, but that's about it from what I've experienced. I'm trying to find a way to basically keep the same interface as shown below, but using JOGL instead.

I hope I'm making sense.

Thanks again,

-x

        private void setupShader() {
		shaderMgr = new GpuShaderProgramManager();
		GpuShaderProgram program = shaderMgr.createShaderProgram(PROGRAM_NAME, GpuShaderProgram.Type.GLSL);
		GpuShaderSubProgram vertexShader = program.createSubProgram(VERTEX_NAME, Stage.VERTEX_SHADER, getSourceVS());
		GpuShaderSubProgram fragShader = program.createSubProgram(FRAGMENT_NAME, Stage.FRAGMENT_SHADER, getSourceFS());
		program.add(vertexShader);
		program.add(fragShader);
		program.build();

		program.add(program.createFloatInput("position_x", GpuShaderProgram.Input.Type.ATTRIBUTE));
		program.add(program.createFloatInput("position_y", GpuShaderProgram.Input.Type.UNIFORM));
		program.add(program.createVec4Input("position_v", GpuShaderProgram.Input.Type.ATTRIBUTE));
		program.add(program.createVec4Input("frag_color", GpuShaderProgram.Input.Type.UNIFORM));
                // ...
	}

	public void run() {
		while (...) {
                        // ...
			GpuShaderProgram program = shaderMgr.getShaderProgram(PROGRAM_NAME);
			program.attach();
			program.<Float> getInput("position_x").set((float) (Math.sin(System.currentTimeMillis() / 1000.0) * 0.5));
			program.<Float> getInput("position_y").set((float) (Math.cos(System.currentTimeMillis() / 1000.0) * 0.5));
			program.<Vec4> getInput("position_v").set(Vec4f.createFrom(0f, 0f, 0f, 1f));
			program.<Vec4> getInput("frag_color").set(Vec4f.createFrom(1f, 1f, 1f, 1f));
			glDrawArrays(GL_POINTS, 0, 1);
			program.detach();
		}
	}