www.jpct.net

jPCT-AE - a 3d engine for Android => Support => Topic started by: AeroShark333 on December 01, 2016, 04:59:09 am

Title: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 01, 2016, 04:59:09 am
Hello,

Well I guess the title explains all...
I wondered because when textures get uploaded to the GPU (even when pixeldata is kept so it should be safe for any context change) why does it still need the texture data in the VM memory?

Is it possible to not have the textures in VM memory but uploaded to the GPU only?

Cheers,
AeroShark333
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 01, 2016, 09:22:15 am
It needs it for managing re-uploads after a context change. You can change that behaviour with the ...keepPixels...methods in Texture, but you have to reinitialize es everything on your own again in case of a context change then. I don't think it's worth it...
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 01, 2016, 08:38:41 pm
Hmmm, well (re-)uploads seem like the most time-consuming task, especially with bigger textures I suppose...?
I don't know if jPCT still re-uploads Textures that are actually still in the GPU with keepPixels enabled... (seems pretty useless to me? I don't know)
Hmhm, why wouldn't it be worth it? I don't really completely understand it I guess.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 02, 2016, 03:47:51 pm
I'm not sure if I got the question correctly. It uploads textures when it has to. Not more and not less. It has to do it on a context change, which basically means every time you create a new FrameBuffer instance. You can minimize the creations of new FrameBuffers and thus the context changes by adding this to your GL init code:

Code: [Select]
mGLView.setPreserveEGLContextOnPause(true);

and then in onSurfaceChanged() check if the given GL10 instance equals the last one. It it does, you can reuse the FrameBuffer. If it doesn't, you have to create a new one. It doesn't matter if you are actually using that instance (i.e. if you are using GLES 1.x or GLES 2.0), the test is still valid.

