MultiPassView - Can I add it as a package to xith.tk?

I made these two classes for the multipass rendering that got spawned from this thread: http://www.java-gaming.org/forums/index.php?topic=10611.0

MultiPassView.java


import java.util.ArrayList;

import com.xith3d.render.jogl.*;
import com.xith3d.scenegraph.*;


public class MultiPassView extends View {
	private CanvasPeerImpl m_peerImpl;
	private ArrayList<RenderPass> m_renderPasses;
	private BranchGroup m_sceneGraph;
	
	public MultiPassView(CanvasPeerImpl peerImpl, Locale locale) {
		super();
		m_peerImpl = peerImpl;
		m_renderPasses = new ArrayList<RenderPass>(128);
		m_sceneGraph = new BranchGroup();
		m_sceneGraph.setPickable(true);
		locale.addBranchGraph(m_sceneGraph);	
	}
	
	public void addRenderPass(RenderPass pass) {
		if (m_renderPasses.size() == 0) {
			m_renderPasses.add(pass);
		} else {
			switch (pass.getZAlignment()) {
				default:
				case RenderPass.ALIGN_Z_FAR :
					m_renderPasses.add(0, pass);
					break;
				case RenderPass.ALIGN_Z_CLOSE :
					m_renderPasses.add(m_renderPasses.size() - 1, pass);
					break;
				case RenderPass.ALIGN_Z_CLOSEST :
					m_renderPasses.add(pass);
					break;
			}
		}

		m_sceneGraph.addChild(pass.getNode());
	}
	
	public void removeRenderPass(RenderPass pass) {
		int index = m_renderPasses.indexOf(pass);
		m_renderPasses.set(index, null);
		m_sceneGraph.removeChild(pass.getNode());
	}
	
	public void renderAll() {
		for (int i = 0; i < m_renderPasses.size(); i++) {
			
			// get render pass
			RenderPass pass = m_renderPasses.get(i);
			
			// set node
			pass.getNode().setRenderable(true);

			// set projection policy
			if (pass.getProjectionPolicy() == View.PARALLEL_PROJECTION) {
				setProjectionPolicy(View.PARALLEL_PROJECTION);
			} else {
				setProjectionPolicy(View.PERSPECTIVE_PROJECTION);
			}
			
			// set clear buffer state
			if (i == 0) {
				m_peerImpl.setDisableClearBuffer(false);
			} else {
				m_peerImpl.setDisableClearBuffer(true);
			}
			
			// set force swap state
			if (i < m_renderPasses.size() - 1) {
				m_peerImpl.setForceNoSwap(true);
			} else {
				m_peerImpl.setForceNoSwap(false);
			}
			
			// render
			renderOnce();
			
			// unset node
			pass.getNode().setRenderable(false);
		}
	}
}

and

RenderPass.java


import com.xith3d.scenegraph.Node;

/**
 * @author Jaakko
 *
 */
public class RenderPass {

	public static final int ALIGN_Z_FAR = 0;
	public static final int ALIGN_Z_CLOSE = 1;
	public static final int ALIGN_Z_CLOSEST = 2;

	private int m_projectionPolicy;
	private float m_nearClip;
	private float m_farClip;
	private Node m_node;
	private int m_zAlignment;
	
	/**
	 * 
	 */
	public RenderPass(int projectionPolicy, float nearClip, float farClip, Node node) {
		this(projectionPolicy, nearClip, farClip, node, ALIGN_Z_CLOSE);
	}
	
	/**
	 * 
	 */
	public RenderPass(int projectionPolicy, float nearClip, float farClip, Node node, int zAlignment) {
		m_projectionPolicy = projectionPolicy;
		m_nearClip = nearClip;
		m_farClip = farClip;
		m_node = node;
		m_zAlignment = zAlignment;
		m_node.setRenderable(false);
	}
	
	/**
	 * @return Returns the zAlignment.
	 */
	public int getZAlignment() {
		return m_zAlignment;
	}

	/**
	 * @param alignment The zAlignment to set.
	 */
	public void setZAlignment(int zAlignment) {
		m_zAlignment = zAlignment;
	}

	/**
	 * @return Returns the farClip.
	 */
	public float getFarClip() {
		return m_farClip;
	}
	
