OpenGL textures - Motorola Droid

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

OpenGL textures - Motorola Droid

Postby rHalf » Sat Feb 06, 2010 6:04 am

I'm having problems with texturing on my motorola droid.

I've read a few things about EGL configurations. I'm not sure what that is, it may be my problem.

Pretty much I designed a basic openGL project. Then I try to port it to my physical Moto Droid. It works just fine on the emulator, but on the droid there are no textures.

I'm trying to make a HUD for a game. I create a rectangle with w = screenW and h = screenH.

Here's pseudo what I'm doing:

//Create dynamic Bitmap
Bitmap bmp = Bitmap.createBitmap((int)screenW, (int)screenH, Bitmap.Config.ARGB_8888);

//Create a canvas from bitmap
//Draw words and shapes to the Canvas

//Prepare bitmap for next surface
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
bmp.recycle();

gl.glColor4f(1f, 1f, 1f, 1f);

//Step through texture buffer and vertexBuffer to cover surface(size of screen) with this bitmap
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, textureBuffer);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

Pretty much all i get is a screen filled with the glColor4f command whether that's placed before or after the texture loading code.

Please any suggestions would help. Why this works fine in te emulator and not on the droid.
rHalf
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sun Dec 20, 2009 1:54 am

Top

Postby MichaelEGR » Sat Feb 06, 2010 9:06 am

A quick head check before continuing and without looking at any of your code.

Are your textures power of 2 (width/height)? IE 128x128, 256x256, 512x64, etc.

OpenGL requires this unless you are using a NPOT extension.

I understand the emulator will load non power of two textures just fine and not complain, but once you try on device things will fail.

It is good to ditch the emulator as soon as possible when it comes to doing OpenGL development with Android. The emulator is great for stock Android GUI layout/dev with stock GUI components, but OpenGL dev is another beast all to itself and the emulator does not cut it.

Also you'll be surprised how many differences there are between OS builds and devices when it comes to OpenGL bugs and implementation. Though things seem to be stabilizing nicely after 2.0.1
Founder & Principal Architect; EGR Software LLC
http://www.typhonrt.org
http://www.egrsoftware.com
User avatar
MichaelEGR
Senior Developer
Senior Developer
 
Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

Postby rHalf » Sat Feb 06, 2010 12:48 pm

I've read about that in different places too. Except I thought that doesn't apply in my case:

"This does not apply for the case that an application creates an in-memory bitmap internally and draws something on it, for later display on the screen. The platform auto-scales such bitmaps on the fly, at draw time. Other side effects of such a case might be that fonts drawn in such a bitmap will be scaled at the bitmap level, when the off-screen bitmap is finally rendered to the display, resulting in scaling artifacts."
http://developer.android.com/guide/prac ... dependence


In my case you can see I'm creating a dynamic Bitmap based on the height and the width. Am I understanding wrong?
rHalf
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sun Dec 20, 2009 1:54 am

Postby MichaelEGR » Sat Feb 06, 2010 1:37 pm

Actually the screen density auto scaling feature of Android plays havoc on OpenGL compatibility.

We got to back things up a little further actually...

1st if the images are not power of two that is a problem of course and you'll have to remedy it.

2nd if you are working with power of two images and are not using the drawable-nodpi resource directory then your images are likely being scaled by a factor of 1.5 (hdpi density scale factor). When you try and load the images 128x128 becomes 192x192 which is not a power of two thus failure with OpenGL.

Now to complicate things and here is the OS / build fragmentation aspect. drawable-nodpi doesn't work on Android 1.5 OS. For unscaled resources on 1.5 one just needs to put resources in the drawable directory. Unfortunately images in the drawable directory in 1.6+ are auto-scaled. On 1.6+ to remain compatible with 1.5 it's necessary to set a boolean in BitmapFactory.Options or call the setDensity method on bitmaps created neither of which are 1.5 API level 3. This requires reflection to handle properly.

Anyway.. I'm getting ahead of the current situation as you are interested in getting things running on the Droid first let alone the rest of Android devices! :) You need power of two images stored in the drawable-nodpi directory.

---

"In my case you can see I'm creating a dynamic Bitmap based on the height and the width. Am I understanding wrong?"

It's fine to create a dynamic bitmap with the 2D API in fact that is an encouraged way to create/composite images of the right size for the given device. When it comes to loading that image into OpenGL ES though you'll have to make a power of 2 image. So with the Droid an 854x480 image can be stored in the next biggest POT slot 1024x512. If you draw the 854x480 image from the top left of the 1024x512 image you use texture coordinates in OpenGL to display a sub portion of the larger image in this case (0,0) -> (0.833984375, 0.9375).

Depending on the situation you can also cram an image into a smaller texture, but you'll loose data/resolution by doing so. Say for example cramming 854x480 into 512x256 texture. You can scale the bitmap with the 2D API to do this and when you load into OpenGL you can for instance draw in ortho mode the image from (0, 0) -> (854, 480) with texture coordinates (0, 0) -> (1, 1). It will display, but may have some artifacts/stretching depending on how bad the down scaling is; sometimes this works for the given purpose and saves space / memory... In this case unfortunately 854 falls just over the middle point in between 512 and 1024. In this case cramming the image into a smaller texture is probably not a good idea so a 1024x512 image with the given texture coordinates as mentioned above is probably the best way to go especially if it is a detailed HUD.

---

So yeah... Some of the automatic scaling features of Android that are meant to be helpful actually hinder OpenGL development. They are not a part of OpenGL as it is a device independent cross platform API. The automatic scaling features of Android help normal GUIs using the stock Android 2D GUI components and such and icons, etc. It breaks GL compatibility and it must be circumvented; more so if you want to support OS 1.5.
Founder & Principal Architect; EGR Software LLC
http://www.typhonrt.org
http://www.egrsoftware.com
User avatar
MichaelEGR
Senior Developer
Senior Developer
 
Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

Postby snowman » Mon Feb 08, 2010 5:50 pm

you forget to do :
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, <your texture id>);

texture id is the one which was returned from glGenTextures

see any texture mapping tutorial on the net, but basically it should look like this

// allocate a texture name
GLiint textureID
glGenTextures( 1, &textureID );
// select our current texture
glBindTexture( GL_TEXTURE_2D, textureID);

//do stuff that you do on texture loading

// enable texturing
glEnable(GL_TEXTURE_2D);

// draw
snowman
Freshman
Freshman
 
Posts: 5
Joined: Mon Feb 08, 2010 5:41 pm

Top

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest