Can JOGL be used without requiring GLAutoDrawable instances?

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Can JOGL be used without requiring GLAutoDrawable instances?

xghost
This post was updated on .
Hi all,

I'm currently working on a project to develop a relatively small framework with the goal of supporting game development efforts for students in a course. The scope of this project is an OpenGL-based renderer and a 3D scene graph, and must be written in Java. (That's the course pre-req. for students.)

I've been using JOGL for a while and have also played around a bit with LWJGW3 --yes, I dare disturb you by mentioning a competitor :D--

There're some things I'd like to do, but I'm finding the requirement to have a GLAutoDrawable object a bit of a hassle. For example, I want to hide the library dependency from clients (i.e. clients use my interface, not JOGL directly). However, if/when needs to use a shader object (one I make available, not JOGL's ShaderProgram class), they'd need to be able to have a reference to the gl object for it to work, leaking the fact that I'm using JOGL through the interface.

More concretely, code that looks like this example below:

    program.<Float> getInput("position_x").set(0.5f);

would have to look, say, like this:

    GL4 gl = ... // get an drawable.getGL(), etc...
    program.<Float> getInput("position_x").set(gl, 0.5f);

...which is problematic; I want to avoid leaking JOGL 'knowledge' to the client program.

For comparison, the static nature of LWJGL3 allows me use OpenGL functions at any point, without the requirement for an object instance like the GLAutoDrawable or implementing the GLEventListener interface --though it introduces other problems by having its own window mgmt API with GLFW, which causes similar 'leakage' on the input/event management side of the equation (i.e. cannot implement interfaces like MouseListener, KeyListener, etc).

Is there some way in which  JOGL can be used to make OpenGL calls (e.g. glUseProgram(...)) statically without GLAutoDrawable instance inside void display(GLAutoDrawable), or equivalent? I want to be able to make OpenGL calls anytime/anywhere.

I hope this made sense. You should try taking a look at this post where I went into a bit more detail in some areas, if you feel you need clarification.

I'd appreciate concrete suggestions, especially if you can provide actual examples what would illustrate your point more clearly.

Thanks in advance,

-x

PS: BTW I've thought about using LWJGL3 + JOGL simultaneously. Is this even a good idea, or just a bomb of problems waiting go off? For example, if a GLCanvas were to be added to a JFrame and then, instead of using autodrawables in the display(...) override, I end up using OpenGL calls from the LWJGL3 instead. Is this even possible in principle as long as the GLContext is current?
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

jmaasing
So, you are writing a wrapper around a library and that library uses callbacks, then you ofc need to wrap the callbacks also. That means that your library needs to wrap the window/frame/whatever drawable. It should also wrap the input handling. Then the client code register with the your library to get your library to call the client when it is time to draw or get keyboard input et c. That callback from your library to the client will expose only your library classes, these classes in turn can be wrappers around whatever native-bridge library you use.

You can look at the source code for the OSS projects like: LibGDX, Ardour3D, jMonkeyEngine to see how they do it. All of them hide the JOGL implementation by having their own 'render' interface.
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

Xerxes Rånby
In reply to this post by xghost
There is good reasons behind why the JOGL API is NOT static:
Why does JOGL use Instances of GLContext / GL* instead of exposing a Static API?
http://forum.jogamp.org/Why-does-JOGL-use-Instances-of-GLContext-GL-instead-of-exposing-a-Static-API-td4034144.html

Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
In reply to this post by jmaasing
jmaasing wrote
So, you are writing a wrapper around a library and that library uses callbacks, then you ofc need to wrap the callbacks also. That means that your library needs to wrap the window/frame/whatever drawable. It should also wrap the input handling. Then the client code register with the your library to get your library to call the client when it is time to draw or get keyboard input et c. That callback from your library to the client will expose only your library classes, these classes in turn can be wrappers around whatever native-bridge library you use.

You can look at the source code for the OSS projects like: LibGDX, Ardour3D, jMonkeyEngine to see how they do it. All of them hide the JOGL implementation by having their own 'render' interface.
Of course I could spend a significant amount of effort wrapping everything... but I think that seems to miss the point of, or not address, what I'm asking. I've checked some, not all, libraries (e.g. a bit of libGDX, a lot of Ogre3D) as I've been working on some things, but I don't think it's immediately practical for me to simply go around chasing every possible library someone can name in a "Check lib ____" comment :)

