Drawing an outline around objects

Started by orsharir, November 22, 2012, 04:15:26 PM

Previous topic - Next topic

orsharir

Hello,

We want to draw an outline / silhouette around selected objects in my scene (see the attachment for example). I've already implemented this effect using pure OpenGL on the iOS version of our app, and now I need to implement it on the Android version that is using jPCT.

How I do this on iOS, is draw the object 4 times:
1) Draw the object with 0 alpha, while disabling the update to the depth mask, and replacing the stencil buffer with ones where the object is painted.
2) Draw a scaled up version of the object with a constant color except where the stencil buffer is 1 (that is, where the actual regular object would be).
3) The same as above but with a scaled down version.
4) Draw the regular object normally.

The effect is quite simple and looks good enough for our use on iOS, but I have no idea how I could implement it using jPCT on Android. I have noticed that I could use IRenderHook to modify the stencil buffer, depth mask etc, so that part is easy. The issue is that I need to control the drawing order, so that I could draw using the above sequence, and I've seen now way to achieve that.

Any help would be greatly appreciated.

[attachment deleted by admin]

EgonOlsen

The IRenderHook has a method repeatRendering(). It that one returns true, the geometry will be rendered again. You might want to try to add your direct gl calls at that stage and trigger a new rendering with the new setting. Just keep in mind that you have to fiddle around the gl matrices yourself at this stage, because changes in scaling of the Object3D won't be taken into account here.

orsharir

Thanks, I'm looking into it right now, though I've stumble upon a small issue: Right now we're using OpenGL 2 with jPCT, so how can we modify the modelview matrix that is passed to the built-in default shader that jPCT uses?

Again, many thanks for the help.

EgonOlsen

In the IRenderHook, you can implement setCurrentObject3D() to store the current object being rendered. Then, in repeatRendering(), you can call getShader() on that Object3D and set your matrix.

orsharir

I'm sorry, but I see no documentation for "getShader()" in Object3D or anywhere else. Is it available on a newer version of the library?

EgonOlsen

Opps, you are right. You can get the beta version that includes it from here: http://jpct.de/download/beta/jpct_ae.jar

orsharir

Great, Thanks!
So I should call it like so to set the model view matrix?
GLSL shader = object.getShader();
shader.setUniform("modelViewMatrix", myModelViewMatrix);

EgonOlsen


EgonOlsen

....thinking of it, i'm not sure if this will actually work. Might be that the uniforms won't be transfered to the actual shader at that stage. Just give it a try....if it doesn't work, we have to find something that will...

orsharir

For some reason getShader() always returns null when called from repeatRendering. Any ideas?

EgonOlsen

Yes...that's because the default shaders as well as their uniforms are somehow implicit. I'll have to change some stuff to make this work. I'll look into it this evening.

EgonOlsen

Ok, i've updated the beta jar. IRenderHook now has an additional method called setCurrentShader(<GLSLShader>); That one will be called after beforeRendering() when the shader has been assigned...may it be a user defined one or a default shader. In repeatRendering(), you can then modify the uniforms of that shader, especially should you be able to set new values for the implicit uniforms like modelViewMatrix and similar.
However, you'll have to write your own shader anyway (or modify one of the default shaders) to switch rendering from textured to single colored. In that process, you could simply add some additional scale value as well, so that you don't have to fiddle around with the matrices directly.

orsharir

#12
Edit: Got it working! Thank you for guiding me through it all.

Thanks for the quick fix and all you help so far! I've actually stated working on my own shader that I've passed explicitly to my class that implements IRenderHook, just as you've suggested (Now I can use the new method you've added instead, which is more flexible).
I have a few more question though:
1) I what stage repeatRendering() is called? Is it after the object was drawn to the framebuffer or before?
2) If several objects share the same instance of the same IRenderHook, is it guaranteed that each object would execute "beforeRendering()->repeatRendering()->afterRendering()" synchronously, or is it asynchronous, that is, under some conditions is it possible that (for instance) between repeatRendering and afterRendering of object A, object B will call beforeRendering or repeatRendering?

Again, thank you so much for your help.