Michael Ludwig avatar Michael Ludwig committed c9d5e4d

Comments (0)

Files changed (11)

 			<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Ferox2/lib"/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="lib" path="data/ferox-textures.jar"/>
+	<classpathentry kind="lib" path="resource/ferox-textures.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

src/com/ferox/renderer/impl/AbstractRenderer.java

 	public static enum RenderState {
 		WAITING_INIT, /** State of the renderer before init() is called */
 		IDLE,		  /** State of the renderer when it's not doing anything */
+		PIPELINE,
+		RESOURCE,
 		RENDERING,    /** State of the renderer when it's in flushRenderer(). */
 		DESTROYED 	  /** State of the renderer after destroy() is called */
 	}

src/com/ferox/renderer/impl/jogl/drivers/JoglTextureStateDriver.java

 		} else if (this.lastApplied != null)
 			this.apply(this.factory.getRenderer(), this.factory.getRecord(), null);
 		
-		// clear single unit if possible
-		if (this.lastApplied == this.singleUnit && this.queuedTexture != this.singleUnit)
-			this.singleUnit.setTexture(0, null); // clear reference here, since we don't need it anymore
 		this.lastApplied = this.queuedTexture;
 		
 		this.reset();
 		this.queuedTexture = null;
 		this.queuedInfluence = -1f;
 		this.lastAppliedDirty = false;
