www.jpct.net

jPCT-AE - a 3d engine for Android => Support => Topic started by: hisong on September 21, 2011, 08:50:28 am

Title: How to use 2048 * 1024 texture on a sphere?
Post by: hisong on September 21, 2011, 08:50:28 am
I was trying to use larger than 1024x1024 textures on a sphere I get from a 3ds file.

But an error of "Out of Memory" occurs during the the program is beginning to run.

And if I use the BitmapHelper to rescale the image to 1024*1024,  It works well.


Code: [Select]
Bitmap bitmap = BitmapHelper.rescale(BitmapFactory
.decodeFile("/sdcard/jpct/hd.jpg"), 1024, 1024);
// Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/jpct/hd.jpg");
Texture texture = new Texture(bitmap);
bitmap.recycle();

TextureManager.getInstance().addTexture("texture", texture);

Dose JPCT-AE not support the 2048*1024 or higher??

ps:I can use Opengl ES to load an image of 2048 * 1024 resolution. and of cause it work well and smoothly.

Thanks for help~~
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: EgonOlsen on September 21, 2011, 09:00:52 am
Well...just do the math. 2048*1024 requires 8mb of memory for it's pixel data. Plus maybe ~4mb for the mipmaps. Plus you have to upload it to the gpu, which doubles memory usage. Combine that with a VM that has around 16-20mb available for all the data and you end up in an out of memory-situation. 2048*1024 is ridicilously high for a mobile device anyway IMHO. Why do you want to use such a large texture? Apart from all that, try to use square textures, because ES2.0 has problems with non-square textures on some devices.

The engine itself supports up to 8192*8192. There's just no hardware that could handle that ATM.

Edit: More info: http://www.jpct.net/wiki/index.php/Reducing_memory_usage (http://www.jpct.net/wiki/index.php/Reducing_memory_usage)
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 21, 2011, 09:53:30 am
Try to keep the textures at 512x512 to increase compatibility. If you set to minimum SDK to Android 2.2 then you can generally be safe using 1024x1024 textures. I wouldn't go higher than that unless you are specifically targeting Honeycomb tablets.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: hisong on September 21, 2011, 10:05:22 am
Thanks for replying so quickly. :)

I use such a large image so I can view  in a  360 degree panoramic scene more  clearly. 

And the image has a size of 200KB, I am confused that why it costs  8MB of memory? 

what I can do if I want to use such a big file with JPCT-AE instead of compressing the resolution?
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: hisong on September 21, 2011, 10:20:16 am
and what does the JPCT-AE base on ? 

If it is base on Opengl ES 1.0 or 1.1, I think it would  support  2048*1024 resolution file for I doing a test with Opengl ES1.0.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: EgonOlsen on September 21, 2011, 11:11:58 am
1.23 is based on 1.0/1.1. 1.24 (alpha) has additional support for 2.0. If you don't want to switch to 2.0 sometimes with this app, you won't run into problems.
   
8mb=2048*1024*4 (as written in the wiki: File size doesn't matter). You can try to save some memory by using the tips that i wrote in the wiki (link in the post above). If that doesn't help, it just won't work.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 21, 2011, 11:22:05 am
Each type/model of Graphics Chip (GPU) has it's own maximum texture size, so you should check the size before creating large textures.

To query the texture size, call glGetIntegerv() in your main Activity's GLSurfaceView.Renderer class. You need a pointer to GL10 so you could place it in onSurfaceCreated().

Code: [Select]
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Do nothing special.
int[] maxTextureSize = new int[1];
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);
Log.v("Log", "Max texture size = " + maxTextureSize[0]);

}

Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: hisong on September 21, 2011, 02:02:24 pm
Each type/model of Graphics Chip (GPU) has it's own maximum texture size, so you should check the size before creating large textures.

To query the texture size, call glGetIntegerv() in your main Activity's GLSurfaceView.Renderer class. You need a pointer to GL10 so you could place it in onSurfaceCreated().

Code: [Select]
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Do nothing special.
int[] maxTextureSize = new int[1];
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);
Log.v("Log", "Max texture size = " + maxTextureSize[0]);

}



I got a value 4096 from the maxTextureSize.  Dose it mean I can handle the texture with as larger as 4096*4096?
But now I can't load a texture with 2048*1024....
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: EgonOlsen on September 21, 2011, 02:26:47 pm
Because a 2048*4096 texture has 32mb without any mip maps...heeeeelllooo...we are on a limited, mobile device here. Please keep that in mind before going crazy on texture size.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: hisong on September 21, 2011, 02:51:47 pm
Hehe,   I haven't gotten  crazy yet.  Thanks for your suggestions.