	/**
	 * @param clip The farClip to set.
	 */
	public void setFarClip(float clip) {
		m_farClip = clip;
	}
	
	/**
	 * @return Returns the nearClip.
	 */
	public float getNearClip() {
		return m_nearClip;
	}
	
	/**
	 * @param clip The nearClip to set.
	 */
	public void setNearClip(float clip) {
		m_nearClip = clip;
	}
	
	/**
	 * @return Returns the node.
	 */
	public Node getNode() {
		return m_node;
	}
	
	/**
	 * @param m_node The node to set.
	 */
	public void setNode(Node node) {
		m_node = node;
	}
	
	/**
	 * @return Returns the projectionPolicy.
	 */
	public int getProjectionPolicy() {
		return m_projectionPolicy;
	}
	
	/**
	 * @param policy The projectionPolicy to set.
	 */
	public void setProjectionPolicy(int policy) {
		m_projectionPolicy = policy;
	}
}

Now can I add them as a new package to the toolkit?
I’ll provide good javadoc comments and make a test program as required.

:slight_smile:

Looks nice to me.

Only one thing:

I believe code should be 1.4 for compilant for the toolkit, you’re using 1.5 (generics)

Oh yeah you are right, I’ll change that…
Also I noticed that there is potentially a NullPointerExeption thrown in the render() method.

Well, ill fix those and then, who do I need to get the “green light” from for committing the new package?

Java 6.0 will be released this Summer. We should start thinking about permitting 5.0 contributions to Xith.

Yeah, there are other nice things in 5.0. Like for example System.nanoTime() , a high resolution timer. Perfect for counting update times.

Now that Java 1.5 is fairly mature, I personally don’t have a problem with moving to it. I don’t plan to distribute anything in the near future though, people who do may think differently (I don’t know). Perhaps the community should vote on this?

Until we officially switch (if we do), contributions should be 1.4 though.

You are certainly welcome to add this as a tool to the Xith-TK project. I wonder if they should be added to the core instead though, seems like something a lot of people may want and could become an integral part of Xith3D.

I’m thinking of ways this class can be expanded

Perhaps you could add a [url=http://www.xith.org/tutes/GettingStarted-back-3/html/using_renderoptions.htmlRenderOptions[/url] variable to the RenderPass class (and call SetRenderOptions on CanvasPeer prior to rendering) so it’s even more customisable?

I wonder - would there be a way of integrating features like render to texture into this framework? This has been a long standing request and there is an example implementation: http://www.java-gaming.org/forums/index.php?topic=8361.0 (not sure those links still work - one very good example of why to use IssueZilla and not the forums for these things…)

More discussions on such issues:
http://www.java-gaming.org/forums/index.php?topic=8657.0
https://xith3d.dev.java.net/issues/show_bug.cgi?id=93
https://xith3d.dev.java.net/issues/show_bug.cgi?id=101

As Yuri mentions in Issue #101, one thing you lose when using a Scenegraph is more direct control over the rendering, etc.

Depending on how you use your new MultiPassView class, you could have much more control over the render order which is nice.

Thanks for your contribution!

Cheers,

Will.

Ok, well ill add it to the toolkit now so i get it out, then you decide weather it will end up in the core.
I’ll look into those subjects as i have done that.

I have been thinking about that too, and i came up with an idea which im not sure if it would work, but here it is:

Make a Node (I used extending from Group) that doesnt get drawn when its getting processed during render time. Instead it executes a code snippet provided by the programmer. I overided the getChildren() method so that it calls its own run() method – containing the code you wanna execute in the middle of render time – then it returns a empty ArrayList. I havent really tested this since im not so good at immediate mode rendering ( which i think this could be used to ). I guess it could be used for just about anything you usually would like to do in the midst of the rendering.
Does this sound like a awful hack? If it does, i better shut my mouth and keep the wild ones to my self… :smiley:

Sounds good, put it into the toolkit, we can see how it goes (and think about other enhancements).

What package name are you thinking of using?

It does work, but the catch is, as Yuri comments in 101 (worth a read if you havn’t), you mess with Xith3D’s state management system and abstraction layer with LWJGL and JOGL. It might get the job done, but your code will probably break when Xith3D’s updated. Most reasons for needing this I think probably could be added to Xith3d proper, and using the multiple render passes is probably a part of this.

Will.

How would org.xith3d.scenegraph.MultiPassView and org.xith3d.scenegraph.RenderPass be?

Or maybe just org.xith3d.multipass.*

com.xith3d.scenegraph.MultiPassView and com.xith3d.scenegraph.RenderPass seems fine to me.
Yes it needs to be in the core, and yes you should be able to have control on rendering order.

I tried to add the package to the toolkit but i dont have ‘Add’ rights to the project.
Id like to have a folder named org.xith3d.multipass.

I tested that the tookit builds fine with the ant build and javadoced the sources.
I still have to write the package level javadoc description and a test program.

Anyway here is the whole package…

Did you re-checkout your xith-tk with your user name (as opposed to anonymous which is possibly what you used when you firsed checked it out)? I think you should have ‘add’ permissions. I have added the folder as requested anyway.

Will.

Ok, thanks. Ill try it tonight.

I would ber interested in seeing a small example of how to use these.

Still cant add… :frowning:

I’ll make a complete example when i can commit properly, unitll that here is a quick incomplete example:

`

// create the render peer
renderPeer = new RenderPeerImpl();
canvasPeerImpl = (CanvasPeerImpl) renderPeer.makeCanvas(frame, frame.getWidth(), frame.getHeight(), graphicsMode.getBitDepth(), graphicsDevice.getFullScreenWindow() != null);
canvas3d = new Canvas3D();
canvas3d.set3DPeer(canvasPeer);

// create the virtual universe
virtualUniverse = new VirtualUniverse();

// create a locale for the universe
locale = new Locale();
virtualUniverse.addLocale(locale);

// create a view for the universe
view = new MultiPassView(canvasPeer, locale);

virtualUniverse.addView(view);

// This far all looks pretty normal, but now comes the multiview setup

RenderPass background = new RenderPass(View.PERSPECTIVE_PROJECTION, 0.1f, 10.0f, new Background(new Color3f(0,0,0)));
view.addRenderPass(background);

RenderPass scene = new RenderPass(View.PERSPECTIVE_PROJECTION, 0.1f, 3000.0f, new BranchGroup(), RenderPass.ALIGN_Z_CLOSEST);
view.addRenderPass(scene);

RenderPass hud = new RenderPass(View.PARALLEL_PROJECTION, 0.1f, 100.0f, new Foreground(new BranchGroup(), View.VIEW_FIXED), RenderPass.ALIGN_Z_CLOSEST);
view.addRenderPass(“gui”, hud); // <-- Note that we add a name for this pass so that we can refer to it easily later

// add the canvas to the view
view.addCanvas3D(canvas3d);

// the render loop
while(true) {
// Any scenegraphg updates

// for example:
// Node gui = view.getRenderPass(“gui”).getNode();
// do something with the gui, update for example a FPS counter

[i]// render in multi pass[/i]
view.renderAll();

}
`

What is your error message?

Will.

The server reported an error while performing the “cvs add” command.
xith-tk: User jaakko777 doesn’t have <VersionControl - Add> access to project xith-tk

Odd, your name didn’t appear in the xith-tk list which explains the error. Normally how it works is that a user can request a role, I get an email and approve it.

I’ve added your username as a developer - so try it again now.

Cheers,
Will.

Hi,

As a quick and simple implementation of multipass rendering it is 100% correct (I did nearly the same when was playing with pseudo-stereo (stereoglypgh) rendering with Xith3D).

Time ago I was reviewing several different engines how do they implement multipass, but still found no concept that will cover most of the needs:

  • Fullscreen Multipass (similar to one presented here)
  • Per-object multipass
  • Mixed on-screen+off-screen multipass
  • Stereo multipass
  • Multicanvas multipass
  • …and some others very specific to my applications…

The best idea that I have up to now is to … use the same concept as OrderedGroup is using, or even use the same ordered group mechanism, and add a bit more of sub-graph sharing features and extra rendering control nodes. …but I still did not finalize the concept for such a change, so treat it just as an idea.

Yuri