That applies to normal apps. For wallpapers (just in case we are talking these here), I don't know if that's applicable.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 02, 2016, 11:36:48 pm
I guess I understood that, but aren't there scenarios when textures don't have to be re-uploaded? (so the textures don't need to stay in VM any more, right?)
So isn't it possible to clear the texture data in VM? Setting the texture data instances to null I suppose, so the GC can pick it up...
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 03, 2016, 10:41:32 am
As mentioned, you can use the keepPixels methods to discard the VM copy. But once the context changes then, you are screwed and your textures will all turn into white (in the best case).
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 03, 2016, 04:44:52 pm
Does jPCT automatically 'discard' these VM copies? Or do I have to do this myself?
If so, how?
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 04, 2016, 03:26:58 pm
No, it keeps them. Unless you tell it not to by using these keepPixels() methods. But honestly... Why do you want to do all this? It's usually asking for more trouble than it's worth.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 06, 2016, 03:53:23 am
Well I'm using high resolution textures and VM memory is pretty limited on Android devices...
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 06, 2016, 07:52:17 am
You could use the Virtualizer class, if you really want to.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 08, 2016, 04:11:31 pm
Hmmm, so I did some testing... And I wondered, why can jPCT not use the uploaded textures in the GPU when the context has changed? After all... the 2D texture images don't change, right?
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 08, 2016, 11:16:51 pm
Because it just doesn't work. Once the context is lost, GPU memory is empty. It's been reset.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 19, 2016, 07:07:12 pm
Using the Virtualizer class would significantly slow down loading time, right?
Especially with big resolution textures...?

Sooo, I tried this with my live wallpaper:
Code: [Select]
gLView.setPreserveEGLContextOnPause(true);And it seems to work fine I guess; even when not keeping textures in VM.

When the context changes, it seems that the GLSurfaceView and Renderer will get disposed and will get recreated.
Textures will be reuploaded so that's fine I guess.
Context changes aren't supposed to happen anyway I think, but it seems to happen in the Live Wallpaper picker for some reason when changing the orientation...
While context changes do not seem to happen, when applied in a certain launcher and then changing the orientation.

So now I basically only load textures when the Live wallpaper is launched (and on context changes).
This loading process is a one time thing only but it does seem to take up some time...
Also I noticed that when I'm adding textures to the texturemanager, the VM copy is still kept until the texture is actually used on a visible Object3D in a World.draw() call.

Is it somehow possible to upload textures to the GPU immediately when the texture is added to the texturemanager? (except the textures that are only being blit since I guess they don't need to be uploaded to the GPU...)
So I thought this would be possible by using a world.draw() call after an Object3D with a texture is added to the world.
But then it also needs to be visible in order to get the texture uploaded to the GPU; So is there some way to make all objects in my world 'visible'?
Sooner or later all my objects are visible anyway...

So how it now works:
[add Texture to texturemanager -> apply Texture to Object3D -> add Object3D to world -> world.draw() -> rendering starts -> after a few seconds there is a hiccup because the added Object3D has become visible -> uploading texture to GPU -> continue rendering]
And what I want:
[add Texture to TextureManager (as VM copy) -> apply texture to Object3D -> add Object3D to world -> upload texture to GPU -> rendering starts]
I think I could possibly achieve this my pointing the camera at the Object3D so it becomes visible:
[add Texture to TextureManager (as VM copy) -> apply texture to Object3D -> add Object3D to world -> make Camera face the Object3D -> upload texture to GPU -> rendering starts]

And since I guess I never actually really need a VM copy of these textures anyway (but only for the initial uploading), would it be possible to upload textures to the GPU immediately from a given InputStream (of a .png file)? (I suppose this would save VM memory...)

So what I originally wanted:
[add Texture to TextureManager (as VM copy) -> apply texture to Object3D -> add Object3D to world -> upload texture to GPU -> rendering starts]
What I would want now:
[apply Texture PNG-InputStream to Object3D (no VM copy of the Texture) -> add Object3D to world -> upload texture to GPU using PNG-InputSteam -> rendering starts] (or perhaps a bitmap byte-inputstream if that works better...)
Basically what I want to achieve here is that I don't want a Texture to take up VM memory if the VM copy of the Texture gets disposed after uploading anyway...
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 20, 2016, 08:36:29 am
You could use this: http://www.jpct.net/jpct-ae/doc/com/threed/jpct/TextureManager.html#preWarm(com.threed.jpct.FrameBuffer) (http://www.jpct.net/jpct-ae/doc/com/threed/jpct/TextureManager.html#preWarm(com.threed.jpct.FrameBuffer))
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 21, 2016, 12:19:00 pm
Euh, so instantly uploading textures to the GPU wouldn't be possible? With a Bytebuffer InputSteam from a Bitmap image then maybe?

I tried TextureManager.preWarm(fB); but it didn't seem to upload all Textures that I needed... Some were uploaded only when the first World.draw(fB); call was made
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 21, 2016, 11:44:25 pm
No, it's not possible to stream them into the GPU directly. preWarm() uploads every texture that the texture manager knows when you call the method. It has to be called in onDraw(), of course because it has to have access to a current, active GL context.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 22, 2016, 04:55:23 am
What will preWarm() do if a Texture has already been uploaded to the GPU? Nothing I suppose?
And what about Textures that will only be blit? Those don't need to be uploaded, do they? :|
Is there some way to not make them get uploaded in case they do?

_________________________

I wondered about something else as well:
Code: [Select]
// Test zone
IntBuffer max = IntBuffer.allocate(1);
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_IMAGE_UNITS, max);
Log.d("e3d-tag","Texture units (shader): " + max.get());

max = IntBuffer.allocate(1);
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, max);
Log.d("e3d-tag","Texture size: " + max.get());

max = IntBuffer.allocate(1);
GLES20.glGetIntegerv(GLES20.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, max);
Log.d("e3d-tag","Texture units (shaders): " + max.get());

Output:
D/e3d-tag(31156): Texture units (shader): 16
D/e3d-tag(31156): Texture size: 16384
D/e3d-tag(31156): Texture units (shaders): 96

So I read somewhere that jPCT-AE supports up to 8192x8192 pixels textures; what happens if I try 16384x16383 since my device seems to support it...?
And I don't understand these texture units values...
The first output line is for the texture units available to the fragment shader I thought...
And the third line for the texture units available for the fragment shader AND vertex shader combined, right?
So does this apply for one Object3D or for all?
And how does it work when a Texture is shared between Object3D's, is there something I need to keep in mind?

