Merge remote-tracking branch 'origin/master' into jme3-vr-dev
This commit is contained in:
commit
52eb6946af
@ -20,6 +20,7 @@ The engine is used by several commercial game studios and computer-science cours
|
||||
- [3089 (on steam)](http://store.steampowered.com/app/263360/)
|
||||
- [3079 (on steam)](http://store.steampowered.com/app/259620/)
|
||||
- [Lightspeed Frontier](http://www.lightspeedfrontier.com/)
|
||||
- [Skullstone](http://www.skullstonegame.com/)
|
||||
|
||||
## Getting started
|
||||
|
||||
|
@ -33,8 +33,8 @@
|
||||
package com.jme3.app;
|
||||
|
||||
import android.os.Build;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.profile.AppStep;
|
||||
import com.jme3.profile.*;
|
||||
|
||||
import static com.jme3.profile.AppStep.BeginFrame;
|
||||
import static com.jme3.profile.AppStep.EndFrame;
|
||||
import static com.jme3.profile.AppStep.ProcessAudio;
|
||||
@ -47,7 +47,6 @@ import static com.jme3.profile.AppStep.RenderPreviewViewPorts;
|
||||
import static com.jme3.profile.AppStep.SpatialUpdate;
|
||||
import static com.jme3.profile.AppStep.StateManagerRender;
|
||||
import static com.jme3.profile.AppStep.StateManagerUpdate;
|
||||
import com.jme3.profile.VpStep;
|
||||
import static com.jme3.profile.VpStep.BeginRender;
|
||||
import static com.jme3.profile.VpStep.EndRender;
|
||||
import static com.jme3.profile.VpStep.FlushQueue;
|
||||
@ -164,4 +163,10 @@ public class DefaultAndroidProfiler implements AppProfiler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spStep(SpStep step, String... additionalInfo) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ package com.jme3.app.state;
|
||||
import android.graphics.Bitmap;
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
@ -226,6 +227,7 @@ public class VideoRecorderAppState extends AbstractAppState {
|
||||
private LinkedBlockingQueue<WorkItem> usedItems = new LinkedBlockingQueue<WorkItem>();
|
||||
private MjpegFileWriter writer;
|
||||
private boolean fastMode = true;
|
||||
private AppProfiler prof;
|
||||
|
||||
public void addImage(Renderer renderer, FrameBuffer out) {
|
||||
if (freeItems == null) {
|
||||
@ -313,6 +315,11 @@ public class VideoRecorderAppState extends AbstractAppState {
|
||||
}
|
||||
writer = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class IsoTimer extends com.jme3.system.Timer {
|
||||
|
@ -31,11 +31,10 @@
|
||||
*/
|
||||
package com.jme3.renderer.android;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.*;
|
||||
import com.jme3.renderer.RendererException;
|
||||
import com.jme3.renderer.opengl.GL;
|
||||
import com.jme3.renderer.opengl.GLExt;
|
||||
import com.jme3.renderer.opengl.GLFbo;
|
||||
import com.jme3.renderer.opengl.*;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
@ -92,6 +91,11 @@ public class AndroidGL implements GL, GLExt, GLFbo {
|
||||
GLES20.glAttachShader(program, shader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glBeginQuery(int target, int query) {
|
||||
GLES30.glBeginQuery(target, query);
|
||||
}
|
||||
|
||||
public void glBindBuffer(int target, int buffer) {
|
||||
GLES20.glBindBuffer(target, buffer);
|
||||
}
|
||||
@ -234,6 +238,11 @@ public class AndroidGL implements GL, GLExt, GLFbo {
|
||||
GLES20.glEnableVertexAttribArray(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glEndQuery(int target) {
|
||||
GLES30.glEndQuery(target);
|
||||
}
|
||||
|
||||
public void glGenBuffers(IntBuffer buffers) {
|
||||
checkLimit(buffers);
|
||||
GLES20.glGenBuffers(buffers.limit(), buffers);
|
||||
@ -244,6 +253,11 @@ public class AndroidGL implements GL, GLExt, GLFbo {
|
||||
GLES20.glGenTextures(textures.limit(), textures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenQueries(int num, IntBuffer buff) {
|
||||
GLES30.glGenQueries(num, buff);
|
||||
}
|
||||
|
||||
public int glGetAttribLocation(int program, String name) {
|
||||
return GLES20.glGetAttribLocation(program, name);
|
||||
}
|
||||
@ -271,6 +285,21 @@ public class AndroidGL implements GL, GLExt, GLFbo {
|
||||
return GLES20.glGetProgramInfoLog(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long glGetQueryObjectui64(int query, int pname) {
|
||||
IntBuffer buff = IntBuffer.allocate(1);
|
||||
//FIXME This is wrong IMO should be glGetQueryObjectui64v with a LongBuffer but it seems the API doesn't provide it.
|
||||
GLES30.glGetQueryObjectuiv(query, pname, buff);
|
||||
return buff.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetQueryObjectiv(int query, int pname) {
|
||||
IntBuffer buff = IntBuffer.allocate(1);
|
||||
GLES30.glGetQueryiv(query, pname, buff);
|
||||
return buff.get(0);
|
||||
}
|
||||
|
||||
public void glGetShader(int shader, int pname, IntBuffer params) {
|
||||
checkLimit(params);
|
||||
GLES20.glGetShaderiv(shader, pname, params);
|
||||
|
@ -121,6 +121,7 @@ public class CharacterControl extends PhysicsCharacter implements PhysicsControl
|
||||
control.setUpAxis(getUpAxis());
|
||||
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
|
||||
control.spatial = this.spatial;
|
||||
control.setEnabled(isEnabled());
|
||||
return control;
|
||||
}
|
||||
|
||||
@ -207,11 +208,12 @@ public class CharacterControl extends PhysicsCharacter implements PhysicsControl
|
||||
added = false;
|
||||
}
|
||||
} else {
|
||||
if (this.space == space) {
|
||||
return;
|
||||
if(this.space == space) return;
|
||||
// if this object isn't enabled, it will be added when it will be enabled.
|
||||
if (isEnabled()) {
|
||||
space.addCollisionObject(this);
|
||||
added = true;
|
||||
}
|
||||
space.addCollisionObject(this);
|
||||
added = true;
|
||||
}
|
||||
this.space = space;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ import com.jme3.scene.shape.Box;
|
||||
import com.jme3.scene.shape.Sphere;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -143,6 +144,8 @@ public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl
|
||||
}
|
||||
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
|
||||
control.spatial = this.spatial;
|
||||
control.setEnabled(isEnabled());
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
@ -273,9 +276,12 @@ public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl
|
||||
added = false;
|
||||
}
|
||||
} else {
|
||||
if(this.space==space) return;
|
||||
space.addCollisionObject(this);
|
||||
added = true;
|
||||
if (this.space == space) return;
|
||||
// if this object isn't enabled, it will be added when it will be enabled.
|
||||
if (isEnabled()) {
|
||||
space.addCollisionObject(this);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
this.space = space;
|
||||
}
|
||||
|
@ -200,6 +200,7 @@ public class VehicleControl extends PhysicsVehicle implements PhysicsControl, Jm
|
||||
newWheel.setWheelSpatial(wheel.getWheelSpatial());
|
||||
}
|
||||
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
|
||||
control.setEnabled(isEnabled());
|
||||
|
||||
control.spatial = spatial;
|
||||
return control;
|
||||
@ -268,9 +269,12 @@ public class VehicleControl extends PhysicsVehicle implements PhysicsControl, Jm
|
||||
added = false;
|
||||
}
|
||||
} else {
|
||||
if(this.space==space) return;
|
||||
space.addCollisionObject(this);
|
||||
added = true;
|
||||
if(this.space == space) return;
|
||||
// if this object isn't enabled, it will be added when it will be enabled.
|
||||
if (isEnabled()) {
|
||||
space.addCollisionObject(this);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
this.space = space;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ public class MeshCollisionShape extends CollisionShape {
|
||||
this.vertexStride = 12;
|
||||
this.triangleIndexStride = 12;
|
||||
this.memoryOptimized = memoryOptimized;
|
||||
this.createShape(true);
|
||||
this.createShape(null);
|
||||
}
|
||||
|
||||
private void createCollisionMesh(Mesh mesh) {
|
||||
@ -150,7 +150,7 @@ public class MeshCollisionShape extends CollisionShape {
|
||||
vertices.rewind();
|
||||
vertices.clear();
|
||||
|
||||
this.createShape(true);
|
||||
this.createShape(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -191,25 +191,19 @@ public class MeshCollisionShape extends CollisionShape {
|
||||
this.vertexBase = BufferUtils.createByteBuffer(capsule.readByteArray(MeshCollisionShape.VERTEX_BASE, null));
|
||||
|
||||
byte[] nativeBvh = capsule.readByteArray(MeshCollisionShape.NATIVE_BVH, null);
|
||||
if (nativeBvh == null) {
|
||||
// Either using non memory optimized BVH or old J3O file
|
||||
memoryOptimized = false;
|
||||
createShape(true);
|
||||
} else {
|
||||
// Using memory optimized BVH, load from J3O, then assign it.
|
||||
memoryOptimized = true;
|
||||
createShape(false);
|
||||
nativeBVHBuffer = setBVH(nativeBvh, this.objectId);
|
||||
}
|
||||
memoryOptimized=nativeBvh != null;
|
||||
createShape(nativeBvh);
|
||||
}
|
||||
|
||||
private void createShape(boolean buildBvt) {
|
||||
private void createShape(byte bvh[]) {
|
||||
boolean buildBvh=bvh==null||bvh.length==0;
|
||||
this.meshId = NativeMeshUtil.createTriangleIndexVertexArray(this.triangleIndexBase, this.vertexBase, this.numTriangles, this.numVertices, this.vertexStride, this.triangleIndexStride);
|
||||
Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Created Mesh {0}", Long.toHexString(this.meshId));
|
||||
this.objectId = createShape(memoryOptimized, buildBvt, this.meshId);
|
||||
this.objectId = createShape(memoryOptimized, buildBvh, this.meshId);
|
||||
Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Created Shape {0}", Long.toHexString(this.objectId));
|
||||
if(!buildBvh) nativeBVHBuffer = setBVH(bvh, this.objectId);
|
||||
this.setScale(this.scale);
|
||||
this.setMargin(this.margin);
|
||||
this.setMargin(this.margin);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,9 +32,7 @@
|
||||
|
||||
package com.jme3.app;
|
||||
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.profile.AppStep;
|
||||
import com.jme3.profile.VpStep;
|
||||
import com.jme3.profile.*;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue.Bucket;
|
||||
import com.jme3.scene.Mesh;
|
||||
@ -191,7 +189,13 @@ public class BasicProfiler implements AppProfiler {
|
||||
|
||||
@Override
|
||||
public void vpStep( VpStep step, ViewPort vp, Bucket bucket ) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spStep(SpStep step, String... additionalInfo) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@ import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.controls.ActionListener;
|
||||
import com.jme3.input.controls.KeyTrigger;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
@ -67,6 +68,7 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
|
||||
private String shotName;
|
||||
private long shotIndex = 0;
|
||||
private int width, height;
|
||||
private AppProfiler prof;
|
||||
|
||||
/**
|
||||
* Using this constructor, the screenshot files will be written sequentially to the system
|
||||
@ -256,7 +258,12 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by postFrame() once the screen has been captured to outBuf.
|
||||
*/
|
||||
|
@ -214,6 +214,7 @@ public class MotionEvent extends AbstractCinematicEvent implements Control, JmeC
|
||||
oc.write(rotation, "rotation", null);
|
||||
oc.write(directionType, "directionType", Direction.None);
|
||||
oc.write(path, "path", null);
|
||||
oc.write(spatial, "spatial", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,6 +226,7 @@ public class MotionEvent extends AbstractCinematicEvent implements Control, JmeC
|
||||
rotation = (Quaternion) in.readSavable("rotation", null);
|
||||
directionType = in.readEnum("directionType", Direction.class, Direction.None);
|
||||
path = (MotionPath) in.readSavable("path", null);
|
||||
spatial = (Spatial) in.readSavable("spatial", null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1101,9 +1101,12 @@ public class ParticleEmitter extends Geometry {
|
||||
|
||||
lastPos.set(getWorldTranslation());
|
||||
|
||||
BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
|
||||
bbox.setMinMax(min, max);
|
||||
this.setBoundRefresh();
|
||||
//This check avoids a NaN bounds when all the particles are dead during the first update.
|
||||
if (!min.equals(Vector3f.POSITIVE_INFINITY) && !max.equals(Vector3f.NEGATIVE_INFINITY)) {
|
||||
BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
|
||||
bbox.setMinMax(min, max);
|
||||
this.setBoundRefresh();
|
||||
}
|
||||
|
||||
vars.release();
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ package com.jme3.light;
|
||||
|
||||
import com.jme3.bounding.BoundingSphere;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
@ -56,6 +57,7 @@ public class LightProbeBlendingProcessor implements SceneProcessor {
|
||||
private RenderManager renderManager;
|
||||
private LightProbe probe = new LightProbe();
|
||||
private Spatial poi;
|
||||
private AppProfiler prof;
|
||||
|
||||
public LightProbeBlendingProcessor(Spatial poi) {
|
||||
this.poi = poi;
|
||||
@ -177,8 +179,12 @@ public class LightProbeBlendingProcessor implements SceneProcessor {
|
||||
public void setPoi(Spatial poi) {
|
||||
this.poi = poi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
private class BlendFactor implements Comparable<BlendFactor>{
|
||||
|
||||
LightProbe lightProbe;
|
||||
|
@ -237,7 +237,11 @@ When arrays can be inserted in J3M files
|
||||
Texture texVal = (Texture) value;
|
||||
TextureKey texKey = (TextureKey) texVal.getKey();
|
||||
if (texKey == null){
|
||||
throw new UnsupportedOperationException("The specified MatParam cannot be represented in J3M");
|
||||
//throw new UnsupportedOperationException("The specified MatParam cannot be represented in J3M");
|
||||
// this is used in toString and the above line causes blender materials to throw this exception.
|
||||
// toStrings should be very robust IMO as even debuggers often invoke toString and logging code
|
||||
// often does as well, even implicitly.
|
||||
return texVal+":returned null key";
|
||||
}
|
||||
|
||||
String ret = "";
|
||||
|
288
jme3-core/src/main/java/com/jme3/post/DetailedProfiler.java
Normal file
288
jme3-core/src/main/java/com/jme3/post/DetailedProfiler.java
Normal file
@ -0,0 +1,288 @@
|
||||
package com.jme3.post;
|
||||
|
||||
import com.jme3.profile.*;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by Nehon on 25/01/2017.
|
||||
*/
|
||||
public class DetailedProfiler implements AppProfiler {
|
||||
|
||||
private final static int MAX_FRAMES = 100;
|
||||
private Map<String, StatLine> data;
|
||||
private Map<String, StatLine> pool;
|
||||
private long startFrame;
|
||||
private static int currentFrame = 0;
|
||||
private String prevPath = null;
|
||||
private boolean frameEnded = false;
|
||||
private Renderer renderer;
|
||||
private boolean ongoingGpuProfiling = false;
|
||||
|
||||
|
||||
private String curAppPath = null;
|
||||
private String curVpPath = null;
|
||||
private String curSpPath = null;
|
||||
private VpStep lastVpStep = null;
|
||||
|
||||
private StringBuilder path = new StringBuilder(256);
|
||||
private StringBuilder vpPath = new StringBuilder(256);
|
||||
|
||||
private Deque<Integer> idsPool = new ArrayDeque<>(100);
|
||||
|
||||
StatLine frameTime;
|
||||
|
||||
|
||||
@Override
|
||||
public void appStep(AppStep step) {
|
||||
curAppPath = step.name();
|
||||
|
||||
if (step == AppStep.BeginFrame) {
|
||||
if (data == null) {
|
||||
data = new LinkedHashMap<>();
|
||||
pool = new HashMap<>();
|
||||
frameTime = new StatLine(currentFrame);
|
||||
}
|
||||
if (frameTime.isActive()) {
|
||||
frameTime.setValueCpu(System.nanoTime() - frameTime.getValueCpu());
|
||||
frameTime.closeFrame();
|
||||
|
||||
}
|
||||
frameTime.setNewFrameValueCpu(System.nanoTime());
|
||||
|
||||
frameEnded = false;
|
||||
for (StatLine statLine : data.values()) {
|
||||
for (Iterator<Integer> i = statLine.taskIds.iterator(); i.hasNext(); ) {
|
||||
int id = i.next();
|
||||
if (renderer.isTaskResultAvailable(id)) {
|
||||
long val = renderer.getProfilingTime(id);
|
||||
statLine.setValueGpu(val);
|
||||
i.remove();
|
||||
idsPool.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
data.clear();
|
||||
}
|
||||
|
||||
if (data != null) {
|
||||
String path = getPath(step.name());
|
||||
if (step == AppStep.EndFrame) {
|
||||
if (frameEnded) {
|
||||
return;
|
||||
}
|
||||
addStep(path, System.nanoTime());
|
||||
StatLine end = data.get(path);
|
||||
end.setValueCpu(System.nanoTime() - startFrame);
|
||||
frameEnded = true;
|
||||
} else {
|
||||
addStep(path, System.nanoTime());
|
||||
}
|
||||
}
|
||||
if (step == AppStep.EndFrame) {
|
||||
|
||||
closeFrame();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeFrame() {
|
||||
//close frame
|
||||
if (data != null) {
|
||||
|
||||
prevPath = null;
|
||||
|
||||
for (StatLine statLine : data.values()) {
|
||||
statLine.closeFrame();
|
||||
}
|
||||
currentFrame++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vpStep(VpStep step, ViewPort vp, RenderQueue.Bucket bucket) {
|
||||
|
||||
if (data != null) {
|
||||
vpPath.setLength(0);
|
||||
vpPath.append(vp.getName()).append("/").append((bucket == null ? step.name() : bucket.name() + " Bucket"));
|
||||
path.setLength(0);
|
||||
if ((lastVpStep == VpStep.PostQueue || lastVpStep == VpStep.PostFrame) && bucket != null) {
|
||||
path.append(curAppPath).append("/").append(curVpPath).append(curSpPath).append("/").append(vpPath);
|
||||
curVpPath = vpPath.toString();
|
||||
} else {
|
||||
if (bucket != null) {
|
||||
path.append(curAppPath).append("/").append(curVpPath).append("/").append(bucket.name() + " Bucket");
|
||||
} else {
|
||||
path.append(curAppPath).append("/").append(vpPath);
|
||||
curVpPath = vpPath.toString();
|
||||
}
|
||||
}
|
||||
lastVpStep = step;
|
||||
|
||||
addStep(path.toString(), System.nanoTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spStep(SpStep step, String... additionalInfo) {
|
||||
|
||||
if (data != null) {
|
||||
curSpPath = getPath("", additionalInfo);
|
||||
path.setLength(0);
|
||||
path.append(curAppPath).append("/").append(curVpPath).append(curSpPath);
|
||||
addStep(path.toString(), System.nanoTime());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Map<String, StatLine> getStats() {
|
||||
if (data != null) {
|
||||
return data;//new LinkedHashMap<>(data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public double getAverageFrameTime() {
|
||||
return frameTime.getAverageCpu();
|
||||
}
|
||||
|
||||
|
||||
private void addStep(String path, long value) {
|
||||
if (ongoingGpuProfiling && renderer != null) {
|
||||
renderer.stopProfiling();
|
||||
ongoingGpuProfiling = false;
|
||||
}
|
||||
|
||||
if (prevPath != null) {
|
||||
StatLine prevLine = data.get(prevPath);
|
||||
if (prevLine != null) {
|
||||
prevLine.setValueCpu(value - prevLine.getValueCpu());
|
||||
}
|
||||
}
|
||||
|
||||
StatLine line = pool.get(path);
|
||||
if (line == null) {
|
||||
line = new StatLine(currentFrame);
|
||||
pool.put(path, line);
|
||||
}
|
||||
data.put(path, line);
|
||||
line.setNewFrameValueCpu(value);
|
||||
if (renderer != null) {
|
||||
int id = getUnusedTaskId();
|
||||
line.taskIds.add(id);
|
||||
renderer.startProfiling(id);
|
||||
}
|
||||
ongoingGpuProfiling = true;
|
||||
prevPath = path;
|
||||
|
||||
}
|
||||
|
||||
private String getPath(String step, String... subPath) {
|
||||
StringBuilder path = new StringBuilder(step);
|
||||
if (subPath != null) {
|
||||
for (String s : subPath) {
|
||||
path.append("/").append(s);
|
||||
}
|
||||
}
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
public void setRenderer(Renderer renderer) {
|
||||
this.renderer = renderer;
|
||||
poolTaskIds(renderer);
|
||||
}
|
||||
|
||||
private void poolTaskIds(Renderer renderer) {
|
||||
int[] ids = renderer.generateProfilingTasks(100);
|
||||
for (int id : ids) {
|
||||
idsPool.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
private int getUnusedTaskId() {
|
||||
if (idsPool.isEmpty()) {
|
||||
poolTaskIds(renderer);
|
||||
}
|
||||
|
||||
return idsPool.pop();
|
||||
}
|
||||
|
||||
public static class StatLine {
|
||||
private long[] cpuTimes = new long[MAX_FRAMES];
|
||||
private long[] gpuTimes = new long[MAX_FRAMES];
|
||||
private int startCursor = 0;
|
||||
private int cpuCursor = 0;
|
||||
private int gpuCursor = 0;
|
||||
private long cpuSum = 0;
|
||||
private long gpuSum = 0;
|
||||
private long lastValue = 0;
|
||||
private int nbFramesCpu;
|
||||
private int nbFramesGpu;
|
||||
List<Integer> taskIds = new ArrayList<>();
|
||||
|
||||
|
||||
private StatLine(int currentFrame) {
|
||||
startCursor = currentFrame % MAX_FRAMES;
|
||||
cpuCursor = startCursor;
|
||||
gpuCursor = startCursor;
|
||||
}
|
||||
|
||||
private void setNewFrameValueCpu(long value) {
|
||||
int newCursor = currentFrame % MAX_FRAMES;
|
||||
if (nbFramesCpu == 0) {
|
||||
startCursor = newCursor;
|
||||
}
|
||||
cpuCursor = newCursor;
|
||||
lastValue = value;
|
||||
}
|
||||
|
||||
private void setValueCpu(long val) {
|
||||
lastValue = val;
|
||||
}
|
||||
|
||||
private long getValueCpu() {
|
||||
return lastValue;
|
||||
}
|
||||
|
||||
private void closeFrame() {
|
||||
if (isActive()) {
|
||||
cpuSum -= cpuTimes[cpuCursor];
|
||||
cpuTimes[cpuCursor] = lastValue;
|
||||
cpuSum += lastValue;
|
||||
nbFramesCpu++;
|
||||
} else {
|
||||
nbFramesCpu = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void setValueGpu(long value) {
|
||||
gpuSum -= gpuTimes[gpuCursor];
|
||||
gpuTimes[gpuCursor] = value;
|
||||
gpuSum += value;
|
||||
nbFramesGpu++;
|
||||
gpuCursor = (gpuCursor + 1) % MAX_FRAMES;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return cpuCursor >= currentFrame % MAX_FRAMES - 1;
|
||||
}
|
||||
|
||||
public double getAverageCpu() {
|
||||
if (nbFramesCpu == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (double) cpuSum / (double) Math.min(nbFramesCpu, MAX_FRAMES);
|
||||
}
|
||||
|
||||
public double getAverageGpu() {
|
||||
if (nbFramesGpu == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (double) gpuSum / (double) Math.min(nbFramesGpu, MAX_FRAMES);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
448
jme3-core/src/main/java/com/jme3/post/DetailedProfilerState.java
Normal file
448
jme3-core/src/main/java/com/jme3/post/DetailedProfilerState.java
Normal file
@ -0,0 +1,448 @@
|
||||
package com.jme3.post;
|
||||
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.app.SimpleApplication;
|
||||
import com.jme3.app.state.BaseAppState;
|
||||
import com.jme3.font.BitmapFont;
|
||||
import com.jme3.font.BitmapText;
|
||||
import com.jme3.input.*;
|
||||
import com.jme3.input.controls.*;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.profile.AppStep;
|
||||
import com.jme3.scene.*;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.*;
|
||||
|
||||
import static com.jme3.post.DetailedProfiler.*;
|
||||
|
||||
/**
|
||||
* Created by Nehon on 25/01/2017.
|
||||
*/
|
||||
public class DetailedProfilerState extends BaseAppState {
|
||||
|
||||
private static final int PANEL_WIDTH = 400;
|
||||
private static final int PADDING = 10;
|
||||
private static final int LINE_HEIGHT = 12;
|
||||
private static final int HEADER_HEIGHT = 100;
|
||||
private static final float REFRESH_TIME = 1.0f;
|
||||
private static final String TOGGLE_KEY = "Toggle_Detailed_Profiler";
|
||||
private static final String CLICK_KEY = "Click_Detailed_Profiler";
|
||||
private static final String INSIGNIFICANT = "Hide insignificant stat";
|
||||
private DetailedProfiler prof = new DetailedProfiler();
|
||||
|
||||
private float time = 0;
|
||||
private BitmapFont font;
|
||||
private BitmapFont bigFont;
|
||||
private Node ui = new Node("Stats ui");
|
||||
private Map<String, StatLineView> lines = new HashMap<>();
|
||||
private double totalTimeCpu;
|
||||
private double totalTimeGpu;
|
||||
private int maxLevel = 0;
|
||||
|
||||
private BitmapText frameTimeValue;
|
||||
private BitmapText frameCpuTimeValue;
|
||||
private BitmapText frameGpuTimeValue;
|
||||
private BitmapText hideInsignificantField;
|
||||
|
||||
private BitmapText selectedField;
|
||||
private double selectedValueCpu = 0;
|
||||
private double selectedValueGpu = 0;
|
||||
private boolean hideInsignificant = false;
|
||||
|
||||
private StatLineView rootLine;
|
||||
private int height = 0;
|
||||
private DecimalFormat df = new DecimalFormat("##0.00", new DecimalFormatSymbols(Locale.US));
|
||||
|
||||
private ColorRGBA dimmedWhite = ColorRGBA.White.mult(0.7f);
|
||||
private ColorRGBA dimmedGreen = ColorRGBA.Green.mult(0.7f);
|
||||
private ColorRGBA dimmedOrange = ColorRGBA.Orange.mult(0.7f);
|
||||
private ColorRGBA dimmedRed = ColorRGBA.Red.mult(0.7f);
|
||||
|
||||
public DetailedProfilerState() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize(Application app) {
|
||||
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
mat.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f));
|
||||
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
|
||||
Geometry darkenStats = new Geometry("StatsDarken", new Quad(PANEL_WIDTH, app.getCamera().getHeight()));
|
||||
darkenStats.setMaterial(mat);
|
||||
darkenStats.setLocalTranslation(0, -app.getCamera().getHeight(), -1);
|
||||
|
||||
ui.attachChild(darkenStats);
|
||||
ui.setLocalTranslation(app.getCamera().getWidth() - PANEL_WIDTH, app.getCamera().getHeight(), 0);
|
||||
font = app.getAssetManager().loadFont("Interface/Fonts/Console.fnt");
|
||||
bigFont = app.getAssetManager().loadFont("Interface/Fonts/Default.fnt");
|
||||
prof.setRenderer(app.getRenderer());
|
||||
rootLine = new StatLineView("Frame");
|
||||
rootLine.attachTo(ui);
|
||||
|
||||
BitmapText frameLabel = new BitmapText(bigFont);
|
||||
frameLabel.setText("Total Frame Time: ");
|
||||
ui.attachChild(frameLabel);
|
||||
frameLabel.setLocalTranslation(new Vector3f(PANEL_WIDTH / 2 - bigFont.getLineWidth(frameLabel.getText()), -PADDING, 0));
|
||||
|
||||
BitmapText cpuLabel = new BitmapText(bigFont);
|
||||
cpuLabel.setText("CPU");
|
||||
ui.attachChild(cpuLabel);
|
||||
cpuLabel.setLocalTranslation(PANEL_WIDTH / 4 - bigFont.getLineWidth(cpuLabel.getText()) / 2, -PADDING - 30, 0);
|
||||
|
||||
BitmapText gpuLabel = new BitmapText(bigFont);
|
||||
gpuLabel.setText("GPU");
|
||||
ui.attachChild(gpuLabel);
|
||||
gpuLabel.setLocalTranslation(3 * PANEL_WIDTH / 4 - bigFont.getLineWidth(gpuLabel.getText()) / 2, -PADDING - 30, 0);
|
||||
|
||||
frameTimeValue = new BitmapText(bigFont);
|
||||
frameCpuTimeValue = new BitmapText(bigFont);
|
||||
frameGpuTimeValue = new BitmapText(bigFont);
|
||||
|
||||
selectedField = new BitmapText(font);
|
||||
selectedField.setText("Selected: ");
|
||||
selectedField.setLocalTranslation(PANEL_WIDTH / 2, -PADDING - 75, 0);
|
||||
selectedField.setColor(ColorRGBA.Yellow);
|
||||
|
||||
|
||||
ui.attachChild(frameTimeValue);
|
||||
ui.attachChild(frameCpuTimeValue);
|
||||
ui.attachChild(frameGpuTimeValue);
|
||||
ui.attachChild(selectedField);
|
||||
|
||||
hideInsignificantField = new BitmapText(font);
|
||||
hideInsignificantField.setText("O " + INSIGNIFICANT);
|
||||
hideInsignificantField.setLocalTranslation(PADDING, -PADDING - 75, 0);
|
||||
ui.attachChild(hideInsignificantField);
|
||||
|
||||
final InputManager inputManager = app.getInputManager();
|
||||
if (inputManager != null) {
|
||||
inputManager.addMapping(TOGGLE_KEY, new KeyTrigger(KeyInput.KEY_F6));
|
||||
inputManager.addMapping(CLICK_KEY, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
|
||||
inputManager.addListener(new ActionListener() {
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (name.equals(TOGGLE_KEY) && isPressed) {
|
||||
setEnabled(!isEnabled());
|
||||
}
|
||||
if (isEnabled() && name.equals(CLICK_KEY) && isPressed) {
|
||||
handleClick(inputManager.getCursorPosition());
|
||||
}
|
||||
}
|
||||
}, TOGGLE_KEY, CLICK_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanup(Application app) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float tpf) {
|
||||
time += tpf;
|
||||
}
|
||||
|
||||
private void displayData(Map<String, DetailedProfiler.StatLine> data) {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (StatLineView statLine : lines.values()) {
|
||||
statLine.reset();
|
||||
statLine.removeFromParent();
|
||||
}
|
||||
rootLine.reset();
|
||||
maxLevel = 0;
|
||||
for (String path : data.keySet()) {
|
||||
if (path.equals("EndFrame")) {
|
||||
continue;
|
||||
}
|
||||
maxLevel = Math.max(maxLevel, path.split("/").length);
|
||||
StatLineView line = getStatLineView(path);
|
||||
StatLine statLine = data.get(path);
|
||||
line.updateValues(statLine.getAverageCpu(), statLine.getAverageGpu());
|
||||
String parent = getParent(path);
|
||||
while (parent != null) {
|
||||
StatLineView parentView = getStatLineView(parent);
|
||||
parentView.updateValues(statLine.getAverageCpu(), statLine.getAverageGpu());
|
||||
parentView.children.add(line);
|
||||
line.attachTo(ui);
|
||||
line = parentView;
|
||||
parent = getParent(parent);
|
||||
}
|
||||
rootLine.children.add(line);
|
||||
line.attachTo(ui);
|
||||
rootLine.updateValues(statLine.getAverageCpu(), statLine.getAverageGpu());
|
||||
}
|
||||
|
||||
totalTimeCpu = rootLine.cpuValue;
|
||||
totalTimeGpu = rootLine.gpuValue + data.get("EndFrame").getAverageGpu();
|
||||
|
||||
layout();
|
||||
|
||||
}
|
||||
|
||||
private void layout() {
|
||||
height = 0;
|
||||
selectedValueCpu = 0;
|
||||
selectedValueGpu = 0;
|
||||
rootLine.layout(0);
|
||||
|
||||
frameTimeValue.setText(df.format(getMsFromNs(prof.getAverageFrameTime())) + "ms");
|
||||
frameTimeValue.setLocalTranslation(PANEL_WIDTH / 2, -PADDING, 0);
|
||||
setColor(frameTimeValue, prof.getAverageFrameTime(), totalTimeCpu, false, false);
|
||||
|
||||
frameCpuTimeValue.setText(df.format(getMsFromNs(totalTimeCpu)) + "ms");
|
||||
frameCpuTimeValue.setLocalTranslation(new Vector3f(PANEL_WIDTH / 4 - bigFont.getLineWidth(frameCpuTimeValue.getText()) / 2, -PADDING - 50, 0));
|
||||
setColor(frameCpuTimeValue, totalTimeCpu, totalTimeCpu, false, false);
|
||||
|
||||
frameGpuTimeValue.setText(df.format(getMsFromNs(totalTimeGpu)) + "ms");
|
||||
frameGpuTimeValue.setLocalTranslation(new Vector3f(3 * PANEL_WIDTH / 4 - bigFont.getLineWidth(frameGpuTimeValue.getText()) / 2, -PADDING - 50, 0));
|
||||
setColor(frameGpuTimeValue, totalTimeGpu, totalTimeGpu, false, false);
|
||||
|
||||
selectedField.setText("Selected: " + df.format(getMsFromNs(selectedValueCpu)) + "ms / " + df.format(getMsFromNs(selectedValueGpu)) + "ms");
|
||||
|
||||
selectedField.setLocalTranslation(3 * PANEL_WIDTH / 4 - font.getLineWidth(selectedField.getText()) / 2, -PADDING - 75, 0);
|
||||
}
|
||||
|
||||
private StatLineView getStatLineView(String path) {
|
||||
StatLineView line = lines.get(path);
|
||||
|
||||
if (line == null) {
|
||||
line = new StatLineView(getLeaf(path));
|
||||
lines.put(path, line);
|
||||
line.attachTo(ui);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
private String getLeaf(String path) {
|
||||
int idx = path.lastIndexOf("/");
|
||||
return idx >= 0 ? path.substring(idx + 1) : path;
|
||||
}
|
||||
|
||||
private String getParent(String path) {
|
||||
int idx = path.lastIndexOf("/");
|
||||
return idx >= 0 ? path.substring(0, idx) : null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postRender() {
|
||||
if (time > REFRESH_TIME) {
|
||||
prof.appStep(AppStep.EndFrame);
|
||||
Map<String, StatLine> data = prof.getStats();
|
||||
displayData(data);
|
||||
time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private double getMsFromNs(double time) {
|
||||
return time / 1000000.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnable() {
|
||||
getApplication().setAppProfiler(prof);
|
||||
((SimpleApplication) getApplication()).getGuiNode().attachChild(ui);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDisable() {
|
||||
getApplication().setAppProfiler(null);
|
||||
ui.removeFromParent();
|
||||
}
|
||||
|
||||
public boolean setColor(BitmapText t, double value, double totalTime, boolean isParent, boolean expended) {
|
||||
|
||||
boolean dimmed = isParent && expended;
|
||||
boolean insignificant = false;
|
||||
|
||||
if (value > 1000000000.0 / 30.0) {
|
||||
t.setColor(dimmed ? dimmedRed : ColorRGBA.Red);
|
||||
} else if (value > 1000000000.0 / 60.0) {
|
||||
t.setColor(dimmed ? dimmedOrange : ColorRGBA.Orange);
|
||||
} else if (value > totalTime / 3) {
|
||||
t.setColor(dimmed ? dimmedGreen : ColorRGBA.Green);
|
||||
} else if (value < 30000) {
|
||||
t.setColor(ColorRGBA.DarkGray);
|
||||
insignificant = true;
|
||||
} else {
|
||||
t.setColor(dimmed ? dimmedWhite : ColorRGBA.White);
|
||||
}
|
||||
return insignificant;
|
||||
}
|
||||
|
||||
private void handleClick(Vector2f pos) {
|
||||
|
||||
Vector3f lp = hideInsignificantField.getWorldTranslation();
|
||||
float width = font.getLineWidth(hideInsignificantField.getText());
|
||||
if (pos.x > lp.x && pos.x < (lp.x + width)
|
||||
&& pos.y < lp.y && pos.y > lp.y - LINE_HEIGHT) {
|
||||
hideInsignificant = !hideInsignificant;
|
||||
hideInsignificantField.setText((hideInsignificant ? "X " : "O ") + INSIGNIFICANT);
|
||||
if (!hideInsignificant) {
|
||||
rootLine.setExpended(true);
|
||||
}
|
||||
}
|
||||
|
||||
rootLine.onClick(pos);
|
||||
for (StatLineView statLineView : lines.values()) {
|
||||
statLineView.onClick(pos);
|
||||
}
|
||||
layout();
|
||||
}
|
||||
|
||||
private class StatLineView {
|
||||
BitmapText label;
|
||||
BitmapText cpuText;
|
||||
BitmapText gpuText;
|
||||
BitmapText checkBox;
|
||||
double cpuValue;
|
||||
double gpuValue;
|
||||
private boolean expended = true;
|
||||
private boolean visible = true;
|
||||
private boolean selected = false;
|
||||
String text;
|
||||
|
||||
Set<StatLineView> children = new LinkedHashSet<>();
|
||||
|
||||
public StatLineView(String label) {
|
||||
this.text = label;
|
||||
this.label = new BitmapText(font);
|
||||
this.checkBox = new BitmapText(font);
|
||||
this.checkBox.setText("O");
|
||||
this.label.setText("- " + label);
|
||||
this.cpuText = new BitmapText(font);
|
||||
this.gpuText = new BitmapText(font);
|
||||
}
|
||||
|
||||
public void onClick(Vector2f pos) {
|
||||
|
||||
if (!visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3f lp = label.getWorldTranslation();
|
||||
Vector3f cp = checkBox.getWorldTranslation();
|
||||
if (pos.x > cp.x
|
||||
&& pos.y < lp.y && pos.y > lp.y - LINE_HEIGHT) {
|
||||
|
||||
float width = font.getLineWidth(checkBox.getText());
|
||||
if (pos.x >= cp.x && pos.x <= (cp.x + width)) {
|
||||
selected = !selected;
|
||||
if (selected) {
|
||||
checkBox.setText("X");
|
||||
} else {
|
||||
checkBox.setText("O");
|
||||
}
|
||||
} else {
|
||||
setExpended(!expended);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setExpended(boolean expended) {
|
||||
this.expended = expended;
|
||||
if (expended) {
|
||||
label.setText("- " + text);
|
||||
} else {
|
||||
label.setText("+ " + text);
|
||||
}
|
||||
for (StatLineView child : children) {
|
||||
child.setVisible(expended);
|
||||
}
|
||||
}
|
||||
|
||||
public void layout(int indent) {
|
||||
|
||||
boolean insignificant;
|
||||
cpuText.setText(df.format(getMsFromNs(cpuValue)) + "ms /");
|
||||
insignificant = setColor(cpuText, cpuValue, totalTimeCpu, !children.isEmpty(), expended);
|
||||
gpuText.setText(" " + df.format(getMsFromNs(gpuValue)) + "ms");
|
||||
insignificant &= setColor(gpuText, gpuValue, totalTimeGpu, !children.isEmpty(), expended);
|
||||
|
||||
if (insignificant && hideInsignificant) {
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
if (!visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
label.setColor(ColorRGBA.Yellow);
|
||||
selectedValueCpu += cpuValue;
|
||||
selectedValueGpu += gpuValue;
|
||||
} else {
|
||||
label.setColor(ColorRGBA.White);
|
||||
}
|
||||
|
||||
int y = -(height * LINE_HEIGHT + HEADER_HEIGHT);
|
||||
|
||||
label.setLocalTranslation(PADDING + indent * PADDING, y, 0);
|
||||
float gpuPos = PANEL_WIDTH - font.getLineWidth(gpuText.getText()) - PADDING * (maxLevel - indent + 1);
|
||||
cpuText.setLocalTranslation(gpuPos - font.getLineWidth(cpuText.getText()), y, 0);
|
||||
gpuText.setLocalTranslation(gpuPos, y, 0);
|
||||
|
||||
checkBox.setLocalTranslation(3, y, 0);
|
||||
height++;
|
||||
for (StatLineView child : children) {
|
||||
child.layout(indent + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateValues(double cpu, double gpu) {
|
||||
cpuValue += cpu;
|
||||
gpuValue += gpu;
|
||||
}
|
||||
|
||||
public void attachTo(Node node) {
|
||||
node.attachChild(label);
|
||||
node.attachChild(cpuText);
|
||||
node.attachChild(gpuText);
|
||||
node.attachChild(checkBox);
|
||||
}
|
||||
|
||||
public void removeFromParent() {
|
||||
label.removeFromParent();
|
||||
cpuText.removeFromParent();
|
||||
gpuText.removeFromParent();
|
||||
checkBox.removeFromParent();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
children.clear();
|
||||
cpuValue = 0;
|
||||
gpuValue = 0;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
label.setCullHint(visible ? Spatial.CullHint.Dynamic : Spatial.CullHint.Always);
|
||||
cpuText.setCullHint(visible ? Spatial.CullHint.Dynamic : Spatial.CullHint.Always);
|
||||
gpuText.setCullHint(visible ? Spatial.CullHint.Dynamic : Spatial.CullHint.Always);
|
||||
checkBox.setCullHint(visible ? Spatial.CullHint.Dynamic : Spatial.CullHint.Always);
|
||||
|
||||
|
||||
for (StatLineView child : children) {
|
||||
child.setVisible(visible && expended);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label.getText() + " - " + df.format(getMsFromNs(cpuValue)) + "ms / " + df.format(getMsFromNs(gpuValue)) + "ms";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,14 @@ public abstract class Filter implements Savable {
|
||||
protected Texture2D renderedTexture;
|
||||
protected Texture2D depthTexture;
|
||||
protected Material passMaterial;
|
||||
protected String name;
|
||||
|
||||
public Pass(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Pass() {
|
||||
}
|
||||
|
||||
/**
|
||||
* init the pass called internally
|
||||
@ -197,6 +205,11 @@ public abstract class Filter implements Savable {
|
||||
depthTexture.getImage().dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name == null ? super.toString() : name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,7 @@ package com.jme3.post;
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.export.*;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.profile.*;
|
||||
import com.jme3.renderer.*;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.texture.FrameBuffer;
|
||||
@ -56,6 +57,7 @@ import java.util.List;
|
||||
*/
|
||||
public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
|
||||
public static final String FPP = FilterPostProcessor.class.getSimpleName();
|
||||
private RenderManager renderManager;
|
||||
private Renderer renderer;
|
||||
private ViewPort viewPort;
|
||||
@ -80,6 +82,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
private int lastFilterIndex = -1;
|
||||
private boolean cameraInit = false;
|
||||
private boolean multiView = false;
|
||||
private AppProfiler prof;
|
||||
|
||||
private Format fbFormat = Format.RGB111110F;
|
||||
|
||||
@ -216,7 +219,6 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
r.setFrameBuffer(buff);
|
||||
r.clearBuffers(true, true, true);
|
||||
renderManager.renderGeometry(fsQuad);
|
||||
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
@ -224,13 +226,12 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
}
|
||||
|
||||
public void postQueue(RenderQueue rq) {
|
||||
|
||||
for (Filter filter : filters.getArray()) {
|
||||
if (filter.isEnabled()) {
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostQueue, FPP, filter.getName());
|
||||
filter.postQueue(rq);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,10 +245,12 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
boolean msDepth = depthTexture != null && depthTexture.getImage().getMultiSamples() > 1;
|
||||
for (int i = 0; i < filters.size(); i++) {
|
||||
Filter filter = filters.get(i);
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostFrame, FPP, filter.getName());
|
||||
if (filter.isEnabled()) {
|
||||
if (filter.getPostRenderPasses() != null) {
|
||||
for (Iterator<Filter.Pass> it1 = filter.getPostRenderPasses().iterator(); it1.hasNext();) {
|
||||
Filter.Pass pass = it1.next();
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostFrame, FPP, filter.getName(), pass.toString());
|
||||
pass.beforeRender();
|
||||
if (pass.requiresSceneAsTexture()) {
|
||||
pass.getPassMaterial().setTexture("Texture", tex);
|
||||
@ -269,7 +272,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
renderProcessing(r, pass.getRenderFrameBuffer(), pass.getPassMaterial());
|
||||
}
|
||||
}
|
||||
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostFrame, FPP, filter.getName(), "postFrame");
|
||||
filter.postFrame(renderManager, viewPort, buff, sceneFb);
|
||||
|
||||
Material mat = filter.getMaterial();
|
||||
@ -298,7 +301,9 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
tex = filter.getRenderedTexture();
|
||||
|
||||
}
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostFrame, FPP, filter.getName(), "render");
|
||||
renderProcessing(r, buff, mat);
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostFrame, FPP, filter.getName(), "postFilter");
|
||||
filter.postFilter(r, buff);
|
||||
|
||||
if (wantsBilinear) {
|
||||
@ -324,7 +329,6 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
if (viewPort != null) {
|
||||
renderManager.setCamera(viewPort.getCamera(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void preFrame(float tpf) {
|
||||
@ -351,6 +355,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
|
||||
for (Filter filter : filters.getArray()) {
|
||||
if (filter.isEnabled()) {
|
||||
if (prof != null) prof.spStep(SpStep.ProcPreFrame, FPP, filter.getName());
|
||||
filter.preFrame(tpf);
|
||||
}
|
||||
}
|
||||
@ -419,6 +424,11 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
public void reshape(ViewPort vp, int w, int h) {
|
||||
Camera cam = vp.getCamera();
|
||||
//this has no effect at first init but is useful when resizing the canvas with multi views
|
||||
|
@ -34,6 +34,7 @@ package com.jme3.post;
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.*;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.texture.FrameBuffer;
|
||||
@ -61,6 +62,7 @@ public class HDRRenderer implements SceneProcessor {
|
||||
private RenderManager renderManager;
|
||||
private ViewPort viewPort;
|
||||
private static final Logger logger = Logger.getLogger(HDRRenderer.class.getName());
|
||||
private AppProfiler prof;
|
||||
|
||||
private Camera fbCam = new Camera(1, 1);
|
||||
|
||||
@ -418,4 +420,9 @@ public class HDRRenderer implements SceneProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import com.jme3.asset.AssetManager;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.material.RenderState.FaceCullMode;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
@ -51,6 +52,7 @@ public class PreDepthProcessor implements SceneProcessor {
|
||||
private AssetManager assetManager;
|
||||
private Material preDepth;
|
||||
private RenderState forcedRS;
|
||||
private AppProfiler prof;
|
||||
|
||||
public PreDepthProcessor(AssetManager assetManager){
|
||||
this.assetManager = assetManager;
|
||||
@ -96,4 +98,9 @@ public class PreDepthProcessor implements SceneProcessor {
|
||||
vp = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
*/
|
||||
package com.jme3.post;
|
||||
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
@ -90,4 +91,11 @@ public interface SceneProcessor {
|
||||
*/
|
||||
public void cleanup();
|
||||
|
||||
/**
|
||||
* Sets a profiler Instance for this processor.
|
||||
*
|
||||
* @param profiler the profiler instance.
|
||||
*/
|
||||
public void setProfiler(AppProfiler profiler);
|
||||
|
||||
}
|
||||
|
@ -57,7 +57,12 @@ public interface AppProfiler {
|
||||
* steps the Bucket parameter will be non-null.
|
||||
*/
|
||||
public void vpStep(VpStep step, ViewPort vp, Bucket bucket);
|
||||
|
||||
|
||||
/**
|
||||
* Called at the beginning of the specified SpStep (SceneProcessor step).
|
||||
* For more detailed steps it is possible to provide additional information as strings, like the name of the processor.
|
||||
*/
|
||||
public void spStep(SpStep step, String... additionalInfo);
|
||||
}
|
||||
|
||||
|
||||
|
13
jme3-core/src/main/java/com/jme3/profile/SpStep.java
Normal file
13
jme3-core/src/main/java/com/jme3/profile/SpStep.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.jme3.profile;
|
||||
|
||||
/**
|
||||
* Indicates a scene processor-level step within the profiled
|
||||
* frame.
|
||||
* <p>
|
||||
* Created by Nehon on 25/01/2017.
|
||||
*/
|
||||
public enum SpStep {
|
||||
ProcPreFrame,
|
||||
ProcPostQueue,
|
||||
ProcPostFrame,
|
||||
}
|
@ -42,9 +42,11 @@ package com.jme3.profile;
|
||||
public enum VpStep {
|
||||
BeginRender,
|
||||
RenderScene,
|
||||
PreFrame,
|
||||
PostQueue,
|
||||
FlushQueue,
|
||||
PostFrame,
|
||||
ProcEndRender,
|
||||
RenderBucket,
|
||||
EndRender
|
||||
}
|
||||
|
@ -42,9 +42,7 @@ import com.jme3.material.Technique;
|
||||
import com.jme3.material.TechniqueDef;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.profile.AppStep;
|
||||
import com.jme3.profile.VpStep;
|
||||
import com.jme3.profile.*;
|
||||
import com.jme3.renderer.queue.GeometryList;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.renderer.queue.RenderQueue.Bucket;
|
||||
@ -1070,10 +1068,13 @@ public class RenderManager {
|
||||
}
|
||||
|
||||
if (processors != null) {
|
||||
if (prof != null) prof.vpStep(VpStep.PreFrame, vp, null);
|
||||
for (SceneProcessor proc : processors.getArray()) {
|
||||
if (!proc.isInitialized()) {
|
||||
proc.initialize(this, vp);
|
||||
}
|
||||
proc.setProfiler(this.prof);
|
||||
if (prof != null) prof.spStep(SpStep.ProcPreFrame, proc.getClass().getSimpleName());
|
||||
proc.preFrame(tpf);
|
||||
}
|
||||
}
|
||||
@ -1098,6 +1099,7 @@ public class RenderManager {
|
||||
if (processors != null) {
|
||||
if (prof!=null) prof.vpStep(VpStep.PostQueue, vp, null);
|
||||
for (SceneProcessor proc : processors.getArray()) {
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostQueue, proc.getClass().getSimpleName());
|
||||
proc.postQueue(vp.getQueue());
|
||||
}
|
||||
}
|
||||
@ -1108,14 +1110,16 @@ public class RenderManager {
|
||||
if (processors != null) {
|
||||
if (prof!=null) prof.vpStep(VpStep.PostFrame, vp, null);
|
||||
for (SceneProcessor proc : processors.getArray()) {
|
||||
if (prof != null) prof.spStep(SpStep.ProcPostFrame, proc.getClass().getSimpleName());
|
||||
proc.postFrame(vp.getOutputFrameBuffer());
|
||||
}
|
||||
if (prof != null) prof.vpStep(VpStep.ProcEndRender, vp, null);
|
||||
}
|
||||
//renders the translucent objects queue after processors have been rendered
|
||||
renderTranslucentQueue(vp);
|
||||
// clear any remaining spatials that were not rendered.
|
||||
clearQueue(vp);
|
||||
|
||||
|
||||
if (prof!=null) prof.vpStep(VpStep.EndRender, vp, null);
|
||||
}
|
||||
|
||||
|
@ -387,4 +387,46 @@ public interface Renderer {
|
||||
*/
|
||||
public void setLinearizeSrgbImages(boolean linearize);
|
||||
|
||||
|
||||
/**
|
||||
* Generates a pool of gpu queries meant to use as profiling tasks
|
||||
*
|
||||
* @param numTasks the number of task ids to generate
|
||||
* @return an array of tasks ids.
|
||||
*/
|
||||
public int[] generateProfilingTasks(int numTasks);
|
||||
|
||||
/**
|
||||
* Starts a time profiling task on the GPU.
|
||||
* This will profile all operations called between startProfiling and stopProfiling
|
||||
*
|
||||
* @param taskId the id of the task to start profiling.
|
||||
*/
|
||||
public void startProfiling(int taskId);
|
||||
|
||||
/**
|
||||
* Will stop the last profiling task started with startProfiling
|
||||
*/
|
||||
public void stopProfiling();
|
||||
|
||||
/**
|
||||
* Returns the time in nano seconds elapsed for the task with the given id.
|
||||
* Note that the result may not be available right after stopProfiling has been called.
|
||||
* You need to check if the result is available with isTaskResultAvailable.
|
||||
* Also note that it's guaranteed that the result will be available on next frame.
|
||||
* If you use getProfilingTime on the next frame you called stopProfiling, you don't need to check the result availability with isTaskResultAvailable
|
||||
*
|
||||
* @param taskId the id of the task given by startProfiling.
|
||||
* @return the time in nano second of the profiling task with the given id.
|
||||
*/
|
||||
public long getProfilingTime(int taskId);
|
||||
|
||||
/**
|
||||
* Check if the profiling results are available
|
||||
*
|
||||
* @param taskId the id of the task provided by startProfiling
|
||||
* @return true if the resulst of the task with the given task id are available.
|
||||
*/
|
||||
public boolean isTaskResultAvailable(int taskId);
|
||||
|
||||
}
|
||||
|
@ -126,6 +126,8 @@ public interface GL {
|
||||
public static final int GL_OUT_OF_MEMORY = 0x505;
|
||||
public static final int GL_POINTS = 0x0;
|
||||
public static final int GL_POLYGON_OFFSET_FILL = 0x8037;
|
||||
public static final int GL_QUERY_RESULT = 0x8866;
|
||||
public static final int GL_QUERY_RESULT_AVAILABLE = 0x8867;
|
||||
public static final int GL_RED = 0x1903;
|
||||
public static final int GL_RENDERER = 0x1F01;
|
||||
public static final int GL_REPEAT = 0x2901;
|
||||
@ -177,6 +179,7 @@ public interface GL {
|
||||
public static final int GL_TEXTURE_MIN_FILTER = 0x2801;
|
||||
public static final int GL_TEXTURE_WRAP_S = 0x2802;
|
||||
public static final int GL_TEXTURE_WRAP_T = 0x2803;
|
||||
public static final int GL_TIME_ELAPSED = 0x88BF;
|
||||
public static final int GL_TRIANGLES = 0x4;
|
||||
public static final int GL_TRIANGLE_FAN = 0x6;
|
||||
public static final int GL_TRIANGLE_STRIP = 0x5;
|
||||
@ -196,6 +199,7 @@ public interface GL {
|
||||
|
||||
public void glActiveTexture(int texture);
|
||||
public void glAttachShader(int program, int shader);
|
||||
public void glBeginQuery(int target, int query);
|
||||
public void glBindBuffer(int target, int buffer);
|
||||
public void glBindTexture(int target, int texture);
|
||||
public void glBlendEquationSeparate(int colorMode, int alphaMode);
|
||||
@ -232,8 +236,10 @@ public interface GL {
|
||||
public void glDrawRangeElements(int mode, int start, int end, int count, int type, long indices); /// GL2+
|
||||
public void glEnable(int cap);
|
||||
public void glEnableVertexAttribArray(int index);
|
||||
public void glEndQuery(int target);
|
||||
public void glGenBuffers(IntBuffer buffers);
|
||||
public void glGenTextures(IntBuffer textures);
|
||||
public void glGenQueries(int number, IntBuffer ids);
|
||||
public int glGetAttribLocation(int program, String name);
|
||||
public void glGetBoolean(int pname, ByteBuffer params);
|
||||
public void glGetBufferSubData(int target, long offset, ByteBuffer data);
|
||||
@ -241,7 +247,9 @@ public interface GL {
|
||||
public void glGetInteger(int pname, IntBuffer params);
|
||||
public void glGetProgram(int program, int pname, IntBuffer params);
|
||||
public String glGetProgramInfoLog(int program, int maxSize);
|
||||
public void glGetShader(int shader, int pname, IntBuffer params);
|
||||
public long glGetQueryObjectui64(int query, int pname);
|
||||
public int glGetQueryObjectiv(int query, int pname);
|
||||
public void glGetShader(int shader, int pname, IntBuffer params);
|
||||
public String glGetShaderInfoLog(int shader, int maxSize);
|
||||
public String glGetString(int name);
|
||||
public int glGetUniformLocation(int program, String name);
|
||||
|
@ -30,6 +30,12 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glBeginQuery(int target, int query) {
|
||||
gl.glBeginQuery(target, query);
|
||||
checkError();
|
||||
}
|
||||
|
||||
public void glBindBuffer(int target, int buffer) {
|
||||
gl.glBindBuffer(target, buffer);
|
||||
checkError();
|
||||
@ -198,6 +204,11 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glEndQuery(int target) {
|
||||
checkError();
|
||||
}
|
||||
|
||||
public void glGenBuffers(IntBuffer buffers) {
|
||||
gl.glGenBuffers(buffers);
|
||||
checkError();
|
||||
@ -208,6 +219,12 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
|
||||
checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenQueries(int num, IntBuffer ids) {
|
||||
glGenQueries(num, ids);
|
||||
checkError();
|
||||
}
|
||||
|
||||
public int glGetAttribLocation(int program, String name) {
|
||||
int location = gl.glGetAttribLocation(program, name);
|
||||
checkError();
|
||||
@ -240,6 +257,20 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
|
||||
return infoLog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long glGetQueryObjectui64(int query, int pname) {
|
||||
long res = gl.glGetQueryObjectui64(query, pname);
|
||||
checkError();
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetQueryObjectiv(int query, int pname) {
|
||||
int res = gl.glGetQueryObjectiv(query, pname);
|
||||
checkError();
|
||||
return res;
|
||||
}
|
||||
|
||||
public void glGetShader(int shader, int pname, IntBuffer params) {
|
||||
gl.glGetShader(shader, pname, params);
|
||||
checkError();
|
||||
|
@ -2851,4 +2851,31 @@ public final class GLRenderer implements Renderer {
|
||||
linearizeSrgbImages = linearize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] generateProfilingTasks(int numTasks) {
|
||||
IntBuffer ids = BufferUtils.createIntBuffer(numTasks);
|
||||
gl.glGenQueries(numTasks, ids);
|
||||
return BufferUtils.getIntArray(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startProfiling(int taskId) {
|
||||
gl.glBeginQuery(GL.GL_TIME_ELAPSED, taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopProfiling() {
|
||||
gl.glEndQuery(GL.GL_TIME_ELAPSED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getProfilingTime(int taskId) {
|
||||
return gl.glGetQueryObjectui64(taskId, GL.GL_QUERY_RESULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTaskResultAvailable(int taskId) {
|
||||
return gl.glGetQueryObjectiv(taskId, GL.GL_QUERY_RESULT_AVAILABLE) == 1;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
@ -99,6 +100,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable,
|
||||
protected Picture[] dispPic;
|
||||
protected RenderState forcedRenderState = new RenderState();
|
||||
protected Boolean renderBackFacesShadows = true;
|
||||
protected AppProfiler prof;
|
||||
|
||||
/**
|
||||
* true if the fallback material should be used, otherwise false
|
||||
@ -807,6 +809,10 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable,
|
||||
init(assetManager, nbShadowMaps, (int) shadowMapSize);
|
||||
}
|
||||
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* De-serialize this instance, for example when loading from a J3O file.
|
||||
*
|
||||
|
@ -35,6 +35,7 @@ import com.jme3.asset.AssetManager;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
@ -75,7 +76,8 @@ public class BasicShadowRenderer implements SceneProcessor {
|
||||
|
||||
protected GeometryList lightReceivers = new GeometryList(new OpaqueComparator());
|
||||
protected GeometryList shadowOccluders = new GeometryList(new OpaqueComparator());
|
||||
|
||||
private AppProfiler prof;
|
||||
|
||||
/**
|
||||
* Creates a BasicShadowRenderer
|
||||
* @param manager the asset manager
|
||||
@ -221,6 +223,11 @@ public class BasicShadowRenderer implements SceneProcessor {
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
public void reshape(ViewPort vp, int w, int h) {
|
||||
dispPic.setPosition(w / 20f, h / 20f);
|
||||
dispPic.setWidth(w / 5f);
|
||||
|
@ -38,6 +38,7 @@ import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.Caps;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
@ -76,6 +77,8 @@ import java.util.List;
|
||||
@Deprecated
|
||||
public class PssmShadowRenderer implements SceneProcessor {
|
||||
|
||||
private AppProfiler prof;
|
||||
|
||||
/**
|
||||
* <code>FilterMode</code> specifies how shadows are filtered
|
||||
* @deprecated use {@link EdgeFilteringMode}
|
||||
@ -725,6 +728,11 @@ public class PssmShadowRenderer implements SceneProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the length over which the shadow will fade out when using a
|
||||
* shadowZextend
|
||||
|
@ -172,6 +172,31 @@ public class NullRenderer implements Renderer {
|
||||
public void setLinearizeSrgbImages(boolean linearize) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] generateProfilingTasks(int numTasks) {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startProfiling(int id) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopProfiling() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getProfilingTime(int taskId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTaskResultAvailable(int taskId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void readFrameBufferWithFormat(FrameBuffer fb, ByteBuffer byteBuf, Image.Format format) {
|
||||
}
|
||||
|
||||
|
@ -148,18 +148,6 @@ void main(){
|
||||
vec3 normal = normalize(wNormal);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LIGHTMAP
|
||||
vec3 lightMapColor;
|
||||
#ifdef SEPARATE_TEXCOORD
|
||||
lightMapColor = texture2D(m_LightMap, texCoord2).rgb;
|
||||
#else
|
||||
lightMapColor = texture2D(m_LightMap, texCoord).rgb;
|
||||
#endif
|
||||
specularColor.rgb *= lightMapColor;
|
||||
albedo.rgb *= lightMapColor;
|
||||
#endif
|
||||
|
||||
float specular = 0.5;
|
||||
#ifdef SPECGLOSSPIPELINE
|
||||
vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
|
||||
@ -171,6 +159,17 @@ void main(){
|
||||
vec4 diffuseColor = albedo - albedo * Metallic;
|
||||
#endif
|
||||
|
||||
#ifdef LIGHTMAP
|
||||
vec3 lightMapColor;
|
||||
#ifdef SEPARATE_TEXCOORD
|
||||
lightMapColor = texture2D(m_LightMap, texCoord2).rgb;
|
||||
#else
|
||||
lightMapColor = texture2D(m_LightMap, texCoord).rgb;
|
||||
#endif
|
||||
specularColor.rgb *= lightMapColor;
|
||||
albedo.rgb *= lightMapColor;
|
||||
#endif
|
||||
|
||||
gl_FragColor.rgb = vec3(0.0);
|
||||
float ndotv = max( dot( normal, viewDir ),0.0);
|
||||
for( int i = 0;i < NB_LIGHTS; i+=3){
|
||||
|
@ -33,6 +33,7 @@ package com.jme3.app.state;
|
||||
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
@ -220,6 +221,7 @@ public class VideoRecorderAppState extends AbstractAppState {
|
||||
private LinkedBlockingQueue<WorkItem> freeItems;
|
||||
private LinkedBlockingQueue<WorkItem> usedItems = new LinkedBlockingQueue<WorkItem>();
|
||||
private MjpegFileWriter writer;
|
||||
private AppProfiler prof;
|
||||
|
||||
public void addImage(Renderer renderer, FrameBuffer out) {
|
||||
if (freeItems == null) {
|
||||
@ -298,6 +300,11 @@ public class VideoRecorderAppState extends AbstractAppState {
|
||||
}
|
||||
writer = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class IsoTimer extends com.jme3.system.Timer {
|
||||
|
@ -32,6 +32,7 @@
|
||||
package com.jme3.system.awt;
|
||||
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
@ -79,6 +80,7 @@ public class AwtPanel extends Canvas implements SceneProcessor {
|
||||
private int newHeight = 1;
|
||||
private AtomicBoolean reshapeNeeded = new AtomicBoolean(false);
|
||||
private final Object lock = new Object();
|
||||
private AppProfiler prof;
|
||||
|
||||
public AwtPanel(PaintMode paintMode) {
|
||||
this(paintMode, false);
|
||||
@ -333,4 +335,9 @@ public class AwtPanel extends Canvas implements SceneProcessor {
|
||||
@Override
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ public class SSAOFilter extends Filter {
|
||||
random.setWrap(Texture.WrapMode.Repeat);
|
||||
ssaoMat.setTexture("RandomMap", random);
|
||||
|
||||
ssaoPass = new Pass() {
|
||||
ssaoPass = new Pass("SSAO pass") {
|
||||
|
||||
@Override
|
||||
public boolean requiresDepthAsTexture() {
|
||||
|
@ -33,6 +33,7 @@ package com.jme3.water;
|
||||
|
||||
import com.jme3.math.Plane;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
@ -50,6 +51,7 @@ public class ReflectionProcessor implements SceneProcessor {
|
||||
private Camera reflectionCam;
|
||||
private FrameBuffer reflectionBuffer;
|
||||
private Plane reflectionClipPlane;
|
||||
private AppProfiler prof;
|
||||
|
||||
/**
|
||||
* Creates a ReflectionProcessor
|
||||
@ -100,6 +102,11 @@ public class ReflectionProcessor implements SceneProcessor {
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only<br>
|
||||
* returns the frame buffer
|
||||
|
@ -35,21 +35,16 @@ import com.jme3.asset.AssetManager;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.*;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.jme3.texture.FrameBuffer;
|
||||
import com.jme3.texture.*;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.Texture.WrapMode;
|
||||
import com.jme3.texture.Texture2D;
|
||||
import com.jme3.ui.Picture;
|
||||
import com.jme3.util.TempVars;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -125,8 +120,9 @@ public class SimpleWaterProcessor implements SceneProcessor {
|
||||
private float distortionScale = 0.2f;
|
||||
private float distortionMix = 0.5f;
|
||||
private float texScale = 1f;
|
||||
|
||||
|
||||
private AppProfiler prof;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SimpleWaterProcessor
|
||||
* @param manager the asset manager
|
||||
@ -222,6 +218,11 @@ public class SimpleWaterProcessor implements SceneProcessor {
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
//debug only : displays maps
|
||||
protected void displayMap(Renderer r, Picture pic, int left) {
|
||||
Camera cam = vp.getCamera();
|
||||
@ -585,6 +586,7 @@ public class SimpleWaterProcessor implements SceneProcessor {
|
||||
|
||||
RenderManager rm;
|
||||
ViewPort vp;
|
||||
private AppProfiler prof;
|
||||
|
||||
public void initialize(RenderManager rm, ViewPort vp) {
|
||||
this.rm = rm;
|
||||
@ -611,5 +613,10 @@ public class SimpleWaterProcessor implements SceneProcessor {
|
||||
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ vec3 getPosition(float depthv, in vec2 uv){
|
||||
vec3 approximateNormal(in vec3 pos,in vec2 texCoord){
|
||||
float step = g_ResolutionInverse.x ;
|
||||
float stepy = g_ResolutionInverse.y ;
|
||||
float depth2 = texture2D(m_DepthTexture,texCoord + vec2(step,-stepy)).r;
|
||||
float depth3 = texture2D(m_DepthTexture,texCoord + vec2(-step,-stepy)).r;
|
||||
float depth2 = getDepth(m_DepthTexture,texCoord + vec2(step,-stepy)).r;
|
||||
float depth3 = getDepth(m_DepthTexture,texCoord + vec2(-step,-stepy)).r;
|
||||
vec3 pos2 = vec3(getPosition(depth2,texCoord + vec2(step,-stepy)));
|
||||
vec3 pos3 = vec3(getPosition(depth3,texCoord + vec2(-step,-stepy)));
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class SSAOUI {
|
||||
}
|
||||
|
||||
private void init(InputManager inputManager) {
|
||||
System.out.println("----------------- Water UI Debugger --------------------");
|
||||
System.out.println("----------------- SSAO UI Debugger --------------------");
|
||||
System.out.println("-- Sample Radius : press Y to increase, H to decrease");
|
||||
System.out.println("-- AO Intensity : press U to increase, J to decrease");
|
||||
System.out.println("-- AO scale : press I to increase, K to decrease");
|
||||
|
@ -41,6 +41,7 @@ import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
@ -231,4 +232,9 @@ public class TestMultiRenderTarget extends SimpleApplication implements ScenePro
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
@ -256,5 +257,10 @@ public class TestRenderToMemory extends SimpleApplication implements SceneProces
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -36,11 +36,10 @@ import com.jme3.light.*;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.post.FilterPostProcessor;
|
||||
import com.jme3.post.DetailedProfilerState;
|
||||
import com.jme3.post.ssao.SSAOFilter;
|
||||
import com.jme3.scene.*;
|
||||
import com.jme3.scene.control.LodControl;
|
||||
import com.jme3.scene.shape.Box;
|
||||
import com.jme3.texture.Texture;
|
||||
|
||||
public class TestSSAO2 extends SimpleApplication {
|
||||
|
||||
@ -57,6 +56,11 @@ public class TestSSAO2 extends SimpleApplication {
|
||||
dl.setDirection(new Vector3f(-1,-1,-1).normalizeLocal());
|
||||
rootNode.addLight(dl);
|
||||
|
||||
flyCam.setDragToRotate(true);
|
||||
setPauseOnLostFocus(false);
|
||||
|
||||
getStateManager().attach(new DetailedProfilerState());
|
||||
|
||||
Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
|
||||
mat.setFloat("Shininess", 16f);
|
||||
//mat.setBoolean("VertexLighting", true);
|
||||
@ -96,7 +100,12 @@ public class TestSSAO2 extends SimpleApplication {
|
||||
|
||||
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
|
||||
SSAOFilter ssaoFilter = new SSAOFilter(2.9299974f,25f,5.8100376f,0.091000035f);
|
||||
ssaoFilter.setApproximateNormals(true);
|
||||
int numSamples = context.getSettings().getSamples();
|
||||
if (numSamples > 0) {
|
||||
fpp.setNumSamples(numSamples);
|
||||
}
|
||||
|
||||
//ssaoFilter.setApproximateNormals(true);
|
||||
fpp.addFilter(ssaoFilter);
|
||||
SSAOUI ui = new SSAOUI(inputManager, ssaoFilter);
|
||||
|
||||
|
@ -6,9 +6,7 @@ import com.jme3.material.Material;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.profile.AppStep;
|
||||
import com.jme3.profile.VpStep;
|
||||
import com.jme3.profile.*;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.scene.Geometry;
|
||||
@ -98,5 +96,10 @@ public class TestShaderNodesStress extends SimpleApplication {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spStep(SpStep step, String... additionalInfo) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +124,11 @@ public class IosGL implements GL, GLExt, GLFbo {
|
||||
JmeIosGLES.glAttachShader(program, shader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glBeginQuery(int target, int query) {
|
||||
throw new UnsupportedOperationException("Today is not a good day for this");
|
||||
}
|
||||
|
||||
public void glBindBuffer(int target, int buffer) {
|
||||
JmeIosGLES.glBindBuffer(target, buffer);
|
||||
}
|
||||
@ -269,6 +274,11 @@ public class IosGL implements GL, GLExt, GLFbo {
|
||||
JmeIosGLES.glEnableVertexAttribArray(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glEndQuery(int target) {
|
||||
throw new UnsupportedOperationException("Today is not a good day for this");
|
||||
}
|
||||
|
||||
public void glGenBuffers(IntBuffer buffers) {
|
||||
checkLimit(buffers);
|
||||
JmeIosGLES.glGenBuffers(buffers.remaining(), temp_array, 0);
|
||||
@ -281,6 +291,11 @@ public class IosGL implements GL, GLExt, GLFbo {
|
||||
fromArray(textures.remaining(), temp_array, textures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenQueries(int num, IntBuffer buff) {
|
||||
throw new UnsupportedOperationException("Today is not a good day for this");
|
||||
}
|
||||
|
||||
public int glGetAttribLocation(int program, String name) {
|
||||
return JmeIosGLES.glGetAttribLocation(program, name);
|
||||
}
|
||||
@ -311,6 +326,16 @@ public class IosGL implements GL, GLExt, GLFbo {
|
||||
return JmeIosGLES.glGetProgramInfoLog(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long glGetQueryObjectui64(int query, int pname) {
|
||||
throw new UnsupportedOperationException("Today is not a good day for this");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetQueryObjectiv(int query, int pname) {
|
||||
throw new UnsupportedOperationException("Today is not a good day for this");
|
||||
}
|
||||
|
||||
public void glGetShader(int shader, int pname, IntBuffer params) {
|
||||
checkLimit(params);
|
||||
JmeIosGLES.glGetShaderiv(shader, pname, temp_array, 0);
|
||||
|
@ -5,12 +5,7 @@ import com.jme3.renderer.opengl.GL;
|
||||
import com.jme3.renderer.opengl.GL2;
|
||||
import com.jme3.renderer.opengl.GL3;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.nio.*;
|
||||
|
||||
import com.jme3.renderer.opengl.GL4;
|
||||
import com.jogamp.opengl.GLContext;
|
||||
@ -69,7 +64,12 @@ public class JoglGL implements GL, GL2, GL3, GL4 {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glBindBuffer(int param1, int param2) {
|
||||
public void glBeginQuery(int target, int query) {
|
||||
GLContext.getCurrentGL().getGL2ES2().glBeginQuery(target, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glBindBuffer(int param1, int param2) {
|
||||
GLContext.getCurrentGL().glBindBuffer(param1, param2);
|
||||
}
|
||||
|
||||
@ -271,13 +271,23 @@ public class JoglGL implements GL, GL2, GL3, GL4 {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenBuffers(IntBuffer param1) {
|
||||
public void glEndQuery(int target) {
|
||||
GLContext.getCurrentGL().getGL2ES2().glEndQuery(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenBuffers(IntBuffer param1) {
|
||||
checkLimit(param1);
|
||||
GLContext.getCurrentGL().glGenBuffers(param1.limit(), param1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenTextures(IntBuffer param1) {
|
||||
public void glGenQueries(int num, IntBuffer buff) {
|
||||
GLContext.getCurrentGL().getGL2ES2().glGenQueries(num, buff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenTextures(IntBuffer param1) {
|
||||
checkLimit(param1);
|
||||
GLContext.getCurrentGL().glGenTextures(param1.limit(), param1);
|
||||
}
|
||||
@ -569,6 +579,20 @@ public class JoglGL implements GL, GL2, GL3, GL4 {
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long glGetQueryObjectui64(int query, int target) {
|
||||
LongBuffer buff = LongBuffer.allocate(1);
|
||||
GLContext.getCurrentGL().getGL2ES2().glGetQueryObjectui64v(query, target, buff);
|
||||
return buff.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetQueryObjectiv(int query, int pname) {
|
||||
IntBuffer buff = IntBuffer.allocate(1);
|
||||
GLContext.getCurrentGL().getGL2ES2().glGetQueryObjectiv(query, pname, buff);
|
||||
return buff.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String glGetShaderInfoLog(int shader, int maxSize) {
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(maxSize);
|
||||
|
@ -11,9 +11,12 @@ import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import com.jme3.renderer.opengl.GL4;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import org.lwjgl.opengl.*;
|
||||
|
||||
public final class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
|
||||
IntBuffer tmpBuff = BufferUtils.createIntBuffer(1);
|
||||
|
||||
private static void checkLimit(Buffer buffer) {
|
||||
if (buffer == null) {
|
||||
@ -42,6 +45,11 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
GL20.glAttachShader(param1, param2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glBeginQuery(int target, int query) {
|
||||
GL15.glBeginQuery(target, query);
|
||||
}
|
||||
|
||||
public void glBindBuffer(int param1, int param2) {
|
||||
GL15.glBindBuffer(param1, param2);
|
||||
}
|
||||
@ -206,11 +214,21 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
GL20.glEnableVertexAttribArray(param1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glEndQuery(int target) {
|
||||
GL15.glEndQuery(target);
|
||||
}
|
||||
|
||||
public void glGenBuffers(IntBuffer param1) {
|
||||
checkLimit(param1);
|
||||
GL15.glGenBuffers(param1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenQueries(int num, IntBuffer ids) {
|
||||
GL15.glGenQueries(ids);
|
||||
}
|
||||
|
||||
public void glGenTextures(IntBuffer param1) {
|
||||
checkLimit(param1);
|
||||
GL11.glGenTextures(param1);
|
||||
@ -435,6 +453,16 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
return GL20.glGetProgramInfoLog(program, maxSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long glGetQueryObjectui64(int query, int target) {
|
||||
return ARBTimerQuery.glGetQueryObjectui64(query, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetQueryObjectiv(int query, int pname) {
|
||||
return GL15.glGetQueryObjecti(query, pname);
|
||||
}
|
||||
|
||||
public String glGetShaderInfoLog(int shader, int maxSize) {
|
||||
return GL20.glGetShaderInfoLog(shader, maxSize);
|
||||
}
|
||||
|
@ -71,6 +71,11 @@ public class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
GL20.glAttachShader(param1, param2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glBeginQuery(int target, int query) {
|
||||
GL15.glBeginQuery(target, query);
|
||||
}
|
||||
|
||||
public void glBindBuffer(int param1, int param2) {
|
||||
GL15.glBindBuffer(param1, param2);
|
||||
}
|
||||
@ -235,6 +240,11 @@ public class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
GL20.glEnableVertexAttribArray(param1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glEndQuery(int target) {
|
||||
GL15.glEndQuery(target);
|
||||
}
|
||||
|
||||
public void glGenBuffers(IntBuffer param1) {
|
||||
checkLimit(param1);
|
||||
GL15.glGenBuffers(param1);
|
||||
@ -245,6 +255,11 @@ public class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
GL11.glGenTextures(param1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glGenQueries(int num, IntBuffer ids) {
|
||||
GL15.glGenQueries(ids);
|
||||
}
|
||||
|
||||
public void glGetBoolean(int param1, ByteBuffer param2) {
|
||||
checkLimit(param2);
|
||||
GL11.glGetBooleanv(param1, param2);
|
||||
@ -464,6 +479,16 @@ public class LwjglGL implements GL, GL2, GL3, GL4 {
|
||||
return GL20.glGetProgramInfoLog(program, maxSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long glGetQueryObjectui64(int query, int target) {
|
||||
return ARBTimerQuery.glGetQueryObjectui64(query, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetQueryObjectiv(int query, int pname) {
|
||||
return GL15.glGetQueryObjecti(query, pname);
|
||||
}
|
||||
|
||||
public String glGetShaderInfoLog(int shader, int maxSize) {
|
||||
return GL20.glGetShaderInfoLog(shader, maxSize);
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ import com.jme3.audio.AudioRenderer;
|
||||
import com.jme3.input.InputManager;
|
||||
import com.jme3.input.event.KeyInputEvent;
|
||||
import com.jme3.post.SceneProcessor;
|
||||
import com.jme3.profile.AppProfiler;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
@ -71,6 +72,7 @@ public class NiftyJmeDisplay implements SceneProcessor {
|
||||
protected ResourceLocationJme resourceLocation;
|
||||
|
||||
protected int w, h;
|
||||
private AppProfiler prof;
|
||||
|
||||
protected class ResourceLocationJme implements ResourceLocation {
|
||||
|
||||
@ -359,4 +361,9 @@ public class NiftyJmeDisplay implements SceneProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfiler(AppProfiler profiler) {
|
||||
this.prof = profiler;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user