Dave B
Dave B

Reputation: 23

Moving from bitmap to OpenGL

Ok, time to use OpenGL (gulp!) to render sprites in my apps (games), and forgetting Bitmap.draw etc.

After trawling through hundreds of sites/blogs (well maybe) 'explaining' how to code using OpenGL, I have hit a brick wall.

The problem is my apps are fully functional and on the Market at the moment, but my latest app was developed on an HTC Desire HD, and I am getting many reports of bad performance on less powerful devices.

The obvious route is a move to OpenGL. All the tutorial sites are geared towards developing from scratch. This is great for anyone starting a new project, but I need a 'retro-fit' to my apps. I don't fancy rewriting from scratch!

Has anyone had experience of this? Any thoughts would be hugely appreciated.

Upvotes: 2

Views: 876

Answers (2)

TurqMage
TurqMage

Reputation: 3321

I recently did something similar with my app and did receive a large performance benefit. A lot of what you 'should change' depends on how your application is structured.

For me the hardest thing was translating my UI elements because I had to re-generate the entire 'which control got touched' logic and setup text rendering. Neither of these problems are tough enough to be deal beakers but I'd avoid them if you can.

Fortunately there are some good sides. Since your app is already only 2d you can avoid the most complex parts of learning OpenGL, dealing with the 3d dimension! I'd start by setting up a gl.SurfaceView. Use glOrtho to setup the extents of your GL world, if your game was already resolution independent that should should have idea of how wide the screen is in some 'independent' manner. Just setup glOrtho to use those same extents.

I created a simple sprite class which I used for all my rendering. The Sprite had simple vertex buffer as a members, I just had it make a 1 by 1 rect, then used used scale to setup the size. (So if it was really 30x30, I would set the scale to ScaleX=30 ScaleY=30).

It looked something like this

        ByteBuffer vbb = ByteBuffer.allocateDirect( mNumVerts * 2 * 4 );
        vbb.order( ByteOrder.nativeOrder() );
        mVtxBuf = vbb.asIntBuffer();

        vbb = ByteBuffer.allocateDirect( mNumVerts * 2 * 4 );
        vbb.order( ByteOrder.nativeOrder() );
        mTexBuf = vbb.asIntBuffer();

        mVtxBuf.put( -Fixed32.HALF ); mVtxBuf.put( -Fixed32.HALF ); mTexBuf.put( 0 ); mTexBuf.put( Fixed32.ONE );
        mVtxBuf.put(  Fixed32.HALF ); mVtxBuf.put( -Fixed32.HALF ); mTexBuf.put( Fixed32.ONE ); mTexBuf.put( Fixed32.ONE );
        mVtxBuf.put(  Fixed32.HALF ); mVtxBuf.put(  Fixed32.HALF ); mTexBuf.put( Fixed32.ONE ); mTexBuf.put( 0 );

        mVtxBuf.put( -Fixed32.HALF ); mVtxBuf.put( -Fixed32.HALF ); mTexBuf.put( 0 ); mTexBuf.put( Fixed32.ONE );
        mVtxBuf.put(  Fixed32.HALF ); mVtxBuf.put(  Fixed32.HALF ); mTexBuf.put( Fixed32.ONE ); mTexBuf.put( 0 );        
        mVtxBuf.put( -Fixed32.HALF ); mVtxBuf.put(  Fixed32.HALF ); mTexBuf.put( 0 ); mTexBuf.put( 0 );

        mVtxBuf.position( 0 );        
        mTexBuf.position( 0 );

(Fixed32.HALF is just 0.5 in fixed point, you can just use 0.5 and change the Draw calls to FLOAT instead of FIXED)

With the drawing code of...

        gl.glMatrixMode( GL10.GL_MODELVIEW );
        gl.glLoadIdentity();
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );                 
        gl.glEnableClientState( GL10.GL_TEXTURE_COORD_ARRAY );

        gl.glColor4f( 1.0f * thing.getAlpha() , 1.0f * thing.getAlpha() , 1.0f * thing.getAlpha() , thing.getAlpha() );  

        gl.glTranslatef( thing.getX(), thing.getY(), thing.getZ() );
        gl.glScalef( thing.getXScale(), thing.getYScale(), thing.getZScale() );

        gl.glFrontFace( GL10.GL_CW );
        gl.glVertexPointer( 2, GL10.GL_FIXED, 0, mdl.getVtxBuf() );

        gl.glTexCoordPointer( 2, GL10.GL_FIXED, 0, mdl.getTexBuf() );
        // gl.glColorPointer( 4, GL10.GL_FLOAT, 0, mColorBuffer );
        gl.glDrawArrays( GL10.GL_TRIANGLES, 0, mdl.getVtxCount() ); 

Upvotes: 2

El Marcel
El Marcel

Reputation: 1785

Well, I would suggest you replace as little as you need until you're done (=fast enough).

Hence, it's very import you know exactly where your performance is unacceptable. Profile, profile,profile.

Of course, there are some things you will always need to implement, even if you just want to use Opengl for a tiny part of the game. Context creating, texture loading, etc...

Upvotes: 0

Related Questions