I was just confused why I could load the image with opengl es, but not with jpct-ae.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: EgonOlsen on September 21, 2011, 02:56:04 pm
I was just confused why I could load the image with opengl es...
You can't. The hardware says, that it can handle it...but that doesn't mean that the device provides enough resources to do it.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 21, 2011, 02:58:24 pm
What android device/phone are you using? (please don't say the Android Emulator :p)

Have a read of this article: http://blog.javia.org/how-to-work-around-androids-24-mb-memory-limit/

I don't know how accurate that article is, but it mentions that you can get around the 24MB memory limit by using OpenGL textures, apparently textures are not limited to 24MB.

Also, what is your android:minSdkVersion value in the AndroidManifest.xml file? Increasing it to say "9" (gingerbread) may help relieve limitations.

Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: hisong on September 21, 2011, 03:26:07 pm
What android device/phone are you using? (please don't say the Android Emulator :p)

Have a read of this article: http://blog.javia.org/how-to-work-around-androids-24-mb-memory-limit/

I don't know how accurate that article is, but it mentions that you can get around the 24MB memory limit by using OpenGL textures, apparently textures are not limited to 24MB.

Also, what is your android:minSdkVersion value in the AndroidManifest.xml file? Increasing it to say "9" (gingerbread) may help relieve limitations.

Oh, My device is the Defy of Motorala.  Dose it not support the 24MB Memory limitation?

I got the value of 3502168 from the android.os.Debug.getNativeHeapAllocatedSize().

And I work with the eighth minSDKVersion.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 21, 2011, 03:53:14 pm
you can check how much memory is being used by using the code from here:
http://www.jpct.net/forum2/index.php/topic,2287.msg16929.html#msg16929

Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: hisong on September 21, 2011, 04:12:38 pm
I think that the problem  may be caused by the 3ds file(the segment or the radius are too large for I had set the segment of 32 and the radius of 20).

 I will test it tomorrow.

Good night.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 21, 2011, 04:31:10 pm
I was thinking it may be a 3DS issue, perhaps try texturing a bare sphere using primitives.getSphere.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: EgonOlsen on September 21, 2011, 05:00:10 pm
To upload a texture, a copy into the VM's memory has to exists. Or otherwise, there's nothing to upload. By default, jPCT-AE keeps this copy for handling context changes. You can disable this behaviour, but you still need the memory before it will be uploaded. 2048*2048*4=16mb => crash. I don't really get how one can think that this should actually work on a VM with 16-24mb. And i don't the reason why it should. No game on the desktop is using this crazy resolution maybe except for shadow maps. So why on earth does anybody even think about using it on a mobile device...  ???
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 22, 2011, 08:42:59 am
Is there a way to stream the texture into the GPU or perhaps use Texture compression?
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 22, 2011, 10:37:46 am
I found a way to load huge textures, but only honeycomb (Android 3.x) is supported.

Honeycomb increases the memory size per application to 48MB using the standard heap (as opposed to 24MB and 32MB in previous Androids). But loading a 2048x2048 texture still crashed my app.

Here is the memory allocation (crashes when loading the large texture):
09-22 18:21:08.190: VERBOSE/Tosh(25398): debug.heap native: allocated 3.02MB of 3.04MB (0.01MB free)
09-22 18:21:08.190: VERBOSE/Tosh(25398): debug.memory: allocated: 22.00MB of 48.00MB (6.00MB free)

Then I made the following changes to increase the heap to Large:
In default.properties file, I changed the target to 'target=android-11'
In AndroidManifest.xml file, I added 'android:largeHeap="true"' to the Application tag.

Now that large 2048 texture loads with no problem.
09-22 18:23:14.980: VERBOSE/Tosh(25572): debug.heap native: allocated 3.02MB of 3.02MB (0.00MB free)
09-22 18:23:14.980: VERBOSE/Tosh(25572): debug.memory: allocated: 55.00MB of 256.00MB (22.00MB free)

256MB to play with! But your app won't be able to run on any phone, or at least until Icecream Sandwich phones come out (2012).

Here's the code to log the memory stats
Code: [Select]
public static void logHeap() {
        Double allocated = new Double(Debug.getNativeHeapAllocatedSize())/new Double((1048576));
        Double available = new Double(Debug.getNativeHeapSize())/1048576.0;
        Double free = new Double(Debug.getNativeHeapFreeSize())/1048576.0;
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(2);
        df.setMinimumFractionDigits(2);

        Log.d("Log", "debug. =================================");
        Log.d("Log", "debug.heap native: allocated " + df.format(allocated) + "MB of " + df.format(available) + "MB (" + df.format(free) + "MB free)");
        Log.d("Log", "debug.memory: allocated: " + df.format(new Double(Runtime.getRuntime().totalMemory()/1048576)) + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576)) +"MB free)");
    }


Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: EgonOlsen on September 23, 2011, 05:59:34 pm
...So they finally realized that people might need some more memory...good to know.
Title: Re: How to use 2048 * 1024 texture on a sphere?
Post by: K24A3 on September 23, 2011, 06:48:12 pm
hehe yeah I think we will see a big jump in memory capacity and performance soon.

The Tegra Wiki suggests that performance will be 10x faster with the Tegra 4 chip next year (compared to Tegra2), then 50x faster the following year, including support for OpenGL 4.0
http://en.wikipedia.org/wiki/Nvidia_Tegra#Tegra_3_.28Kal-El.29_series