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
-~----------~----~----~----~------~----~------~--~---