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 <rbgrn....@gmail.com> 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 <bitflips...@gmail.com> 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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to