Render to texture

I’ve just added render to texture feature to my build of Xith3D.

Here are a few screenshots ;

Radial Blur (Nehe lesson 36)

http://vbousquet.free.fr/Xith3d/RadialBlur.png

Cube rendered on the faces of a cube

http://vbousquet.free.fr/Xith3d/CubeInCube.png

This is my first post and my first participation to an open source projet. Therefore I don’t know how to contribute so I post everything here ;

Here are the source for the examples and the cvs diff ;
http://vbousquet.free.fr/Xith3d/CubeInCube.java
http://vbousquet.free.fr/Xith3d/RadialBlur.java
http://vbousquet.free.fr/Xith3d/mychanges.diff

This is mainly a first post to get feedback on this work.
I think the code still needs a few improvements to be usable by other peoples.

Bye

           Vincent

Heck !!! This looks nice dude :smiley:
How much rendering efford does it take?

The code is very simple.

I don’t think it costs too much FPS since it uses JOGL PBuffer which are based on either WGL_ARB extension or NVidia extension which are known to be the most effective offscreen surface (compared to render to back buffer then copy, and similar techniques).

Anyway, my videocard is quite old (early Geforce 2) and everything runs at full speed.

Sounds (and looks) great! What does the API look like? Could you submit a patch?

Have to a look to the sample.

The easier to understand is the CubeInCube one.

The code is very easy to use ;

First, you create a texture canvas like this ;

ITextureCanvasPeer tcp = renderPeer.makeTextureCanvas(displayCanvas.get3DPeer(), 256, 256);

And then you can use it just as any canvas peer.

To use the rendered texture, you just have to use the getTexture method the created canvas. For example like this ;

appearance.setTexture(tcp.getTexture());

Now when you want to update your texture (i.e. you want to render to the texture), you just call view.renderOnce() on the view attached to the texture canvas.

Bye

         Vincent

great stuff!