_________________________

And another side question: Will there be support for OpenGLES 3.0 someday maybe?
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 23, 2016, 06:50:29 pm
preWarm() uploads anything that hasn't been uploaded yet and that is known to the TextureManager. Textures for blitting have to be uploaded as well but preWarm won't do this unless you've added them to the manager (what you can do, it doesn't hurt).
16384*16384 should work in theory...but honestly...why would you want to do this? Just do the math: A 16384 textures needs 1 GB of memory without mipmaps and without the actual data in the VM's memory. Add those, and you are somewhere around 2.5 GB for ONE texture. That's just insane.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 25, 2016, 04:16:16 am
I see, thanks for answering :)
And eh, nevermind the 16k resolution textures...
I guess I just got curious there

I have a small request however...
May I have the source code of the LensFlare class, learn from it, modify it and use it? (I'll probably end up writing my own class then)
So why?...
Well there's a few things I want to change/add I guess:
-> I want to use 5 textures in total
-> I don't want the burst texture to be repeated in the lens flare (that's where the 5th texture comes in)
-> I want to give the burst it's own scaling which isn't done with the global scaling
-> I don't really know how to get the 2D coordinates for blitting from this 3D world
-> I want to use 1/4th part of a 'complete texture'

My lens flare images are all spherical so...
I basically could just use 1/4th of this texture and blit it 4 times (by flipping the blit). (relying on the assumption that the LensFlare class uses blits and not it's own Object3D's)

And Merry Christmas by the way :D
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on December 26, 2016, 09:23:12 pm
Sure, here it is:

Code: [Select]
package com.threed.jpct.util;

import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Interact2D;
import com.threed.jpct.Object3D;
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;

/**
 * A simple lens flare effect. You need four different textures for this, one burst and three halos. How
 * to create/get these textures is up to you. jPCT doesn't come with any.
 * @author EgonOlsen
 */
