Author Topic: Version updates!  (Read 177845 times)

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #180 on: February 17, 2011, 10:18:41 am »
As Kaiidyn mentions, you have to do a complete render cycle, i.e. with renderScene, draw, display. A simple blit isn't sufficient. It might work to use display only if all you do is blitting into the render target, but i'm not 100% sure about this. If it doesn't work, just use a dummy world.

Offline Thomas.

  • double
  • *****
  • Posts: 833
    • View Profile
Re: Version updates!
« Reply #181 on: February 17, 2011, 11:48:42 am »
I use code without renderScene and draw in another case and it is working... so now I add fb.display() (also tried renderScene and draw), same result with texture, but it look like every rendered frame is in lower resolution...
Code: [Select]
fb.setRenderTarget(tex);
fb.clear();
textureBlitter();
fb.display();
fb.removeRenderTarget();
fb.clear();

Offline Kaiidyn

  • long
  • ***
  • Posts: 103
    • View Profile
Re: Version updates!
« Reply #182 on: February 17, 2011, 11:55:54 am »
I think you should not set and remove the renderTarget in every frame, set it in your initialization.. then put the clear, blitter and display in your loop, also remove the 2nd clear, as there is no point in doing it twice (except for making your render slower)
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #183 on: February 17, 2011, 12:09:43 pm »
No, you have to add and remove it in every frame or otherwise, you'll render everything into the texture and nothing on screen. Maybe it helps if i clarify a little what this actually does (at least in the Android implementation, because it lacks fbo support):

When setting a render target, the view port is limited to the texture size. Then you render your scene as usual. After calling display, the rendered image is copied from the frame buffer into the render target texture. If you remove the render target, the viewport is reset to match the frame buffer's size.

@Thomas: I don't get that "lower resolution" description...do you have a screen shot?

Offline Thomas.

  • double
  • *****
  • Posts: 833
    • View Profile
Re: Version updates!
« Reply #184 on: February 17, 2011, 12:23:02 pm »
In my app I use this test code... Can anybody provide some part of code, that render to texture working?

Code: [Select]
if (first) {
Thread lb = new GameLoader();
lb.start();
fb.setRenderTarget(tex);
fb.clear();
textureBlitter();
fb.display();
fb.removeRenderTarget();
fb.clear();
}
showLoading(loaded);
fb.display();
first = false;

and here is screen ... after I call renderScene and draw it, "resolution" is correct

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #185 on: February 17, 2011, 12:44:26 pm »

Offline Thomas.

  • double
  • *****
  • Posts: 833
    • View Profile
Re: Version updates!
« Reply #186 on: February 17, 2011, 04:15:32 pm »
this happens when I blit something or render world... is there any solution?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #187 on: February 17, 2011, 04:33:26 pm »
Have you tried to add a clear like i've mentioned in the linked thread? If not, please provide a test case as i don't fully understand what you are doing there.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #188 on: February 17, 2011, 05:08:19 pm »
Example that works in the emulator and on my phone:
Code: [Select]
package com.threed.jpct.example;

import java.lang.reflect.Field;

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

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.BitmapHelper;
import com.threed.jpct.util.MemoryHelper;

/**
 * @author EgonOlsen
 *
 */
public class HelloWorld extends Activity {

private static HelloWorld master = null;

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer fb = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);

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

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

private Object3D cube0 = null;
private Object3D cube1 = null;
private Object3D cube2 = null;
private Object3D cube3 = null;
private Object3D dummy = null;

private Texture renderTarget = null;

private int fps = 0;

private int cnt = 0;

protected void onCreate(Bundle savedInstanceState) {

Logger.log("onCreate");

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

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

mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});

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

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

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

protected void 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);
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();
private boolean stop = false;

public MyRenderer() {
}

public void stop() {
stop = true;
}

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

