use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.
the class BinaryExporter method save.
public void save(Savable object, OutputStream os) throws IOException {
// reset some vars
aliasCount = 1;
idCount = 1;
classes.clear();
contentTable.clear();
locationTable.clear();
contentKeys.clear();
// write signature and version
os.write(ByteUtils.convertToBytes(FormatVersion.SIGNATURE));
os.write(ByteUtils.convertToBytes(FormatVersion.VERSION));
int id = processBinarySavable(object);
// write out tag table
int classTableSize = 0;
int classNum = classes.keySet().size();
// make all
int aliasSize = ((int) FastMath.log(classNum, 256) + 1);
// aliases a
// fixed width
os.write(ByteUtils.convertToBytes(classNum));
for (String key : classes.keySet()) {
BinaryClassObject bco = classes.get(key);
// write alias
byte[] aliasBytes = fixClassAlias(bco.alias, aliasSize);
os.write(aliasBytes);
classTableSize += aliasSize;
// jME3 NEW: Write class hierarchy version numbers
os.write(bco.classHierarchyVersions.length);
for (int version : bco.classHierarchyVersions) {
os.write(ByteUtils.convertToBytes(version));
}
classTableSize += 1 + bco.classHierarchyVersions.length * 4;
// write classname size & classname
byte[] classBytes = key.getBytes();
os.write(ByteUtils.convertToBytes(classBytes.length));
os.write(classBytes);
classTableSize += 4 + classBytes.length;
// for each field, write alias, type, and name
os.write(ByteUtils.convertToBytes(bco.nameFields.size()));
for (String fieldName : bco.nameFields.keySet()) {
BinaryClassField bcf = bco.nameFields.get(fieldName);
os.write(bcf.alias);
os.write(bcf.type);
// write classname size & classname
byte[] fNameBytes = fieldName.getBytes();
os.write(ByteUtils.convertToBytes(fNameBytes.length));
os.write(fNameBytes);
classTableSize += 2 + 4 + fNameBytes.length;
}
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
// write out data to a seperate stream
int location = 0;
// keep track of location for each piece
HashMap<String, ArrayList<BinaryIdContentPair>> alreadySaved = new HashMap<String, ArrayList<BinaryIdContentPair>>(contentTable.size());
for (Savable savable : contentKeys) {
// look back at previous written data for matches
String savableName = savable.getClass().getName();
BinaryIdContentPair pair = contentTable.get(savable);
ArrayList<BinaryIdContentPair> bucket = alreadySaved.get(savableName + getChunk(pair));
int prevLoc = findPrevMatch(pair, bucket);
if (prevLoc != -1) {
locationTable.put(pair.getId(), prevLoc);
continue;
}
locationTable.put(pair.getId(), location);
if (bucket == null) {
bucket = new ArrayList<BinaryIdContentPair>();
alreadySaved.put(savableName + getChunk(pair), bucket);
}
bucket.add(pair);
byte[] aliasBytes = fixClassAlias(classes.get(savableName).alias, aliasSize);
out.write(aliasBytes);
location += aliasSize;
BinaryOutputCapsule cap = contentTable.get(savable).getContent();
out.write(ByteUtils.convertToBytes(cap.bytes.length));
// length of bytes
location += 4;
out.write(cap.bytes);
location += cap.bytes.length;
}
// write out location table
// tag/location
int numLocations = locationTable.keySet().size();
os.write(ByteUtils.convertToBytes(numLocations));
int locationTableSize = 0;
for (Integer key : locationTable.keySet()) {
os.write(ByteUtils.convertToBytes(key));
os.write(ByteUtils.convertToBytes(locationTable.get(key)));
locationTableSize += 8;
}
// write out number of root ids - hardcoded 1 for now
os.write(ByteUtils.convertToBytes(1));
// write out root id
os.write(ByteUtils.convertToBytes(id));
// append stream to the output stream
out.writeTo(os);
out = null;
os = null;
if (debug) {
logger.fine("Stats:");
logger.log(Level.FINE, "classes: {0}", classNum);
logger.log(Level.FINE, "class table: {0} bytes", classTableSize);
logger.log(Level.FINE, "objects: {0}", numLocations);
logger.log(Level.FINE, "location table: {0} bytes", locationTableSize);
logger.log(Level.FINE, "data: {0} bytes", location);
}
}
use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.
the class TestDepthFuncChange method simpleInitApp.
public void simpleInitApp() {
viewPort.setBackgroundColor(ColorRGBA.DarkGray);
flyCam.setMoveSpeed(20);
//top of the screen
//default depth func (less or equal) rendering.
//2 cubes, a blue and a red. the red cube is offset by 0.2 WU to the right
//the red cube is put in the transparent bucket to be sure it's rendered after the blue one (but there is no transparency involved).
//You should see a small part of the blue cube on the left and the whole red cube
Box boxshape1 = new Box(1f, 1f, 1f);
Geometry cube1 = new Geometry("box", boxshape1);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
cube1.setMaterial(mat);
rootNode.attachChild(cube1);
cube1.move(0, 1.5f, 0);
Geometry cube2 = cube1.clone(true);
cube2.move(0.2f, 0, 0);
cube2.setQueueBucket(RenderQueue.Bucket.Transparent);
cube2.getMaterial().setColor("Color", ColorRGBA.Red);
rootNode.attachChild(cube2);
//Bottom of the screen
//here the 2 cubes are clonned and the depthFunc for the red cube's material is set to Less
//You should see the whole bleu cube and a small part of the red cube on the right
Geometry cube3 = cube1.clone();
Geometry cube4 = cube2.clone(true);
cube4.getMaterial().getAdditionalRenderState().setDepthFunc(RenderState.TestFunction.Less);
cube3.move(0, -3, 0);
cube4.move(0, -3, 0);
rootNode.attachChild(cube3);
rootNode.attachChild(cube4);
//Note that if you move the camera z fighting will occur but that's expected.
}
use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.
the class RenderManager method renderViewPortQueues.
/**
* Render the given viewport queues.
* <p>
* Changes the {@link Renderer#setDepthRange(float, float) depth range}
* appropriately as expected by each queue and then calls
* {@link RenderQueue#renderQueue(com.jme3.renderer.queue.RenderQueue.Bucket, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera, boolean) }
* on the queue. Makes sure to restore the depth range to [0, 1]
* at the end of the call.
* Note that the {@link Bucket#Translucent translucent bucket} is NOT
* rendered by this method. Instead the user should call
* {@link #renderTranslucentQueue(com.jme3.renderer.ViewPort) }
* after this call.
*
* @param vp the viewport of which queue should be rendered
* @param flush If true, the queues will be cleared after
* rendering.
*
* @see RenderQueue
* @see #renderTranslucentQueue(com.jme3.renderer.ViewPort)
*/
public void renderViewPortQueues(ViewPort vp, boolean flush) {
RenderQueue rq = vp.getQueue();
Camera cam = vp.getCamera();
boolean depthRangeChanged = false;
// opaque objects are sorted front-to-back, reducing overdraw
if (prof != null)
prof.vpStep(VpStep.RenderBucket, vp, Bucket.Opaque);
rq.renderQueue(Bucket.Opaque, this, cam, flush);
// render the sky, with depth range set to the farthest
if (!rq.isQueueEmpty(Bucket.Sky)) {
if (prof != null)
prof.vpStep(VpStep.RenderBucket, vp, Bucket.Sky);
renderer.setDepthRange(1, 1);
rq.renderQueue(Bucket.Sky, this, cam, flush);
depthRangeChanged = true;
}
// back-to-front.
if (!rq.isQueueEmpty(Bucket.Transparent)) {
if (prof != null)
prof.vpStep(VpStep.RenderBucket, vp, Bucket.Transparent);
if (depthRangeChanged) {
renderer.setDepthRange(0, 1);
depthRangeChanged = false;
}
rq.renderQueue(Bucket.Transparent, this, cam, flush);
}
if (!rq.isQueueEmpty(Bucket.Gui)) {
if (prof != null)
prof.vpStep(VpStep.RenderBucket, vp, Bucket.Gui);
renderer.setDepthRange(0, 0);
setCamera(cam, true);
rq.renderQueue(Bucket.Gui, this, cam, flush);
setCamera(cam, false);
depthRangeChanged = true;
}
// restore range to default
if (depthRangeChanged) {
renderer.setDepthRange(0, 1);
}
}
use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.
the class Camera method setClipPlane.
/**
* Sets a clipPlane for this camera.
* The clipPlane is used to recompute the
* projectionMatrix using the plane as the near plane
* This technique is known as the oblique near-plane clipping method introduced by Eric Lengyel
* more info here
* <ul>
* <li><a href="http://www.terathon.com/code/oblique.html">http://www.terathon.com/code/oblique.html</a>
* <li><a href="http://aras-p.info/texts/obliqueortho.html">http://aras-p.info/texts/obliqueortho.html</a>
* <li><a href="http://hacksoflife.blogspot.com/2008/12/every-now-and-then-i-come-across.html">http://hacksoflife.blogspot.com/2008/12/every-now-and-then-i-come-across.html</a>
* </ul>
*
* Note that this will work properly only if it's called on each update, and be aware that it won't work properly with the sky bucket.
* if you want to handle the sky bucket, look at how it's done in SimpleWaterProcessor.java
* @param clipPlane the plane
* @param side the side the camera stands from the plane
*/
public void setClipPlane(Plane clipPlane, Plane.Side side) {
float sideFactor = 1;
if (side == Plane.Side.Negative) {
sideFactor = -1;
}
//we are on the other side of the plane no need to clip anymore.
if (clipPlane.whichSide(location) == side) {
return;
}
TempVars vars = TempVars.get();
try {
Matrix4f p = projectionMatrixOverride.set(projectionMatrix);
Matrix4f ivm = viewMatrix;
Vector3f point = clipPlane.getNormal().mult(clipPlane.getConstant(), vars.vect1);
Vector3f pp = ivm.mult(point, vars.vect2);
Vector3f pn = ivm.multNormal(clipPlane.getNormal(), vars.vect3);
Vector4f clipPlaneV = vars.vect4f1.set(pn.x * sideFactor, pn.y * sideFactor, pn.z * sideFactor, -(pp.dot(pn)) * sideFactor);
Vector4f v = vars.vect4f2.set(0, 0, 0, 0);
v.x = (Math.signum(clipPlaneV.x) + p.m02) / p.m00;
v.y = (Math.signum(clipPlaneV.y) + p.m12) / p.m11;
v.z = -1.0f;
v.w = (1.0f + p.m22) / p.m23;
//clipPlaneV.x * v.x + clipPlaneV.y * v.y + clipPlaneV.z * v.z + clipPlaneV.w * v.w;
float dot = clipPlaneV.dot(v);
Vector4f c = clipPlaneV.multLocal(2.0f / dot);
p.m20 = c.x - p.m30;
p.m21 = c.y - p.m31;
p.m22 = c.z - p.m32;
p.m23 = c.w - p.m33;
setProjectionMatrix(p);
} finally {
vars.release();
}
}
use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.
the class TestShaderNodesStress method simpleInitApp.
@Override
public void simpleInitApp() {
Quad q = new Quad(1, 1);
Geometry g = new Geometry("quad", q);
g.setLocalTranslation(-500, -500, 0);
g.setLocalScale(1000);
rootNode.attachChild(g);
cam.setLocation(new Vector3f(0.0f, 0.0f, 0.40647888f));
cam.setRotation(new Quaternion(0.0f, 1.0f, 0.0f, 0.0f));
Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md");
//Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Yellow);
mat.setTexture("ColorMap", tex);
g.setMaterial(mat);
//place the geoms in the transparent bucket so that they are rendered back to front for maximum overdraw
g.setQueueBucket(RenderQueue.Bucket.Transparent);
for (int i = 0; i < 1000; i++) {
Geometry cl = g.clone(false);
cl.move(0, 0, -(i + 1));
rootNode.attachChild(cl);
}
flyCam.setMoveSpeed(20);
Logger.getLogger("com.jme3").setLevel(Level.WARNING);
this.setAppProfiler(new Profiler());
}
Aggregations