Mark,

1)  It depends.  It may be fastest, but the lag you're noticing is
probably the resource manager loading the bitmap.  Do whatever you can
to preload stuff.  If you can fit all of your textures into vram at
once, do it.  Canvas.drawBitmap is pretty fast.  texImage2D is pretty
fast on a G1 but slow on the emulator.  I'd make sure that when you
switch textures, you're not loading it from disk (should already be
loaded somehow) and you're not allocating new bitmaps or allocating
new texture space.  I have animating textures but I put every frame of
the animation onto a 512x512 texture and animate by switching which
group of texture coordinates I use.  It works for animating on a quad
but would be much harder on a complex object.

2)  Does the problem happen on both the emulator and a real device?
If so, it's probably not a bug but is something wrong with what you're
doing.  The emulator has a different opengl implementation than a
device, which is a hardware implementation.

On Sep 21, 11:15 am, Mark Gjøl <[email protected]> wrote:
> Thank you for that elaborate response. Your assumptions were all
> correct (and I _did_ do a little too much work when I called
> texImage2D, I only really needed to do that once, not every time I
> updated the texture).
>
> I now make a Canvas, which I draw my dynamic bitmap to, and just bind
> that texture with texImage2D without using texSubImage2D. This works
> perfectly, however, I feel a slight lag (although I haven't done any
> performance tests on it) when I change the texture, that I didn't
> notice before. I am certain my textures are at most 100x100 but
> usually smaller on one dimension. As I don't replace the entire
> texture, but only a portion of it, texSubImage2D might be the faster
> choice - if only it worked. Also, I didn't get any GL errors
> (gl.getError()) when using texSubImage2D.
>
> So what's left for me is this:
> * Is drawing the image to a canvas using drawBitmap the fastest way to
> make a npot texture pot?
> * Is texSubImage2D broken, in which case I should report it?
>
> Regards, Mark Gjøl
>
> On Sep 21, 2:32 am, Robert Green <[email protected]> wrote:
>
> > I'm a little confused by what you're doing.
>
> > You're first calling texImage2D, which uploads mImg to vram as your
> > texture.
> > The very next call you make is texSubImage2D with an offset of 0 and
> > 0, which uploads "texture" to vram, overwriting mImg.
>
> > I'm assuming that:
>
> > 1)  mImg is 128x128
> > 2)  You first upload mImg to allocate a space as big as mImg
> > 3)  None of your textures are greater than mImg's width or height
>
> > I'm going to suggest you change your code to do the following:
>
> > 1)  Create a bitmap of 128x128 or whatever size is appropriate for
> > each dynamic texture, unless you have many different images you want
> > to use.
> > 2)  Draw your texture to that bitmap
> > 3)  Upload that texture using regular texImage2D (in my tests, it's
> > faster for full-size updates than using texSubImage2D).
> > 4)  If using one "scratchpad" bitmap, just erase it and reuse.
> > Remember to .recycle() when done with it.
>
> > basically, I suggest that you only upload once to vram and do any pre-
> > processing on the client-side using a Bitmap or many Bitmaps depending
> > on your app/game.  That's how I do it.  You can texImage2D the same
> > textureId as many times as you like.
>
> > Also, I recommend using GL_NICEST for perspective correction when
> > dealing with large projected quads.  It's not as fast as GL_FASTEST
> > but for big triangles, it's the only way to guarantee they won't get
> > really weird when cut off at near-Z.
>
> > I have "renderer" classes that render game objects for my games.  My
> > renderers all look like this:
>
> > public MyRenderer(GL10 gl) {
> >   // read geometry from disk resource
> >   reInit(gl);
>
> > }
>
> > public void reInit(GL10 gl) {
> >   // create VBOIds
> >   // upload VBOs
> >   // create textureIds
> >   // upload textures
>
> > }
>
> > public void draw(GL10 gl, GameObject obj) {
> >   // bind VBOs and TextureIds
> >   // transform for obj
> >   // draw elements
>
> > }
>
> > so if I wanted a dynamic texture, I'd just add in this:
>
> > public void setTexture(GL10 gl, Bitmap texture) {
> >   // bind to appropriate textureId
> >   // upload whichTex
>
> > }
>
> > though I'd never let the main renderer hang on to bitmaps that an
> > object render will be drawing - I would be managing that in the object
> > renderer, so probably passing a sort of pointer or configuration,
> > usually in the form of an int constant, like:
>
> > public static final int TEXTURE_HAPPY_FACE = 0;
> > public static final int TEXTURE_ANGRY_FACE = 1;
>
> > public void setTexture(GL10 gl, int whichTex) {
> >   // bind to appropriate textureId
> >   // upload bitmap associated with whichTex
> >   if (whichTex == TEXTURE_HAPPY_FACE) {
> >     // upload happy face bitmap that we loadad probably in our
> > constructor or somewhere before runtime.
> >   }
>
> > }
>
> > I know I'm not solving your exact problem, but I think if you followed
> > this, you wouldn't have it anymore.
>
> > If you want to stick with what you've got, throw some debug statements
> > in there to print out the image size and the texture coordinates so
> > you can make sure that it's not just a problem with those.  If they
> > look exactly right, Just make sure you're not doing something goofy
> > like uploading an image that's bigger than the original.
>
> > On Sep 20, 4:53 pm, Mark Gjøl <[email protected]> wrote:
>
> > > I am developing an application that dynamically changes the texture of
> > > an object. The textures I download from the internet and are of fairly
> > > random aspect ratios. I apply these textures to a 2^nth texture using
> > >GLUtils.texSubImage2D supplying the bitmap containing the texture, and
> > > only use the part of the constructed texture that holds the newly
> > > applied data.
>
> > > This works fine when using textures with a greater width than height.
> > > However, when using tall images, I sometimes get images that are
> > > skewed. That is, it seems as if the texture is copied to the new
> > > texture, but with the width being one off, so each line just one pixel
> > > too short.
>
> > > This happens consistently when using the same images, however it does
> > > not happen for all tall images.
>
> > > Code for applying the texture:
>
> > > public void setTexture(GL10 gl, Bitmap texture) {
> > >                 int height = texture.getHeight();
> > >                 int width  = texture.getWidth();
> > >                 float heightRatio = ((float)height) / 128;
> > >                 float widthRatio = ((float)width) / 128;
> > >                 maspect = width / (float)height;
> > >                 int[] textures = new int[1];
> > >         gl.glGenTextures(1, textures, 0);
> > >                 mTextureID = textures[0];
> > >         gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
>
> > >         gl.glTexParameterf(GL10.GL_TEXTURE_2D,
> > > GL10.GL_TEXTURE_MIN_FILTER,
> > >                 GL10.GL_NEAREST);
> > >         gl.glTexParameterf(GL10.GL_TEXTURE_2D,
> > >                 GL10.GL_TEXTURE_MAG_FILTER,
> > >                 GL10.GL_LINEAR);
>
> > >         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
> > >                 GL10.GL_CLAMP_TO_EDGE);
> > >         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
> > >                 GL10.GL_CLAMP_TO_EDGE);
>
> > >         gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
> > >                 GL10.GL_BLEND);
>
> > >        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mImg, 0);
> > >        GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, texture);
>
> > >         Buffer texBuf = ByteBuffer.allocateDirect(texture.getRowBytes
> > > () * height);
> > >         texture.copyPixelsToBuffer(texBuf);
>
> > >         ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
> > >         tbb.order(ByteOrder.nativeOrder());
> > >         mTexBuffer = tbb.asFloatBuffer();
>
> > >         float tex[] = {
> > >                 0.0f,  0.0f,
> > >                 0.0f,  heightRatio,
> > >                 widthRatio,  0.0f,
> > >                 widthRatio,  heightRatio,
> > >         };
> > >         mTexBuffer.put(tex);
> > >         mTexBuffer.position(0);
>
> > > }
>
> > > Code for drawing it to screen:
>
> > > public void draw(GL10 gl, long offset){
> > >                 if(maspect < 1.25f){
> > >                         szX = maspect;
> > >                         szY = 1;
> > >                 }else{
> > >                         szX = 1.25f;
> > >                         szY = 1 / maspect * 1.25f;
> > >                 }
>
> > >                 gl.glTexEnvx(GL10.GL_TEXTURE_ENV, 
> > > GL10.GL_TEXTURE_ENV_MODE,
> > > GL10.GL_REPLACE);
> > >                 gl.glActiveTexture(GL10.GL_TEXTURE0);
> > >         gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
> > >                 gl.glFrontFace(GL10.GL_CCW);
> > >                 gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
> > >                 gl.glEnable(GL10.GL_TEXTURE_2D);
> > >                 gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
>
> > >                 gl.glTexParameterf(GL10.GL_TEXTURE_2D,
> > > GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
> > >         gl.glTexParameterf
> > > (GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
> > >         gl.glTexParameterf(GL10.GL_TEXTURE_2D,
> > > GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
> > >         gl.glTexParameterf(GL10.GL_TEXTURE_2D,
> > > GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE);
>
> > >                 gl.glPushMatrix();
>
> > >                 gl.glTranslatef(x, y, z);
> > >                 gl.glScalef(szX, szY, 1);
> > >                 gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, 
> > > GL10.GL_UNSIGNED_BYTE,
> > > mIndexBuffer);
>
> > >         gl.glPopMatrix();
>
> > > }
>
> > > This is really bugging me, so any help would be great!
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to