-		// we can't reset singleUnit here because it may be in use in lastAppliedState
 	}
 	
 	/* Modify the given context so that its TextureRecord matches the given MultiTexture.

src/com/ferox/renderer/util/RenderQueueDataCache.java

 package com.ferox.renderer.util;
 
-import java.lang.ref.WeakReference;
 import java.util.WeakHashMap;
 
 import com.ferox.renderer.RenderQueue;
  *
  */
 public class RenderQueueDataCache {
-	private static WeakReference<RenderQueue> frequentContext = null;
+	private static RenderQueue frequentContext = null;
 	private static int frequentId = -1;
 	
 	private static WeakHashMap<RenderQueue, Integer> idMap = new WeakHashMap<RenderQueue, Integer>();
 	 * any previous value.
 	 * 
 	 * Does nothing if the RenderQueue is null. */
-	public void setRenderQueueData(RenderQueue RenderQueue, Object data) {
-		if (RenderQueue == null)
+	public void setRenderQueueData(RenderQueue renderQueue, Object data) {
+		if (renderQueue == null)
 			return;
 		
-		int id = getId(RenderQueue);
+		int id = getId(renderQueue);
 		if (id >= this.renderQueueData.length) {
 			Object[] temp = new Object[id + 1];
 			System.arraycopy(this.renderQueueData, 0, temp, 0, this.renderQueueData.length);
 	 * Returns null if the RenderQueue never set any data, or if it set null.
 	 * 
 	 * Returns null if the RenderQueue is null. */
-	public Object getRenderQueueData(RenderQueue RenderQueue) {
-		if (RenderQueue == null)
+	public Object getRenderQueueData(RenderQueue renderQueue) {
+		if (renderQueue == null)
 			return null;
 		
-		int id = getId(RenderQueue);
+		int id = getId(renderQueue);
 		if (id >= this.renderQueueData.length)
 			return null;
 		return this.renderQueueData[id];
 	
 	// internally manage and retrieve RenderQueue ids, assumes RenderQueue isn't null
 	private static int getId(RenderQueue renderQueue) {
-		if (frequentContext != null && frequentContext.get() == renderQueue)
+		if (frequentContext != null && frequentContext == renderQueue)
 			return frequentId;
 		
 		Integer id = idMap.get(renderQueue);
 			idMap.put(renderQueue, id);
 		}
 		
-		frequentContext = new WeakReference<RenderQueue>(renderQueue);
+		frequentContext = renderQueue;
 		frequentId = id;
 		return id;
 	}

src/com/ferox/resource/GeometryBoundsCache.java

+package com.ferox.resource;
+
+import com.ferox.math.AxisAlignedBox;
+import com.ferox.math.BoundSphere;
+import com.ferox.math.BoundVolume;
+
+/** GeometryBoundsCache is a convenience class that implements 
+ * bound volume caching for spheres and axis-aligned boxes to
+ * make it easier for Geometry implementations to implement
+ * their getBounds() method.
+ * 
+ * @author Michael Ludwig
+ *
+ */
+public class GeometryBoundsCache {
+	private final Geometry geometry;
+	
+	private final AxisAlignedBox axisCache;
+	private final BoundSphere sphereCache;
+	
+	private boolean axisDirty;
+	private boolean sphereDirty;
+	
+	/** Construct a bounds cache for the given geometry instance.
+	 * If it's null, an exception is thrown. */
+	public GeometryBoundsCache(Geometry geom) throws NullPointerException {
+		if (geom == null)
+			throw new NullPointerException("geom can't be null");
+		
+		this.geometry = geom;
+		this.axisCache = new AxisAlignedBox();
+		this.sphereCache = new BoundSphere();
+		
+		this.axisDirty = true;
+		this.sphereDirty = true;
+	}
+	
+	/** Store the bounds of this cache's geometry into result.
+	 * Does nothing if result is null.
+	 * 
+	 * If the cache has been marked dirty since the last getBounds()
+	 * call, the axis or sphere cache will first be updated by calling
+	 * enclose() on this cache's geometry. */
+	public void getBounds(BoundVolume result) {
+		if (result != null) {
+			if (result instanceof AxisAlignedBox) {
+				if (this.axisDirty) {
+					this.axisCache.enclose(this.geometry);
+					this.axisDirty = false;
+				}
+				this.axisCache.clone(result);
+			} else if (result instanceof BoundSphere) {
+				if (this.sphereDirty) {
+					this.sphereCache.enclose(this.geometry);
+					this.sphereDirty = false;
+				}
+				this.sphereCache.clone(result);
+			} else
+				result.enclose(this.geometry);
+		}
+	}
+	
+	/** Mark the cache as dirty, so that the next call to getBounds()
+	 * will update the cache to reflect changes to the geometry. */
+	public void setCacheDirty() {
+		this.axisDirty = true;
+		this.sphereDirty = true;
+	}
+}

src/com/ferox/resource/geometry/BufferedGeometry.java

 
 import java.util.List;
 
-import com.ferox.math.AxisAlignedBox;
-import com.ferox.math.BoundSphere;
 import com.ferox.math.BoundVolume;
 import com.ferox.math.Boundable;
 import com.ferox.resource.BufferData;
 import com.ferox.resource.Geometry;
+import com.ferox.resource.GeometryBoundsCache;
 import com.ferox.resource.UnitList;
 import com.ferox.resource.BufferData.DataType;
 import com.ferox.resource.UnitList.Unit;
 		}
 	}
 	
-	private BoundSphere sphereCache;
-	private AxisAlignedBox axisCache;
+	private final GeometryBoundsCache boundsCache;
 	
 	private GeometryArray<T> vertices;
 	private GeometryArray<T> normals;
 	protected BufferedGeometry() {
 		this.texCoords = new UnitList<GeometryArray<T>>();
 		this.vertexAttribs = new UnitList<GeometryArray<T>>();
+		this.boundsCache = new GeometryBoundsCache(this);
 	}
 	
 	/*
 		return this.polyCount;
 	}
 	
-	/** Force the bound volume caches to be re-updated,
-	 * possibly before a call to getBounds().  It is recommended
-	 * to call this before prior to clearing the client memory
-	 * for the vertices. */
-	public void computeBoundsCache() {
-		this.axisCache = new AxisAlignedBox();
-		this.axisCache.enclose(this);
-		
-		this.sphereCache = new BoundSphere();
-		this.sphereCache.enclose(this);
-	}
-	
 	/** Clear the cached bounding volumes.  The next time
 	 * getBounds is called with either a AxisAlignedBox,
 	 * or BoundSphere, the cached bounds for that type will
 	 * be re-computed from scratch. */
 	public void clearBoundsCache() {
-		this.axisCache = null;
-		this.sphereCache = null;
+		this.boundsCache.setCacheDirty();
 	}
 	
 	/*
 	
 	@Override
 	public void getBounds(BoundVolume result) {
-		if (result != null) {
-			if (result instanceof AxisAlignedBox) {
-				if (this.axisCache == null) {
-					this.axisCache = new AxisAlignedBox();
-					this.axisCache.enclose(this);
-				}
-				this.axisCache.clone(result);
-			} else if (result instanceof BoundSphere) {
-				if (this.sphereCache == null) {
-					this.sphereCache = new BoundSphere();
-					this.sphereCache.enclose(this);
-				}
-				this.sphereCache.clone(result);
-			} else
-				result.enclose(this);
-		}
+		this.boundsCache.getBounds(result);
 	}
 
 	@Override

src/com/ferox/resource/geometry/Sphere.java

 	}
 	
 	public Sphere(float radius, int zSamples, int radialSamples) {
-		this(null, radius, zSamples, radialSamples, SphereTextureMode.ORIGINAL);
+		this(radius, zSamples, radialSamples, SphereTextureMode.ORIGINAL);
+	}
+	
+	public Sphere(float radius, int zSamples, int radialSamples, SphereTextureMode mode) {
+		this(null, radius, zSamples, radialSamples, mode);
 	}
 	
 	public Sphere(Vector3f center, float radius, int zSamples, int radialSamples, SphereTextureMode mode) {
 		if (zSamples < 0 || radialSamples <= 0)
 			throw new IllegalArgumentException("zSamples and radialSamples must be > 0");
 		
-		int vertexCount = (this.zSamples - 2) * (this.radialSamples + 1) + 2;
+		int vertexCount = (zSamples - 2) * (radialSamples + 1) + 2;
 		this.vertices = new float[vertexCount * 3];
 		this.normals = new float[vertexCount * 3];
 		this.texCoords = new float[vertexCount * 2];
 		
-		int triCount = 6 * this.radialSamples * (this.zSamples - 2);
+		int triCount = 6 * radialSamples * (zSamples - 2);
 		this.indices = new int[triCount];
 
 		this.center = new Vector3f();

src/com/ferox/resource/glsl/GlslVertexAttribute.java

 		if (owner == null)
 			throw new NullPointerException("GlslProgram cannot be null");
 		
-		if (bindingSlot < 0)
-			throw new IllegalArgumentException("BindingSlot must be >= 0: " + bindingSlot);
+		if (bindingSlot < 1)
+			throw new IllegalArgumentException("BindingSlot must be >= 1: " + bindingSlot);
 		if (name.startsWith("gl"))
 			throw new IllegalArgumentException("Name cannot start with 'gl': " + name + ", that is reserved");
 		

src/com/ferox/resource/text/Text.java

 
 import java.awt.font.LineMetrics;
 
-import com.ferox.math.AxisAlignedBox;
-import com.ferox.math.BoundSphere;
 import com.ferox.math.BoundVolume;
 import com.ferox.math.Color;
 import com.ferox.resource.Geometry;
+import com.ferox.resource.GeometryBoundsCache;
 import com.ferox.state.AlphaTest;
 import com.ferox.state.Appearance;
 import com.ferox.state.BlendMode;
 	private float[] coords; // it is interleaved T2F_V3F
 	private int numCoords;
 	
-	private AxisAlignedBox cacheBox;
-	private BoundSphere cacheSphere;
+	private final GeometryBoundsCache boundsCache;
 	
 	private Object renderData;
 	
 			throw new NullPointerException("Must provide a non-null CharacterSet");
 		
 		this.charSet = charSet;
+		this.boundsCache = new GeometryBoundsCache(this);
+		
 		this.setText(text);
 		this.setWrapWidth(-1f);
 		
 		this.numCoords = tl.getNumGlyphs() * 4;
 		this.layoutDirty = false;
 		
-		// reset the bound caches
-		this.cacheBox = null;
-		this.cacheSphere = null;
+		this.boundsCache.setCacheDirty();
 	}
 
 	@Override
 	public void getBounds(BoundVolume result) {
-		if (result != null) {
-			if (result instanceof AxisAlignedBox) {
-				if (this.cacheBox == null) {
-					this.cacheBox = new AxisAlignedBox();
-					this.cacheBox.enclose(this);
-				}
-				this.cacheBox.clone(result);
-			} else if (result instanceof BoundSphere) {
-				if (this.cacheSphere == null) {
-					this.cacheSphere = new BoundSphere();
-					this.cacheSphere.enclose(this);
-				}
-				this.cacheSphere.clone(result);
-			} else
-				result.enclose(this);
-		}
+		this.boundsCache.getBounds(result);
 	}
 
 	@Override

test/com/ferox/BasicApplication.java

 
 import java.awt.Font;
 import java.awt.Frame;
+import java.util.Formatter;
 
 import org.openmali.vecmath.Vector3f;
 
  */
 public abstract class BasicApplication extends ApplicationBase {
 	public static final long UPDATE_TIME = 100; // ms between updates of fps text
-	
+		
 	protected OnscreenSurface window;
 	protected BasicRenderPass pass;
 	protected BasicRenderPass fpsPass;
 	
 	private long lastFpsUpdate;
 	
+	private StringBuilder fpsStringBuilder;
+	private Formatter fpsFormatter;
+	
 	public BasicApplication(boolean debug) {
 		super(debug);
 	}
 		
 		this.pass = new BasicRenderPass(null, v, this.createQueue(), false);
 		
-		//this.window = renderer.createFullscreenSurface(new DisplayOptions(), 800, 600);
-		this.window = renderer.createWindowSurface(this.createOptions(), 10, 10, 1024, 768, false, false);
+		//this.window = renderer.createFullscreenSurface(new DisplayOptions(), 1024, 768);
+		this.window = renderer.createWindowSurface(this.createOptions(), 10, 10, 640, 480, false, false);
 		this.window.addRenderPass(this.pass);
 		this.window.setTitle(this.getClass().getSimpleName());
 		
 		this.pass.setScene(this.scene);
 		
 		CharacterSet charSet = new CharacterSet(Font.decode("Arial-Bold-16"), true, false);
-		this.fpsText = new Text(charSet, "FPS: \nMeshes: \nPolygons: \nUsed: \nFree: ");
+		this.fpsText = new Text(charSet, "FPS: \nMeshes: \nPolygons: \nUsed: ");
+		this.fpsStringBuilder = new StringBuilder();
+		this.fpsFormatter = new Formatter(this.fpsStringBuilder);
 		
 		renderer.requestUpdate(charSet.getCharacterSet(), true);
 		renderer.requestUpdate(this.fpsText, true);
 		this.lastFpsUpdate = 0;
 	}
 	
+	private static Vector3f origin = new Vector3f();
+	private static Vector3f up = new Vector3f(0f, 1f, 0f);
 	@Override
 	protected boolean update() {
-		this.view.lookAt(new Vector3f(), new Vector3f(0f, 1f, 0f), true);
+		this.view.lookAt(origin, up, true);
 		this.scene.update(true);
 		return false;
 	}
 			if (System.currentTimeMillis() - this.lastFpsUpdate > UPDATE_TIME) {
 				this.lastFpsUpdate = System.currentTimeMillis();
 				Runtime run = Runtime.getRuntime();
-				this.fpsText.setText("FPS: " + this.stats.getFramesPerSecond() + "\nMeshes: " + this.stats.getMeshCount() + "\nPolygons: " + this.stats.getPolygonCount() 
-									 + "\nUsed: " + run.totalMemory() / 1e6f + " M\nFree: " + run.freeMemory() / 1e6f + " M");
+				this.fpsStringBuilder.setLength(0);
+				this.fpsFormatter.format("FPS: %.2f\nMeshes: %d\nPolygons: %d\nUsed: %.2f / %.2f M", this.stats.getFramesPerSecond(), 
+																									 this.stats.getMeshCount(),
+																									 this.stats.getPolygonCount(),
+																									 (run.totalMemory() - run.freeMemory()) / 1e6f,
+																									 run.totalMemory() / 1e6f);
+				this.fpsText.setText(this.fpsStringBuilder.toString());
 				renderer.requestUpdate(this.fpsText, true);
 			}
 			

test/com/ferox/scene/RttCubeTest.java

 import com.ferox.state.Texture.TexCoordGen;
 
 public class RttCubeTest extends BasicApplication {
-	public static final boolean DEBUG = true;
+	public static final boolean DEBUG = false;
 	public static final boolean USE_VBO = true;
 	public static final boolean RANDOM_PLACEMENT = true;
 	
 		if (i % 2 == 0) {
 			lr = new LightReceiver();
 			m.setSmoothShaded(true);
-			lr.setSeparateSpecular(true);
 		} {
 			fr = new FogReceiver();
 			fr.setFogCoordinateSource(FogCoordSource.FRAGMENT_DEPTH);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.