Depth buffer texture

Started by Thomas., June 30, 2012, 01:58:21 AM

Previous topic - Next topic

EgonOlsen

To be honest, i've completely lost track of what blinks when and when not. The only thing that i really got is, that it seems to stop blinking when you add some delay. This makes me want to try one more thing....i've updated the jar. FrameBuffer now has a sync()-method. Please add that instead of your delay and see if that helps. If it doesn't, try to clutter the whole code with sync()-calls to see if any of these might help.

About asking in the dev forums (not that i found one for Mali chips at first try...)...i'll try that if nothing else helps, but after visiting the PowerVR-forums yesterday, i wouldn't bet a single penny on that... :(

Thomas.

#91
With fb.sync() and blit texture from first render is the same result. If I used overlay, correct teapot under black one is not visible, so it something does, but it no help in this case.

EgonOlsen

Have you tried to add it on other locations in the code too?

Thomas.

Yes yes, every time I'm trying all options

EgonOlsen

Well...so, because i'm slightly confused about the current state: Do you have any version (with some delay or whatever) that does work? If so, i would like to see the code for that. Or does non of the variants really works in all cases?

Thomas.

With this code is it fine, but only if I'm blitting texture from the first render. When I use overlay, the first texture is black.

package cz.chladek.shadertest;

import java.lang.reflect.Field;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.DepthBuffer;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.GLSLShader;
import com.threed.jpct.Light;
import com.threed.jpct.Loader;
import com.threed.jpct.Logger;
import com.threed.jpct.NPOTTexture;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.Overlay;

import cz.chladek.shadertest.R;

public class ShaderTest extends Activity {

// Used to handle pause and resume...
private static ShaderTest master = null;

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer fb = null;
private World world = null;

private World secWorld;

private float touchTurn = 0;
private float touchTurnUp = 0;

private float xpos = -1;
private float ypos = -1;

private Texture font = null;

private Object3D[] objects;
private Light light;

private int selectedObject = 0;

private Texture renderTarget;
private Texture renderTarget2;

private Overlay overlay;
private boolean useOverlay;
private boolean clearZBuffer;

protected void onCreate(Bundle savedInstanceState) {
Logger.log("onCreate");
Logger.setLogLevel(Logger.LL_DEBUG);

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(LayoutParams.FLAG_FULLSCREEN, LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);

if (master != null) {
copy(master);
}

super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());

// Enable the OpenGL ES2.0 context
mGLView.setEGLContextClientVersion(2);

renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
}

@Override
protected void onPause() {
Logger.log("onPause");
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
Logger.log("onResume");
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
Logger.log("onStop");
super.onStop();
}

private void copy(Object src) {
try {
Logger.log("Copying data from master Activity!");
Field[] fs = src.getClass().getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true);
f.set(this, f.get(src));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public boolean onTouchEvent(MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;

xpos = me.getX();
ypos = me.getY();

touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

public boolean onKeyDown(int keyCode, KeyEvent msg) {

if (keyCode == KeyEvent.KEYCODE_MENU) {
/*
* selectedObject = (selectedObject + 1 == objects.length) ? 0 : selectedObject + 1; renderer.showObjectIndex(selectedObject);
*/

if (useOverlay) {
useOverlay = false;
overlay.setVisibility(false);
} else {
useOverlay = true;
overlay.setVisibility(true);
}

return true;
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
clearZBuffer = clearZBuffer ? false : true;
return true;
}

return super.onKeyDown(keyCode, msg);
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private int fps = 0;
private int lfps = 0;

private long time = System.currentTimeMillis();

private Resources res;
private GLSLShader pointLightShader;
private TextureManager tm;

private Object3D plane2;

public MyRenderer() {
Config.farPlane = 2000;
Config.useNormalsFromOBJ = true;
Texture.defaultToMipmapping(true);
Texture.defaultTo4bpp(true);
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
if (fb != null)
fb.dispose();

fb = new FrameBuffer(w, h);

if (master == null) {
world = new World();
res = getResources();
tm = TextureManager.getInstance();

font = new Texture(res.openRawResource(R.raw.numbers));
font.setMipmap(false);

pointLightShader = new GLSLShader(Loader.loadTextFile(res.openRawResource(R.raw.pixel_light_vertex)),
Loader.loadTextFile(res.openRawResource(R.raw.pixel_light_fragment_1)));

loadObjects();

light = new Light(world);
light.setIntensity(50, 50, 50);
light.setPosition(new SimpleVector(0, 0, -10));

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 3);
cam.lookAt(objects[selectedObject].getTransformedCenter());

world.setAmbientLight(0, 0, 0);
world.compileAllObjects();

renderTarget = new NPOTTexture(fb.getWidth(), fb.getHeight(), null);
tm.addTexture("renderTarget", renderTarget);

renderTarget2 = new NPOTTexture(fb.getWidth(), fb.getHeight(), null);
tm.addTexture("renderTarget2", renderTarget2);

DepthBuffer depthBuffer = new DepthBuffer(fb.getWidth(), fb.getHeight());
renderTarget.setDepthBuffer(depthBuffer);
renderTarget2.setDepthBuffer(depthBuffer);

secWorld = new World();

plane2 = Primitives.getPlane(1, 1.5f);
plane2.build();
plane2.setName("object");
// plane2.setShader(pointLightShader);
plane2.setAdditionalColor(new RGBColor(50, 10, 10));
plane2.setCulling(false);
secWorld.addObject(plane2);
Light light2 = new Light(secWorld);
light2.setIntensity(50, 50, 50);
light2.setPosition(new SimpleVector(3, 3, -10));
secWorld.getCamera().moveCamera(Camera.CAMERA_MOVEOUT, 3);

overlay = new Overlay(secWorld, 0, fb.getHeight(), fb.getWidth(), 0, "renderTarget");
overlay.getObject3D().setCulling(false);
overlay.setDepth(1000);

if (master == null) {
Logger.log("Saving master Activity!");
master = ShaderTest.this;
}
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Logger.log("onSurfaceCreated");
}

public void loadObjects() {
world.removeAllObjects();

objects = new Object3D[1];
objects[0] = Loader.loadOBJ(res.openRawResource(R.raw.teapot_o), res.openRawResource(R.raw.teapot_m), 1.5f)[0];
// objects[1] = Loader.loadOBJ(res.openRawResource(R.raw.plane_o), res.openRawResource(R.raw.plane_m), 2)[0];
// objects[2] = Loader.loadOBJ(res.openRawResource(R.raw.box_o), res.openRawResource(R.raw.box_m), 2)[0];
// objects[3] = Loader.loadOBJ(res.openRawResource(R.raw.airplane_o), res.openRawResource(R.raw.airplane_m), 0.013f)[0];
// objects[4] = Loader.loadOBJ(res.openRawResource(R.raw.car_o), res.openRawResource(R.raw.car_m), 0.02f)[0];
// objects[5] = Loader.loadOBJ(res.openRawResource(R.raw.car2_o), res.openRawResource(R.raw.car2_m), 0.03f)[0];

for (Object3D object : objects) {
object.setShader(pointLightShader);
object.setAdditionalColor(new RGBColor(10, 50, 10));
}

showObjectIndex(selectedObject);

world.addObjects(objects);
}

public void showObjectIndex(int index) {
for (int i = 0; i < objects.length; i++)
if (i != index)
objects[i].setVisibility(false);
else
objects[i].setVisibility(true);
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
objects[selectedObject].rotateY(touchTurn);
plane2.rotateY(-touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
objects[selectedObject].rotateX(touchTurnUp);
plane2.rotateX(-touchTurnUp);
touchTurnUp = 0;
}

fb.clear();
fb.setRenderTarget(renderTarget);
fb.clear();
world.renderScene(fb);
world.draw(fb);
fb.display();
fb.removeRenderTarget();

fb.setRenderTarget(renderTarget2);
fb.clearColorBufferOnly(RGBColor.BLACK);
if (!useOverlay)
fb.blit(renderTarget, 0, 0, 0, fb.getHeight(), fb.getWidth(), fb.getHeight(), fb.getWidth(), -fb.getHeight(), -1, false,
null);
secWorld.renderScene(fb);
secWorld.draw(fb);
fb.display();
if (clearZBuffer)
fb.clearZBufferOnly();
fb.removeRenderTarget();

fb.blit(renderTarget2, 0, 0, 0, fb.getHeight(), fb.getWidth(), fb.getHeight(), fb.getWidth(), -fb.getHeight(), -1, false, null);

/*
* fb.clear(); world.renderScene(fb); world.draw(fb); secWorld.renderScene(fb); secWorld.draw(fb);
*/

blitNumber(lfps, 5, 5);
fb.display();

try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

if (System.currentTimeMillis() - time >= 1000) {
lfps = fps;
fps = 0;
time = System.currentTimeMillis();
}
fps++;

}

private void blitNumber(float number, int x, int y) {
if (font != null) {
String sNum = Float.toString(number);

for (int i = 0; i < sNum.length(); i++) {
char cNum = sNum.charAt(i);
int iNum = cNum - 48;
fb.blit(font, iNum * 5, 0, x, y, 5, 9, 5, 9, 10, true, null);
x += 5;
}
}
}
}
}

EgonOlsen

...and if i remove the Thread.sleep(20); it's no longer working?

Thomas.

#97
Yes, but wait, I added fb.sync() after every method in onDrawFrame method. Blit of first texture is fine. Overlay is rendered correct, but without depth (the first render is not black as before). Now I'm removing fb.sync() and looking for the best combination.

Thomas.

This is next working combination but only if you use blit method. It feels like a lottery. And it is very slow, just 31fps.

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
objects[selectedObject].rotateY(touchTurn);
plane2.rotateY(-touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
objects[selectedObject].rotateX(touchTurnUp);
plane2.rotateX(-touchTurnUp);
touchTurnUp = 0;
}

fb.clear();
fb.setRenderTarget(renderTarget);
fb.clear();
world.renderScene(fb);
world.draw(fb);
fb.display();
fb.removeRenderTarget();
fb.setRenderTarget(renderTarget2);
fb.clearColorBufferOnly(RGBColor.BLACK);
if (!useOverlay)
fb.blit(renderTarget, 0, 0, 0, fb.getHeight(), fb.getWidth(), fb.getHeight(), fb.getWidth(), -fb.getHeight(), -1, false,
null);
fb.sync(); // if you remove it, clearZBuffer has to be true
secWorld.renderScene(fb);
fb.sync(); // if you remove it, clearZBuffer has to be true
secWorld.draw(fb);
fb.display();
if (clearZBuffer)
fb.clearZBufferOnly();
fb.removeRenderTarget();
fb.blit(renderTarget2, 0, 0, 0, fb.getHeight(), fb.getWidth(), fb.getHeight(), fb.getWidth(), -fb.getHeight(), -1, false, null);

/*
* fb.clear(); world.renderScene(fb); world.draw(fb); secWorld.renderScene(fb); secWorld.draw(fb);
*/

blitNumber(lfps, 5, 5);
fb.display();

/*
* try { Thread.sleep(20); } catch (InterruptedException e) { }
*/

if (System.currentTimeMillis() - time >= 1000) {
lfps = fps;
fps = 0;
time = System.currentTimeMillis();
}
fps++;

}

EgonOlsen

I've just noticed that sync wasn't exactly doing what it was supposed to be doing. Please re-download and start again by replacing the delay with sync and if that doesn't help...well, you know what to do... ;)

In addition, there's a new flush() method in FrameBuffer. If you managed to get a combination working with sync(), try to replace some of the sync()-calls with flush() and see what happens then.

Thomas.

#100
I just added sync() after last display() method and blinking is gone :) but only if I use blit method, overlay is still showing black nothing. Replace sync() by flush() returns old problem with blinking... and fps is about 45, without sync() it is 60...

edit: and overlay... it seems, that texture from first rendering is usable, but is not applied on overlay...
By red lines is indicated plane with applied texture from first rendering

EgonOlsen

I wouldn't care about the Overlay stuff. If it works with blitting, all is well. It's the more efficient way anyway.
sync() makes the cpu wait for the gpu to finish. Usually, this isn't needed for anything but in this case and on this chips, it seems to be.

Thomas.

#102
I don't think, that using sync() is well solution. Just 22 fps with DOF and image post effects. If I turn on DOF only, I have 58 fps, it is render depth buffer, normal scene and render plane with effect (I did optimization of depth texture in comparison with previous results).

EgonOlsen

It's the only solution as far as i can see. Obviously, your gpu or driver continues rendering the next image based on incomplete data because the former image hasn't been fully processed (and it doesn't notice that) if you omit it. You might want to try to move it up, i.e. do the first renderScene()-call, then do the sync() and then do the clear and the draw and stuff...i'm not sure if that will work though but if it does, it might help to get some parallel processing back.

Thomas.

Any idea where is problem? I'm using 3 texture layers. When I comment last adding of texture as REPLACE is it fine.

Config.maxTextureLayers = 4;

...

ti = new TextureInfo(tm.getTextureID(getTextureName(texture)));
ti.add(tm.getTextureID("PPH_image_buffer_first"), TextureInfo.MODE_ADD);
ti.add(tm.getTextureID("PPH_depth_buffer"), TextureInfo.MODE_REPLACE);
object.setTexture(ti);


07-20 16:59:47.446: E/AndroidRuntime(16220): FATAL EXCEPTION: GLThread 1760
07-20 16:59:47.446: E/AndroidRuntime(16220): java.lang.RuntimeException: [ 1342796387234 ] - ERROR: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
07-20 16:59:47.446: E/AndroidRuntime(16220): at com.threed.jpct.GLRenderer.setTextures(GLRenderer.java:2319)
07-20 16:59:47.446: E/AndroidRuntime(16220): at com.threed.jpct.GLRenderer.drawVertexArray(GLRenderer.java:2226)
07-20 16:59:47.446: E/AndroidRuntime(16220): at com.threed.jpct.World.draw(World.java:1319)
07-20 16:59:47.446: E/AndroidRuntime(16220): at com.threed.jpct.World.draw(World.java:1081)
07-20 16:59:47.446: E/AndroidRuntime(16220): at cz.chladek.mygame.post_effects.PostEffectsHelper.renderScene(PostEffectsHelper.java:140)
07-20 16:59:47.446: E/AndroidRuntime(16220): at cz.chladek.mygame.AppActivity$MyRenderer.onDrawFrame(AppActivity.java:632)
07-20 16:59:47.446: E/AndroidRuntime(16220): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
07-20 16:59:47.446: E/AndroidRuntime(16220): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)
07-20 16:59:47.446: E/AndroidRuntime(16220): at com.threed.jpct.Logger.log(Logger.java:189)
07-20 16:59:47.446: E/AndroidRuntime(16220): at com.threed.jpct.Logger.log(Logger.java:148)
07-20 16:59:47.446: E/AndroidRuntime(16220): at cz.chladek.mygame.AppActivity$MyRenderer.onDrawFrame(AppActivity.java:654)
07-20 16:59:47.446: E/AndroidRuntime(16220): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
07-20 16:59:47.446: E/AndroidRuntime(16220): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)