How to use renderTarget?

Started by kiffa, December 05, 2013, 07:19:38 AM

Previous topic - Next topic

kiffa

My purpose is to render the scene 2 times with different camera per frame, the first rendering will render to full screen, the second rendering will render to a smaller(1/4w、1/4h of the screen). But my code seems useless(the result seems like which don't do the second rendering).



  private void init(){
    mTexture = new Texture(256, 128);
    mTexture.setMipmap(false);
    TextureManager.getInstance().addTexture("rt", mTexture);
  }
 
  private void update(World world, FrameBuffer frameBuffer){
    int screenWidth = 800;
    int screenHeight = 480;
   
    //first rendering
    world.renderScene(frameBuffer);
    world.draw(frameBuffer);
   
    //second rendering
    frameBuffer.setRenderTarget(mTexture);
    world.renderScene(frameBuffer);
    world.draw(frameBuffer);
    frameBuffer.blit(mTexture, 0, 0, 0, 0, screenWidth/4, screenHeight/4, false);
    frameBuffer.removeRenderTarget();
   
  }

EgonOlsen

The first thing to be aware of is, that render to texture actually requires OpenGL ES 2.0 to be useful. It might work with 1.x as well, but because of some API limitations in 1.x, it's...well...limited and it doesn't work on all devices.
 
Your code misses some calls that are needed to make this work. You should rather do something like this:
 
 
  //first rendering
  frameBuffer.setRenderTarget(mTexture);
  frameBuffer.clear();
  world.renderScene(frameBuffer);
  world.draw(frameBuffer);
  frameBuffer.display();
  frameBuffer.removeRenderTarget();
 
  //second rendering
  frameBuffer.clear();
  world.renderScene(frameBuffer);
  world.draw(frameBuffer);
  frameBuffer.blit(mTexture, 0, 0, 0, 0, screenWidth/4, screenHeight/4, false);
  frameBuffer.display();
 

 
Note that i've moved the render to texture to the front. That's because it will overwrite the actual framebuffer otherwise if you are using 1.x.
You'll also notice that the blitted result is upside-down. You can fix that by using a negative height (and maybe setting the y start to screenHeight/4...i can't remember if that's needed ATM).

kiffa

> You'll also notice that the blitted result is upside-down. You can fix that by using a negative height (and maybe setting the y start to screenHeight/4...i can't remember if that's needed ATM).

After some try, i am not very clear how to do(to fix the upside-down). Could you give me some sample code?



IZACIZAC

frameBuffer.blit(mTexture, 0, mTexture.getHeight(), 0, 0, mTexture.getWidth(), -mTexture.getHeight(), Display.getWidth()/4, Display.getHeight()/4, -1, false);

This will solve that problem. Also I changed to the blit method that instead scales the image you are blitting, because the previous version was cutting out some of what is shown on the screen (for me at least)

kiffa

#4
Thanks, i have tried this before, but the result is not what i expect, which seems i got an incomplete renderTargetTexture. There is another question:

Assume the size of display is 2X2, and can be spilt to 4 parts:
12
34

If i use a 1X1 (npot)texture as the renderTarget, which one is the correct result:
a, 1

b, 3

c, 4

d, a scaled
12
34

Could i render the full scene into a smaller texture? The following code seems useless:

Texture t = new NPOTTexture(w, h);
frameBuffer.resize(w, h);
renderToTarget();
frameBuffer.resize(oldW, oldH);
framBuffer.blit(t);


EgonOlsen

d) is the correct result. And your problem is....? A screen shot might help.

IZACIZAC

I tested it and think I had the same issue. The texture that is blitted into the corner is not the same as the other full screen rendering, it is a slightly smaller field of view, missing some from the top and bottom.

Doing    buffer.setVirtualDimensions(800, 480);  //your screen width and height
seems to help solve this, though its still a tiny bit out

EgonOlsen

jPCT calculates the fov in a way that the horizontal angle is constant and the vertical angle will adjuated to keep a 1-1 ratio in all resolutions. As mentioned you can override this by setting the virtual dimensions. Another option would be to set fov values all by yourself.