if (master == null) {

world = new World();
world.setAmbientLight(0, 0, 0);

Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.icon)), 64, 64));
TextureManager.getInstance().addTexture("texture", texture);

dummy = Object3D.createDummyObj();

cube0 = Primitives.getCube(10);
cube0.rotateY(-(float) Math.PI / 4f);
cube0.rotateMesh();
cube0.clearRotation();
cube0.calcTextureWrapSpherical();
cube0.setTexture("texture");
cube0.strip();
cube0.build();

cube1 = cube0.cloneObject();
cube2 = cube0.cloneObject();
cube3 = cube0.cloneObject();

world.addObject(cube0);
world.addObject(cube1);
world.addObject(cube2);
world.addObject(cube3);

cube0.translate(-20, -20, 0);
cube1.translate(20, -20, 0);
cube2.translate(-20, 20, 0);
cube3.translate(20, 20, 0);

cube0.setAdditionalColor(RGBColor.WHITE);
cube1.setAdditionalColor(RGBColor.BLUE);
cube2.setAdditionalColor(RGBColor.GREEN);
cube3.setAdditionalColor(RGBColor.RED);

cube0.addParent(dummy);
cube1.addParent(dummy);
cube2.addParent(dummy);
cube3.addParent(dummy);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 100);

renderTarget = new Texture(256, 256, RGBColor.RED);

MemoryHelper.compact();

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

//Logger.setLogLevel(Logger.DEBUG);
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {

try {
if (!stop) {
if (touchTurn != 0) {
dummy.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
dummy.rotateX(touchTurnUp);
touchTurnUp = 0;
}

cnt++;

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

fb.clear(back);
world.renderScene(fb);
world.draw(fb);
fb.blit(renderTarget, 0, 0, 0, 0, 256, 256, false);
fb.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
} else {
if (fb != null) {
fb.dispose();
fb = null;
}
}
} catch (Exception e) {
Logger.log(e, Logger.MESSAGE);
}
}
}
}


Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #189 on: February 17, 2011, 05:22:24 pm »
Another version that does an initial blit into the texture:
Code: [Select]
package com.threed.jpct.example;

import java.lang.reflect.Field;

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

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.BitmapHelper;
import com.threed.jpct.util.MemoryHelper;

/**
 * @author EgonOlsen
 *
 */
public class HelloWorld extends Activity {

private static HelloWorld master = null;

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer fb = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);

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

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

private Object3D cube0 = null;
private Object3D cube1 = null;
private Object3D cube2 = null;
private Object3D cube3 = null;
private Object3D dummy = null;

private Texture renderTarget = null;

private int fps = 0;
private int cnt = 0;

private boolean firstRun = true;

protected void onCreate(Bundle savedInstanceState) {

Logger.log("onCreate");

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

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

mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});

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

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

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

protected void 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);
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();
private boolean stop = false;

public MyRenderer() {
}

public void stop() {
stop = true;
}

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

if (master == null) {

world = new World();
world.setAmbientLight(0, 0, 0);

Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.icon)), 64, 64));
TextureManager.getInstance().addTexture("texture", texture);

dummy = Object3D.createDummyObj();

cube0 = Primitives.getCube(10);
cube0.rotateY(-(float) Math.PI / 4f);
cube0.rotateMesh();
cube0.clearRotation();
cube0.calcTextureWrapSpherical();
cube0.setTexture("texture");
cube0.strip();
cube0.build();

cube1 = cube0.cloneObject();
cube2 = cube0.cloneObject();
cube3 = cube0.cloneObject();

world.addObject(cube0);
world.addObject(cube1);
world.addObject(cube2);
world.addObject(cube3);

cube0.translate(-20, -20, 0);
cube1.translate(20, -20, 0);
cube2.translate(-20, 20, 0);
cube3.translate(20, 20, 0);

cube0.setAdditionalColor(RGBColor.WHITE);
cube1.setAdditionalColor(RGBColor.BLUE);
cube2.setAdditionalColor(RGBColor.GREEN);
cube3.setAdditionalColor(RGBColor.RED);

