This post is an update or an extension to the post 2012/07/10 - [OpenGL] When textures do not show properly without any glerror in Android posted yesterday.


Previously, I found out that for some cases if the image resource is packaged in res/drawable it will cause some problems to create textures. In spite of this discovery, for some images the texture still did not render at all on some devices(namely the Galaxy Player). The research went on.


The research continued on the simple example I have created which I have mentioned in my previous note. The image that wasn't working as a texture was a 1024x512 size image of the earth's surface. Once again, I checked the bitmap's internal format, type, and config. However, I could not see any difference from the case where I was using a different image that works.


The blame now went to the dimension of the image. The image that worked as a texture on the Galaxy Player had a size of 512x512. Could it be possible that it works because it has a dimension of a square? So I scaled the image that isn't working as a texture down to 512x512 and it worked(I was wrong. It still didn't work. I got my situation messed up. updated 2012/7/16). But that didn't make much sense since I wasn't able to find any requirements about textures to have a square dimension. Moreover, OpenGL ES 2.0 specifies that the dimensions of the image does not have to be in the power of two.


Stripping out the power of two requirement and putting in a requirement that a image used for a texture must be a square sounds ridiculous. Also, then why is it working on other devices?


More research went on and I finally found out that the malfunctioning has something to do with setting the GL_TEXTURE_MIN_FILTER. It turns out that on Galaxy Player, the texture does not properly render if the GL_TEXTURE_MIN_FILTER is set to a mipmap filter(either linear or nearest) when the dimension of the image is not a square.


I'm pretty obvious that this is an OpenGL implementation bug on the device, but I had to check. So, I posted a question about this on stackoverflow. If you have any useful information to tell me, please leave a comment here or on stackoverflow. 


Thanks.


Posted by Dansoonie

While I was exploring the features of Rajawali creating some sample code, I have encountered into a strange situation where textures show up on one device and another didn't. Nothing complicated in the sample code going on. Just rendering a sphere object with a texture of the earth's surface. The image used for the texture was saved in res/drawable and the bitmap was created at runtime using BitmapFactory.decodeResource(). Now the most strange thing was that glError was not flagged at any point(at least I think I checked thoroughly).


FYI, the working devices was Galaxy Nexus, and the non-working device was Galaxy Player GB70


To attack this issue, I've created a simple project which renders a flat square with the image that I'm having trouble to use it as the sphere's texture in Rajawali.


The first thing I noticed was that the only difference between the working device and the non-working device was that the image was decoded into a ARGB8888 bitmap config on the working device and RGB565 bitmap config on the non working device. However, if I force the image to be decoded into RGB565 bitmap config on the working device, it still worked.


I've tried changing parameters for glTexImage2D and converting the image file to use another bitmap config(via Bitmap.copy()) and all sorts of things without much luck. So I did more Googling to do more research.


There is probably almost any information you want on the Internet. And I have found the reason why the texture was not showing properly. A piece of meaningful information here. The person who was having a similar problem that I was having posted a question on stackoverflow. Luckily he found the solution on his own and was nice enough to share the information he learned. Special thanks to him/her.



In Android, image resources could be packaged in path res/drawable. Since there exists many Android devices with different screen resolution the image resources are designed to be packaged in various size in drawable-ldpi, drawable-mdpi, drawable-hdpi under res/. And for the sake of convenience you can package resources under simply res/drawable and then the system would automatically handle the resizing. Here's a quote from the Android developer's page regarding supporting multiple screen resolutions.


The "default" resources are those that are not tagged with a configuration qualifier. For example, the resources in drawable/ are the default drawable resources. The system assumes that default resources are designed for the baseline screen size and density, which is a normal screen size and a medium density. As such, the system scales default density resources up for high-density screens and down for low-density screens, as appropriate.


http://developer.android.com/guide/practices/screens_support.html


This is something that I wasn't completely unaware of, but it bit me. The problem might have been when the resource was decoded into a bitmap using the BitmapFactory, the size of the image changes into probably something not in the dimensions of power of two. The OpenGL ES 2.0 specification indicates that it supports non-power of two textures. See the OpenGL ES 2.0 common profile specification  p. 17 on section 3.8 Texturing. However, for some reason I'm suspicious about every OpenGL ES 2.0 implementation strictly following this specification. 


What I didn't really know was that drawable resources under res/drawable-nodpi is dpi independent resource which the system does not perform any resizing when decoded into bitmap. Honestly, I thought drawable resources under res/drawable would be decoded in a dpi independent manner too.

 

I'll have to see if the problem was caused by resizing the resource into a non-power of two dimension. If this were true I'm also surprised that glError was not flagged at all. Anyway, but for now, if you are having trouble loading textures in Android check if your drawable resource that you are using as your texture is packaged under res/drawable.


Problem partly solved, but still the texture is not showing up for some cases on the sphere when using Rajawali. so the research goes on...

If you have any knowledge about this problem or if I have written something incorrect here please leave a comment and let me know.


Posted by Dansoonie