public class LensFlare implements java.io.Serializable {

private static final long serialVersionUID = 1L;

private Texture burst=null;
private Texture halo1=null;
private Texture halo2=null;
private Texture halo3=null;
private SimpleVector sunPos=null;

private Texture[] types=new Texture[7];
private float[][] scales=new float[7][2];
private float globalScale=1;
private int trans=1;
private boolean cover=true;
private float maxDistance=-1;
private boolean revertDirection=false;

private boolean visible=false;
private SimpleVector light2D=null;

private SimpleVector tmp1=new SimpleVector();
private SimpleVector tmp2=new SimpleVector();
private SimpleVector tmp3=new SimpleVector();

/**
* Create a new lens flare for a light source.
* @param lightPos the position of the light source
* @param burst the name of the burst texture as added to the TextureManager
* @param halo1 the name of the first halo texture as added to the TextureManager
* @param halo2 the name of the second halo as added to the TextureManager
* @param halo3 the name of the third halo texture added to the TextureManager
*/
public LensFlare(SimpleVector lightPos, String burst, String halo1, String halo2, String halo3) {
TextureManager tm=TextureManager.getInstance();
this.burst=tm.getTexture(burst);
this.halo1=tm.getTexture(halo1);
this.halo2=tm.getTexture(halo2);
this.halo3=tm.getTexture(halo3);
this.sunPos=new SimpleVector(lightPos);

types[0]=this.burst;
types[1]=this.halo1;
types[2]=this.burst;
types[3]=this.halo2;
types[4]=this.burst;
types[5]=this.halo3;
types[6]=this.burst;

scales[0][0]=1;
scales[0][1]=1;
scales[1][0]=2;
scales[1][1]=0.5f;
scales[2][0]=3;
scales[2][1]=0.25f;
scales[3][0]=8;
scales[3][1]=1;
scales[4][0]=-2;
scales[4][1]=0.5f;
scales[5][0]=-4;
scales[5][1]=0.25f;
scales[6][0]=-5.5f;
scales[6][1]=0.25f;
}

/**
* Sets the transparency of the effect.
* @param trans the transparency. 0 is lowest,
*/
public void setTransparency(int trans) {
this.trans=trans;
}

/**
* Sets a new light position.
* @param lightPos the new position
*/
public void setLightPosition(SimpleVector lightPos) {
sunPos.set(lightPos);
}

/**
* Sets the global scale of the effect.
* @param scale the scale
*/
public void setGlobalScale(float scale) {
globalScale=scale;
}

/**
* If true (default), all geometry that is a potential collider hides the effect if it's located in
* a direct line between the camera and the light source.
* @param hides should geometry hide it or not?
*/
public void setHiding(boolean hides) {
cover=hides;
}

/**
* If hiding is enabled, this value specifies how far away from the camera a polygon can maximally be
* to be considered as a blocker. Anything farer away can't hide the effect. Lowering this value can improve
* performance but may lead to flares where non should be. -1 is default, which means no limits.
* @param distance the distance
*/
public void setMaximumDistance(float distance) {
this.maxDistance=distance;
}

/**
* If hiding is enabled, the visibility calculations can be done camera->light (default) or light->camera. Depending
* on the scene, one or the other will be faster.
* @param lightToCam do it light->camera or vice versa
*/
public void setDirection(boolean lightToCam) {
revertDirection=lightToCam;
}

/**
* Updates the lens flare. Skipping this method and calling render only will cause the lens flare to remain static.
* This method should be called if either the camera or, if hiding is enabled, the hiding objects are moving.
* @param buffer the frame buffer
* @param world the world
*/
public void update(FrameBuffer buffer, World world) {
Camera cam=world.getCamera();
light2D=Interact2D.project3D2D(cam, buffer, sunPos, tmp3);
visible=true;
if (cover) {
SimpleVector camPos=cam.getPosition(tmp1);
if (!revertDirection) {
// From camera to light
SimpleVector delta=camPos;
tmp2.set(camPos);
delta.scalarMul(-1);
delta.add(sunPos);
float dlen=delta.length();
float dist=world.calcMinDistance(tmp2, delta.normalize(delta), maxDistance!=-1?Math.min(maxDistance, dlen*1.05f):dlen*1.05f);
//System.out.println("1: "+ dist+"/"+(dlen-5));
visible=(dist==Object3D.COLLISION_NONE || dist>dlen-5);
} else {
// From light to camera
tmp2.set(sunPos);
tmp2.scalarMul(-1);
SimpleVector delta=camPos;
delta.add(tmp2);
float dlen=delta.length();
float dist=world.calcMinDistance(sunPos, delta.normalize(delta), maxDistance!=-1?Math.min(maxDistance, dlen*1.05f):dlen*1.05f);
visible=(dist==Object3D.COLLISION_NONE || dist>dlen-5);
//System.out.println("2: "+ dist+"/"+(dlen-5));
}
}
}

/**
* Renders the effect.
* @param buffer the frame buffer
*/
public void render(FrameBuffer buffer) {

if (light2D!=null && visible) {
SimpleVector lp=tmp1;
lp.set(light2D);
float mx=buffer.getCenterX();
float my=buffer.getCenterY();
lp.z=0;
SimpleVector cp=tmp2;
cp.set(mx,my,0);
cp.scalarMul(-1);
lp.add(cp);
SimpleVector dir=lp;
float len=dir.length();
dir=dir.normalize(dir);
SimpleVector d=tmp2;
d.set(0, 0, 0);

for (int i=0; i<types.length; i++) {
d.set(dir);
Texture t=types[i];
float l=scales[i][0];
float scale=scales[i][1]*globalScale;
d.scalarMul((1f/l)*len);
int tw=t.getWidth();
int th=t.getHeight();
int x=(int)(d.x-((tw>>1)*scale));
int y=(int)(d.y-((th>>1)*scale));
buffer.blit(t, 0, 0, x+(int)mx, y+(int)my, tw, th, (int)((float)tw*scale), (int)((float)th*scale), trans, true, RGBColor.WHITE);
}
}
}
}

Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on December 27, 2016, 10:36:08 pm
My version:
Code: [Select]
import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Interact2D;
import com.threed.jpct.Object3D;
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;