cube0.addParent(dummy);
cube1.addParent(dummy);
cube2.addParent(dummy);
cube3.addParent(dummy);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 100);

renderTarget = new Texture(256, 256, RGBColor.RED);

MemoryHelper.compact();

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

// Logger.setLogLevel(Logger.DEBUG);
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {

try {
if (!stop) {
if (touchTurn != 0) {
dummy.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
dummy.rotateX(touchTurnUp);
touchTurnUp = 0;
}

cnt++;

if (firstRun) {
fb.setRenderTarget(renderTarget);
fb.clear(RGBColor.BLUE);

Texture t = TextureManager.getInstance().getTexture("texture");
for (int i = 0; i < fb.getWidth(); i += 10) {
fb.blit(t, 0, 0, i, i, t.getWidth(), t.getHeight(), false);
}
fb.display();
fb.removeRenderTarget();
firstRun = false;
}

fb.clear(back);
world.renderScene(fb);
world.draw(fb);
fb.blit(renderTarget, 0, 0, 0, 0, 256, 256, false);
fb.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
} else {
if (fb != null) {
fb.dispose();
fb = null;
}
}
} catch (Exception e) {
Logger.log(e, Logger.MESSAGE);
}
}
}
}

If you want to use render to texture as a blit container, you'll run into the problem that the result is displayed upside-down. That's caused by the way OpenGL maps frame buffer to texture coordinates. For blitting, it's a better idea to compose the texture on the bitmap level anyway, The results will look cleaner because they are unaffected by gpu filtering and potential dithering and its more compatible.

Offline Thomas.

  • double
  • *****
  • Posts: 833
    • View Profile
Re: Version updates!
« Reply #190 on: February 17, 2011, 05:24:28 pm »
sorry, problem is on my side... I wrote new test app, too, and it work, so I will have to look where I have bug in my game... and is normal, that texture is flipped around x axis?
PS: ok :)
« Last Edit: February 17, 2011, 06:29:01 pm by Thomas. »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #191 on: February 17, 2011, 09:35:04 pm »
... and is normal, that texture is flipped around x axis?
Yes. As said above, it's caused by the way how OpenGL maps the frame buffer to the texture.

Offline Polomease

  • byte
  • *
  • Posts: 9
    • View Profile
Re: Version updates!
« Reply #192 on: February 18, 2011, 03:01:36 am »

I tried the new version of jPCT you released using the two examples you posted.
My phone is having a problem with the render targets as well.

I have a Samsung Galaxy S (model: SAMSUNG-SGH-I897) with Android 2.1.

GL Info from LogCat
02-17 16:29:09.463: INFO/jPCT-AE(27067): OpenGL vendor:     Imagination Technologies
02-17 16:29:09.463: INFO/jPCT-AE(27067): OpenGL renderer:   PowerVR SGX 540
02-17 16:29:09.463: INFO/jPCT-AE(27067): OpenGL version:    OpenGL ES-CM 1.1


Here are some screen shots of the first example code you posted, one from the emulator and one from my phone.




Here are some screen shots of the second example code you posted, one from the emulator and one from my phone.


Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #193 on: February 18, 2011, 10:57:19 am »
Which version of jPCT-AE is that? The latest that i've posted in this thread?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Version updates!
« Reply #194 on: February 18, 2011, 04:58:58 pm »
]Yes. As said above, it's caused by the way how OpenGL maps the frame buffer to the texture.
BTW: You can flip a blit by doing something like

Code: [Select]
fb.blit(renderTarget, 0, 0, 0, 256, 256, 256, 256, -256, -1, false, null);

instead of

Code: [Select]
fb.blit(renderTarget, 0, 0, 0, 0, 256, 256, 256, 256, -1, false, null);

It's not an official feature but it works due to the way blitting is implemented.