Sign up to the Xith3D project (https://xith3d.dev.java.net/) for the role BetaTester. I will approve it ASAP.

Once approved, you can submit Issues with patches, etc. Announcing it on the forums is good oto, but though IssueZilla a perminent record is kept which is good. One of the Xith3D dev’s (probably me) will then go though your patch, and then commit it in.

The only thing I would ask is that you port your changes to the LWJGL renderer as well. As this renderer is officially supported by Xith3D, we can’t accept patches that improve one renderer without the other (unless it is currently not possible, which is rare).

I’d love to see this feature in Xith3D. Nice going ;D

Cheers,

Will.

Hi,

This is very good and critical change.

I would like to coordinate addition of Render-to-texture with other changes of Xith3D.

Vincent, I would suggest you to search this forum for my previous posts (maybe half a year or even more ago) discussing multipass rendering, because of RTT is exactly subject for this change.

I have clear concept of how to add multipass rendering to Xith3D (covering stereo rendering, multi-projection rendering, render-to-texture, rendering reflections, etc.), but still not so much time to implement this.

In the meantime, how I already noted in other post, there is a new work coming, and there I will need multipass rendering in Xith3D anyway.

I planned to implement several different techniques for RTT, including true RTT as well as screen buffer re-use technique (involving copying part of screen buffer to texture).

You can contact me via PIM for more details, but of course we can also discuss this on the forum.

Yuri

It will be nice to have this feature.

Are we placing issue 93 on hold (https://xith3d.dev.java.net/issues/show_bug.cgi?id=93) for the time being then?

Yuri, do you have a draft timeline for the addition of these features? They will be very valuable additions to Xith3D.

Will.

Sorry, I’m not so good at this :slight_smile:
How do I install this great update?
Help is appreciated :slight_smile:

Alonzo

The update is just a proposal. It has not yet made it to be ‘official’. It is not finished and is mainly for testing purpose.

If you want to try it, you should use th one posted ont he issue manager (issue 93 i think) which fix a few bugs and support LWJGL as well as JOGL.

This is the result of a cvs diff command against a fresh cvs checkout.

I don’t know how to apply a diff. I suggest you look to cvs manual.

Sorry

Vincent

Vincent,

We can post an experimental build with your changes if you like to xith.org. This is a good way for people to try it out.

If you email me a zip or tar.gz of your xith3d directory, with a compiled xith3d.jar with your changes, I shall upload it.

Will.

Something new in this topic?

+1! I would really like to use this feature soon! Is it close to being added to CVS?

I’ve placed the compiled jar and source tree of my changes under the following links ;

http://vbousquet.free.fr/Xith3d/xith3d.jar
http://vbousquet.free.fr/Xith3d/src.zip

If you want to try/use them, remember that this is just a proposal and that it is likely that render to texture will be implemented an other way in the core.

The jar is compiled with the examples (CubeInCube and RadialBlur) using lwjgl.

Bye

             Vincent

I get the following exception when I create a Window containing a Canvas3D attached to a View that also has a TextureCanvas attached to it:

Exception in thread “AWT-EventQueue-0” net.java.games.jogl.GLException: pbuffer
creation error: wglCreatePbufferARB() failed: tried 8 pixel formats, last error
was: (Unknown error code 0)
at net.java.games.jogl.impl.windows.WindowsPbufferGLContext.createPbuffe
r(WindowsPbufferGLContext.java:304)
at net.java.games.jogl.impl.windows.WindowsOnscreenGLContext.makeCurrent
(WindowsOnscreenGLContext.java:135)
at net.java.games.jogl.impl.GLContext.invokeGL(GLContext.java:246)
at net.java.games.jogl.impl.windows.WindowsOnscreenGLContext.invokeGL(Wi
ndowsOnscreenGLContext.java:76)
at net.java.games.jogl.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas
.java:228)
at net.java.games.jogl.GLCanvas.reshape(GLCanvas.java:125)
at java.awt.Component.setBounds(Unknown Source)
at java.awt.BorderLayout.layoutContainer(Unknown Source)
at java.awt.Container.layout(Unknown Source)
at java.awt.Container.doLayout(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validate(Unknown Source)
at java.awt.Window.pack(Unknown Source)
at jdm.viewer.DinoMorphViewer.(DinoMorphViewer.java:67)
at jdm.DinoMorph.startNewViewer(DinoMorph.java:192)
at jdm.gui.DinoMenuBar$8.actionPerformed(DinoMenuBar.java:369)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown
Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

Any ideas?

Could you post a bit more info or send a bit of the code.

The strange thing in your code is that it seems that you are creating the rendered texture in the reshape JOGL event.

This may cause the problem since the actual code does not implement freeing of the created PBuffers. Therefore you may create a lot of them in a sequence of reshape events whithout freeing anything. I will have a look to add releasing of PBuffers since it’s needed even if it’s not the cause of your problem.

Another question is does the examples work on your system or not ?

And knowing a bit of your hardware/driver could help as well.

     Vincent

Ok… got it working on a different computer. I’m not sure what the problem was, or why it was crashing when I resized the viewer :slight_smile: I am noticing another weirdness though. I want to attach the texture canvas to the same View that the standard canvas is attached to so that I can do high-res captures. When I attach both canvases to the same View, my machine grinds to a halt (memory leak?). This does not seem to be an issue if I use two separate Views.

[quote]+1! I would really like to use this feature soon! Is it close to being added to CVS?
[/quote]
I’m investigating this matter. Hopefully we will have the Render to Texture feature in the core soon, I am looking forward to using it too.

BTW - if anyone want’s to check out Niwak’s source pretty printed, use these links :slight_smile:
http://showsrc.com/$http://vbousquet.free.fr/Xith3d/CubeInCube.java
http://showsrc.com/$http://vbousquet.free.fr/Xith3d/RadialBlur.java

Cheers,

Will.

So using your code, how would one get a BufferedImage from the TextureCanvasPeer or RenderTexture? I have been unsuccessful in doing this :frowning:

It’s not really designed for offscreen rendering so there is no straight forward solution.

I think the easiest solution is to render your scene to a big texture. Then render your texture to a classic canvas (using a simple quad) and take snapshots.

If the texture is bigger than the display canvas, just render it by making 4 passes (one for each corner) and take 4 snapshots. You will have to combine the 4 BufferedImage to get the complete high res snapshot.

     Vincent