/**
 * A simple lens flare effect. You need five different textures for this, one burst and four halos. How
 * to create/get these textures is up to you. jPCT doesn't come with any.
 * @author EgonOlsen & AeroShark333
 */
public class CustomLensFlare implements java.io.Serializable {
private static final long serialVersionUID = 1L;

private final SimpleVector sunPos;

private final Texture[] types;
private final float[][] scales;

private float globalScale=1;
private float burstScale=1;
private int trans=1;
private int burstTrans = 1;

private boolean cover=true;
private float maxDistance=-1;
private boolean revertDirection=false;

private boolean visible=false;
private SimpleVector light2D=null;

private final SimpleVector tmp1;
private final SimpleVector tmp2;
private final SimpleVector tmp3;

/**
* Create a new lens flare for a light source.
* Note: call initializeLensFlare(String texturenames...) before using this LensFlare
* @param lightPos the position of the light source
*/
public CustomLensFlare(final SimpleVector lightPos) {
this.sunPos=new SimpleVector(lightPos);
this.types=new Texture[7];

scales = new float[7][2];
scales[0][0]=1;
scales[0][1]=1;
scales[1][0]=2;
scales[1][1]=0.5f;
scales[2][0]=3;
scales[2][1]=0.25f;
scales[3][0]=8;
scales[3][1]=1;
scales[4][0]=-2;
scales[4][1]=0.5f;
scales[5][0]=-4;
scales[5][1]=0.25f;
scales[6][0]=-5.5f;
scales[6][1]=0.25f;

tmp1=new SimpleVector();
tmp2=new SimpleVector();
tmp3=new SimpleVector();
}
/**
* Create a new lens flare for a light source.
* @param lightPos the position of the light source
* @param burst the name of the burst texture as added to the TextureManager
* @param halo1 the name of the first halo texture as added to the TextureManager
* @param halo2 the name of the second halo as added to the TextureManager
* @param halo3 the name of the third halo texture added to the TextureManager
* @param halo4 the name of the fourth (repeating) halo texture added to the TextureManager
*/
public CustomLensFlare(final SimpleVector lightPos, final String burst, final String halo1, final String halo2, final String halo3, final String halo4) {
this(lightPos);
this.initializeLensFlare(burst, halo1, halo2, halo3, halo4);
}

/**
* Call this when you are sure the textures needed for this lensflare have been set
* @param burst the name of the burst texture as added to the TextureManager
* @param halo1 the name of the first halo texture as added to the TextureManager
* @param halo2 the name of the second halo as added to the TextureManager
* @param halo3 the name of the third halo texture added to the TextureManager
* @param halo4 the name of the fourth (repeating) halo texture added to the TextureManager
*/
public void initializeLensFlare(final String burst, final String halo1, final String halo2, final String halo3, final String halo4){
final TextureManager tm=TextureManager.getInstance();
final Texture repeatedHalo=tm.getTexture(halo4);

types[0]=tm.getTexture(burst);
types[1]=tm.getTexture(halo1);
types[2]=repeatedHalo;
types[3]=tm.getTexture(halo2);
types[4]=repeatedHalo;
types[5]=tm.getTexture(halo3);
types[6]=repeatedHalo;
}

/**
* Sets the transparency of the effect.
* @param trans the transparency. 0 is lowest,
*/
public void setGlobalTransparency(int trans) {
this.trans=trans;
}

/**
* Sets the transparency of the burst effect.
* @param trans the transparency. 0 is lowest,
*/
public void setBurstTransparency(int trans) {
this.burstTrans=trans;
}


/**
* Sets a new light position.
* @param lightPos the new position
*/
public void setLightPosition(SimpleVector lightPos) {
sunPos.set(lightPos);
}

/**
* Sets the burst scale of the effect.
* @param scale the scale
*/
public void setBurstScale(float scale) {
burstScale=scale;
}

/**
* Sets the global scale of the effect.
* @param scale the scale
*/
public void setGlobalScale(float scale) {
globalScale=scale;
}

/**
* If true (default), all geometry that is a potential collider hides the effect if it's located in
* a direct line between the camera and the light source.
* @param hides should geometry hide it or not?
*/
public void setHiding(boolean hides) {
cover=hides;
}

/**
* If hiding is enabled, this value specifies how far away from the camera a polygon can maximally be
* to be considered as a blocker. Anything farer away can't hide the effect. Lowering this value can improve
* performance but may lead to flares where non should be. -1 is default, which means no limits.
* @param distance the distance
*/
public void setMaximumDistance(float distance) {
this.maxDistance=distance;
}

/**
* If hiding is enabled, the visibility calculations can be done camera->light (default) or light->camera. Depending
* on the scene, one or the other will be faster.
* @param lightToCam do it light->camera or vice versa
*/
public void setDirection(boolean lightToCam) {
revertDirection=lightToCam;
}

/**
* Updates the lens flare. Skipping this method and calling render only will cause the lens flare to remain static.
* This method should be called if either the camera or, if hiding is enabled, the hiding objects are moving.
* @param buffer the frame buffer
* @param world the world
*/
public void update(FrameBuffer buffer, World world) {
Camera cam=world.getCamera();
light2D=Interact2D.project3D2D(cam, buffer, sunPos, tmp3);
visible=true;
if (cover) {
SimpleVector camPos=cam.getPosition(tmp1);
if (!revertDirection) {
// From camera to light
SimpleVector delta=camPos;
tmp2.set(camPos);
delta.scalarMul(-1);
delta.add(sunPos);
float dlen=delta.length();
float dist=world.calcMinDistance(tmp2, delta.normalize(delta), maxDistance!=-1?Math.min(maxDistance, dlen*1.05f):dlen*1.05f);
//System.out.println("1: "+ dist+"/"+(dlen-5));
visible=(dist==Object3D.COLLISION_NONE || dist>dlen-5);
} else {
// From light to camera
tmp2.set(sunPos);
tmp2.scalarMul(-1);
SimpleVector delta=camPos;
delta.add(tmp2);
float dlen=delta.length();
float dist=world.calcMinDistance(sunPos, delta.normalize(delta), maxDistance!=-1?Math.min(maxDistance, dlen*1.05f):dlen*1.05f);
visible=(dist==Object3D.COLLISION_NONE || dist>dlen-5);
//System.out.println("2: "+ dist+"/"+(dlen-5));
}
}
}

/**
* Renders the effect.
* @param buffer the frame buffer
*/
public void render(FrameBuffer buffer) {

if (light2D!=null && visible) {
SimpleVector lp=tmp1;
lp.set(light2D);
float mx=buffer.getCenterX();
float my=buffer.getCenterY();
lp.z=0;
SimpleVector cp=tmp2;
cp.set(mx,my,0);
cp.scalarMul(-1);
lp.add(cp);
SimpleVector dir=lp;
float len=dir.length();
dir=dir.normalize(dir);
SimpleVector d=tmp2;
d.set(0, 0, 0);

for (int i=0; i<types.length; i++) {
d.set(dir);
Texture t=types[i];
float l=scales[i][0];
float scale=scales[i][1]*(i==0? burstScale:globalScale);
int trans2 = (i==0? this.burstTrans:this.trans);
d.scalarMul((1f/l)*len);
int tw=t.getWidth();
int th=t.getHeight();
int x=(int)(d.x-((tw>>1)*scale))+(int)mx;
int y=(int)(d.y-((th>>1)*scale))+(int)my;
int dw = (int)((float)tw*scale*0.5f);
int dh = (int)((float)th*scale*0.5f);
// upper-left
buffer.blit(t, 0, 0, x, y, tw, th, dw, dh, trans2, true, RGBColor.WHITE);
// upper-right
buffer.blit(t, 0, 0, x+2*dw, y, tw, th, -dw, dh, trans2, true, RGBColor.WHITE);
// bottom-left
buffer.blit(t, 0, 0, x, y+2*dh, tw, th, dw, -dh, trans2, true, RGBColor.WHITE);
// bottom-right
buffer.blit(t, 0, 0, x+2*dw, y+2*dh, tw, th, -dw, -dh, trans2, true, RGBColor.WHITE);
}
}
}
}

