Merge remote-tracking branch 'origin/master' into jme3-vr-dev

fix-456
Julien Seinturier 8 years ago
commit 52eb6946af
  1. 1
      README.md
  2. 11
      jme3-android/src/main/java/com/jme3/app/DefaultAndroidProfiler.java
  3. 7
      jme3-android/src/main/java/com/jme3/app/state/VideoRecorderAppState.java
  4. 37
      jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java
  5. 8
      jme3-bullet/src/common/java/com/jme3/bullet/control/CharacterControl.java
  6. 8
      jme3-bullet/src/common/java/com/jme3/bullet/control/RigidBodyControl.java
  7. 6
      jme3-bullet/src/common/java/com/jme3/bullet/control/VehicleControl.java
  8. 22
      jme3-bullet/src/main/java/com/jme3/bullet/collision/shapes/MeshCollisionShape.java
  9. 10
      jme3-core/src/main/java/com/jme3/app/BasicProfiler.java
  10. 7
      jme3-core/src/main/java/com/jme3/app/state/ScreenshotAppState.java
  11. 2
      jme3-core/src/main/java/com/jme3/cinematic/events/MotionEvent.java
  12. 3
      jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java
  13. 6
      jme3-core/src/main/java/com/jme3/light/LightProbeBlendingProcessor.java
  14. 6
      jme3-core/src/main/java/com/jme3/material/MatParam.java
  15. 288
      jme3-core/src/main/java/com/jme3/post/DetailedProfiler.java
  16. 448
      jme3-core/src/main/java/com/jme3/post/DetailedProfilerState.java
  17. 13
      jme3-core/src/main/java/com/jme3/post/Filter.java
  18. 20
      jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java
  19. 7
      jme3-core/src/main/java/com/jme3/post/HDRRenderer.java
  20. 7
      jme3-core/src/main/java/com/jme3/post/PreDepthProcessor.java
  21. 8
      jme3-core/src/main/java/com/jme3/post/SceneProcessor.java
  22. 5
      jme3-core/src/main/java/com/jme3/profile/AppProfiler.java
  23. 13
      jme3-core/src/main/java/com/jme3/profile/SpStep.java
  24. 2
      jme3-core/src/main/java/com/jme3/profile/VpStep.java
  25. 10
      jme3-core/src/main/java/com/jme3/renderer/RenderManager.java
  26. 42
      jme3-core/src/main/java/com/jme3/renderer/Renderer.java
  27. 8
      jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java
  28. 31
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java
  29. 27
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
  30. 6
      jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java
  31. 7
      jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java
  32. 8
      jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java
  33. 25
      jme3-core/src/main/java/com/jme3/system/NullRenderer.java
  34. 21
      jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag
  35. 7
      jme3-desktop/src/main/java/com/jme3/app/state/VideoRecorderAppState.java
  36. 7
      jme3-desktop/src/main/java/com/jme3/system/awt/AwtPanel.java
  37. 2
      jme3-effects/src/main/java/com/jme3/post/ssao/SSAOFilter.java
  38. 7
      jme3-effects/src/main/java/com/jme3/water/ReflectionProcessor.java
  39. 23
      jme3-effects/src/main/java/com/jme3/water/SimpleWaterProcessor.java
  40. 4
      jme3-effects/src/main/resources/Common/MatDefs/SSAO/ssao.frag
  41. 2
      jme3-examples/src/main/java/jme3test/post/SSAOUI.java
  42. 6
      jme3-examples/src/main/java/jme3test/post/TestMultiRenderTarget.java
  43. 6
      jme3-examples/src/main/java/jme3test/post/TestRenderToMemory.java
  44. 15
      jme3-examples/src/main/java/jme3test/post/TestSSAO2.java
  45. 9
      jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java
  46. 25
      jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java
  47. 36
      jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java
  48. 28
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
  49. 25
      jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
  50. 7
      jme3-niftygui/src/main/java/com/jme3/niftygui/NiftyJmeDisplay.java

@ -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,12 +208,13 @@ 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;
}
}
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,10 +276,13 @@ public class RigidBodyControl extends PhysicsRigidBody 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;
}
}
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,10 +269,13 @@ public class VehicleControl extends PhysicsVehicle implements PhysicsControl, Jm
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;
}
}
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,23 +191,17 @@ 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);
}

@ -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;
@ -192,6 +190,12 @@ 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
@ -257,6 +259,11 @@ 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());
//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;
@ -178,6 +180,10 @@ public class LightProbeBlendingProcessor implements SceneProcessor {
this.poi = poi;
}
@Override
public void setProfiler(AppProfiler profiler) {
this.prof = profiler;
}
private class BlendFactor implements Comparable<BlendFactor>{

@ -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 = "";

@ -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);
}
}
}

@ -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);
}

@ -58,6 +58,11 @@ public interface AppProfiler {
*/
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);
}

@ -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,8 +1110,10 @@ 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);

@ -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,6 +247,8 @@ 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 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);

@ -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,6 +76,7 @@ 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
@ -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,6 +148,16 @@ void main(){
vec3 normal = normalize(wNormal);
#endif
float specular = 0.5;
#ifdef SPECGLOSSPIPELINE
vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
vec4 diffuseColor = albedo;
Roughness = 1.0 - texture2D(m_GlossMap, newTexCoord).r;
#else
float nonMetalSpec = 0.08 * specular;
vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic;
vec4 diffuseColor = albedo - albedo * Metallic;
#endif
#ifdef LIGHTMAP
vec3 lightMapColor;
@ -160,17 +170,6 @@ void main(){
albedo.rgb *= lightMapColor;
#endif
float specular = 0.5;
#ifdef SPECGLOSSPIPELINE
vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
vec4 diffuseColor = albedo;
Roughness = 1.0 - texture2D(m_GlossMap, newTexCoord).r;
#else
float nonMetalSpec = 0.08 * specular;
vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic;
vec4 diffuseColor = albedo - albedo * Metallic;
#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,6 +120,7 @@ public class SimpleWaterProcessor implements SceneProcessor {
private float distortionScale = 0.2f;
private float distortionMix = 0.5f;
private float texScale = 1f;
private AppProfiler prof;
/**
@ -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;
@ -68,6 +63,11 @@ public class JoglGL implements GL, GL2, GL3, GL4 {
GLContext.getCurrentGL().getGL2ES2().glAttachShader(param1, param2);
}
@Override
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);
@ -270,12 +270,22 @@ public class JoglGL implements GL, GL2, GL3, GL4 {
GLContext.getCurrentGL().getGL2ES2().glEnableVertexAttribArray(param1);
}
@Override
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 glGenQueries(int num, IntBuffer buff) {
GLContext.getCurrentGL().getGL2ES2().glGenQueries(num, buff);
}
@Override
public void glGenTextures(IntBuffer param1) {
checkLimit(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,10 +11,13 @@ 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) {
return;
@ -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…
Cancel
Save