I'll take a brief look at some of those tomorrow to see if I find something relevant to my question in the meantime, but if you'd like me to clarify something in my original post here or the link provided, please let me know.


Xerxes Rånby wrote
There is good reasons behind why the JOGL API is NOT static:
Why does JOGL use Instances of GLContext / GL* instead of exposing a Static API?
http://forum.jogamp.org/Why-does-JOGL-use-Instances-of-GLContext-GL-instead-of-exposing-a-Static-API-td4034144.html
I think you may've misunderstood my post. I'm not questioning design decisions in JOGL or anything like that, so a post on why JOGL was designed like this, although interesting, is not too helpful at this point for me.

Please let me know if there's something I should clarify in my original post, etc.

Thanks again,
-x
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

Sven Gothel
Administrator
In reply to this post by xghost
On 07/23/2015 07:50 AM, xghost [via jogamp] wrote:

> Hi all,
>
> I'm currently working on a project to develop a relatively small
> framework with the goal of supporting game development efforts for
> students in a course. The scope of this project is an OpenGL-based
> renderer and a 3D scene graph, and must be written in Java. (That's
> the course pre-req. for students.)
>
> I've been using JOGL for a while and have also played around a bit
> with LWJGW3 --yes, I dare disturb you by mentioning a competitor
> :D--
>
> There're some things I'd like to do, but I'm finding the requirement
> to have a GLAutoDrawable object a bit of a hassle. For example, I
> want to hide the library dependency from clients (i.e. clients use my
> interface, not JOGL directly). However, if/when needs to use a shader
> object (one I make available, not JOGL's ShaderProgram class), they'd
> need to be able to have a reference to the gl object for it to work,
> leaking the fact that I'm using JOGL through the interface.
>
> More concretely, code that looks like this example below:
>
> program.<Float> getInput("position_x").set(0.5f);
>
> would have to look, say, like this:
>
> GL4 gl = ... // get an drawable.getGL(), etc... program.<Float>
> getInput("position_x").set(gl, 0.5f);
>
> ...which is problematic; I want to avoid leaking JOGL 'knowledge' to
> the client program.
As Xerxes mentioned, there is a good reason for exposing OpenGL's
dynamic instance model
<http://forum.jogamp.org/Why-does-JOGL-use-Instances-of-GLContext-GL-instead-of-exposing-a-Static-API-td4034144.html>.

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.

  public interface APIContext {};
  /** pp */ class APIState implements APIContext { final GL gl; ... }

Or .. not recommended:

[2] In case your API follows some sort of state constraints:
   - makeCurrent
     - user stuff w/ public API
   - release
   You could use thread local storage, i.e. ThreadLocal<>

~Sven



signature.asc (828 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
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();
		}
	}
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

Sven Gothel
Administrator
On 07/25/2015 03:25 AM, xghost [via jogamp] wrote:

>     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.
OK.
Just for the record, the GLAutoDrawable/GLEventListener 'assisted rendering'
paradigm is optional, even though it is recommended.
One can always use plain GLDrawable/GLContext etc. and handle the details
manually.

>
> 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.
You may confuse ShaderProgram w/ ShaderCode.
The latter merely holds the source code or binary code for one shader
and _can_ be instantiated w/o a GL instance.

Yes, ShaderCode's factory create(..) methods require a GL instance (for now),
which is used to query GLSL capabilities.
This can be avoided by using the public ShaderCode constructor
and optionally the readShaderSource(..) method.
We might want to change some of ShaderCode's API, e.g. drop the GL instance.
This can only happen for our next minor release 2.4.*,
where API changes are allowed.

The ShaderCode and ShaderProgram does require the GL instance all of its
methods performing OpenGL operations, ofc.

I hope this helps a bit.

~Sven