I hope it's okay to share this; if not then I guess you can delete my post :P
This modified class should be suitable for circular shaped lensflare textures.
So your texture images can be reduced to this part of the circular texture image: http://etc.usf.edu/clipart/40500/40550/pie_01-04n_40550_lg.gif :)
I guess the original lens flare textures don't take up that much memory anyway but oh well...
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on January 05, 2017, 11:11:30 pm
I wanted to optimize texture loading so I tried splitting the texture into 4 parts.
So a 8192x4096 texture now is 4 * 4096x2048 textures.

So why split?: Because I'll be uploading the texture after it has loaded and textures use a lot in VM memory and I thought this would be a nice solution to split the textures, so the VM memory doesn't go up as much as with a complete texture...

I added these 4 textures to the Object3D and in the shader I'd use the texcoords to select which texture to use (and change the texcoords so it draws the texture properly on the Object3D's vertices)...
However, the results seem kind of ugly and it's not as I hoped it would be... Using a complete texture in the shader looked better than 4 split textures. texture.setClamping(false) helped but it's still kind of visible on the Object3D that the textures are split...

Is there some way to merge these 4 textures into 1 texture without the Bitmap stuff in Android since that obviously just uses memory? The textures are immediately uploaded after loading so the VM memory only 'spikes' up when the Bitmap instance is still used for uploading...
I suppose jPCT and OpenGL see these textures as texture layers but actually they're just next to each other.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on January 06, 2017, 09:47:24 am
I'm not sure if I understand you your "merge" them in the shader!?
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on January 06, 2017, 02:13:51 pm
Basically like in this fragment shader:
Code: [Select]
precision highp float;
precision highp int;

