clearAll option of setRenderTarget doesn't work?

Started by MichaelJPCT, November 01, 2020, 08:17:09 AM

Previous topic - Next topic

MichaelJPCT

fb.setRenderTarget(tex,9,9,9,9,false); fb.clear(0xffff);

with the above code, the whole texture turns blue, why?
tested on powervr 6250.


MichaelJPCT

the question is not about the color , but about the border of texture being cleared , when clearAll option is set to false,
while the java doc says otherwise.

anyway, now i use blitting (from a pure color texture) to replace clearing.

EgonOlsen

Apart from the fact that the docs for this options are strangly worded, this seems to be an oversight that I made when porting the engine from desktop Java to Android. I simply forgot to do something with this parameter. Try this version and see if that helps: https://jpct.de/download/beta/jpct_ar.jar

MichaelJPCT

it works , thanks.

another problem i encounter again is the wrong scaling of blitting , when the target texture is of different size from the real fb.
the blitting system thinks the texture is the same size as real fb, so i need to scale again. for now i can make a scaling function to solve it.
the current api would confuse new users, sometimes it's hard to figure out what is wrong, i encountered that several years ago.
i think the best solution is to use normalized value for positioning if the engine provides a widely compatible api.

EgonOlsen

Yes, blitting into render target's sucks. But that's not a question of normalized coordinates or not. After all, I could easily normalize them in the background. The problem lies somewhere else and it's related to the fact that blits are buffered or something like that...I can't remember it exactly, but at least at the time, I couldn't come up with a good solution or otherwise, I would have done so. My best idea was to add a section to the docs that tell you that it sucks and it's not advised to do it...;-)

For my RPG, I've written a converter class:


package com.threed.jpct.games.gui.glfont;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Texture;

/**
*
* @author EgonOlsen
*
*/
public class RenderTargetModifier implements CoordinateModifier {

private Texture target = null;

public RenderTargetModifier(Texture texture) {
target = texture;
}

@Override
public int convertX(FrameBuffer buffer, int x) {
return (int) ((float) x * ((float) buffer.getWidth() / (float) target.getWidth()));
}

@Override
public int convertY(FrameBuffer buffer, int y) {
return (int) ((float) y * ((float) buffer.getHeight() / (float) target.getHeight()));
}

@Override
public int getHeight() {
return target.getHeight();
}
}


MichaelJPCT

there is another problem which we know already: the rendered image is flipped in texture. but it can be counteracted from app level. i just think it's strange.

EgonOlsen


MichaelJPCT

hi, i encounter a situation that blitting is not fixed by scaling but by offsetting position.
offset size = (fb.width-tex.width)/2 , (fb.height-tex.height)/2 .
the situation is this: setVirtualDimensions(tex size),  render some object3d , then blit.
also ,if camera fov is very small, i must reset fov to a normal one (calling emptyWorld.renderscene) before blitting or blit result is inaccurate.
i think blitting after rendering object3d is different from pure blitting (into texture).

EgonOlsen

I'm not sure. The small fov might be an accuracy issue when recalculating things. The offset....no idea. How exactly are you doing the blitting? This is how I'm doing it in my RPG for the pages of the quest book:


private void writeOnTexture(Page page, Texture texture, FrameBuffer buffer, GLFont textFont, GLFont pageFont) {
textFont.getTexturePack().setCoordinateModifier(modifier);
pageFont.getTexturePack().setCoordinateModifier(modifier);
buffer.sync();
buffer.setRenderTarget(texture);
buffer.clear(0x00ffffff);
if (page != null) {
int end = page.getLineCount();
for (int i = 0; i < end; i++) {
Line line = page.getLine(i);
textFont.blitString(buffer, line.getText(), line.getX(), line.getY(), 300, RGBColor.BLACK);
}

String pageText = "- " + page.getNumber() + " -";
Rectangle rec = pageFont.getStringBounds(pageText, tmpRec);
int xpos = texture.getWidth() / 2 - rec.width / 2;
pageFont.blitString(buffer, pageText, xpos, texture.getHeight() - 4, 200, RGBColor.BLACK);
}
buffer.display();
buffer.removeRenderTarget();
textFont.getTexturePack().setCoordinateModifier(null);
pageFont.getTexturePack().setCoordinateModifier(null);
}

MichaelJPCT

i don't want to copy my code here because my code is scattered in places and there are a lot of dependencies.
but the environment is this: fb size 1920x1080 , tex size 1024x512 , tex has several regions and each has borders to avoid clearing other regions , setvirtualdimensions(1024,512) is called once for the tex before calling setRenderTarget.
i tested removeing rendering of object3d, found that simply resetting the fov (emptyworld.renderscene) can lead to the situation of needing offset but not scaling. which means World.renderScene() changes the situation. test result is consistant.

EgonOlsen

I'm not sure about this. IIRC, changing the fov inbetween is critical when it comes to blitting into a render target, again...that's because blits are actually buffered and this somehow doesn't play well with some other operations when done on a render target. I know that this situation isn't ideal, but it will remain as it is. Mainly for compatiblity reasons but also because if I could have come up with something better back then, I would have done it.

EgonOlsen

Quote from: MichaelJPCT on November 06, 2020, 08:03:32 AM
which means World.renderScene() changes the situation. test result is consistant.
Reading this again, I'm not sure what you mean by this. Even if there are no objects, you have to do a renderScene() call after doing the blits and before doing the next frame, because otherwise, they'll remain buffered and will be executed when the next call to something happens that might execute the buffered blits, which might happen in the next frame sometime inbetween.

MichaelJPCT

i don't mean something need to be fixed/changed.
i'm just saying, i might have found the way to guarantee the blit result is correct.
after setRenderTarget(tex), we either only do blit or do blit after rendering any World.
if we only do blit, we use scaling, if we blit after calling World.renderScene, we use position offset. both lead to correct blit result.
i can miss other conditions, but in the 2 situations i tested, i got correct results.
you can test in your RPG game, if you add emptyWorld.renderScene(fb) just before blitting the quest book, you can see the blit result becomes different. if you add a position offset and remove scaling, you can see the blit result become correct again - if i am right.

MichaelJPCT

Hi Egon,
i found a problem caused by blitting into texture - a following render-to-texture (another texture) operation doesn't work.
tested on powerVR6250 and mali450.
i don't know why blitting would affect rendering into another texture, i tried fb.flush() and sync() before setRenderTarget(the other tex), not helping. any ideas?
if i use object3d/overlay to replace blitting, i expect lots of draw calls or complicated programming.