signature.asc (828 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
Sven Gothel wrote
OK.
Just for the record, the GLAutoDrawable/GLEventListener 'assisted rendering'
paradigm is optional, even though it is recommended.
One can always use plain GLDrawable/GLContext etc. and handle the details
manually.
Hi Sven,

Can you elaborate on this a bit? I'm not sure I'm familiar with this way of using JOGL. Does this mean that I can do something along the following lines without needing to be inside one of the GLEventListener overrides or something?:

private void someMethodThatIsNotGLEventListenerDisplayOverride() {
	GL4 gl = GLContext.getGL().getGL4();
	gl.glUseProgram(...);
	// ... more arbitrary OpenGL calls, etc...
}

I mean, if it's something that would allow me to request and get a GL instance at arbitrary locations, then it seems to be what I'm looking for --at least if I'm understanding this correctly.


Sven Gothel wrote
You may confuse ShaderProgram w/ ShaderCode.
The latter merely holds the source code or binary code for one shader
and _can_ be instantiated w/o a GL instance.
The ShaderProgram class has the link(...) method, which requires a GL instance to be passed in. This is what I had in mind, but yes the thing is that when the class needs to perform OpenGL calls internally, it needs the GL instance, which is what I was trying to avoid in the public interface of my shader classes.

For example, when I instantiate one of my attributes (e.g. below), OpenGL calls need to be issued (at least with the current design):

program.createFloatInput("position_x", GpuShaderProgram.Input.Type.ATTRIBUTE);

It'll be expected to hold its own valid attribute ID. Since I already get the name, and the shader program itself is built, then this will (internally) result in an OpenGL call to glGetAttribLocation:

public Input<Float> createFloatInput(String name, Input.Type type) {
	switch (type) {
		case ATTRIBUTE:
			return new GLSLFloatProgramAttribute1(this, name);
		// ...
	}
}
// ....
GLSLFloatProgramAttribute1(GpuShaderProgram shader, String attributeName) {
	// ... 
	location = glGetAttribLocation(shader.getId(), attributeName);
	// ...
}

Normally, for this to happen a valid/non-cached GL instance would have to be made available somewhere here (e.g. publicly when the client wants to call the createFloatInput method above to allow the gl.glGetAttribLocation(...) call).

Something similar would be true when setting a value for the program input. For example, the line below would be expected to send the value for the GLSL vec4(1, 1, 1, 1) to the vertex program uniform, which would require an OpenGL call to glUniform4f in this case:

program.createVec4Input("frag_color", GpuShaderProgram.Input.Type.UNIFORM);
// ...
program.<Vec4> getInput("frag_color").set(Vec4f.createFrom(1f, 1f, 1f, 1f));
// ...
@Override
public void set(Vec4 v) {
	// setting the frag_color uniform input :)
	glUniform4f(location, v.getX(), v.getY(), v.getZ(), v.getW());
}

But for that, it'd also need a GL instance available.

Perhaps (fingers crossed) your previous suggestion to do things manually might allow me to accomplish/reach the intended goal. That being said, I'm also open to updating my code ofc.


Sven Gothel wrote
The ShaderCode and ShaderProgram does require the GL instance all of its
methods performing OpenGL operations, ofc.
Yes, and this is the part that I'm trying to allow, but without placing a GL parameter in the public interface as I wrap the JOGL binding dependency inside of my own.


Sven Gothel wrote
I hope this helps a bit.

~Sven
It does and I appreciate everyone's time, involvement, and help in this.

Thanks again,
-x
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
xghost wrote
Does this mean that I can do something along the following lines without needing to be inside one of the GLEventListener overrides or something?:

private void someMethodThatIsNotGLEventListenerDisplayOverride() {
	GL4 gl = GLContext.getGL().getGL4();
	gl.glUseProgram(...);
	// ... more arbitrary OpenGL calls, etc...
}
The following seems to be possible, at arbitrary locations and without a need to use GLEventListener:

	GL4 gl = com.jogamp.opengl.GLContext.getCurrentGL().getGL4();
	gl.glUseProgram(0);
	// ...

Please let me know if I'm running into a time-bomb waiting to go off or if this is just fine. If this is a good way to use JOGL, then it seems it might allow me to do exactly what I needed.

I'll wait for advice on this kind of use.

Thanks in advance,
-x
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

Sven Gothel
Administrator
In reply to this post by xghost
On 07/25/2015 11:35 PM, xghost [via jogamp] wrote:

>     Sven Gothel wrote
>     OK.
>     Just for the record, the GLAutoDrawable/GLEventListener 'assisted rendering'
>     paradigm is optional, even though it is recommended.
>     One can always use plain GLDrawable/GLContext etc. and handle the details
>     manually.
>
> Hi Sven,
>
> Can you elaborate on this a bit? I'm not sure I'm familiar with this way of
> using JOGL. Does this mean that I can do something along the following lines
> without needing to be inside one of the GLEventListener overrides or something?:
I am just referring to the fact, that one does not need to use
the GLAutoDrawable/GLEventListener 'assisted' API model,
but can also use the GLDrawableFactory to create a GLDrawable
instance and create the GLContext manually.

I would not recommend this path, since it requires detail knowledge
about the OpenGL and windowing system lifecycle.
All of the latter is handled when using the 'assisted' API model.

This is sort of unrelated to your question, but I wanted to mention it.






signature.asc (828 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

Sven Gothel
Administrator
In reply to this post by xghost
On 07/25/2015 11:41 PM, xghost [via jogamp] wrote:

> The following seems to be possible, at arbitrary locations and without a need
> to use GLEventListener:
>
> GL4 gl = com.jogamp.opengl.GLContext.getCurrentGL().getGL4();
> gl.glUseProgram(0);
> // ...
>
>
> Please let me know if I'm running into a time-bomb waiting to go off or if
> this is just fine. If this is a good way to use JOGL, then it seems it might
> allow me to do exactly what I needed.
Well the above will work iff the desired OpenGL GLContext
is current. Otherwise a GLException is thrown or you receive
the wrong GLContext (if many different are in use).

Note: GLContext.getCurrent() will return null if none is current.

In short: Yes it can work, given above constraints.

However, it is still not the desired safe and recommended way to handle
to handle this task.

- GLContext.getCurrent() uses ThreadLocal<>, i.e. thread local storage (TLS),
  see
<http://forum.jogamp.org/Why-does-JOGL-use-Instances-of-GLContext-GL-instead-of-exposing-a-Static-API-td4034144.html>.

- Why querying an instance of a suppose to be known object
  within the workflow of a determined API/system?

In the end .. it is your design decision, of course!

Cheers, Sven



signature.asc (828 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

gouessej
Administrator
In reply to this post by Sven Gothel
Sven Gothel wrote
I would not recommend this path, since it requires detail knowledge
about the OpenGL and windowing system lifecycle.
All of the latter is handled when using the 'assisted' API model.
It sums up pretty well the situation, thanks.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
In reply to this post by Sven Gothel
Sven Gothel wrote
I would not recommend this path, since it requires detail knowledge
about the OpenGL and windowing system lifecycle.
All of the latter is handled when using the 'assisted' API model.
That makes sense. Thanks for the clarification.

Sven Gothel wrote
Well the above will work iff the desired OpenGL GLContext
is current. Otherwise a GLException is thrown or you receive
the wrong GLContext (if many different are in use).

Note: GLContext.getCurrent() will return null if none is current.

In short: Yes it can work, given above constraints.
Yes, the javadocs seemed to make this point, but It's good to see that I'm not about to cause a massive problem in the long-term, AFAIK. The application is expected to have a single window and OpenGL context, so I don't anticipate this becoming a problem.

Sven Gothel wrote
However, it is still not the desired safe and recommended way to handle
to handle this task.
What would your recommendation be for the kind of task I'm trying to achieve?

For example, one of my GLSL uniform classes looks as shown below. If you notice the 'set' method, it simply allows the client to call/set the value without making the GL instance visible. If there's a safer and better way to achieve this kind of goal, I'm open to it. (Yes, I already refactored the code to use JOGL and I have things working, which is why the code below is no longer showing the static call to LWJGL3.)

class GLSLFloatProgramUniform1 extends GLSLProgramUniform<Float> implements GpuShaderProgram.Input<Float> {

	// ...

	@Override
	public void set(Float value) {
		GL4 gl = GLContext.getCurrentGL().getGL4();
		gl.glUniform1f(location, value);
	}

	// ...

}


Sven Gothel wrote
- GLContext.getCurrent() uses ThreadLocal<>, i.e. thread local storage (TLS),
  see
<http://forum.jogamp.org/Why-does-JOGL-use-Instances-of-GLContext-GL-instead-of-exposing-a-Static-API-td4034144.html>.

- Why querying an instance of a suppose to be known object
  within the workflow of a determined API/system?
Read all of it, but I didn't find the question you seemed to want me to read about.

Sven Gothel wrote
In the end .. it is your design decision, of course!

Cheers, Sven
Yup, just trying to make an informed decision so I won't regret it in hindsight :)

Thanks again,

-x
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

gouessej
Administrator
This post was updated on .
xghost wrote
Yes, the javadocs seemed to make this point, but It's good to see that I'm not about to cause a massive problem in the long-term, AFAIK. The application is expected to have a single window and OpenGL context, so I don't anticipate this becoming a problem.
It might be a problem anyway and I don't see the benefit of not using our assisted API in a trivial case, I don't see any gain.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
gouessej wrote
...I don't the benefit of not using our assisted API in a trivial case, I don't see any gain.
Hi gouessej,

I'll try to simplify.

1. I have a requirement to decouple the client code using my library from the detail/fact that my library is (internally) using JOGL itself.

2. Using the assisted API (e.g. client code implementing GLEventListener) will cause clients to be 'aware' of JOGL's existence inside my library, breaking the JOGL encapsulation requirement (e.g. anything that makes GL instances directly visible/accessible to clients).

3. Client needs to work with shaders directly (e.g. set shader program input values, etc), hence my shader interfaces, as per the above code snippets.

A bit of background: I've started a project that will be used in the long-term, but mostly for teaching purposes. It's not a trivial library, but it also won't be aiming to be a triple-A thing. We want to keep it "simple" enough to be understood within a single semester, but as complicated as needed to support students in game development projects, if that makes sense. We're in the process of replacing an older version of the same framework that has been in use for several years.

gouessej wrote
It might be a problem anyway...
Now, I hear there're problems, though I'm not sure what (specifically) those problems are supposed to be and how to avoid the pitfalls, other than what Sven and the javadocs already mentioned re GLContext.

Could you please expand on these? What recommendation would you make that would help avoid the problems you're thinking about (would appreciate additional info on what they are) and also meet the basic requirements I summarized above?

Please let me know if there's something you think I should clarify.

Thanks in advance,
-x
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

gouessej
Administrator
I'm not sure that using the assisted API forces you to expose anything that would be a concern for the encapsulation.

Sorry for the confusion. If you don't use the assisted API, you might have some problems anyway in some cases, for example when the OpenGL context must be created on a particular thread or when its creation is expected to fail several times on very poor drivers under Windows.

Why not using the assisted API without exposing any GL instances directly? The desire of hiding JOGL sometimes leads to badly designed code. Moreover, if your students need to code in OpenGL, they will have to use JOGL. Look at how I "hide" JOGL most of the time in several major scenegraph API including JogAmp's Ardor3D Continuation and JMonkeyEngine.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
gouessej wrote
I'm not sure that using the assisted API forces you to expose anything that would be a concern for the encapsulation.
Maybe for clarification, but what parts do you consider part of the 'assisted API'? Just want to make we're on the same page and that I'm not misunderstanding something.


gouessej wrote
Sorry for the confusion. If you don't use the assisted API, you might have some problems anyway in some cases, for example when the OpenGL context must be created on a particular thread or when its creation is expected to fail several times on very poor drivers under Windows.
Are you thinking that I'm trying to create an OpenGL context 'manually'? I do intend to implement interfaces like GLEventListener (in a Renderer impl class), and this part is pretty easy to hide from clients.


gouessej wrote
Why not using the assisted API without exposing any GL instances directly?
Pending clarification on 'assisted API', it seems this would be preferable.

gouessej wrote
The desire of hiding JOGL sometimes leads to badly designed code.
But not hiding details that are/should-be internal to my library (e.g. JOGL) would cause undesired coupling. I'm trying to avoid both :)


gouessej wrote
Moreover, if your students need to code in OpenGL, they will have to use JOGL.
They're not expected to work directly with OpenGL, only with a class to manage the scene and, at the lowest level, the renderer, but not directly with OpenGL API. (There's a separate course on graphics using OpenGL for that.) They're however, expected to interact with shaders in an abstracted way, which is where the classes I'm working on come in.


gouessej wrote
Look at how I "hide" JOGL most of the time in several major scenegraph API including JogAmp's Ardor3D Continuation and JMonkeyEngine.
I took a look at the JOGL renderers in both JME3 and Ardor3D frameworks.

The JoglRenderer classes in both frameworks are doing exactly what I'm doing inside of my shader classes when I want to let users apply operations (e.g. set the value for a uniform in a shader) without exposing the JOGL and/or GL instances to them, i.e. using the GLContext to get the GL instance.


This example, starting in line 128, does that when letting clients set the background color:
// in com.ardor3d.renderer.jogl.JoglRenderer
@Override
public void setBackgroundColor(final ReadOnlyColorRGBA c) {
    final GL gl = GLContext.getCurrentGL();

    _backgroundColor.set(c);
    gl.glClearColor(_backgroundColor.getRed(), _backgroundColor.getGreen(), _backgroundColor.getBlue(), _backgroundColor.getAlpha());
}


Something similar happens in JME3's JoglRenderer, with its initialize() method is invoked (starting line 148):
// in com.jme3.renderer.jogl.JoglRenderer
public void initialize() {
    GL gl = GLContext.getCurrentGL();
    // ... some comments ....
    if (gl.isExtensionAvailable("GL_VERSION_2_0")) {
    // ....

For comparison, a relevant portion in one of my shader classes representing a Uniform input for a shader. Notice that the GL instance is not passed in, it's acquired just like in the previous snippets from Ardor3D/JME3:
@Override
public void set(Float value) {
    // ...
    GL4 gl = GLContext.getCurrentGL().getGL4();
    gl.glUniform1f(location, value);
}

However, if I understand you correctly, using JOGL this way is what you're recommending against. Is this correct?

I'm thinking that I may've misunderstood what you mean by 'assisted API' or something else, perhaps.

Thanks again,
-x
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

gouessej
Administrator
I was talking about JogAmp's Ardor3D Continuation, not about the old unmaintained Ardor3D, please look at the bottom of this page, there is a complete section about Ardor3D:
http://jogamp.org/wiki/index.php/Main_Page

Please use an animator and at least one GLEventListener. Don't create your own context manually, use GLAutoDrawable, don't swap your buffers manually except if you have a good reason to do so and if you really know what you are doing.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

xghost
gouessej wrote
I was talking about JogAmp's Ardor3D Continuation, not about the old unmaintained Ardor3D
Thanks for the clarification. Was not aware of the difference.

gouessej wrote
please look at the bottom of this page, there is a complete section about Ardor3D:
http://jogamp.org/wiki/index.php/Main_Page
I took a look (e.g. com.ardor3d.framework.jogl.JoglCanvas) and we seem to be doing similar things, so it seems ok.

gouessej wrote
Please use an animator...
I intended to call the internal GLCanvas' display() method when it's the renderer's "turn" to process things (e.g. renderer.renderScene() ). If you think there's something that makes the Animator a requirement, please let me know. The docs don't seem to give that impression.

gouessej wrote
and at least one GLEventListener. Don't create your own context manually, use GLAutoDrawable, don't swap your buffers manually except if you have a good reason to do so and if you really know what you are doing.
Yup, already had the do's and don't's  covered, and updates to the render target already take place by using the canvas' display method, which is what the Animator makes use of.

Thanks for the help,
-x




Reply | Threaded
Open this post in threaded view
|

Re: Can JOGL be used without requiring GLAutoDrawable instances?

gouessej
Administrator
JogAmp's Ardor3D Continuation contains almost 90 commits ahead of the legacy Ardor3D, I don't advise you to look at com.ardor3d.framework.jogl.JoglCanvas as I hesitated to deprecate it.

Using a plain animator (Animator) would allow you to keep concentrated on the rest. An animator can use some code specific to AWT depending on the drawable you use, look at AWTAnimatorImpl. Therefore, I advise you to use a plain animator even for a very dumb example.
Julien Gouesse | Personal blog | Website
12