uniform sampler2D textureUnit0;
uniform sampler2D textureUnit1;
uniform sampler2D textureUnit2;
uniform sampler2D textureUnit3;
varying vec2 texCoord0;

void main() {
float xVal = texCoord0.x;
float yVal = texCoord0.y;

vec4 base;

if(xVal < 0.5){
// tex0 or tex2
if(yVal < 0.5){
// tex0
base = texture2D(textureUnit0, vec2(xVal*2.0,yVal*2.0));
}else{
base = texture2D(textureUnit2, vec2(xVal*2.0, yVal*2.0 - 1.0));
}
}else{
// tex1 or tex3
if(yVal < 0.5){
// tex1
base = texture2D(textureUnit1, vec2(xVal*2.0 - 1.0,yVal*2.0));
}else{
// tex3
base = texture2D(textureUnit3, vec2(xVal*2.0 - 1.0,yVal*2.0 - 1.0));
}
}

gl_FragColor = base;
}
It works but it kind of looks ugly around the borders of the textures...
I actually used texture.setClamping(true) so not 'false' to make it look better around the borders which kind of worked.
But it only looks better for higher resolution textures.
Let's say I have 4 lower resolution textures, then these borders become visible again which I don't really want. (it should just work like a single texture)

See attachment for clarification :)
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on January 06, 2017, 02:42:43 pm
Yes, that will look ugly, because the texture filtering will be wrong at the borders. I guess you would have to reimplement bilinear filtering (at least) in your shader between different texture stages to fix this...which would be just insane.
Short: I wouldn't do it that way in the first place.
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on January 06, 2017, 04:08:39 pm
Is there another solution? To load textures this way to not hit high VM memory usage and still get the textures to work properly on the Object3D's vertices?
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: EgonOlsen on January 06, 2017, 06:58:46 pm
Yes...just don't use such huge textures. 8192*4096 means 128 MB of texture data on the GPU alone (plus mipmaps). This won't work on older Android versions anyway, so why bother with it? What do you need sich huge texture for?
Title: Re: Why does jPCT-AE need to keep the texture in the VM memory?
Post by: AeroShark333 on January 06, 2017, 11:37:08 pm
Well for example this texture: https://commons.wikimedia.org/wiki/File:ESO_-_Milky_Way.jpg
On lower resolution it looks uglier than with 8192x4096...
So I suppose that's why I thought splitting it into 4 parts would reduce the maximum VM memory usage at a point. (which does happen; but the result is not satisfactory...)