I'm trying to apply texture to a sprite using opengl as follows:
int[] textures=new int[1];
gl.glEnableClientState(GL10.GL_TEXTURE_2D);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
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);
Bitmap bitmap=null;
try {
bitmap= BitmapFactory.decodeStream(contxt.getAssets().open("gfx/garf.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
GLUtils.texImage2D(GL10.GL_VERTEX_ARRAY, 0, bitmap, 0);
bitmap.recycle();
.....
I'm using andEngine framework in android and using onManagedDraw method of Sprite to do this.
Can anyone help in this direction?
I think you need texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
I'm just guessing that your problem is that the texture doesn't show up :)
This is wrong:
GLUtils.texImage2D(GL10.GL_VERTEX_ARRAY, 0, bitmap, 0);
Should be:
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
Related
I'm trying to understand OpenGL ES 2.0 in android. I got a code from a tutorial, but I do not understand how the texture works. I can't even understand where the rendering took place. Here is the code I got.
#Override
public void surfaceCreated(GL10 gl) {
// set up the surface
gl.glDisable(GL10.GL_DITHER);
gl.glHint(
GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_FASTEST);
gl.glClearColor(0.4f, 0.2f, 0.2f, 0.5f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
// fetch the checker-board
initImage(gl);
}
#Override
public void drawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// apply the checker-board to the shape
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glTexEnvx(
GL10.GL_TEXTURE_ENV,
GL10.GL_TEXTURE_ENV_MODE,
GL10.GL_MODULATE);
gl.glTexParameterx(
GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_S,
GL10.GL_REPEAT);
gl.glTexParameterx(
GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_T,
GL10.GL_REPEAT);
// animation
int t = (int) (SystemClock.uptimeMillis() % (10 * 1000L));
gl.glTranslatef(6.0f - (0.0013f * t), 0, 0);
// draw
gl.glFrontFace(GL10.GL_CCW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuf);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuf);
gl.glDrawElements(
GL10.GL_TRIANGLE_STRIP,
5,
GL10.GL_UNSIGNED_SHORT, indexBuf);
}
private void initImage(GL10 gl) {
int[] textures = new int[1];
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
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_REPLACE);
InputStream in = context.getResources().openRawResource(R.drawable.cb);
Bitmap image;
try { image = BitmapFactory.decodeStream(in); }
finally {
try { in.close(); } catch(IOException e) { }
}
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, image, 0);
image.recycle();
}
Can anyone explain to me where the image is loaded from a drawable file, where the conversion to texture, and where the rendering took place? I just can't seem to understand this. I'm familiar with how to do it in OpenGL but it seems OpenGL ES 2.0 uses a different technique?
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, image, 0); is a utility function which converts an android Bitmap into an OpenGL texture.
When this is called, it stores the bitmap in image into the currently bound texture, which in your case is textures[0].
glDrawElements is the command that actually fires off the rendering call. If you want to know what any of the other functions do, I suggest taking a look at their online help pages.
I have a problem where the colors of any textures that I use are bleached, if that's a good word to use to describe it, on two different phones but the textures show up just fine on the emulator.
Here are the images.
The first image is the texture that I'm using.
The second image is how the texture shows up on the emulator and the way it is supposed to show up on the phones.
The third image is how the texture actually shows up on the phone.
Should I include the code where I draw the rectangle? The rectangle is just a vertex buffer and texcoord buffer. Anything that actually is done with the texture is gl.glBindTexture and gl.glBlendFunction(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA). gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f) is also called.
The following code is where I believe my error could exist. I hope someone can help me out here. Thanks!
This is in my GLSurfaceView.Renderer implementation
#Override
public void onSurfaceCreated(final GL10 gl, final EGLConfig config) {
DebugLog.d("onSurfaceCreated");
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glShadeModel(GL10.GL_FLAT);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_MULTISAMPLE);
gl.glEnable(GL10.GL_BLEND);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glFrontFace(GL10.GL_CW);
gl.glCullFace(GL10.GL_BACK);
}
This is in my BitmapTexture class.
#Override
public void loadBitmapToHardware(final GL10 gl) throws IOException {
final Bitmap bitmap = loadBitmap();
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, bitmap, GL10.GL_UNSIGNED_BYTE, 0);
bitmap.recycle();
}
#Override
public Bitmap loadBitmap() {
InputStream is = null;
try {
is = mContext.getAssets().open(mBitmapPath);
return BitmapFactory.decodeStream(is);
} catch (final IOException e) {
DebugLog.e("Failed to load Bitmap in " + this.getClass().getSimpleName() + " from path: " + mBitmapPath, e);
return null;
} finally {
try {
is.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
#Override
public void loadTexture() throws IOException {
gl.glGenTextures(1, TEXTURE_CONTAINER, 0);
mTextureId = TEXTURE_CONTAINER[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
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_MODULATE);
loadBitmapToHardware();
}
It looks like an overexposure issue to me. It is likely that the screen settings for the emulator and your phone handles this problem differently, especially since dither is disabled in your code.
You should try to:
1: Remove the glColor4f() call, and see if that works (from what I know of GL10, it sets the color to white in your case, which might cause problems with blending).
or
2: Turn of blending and turn on depth-test to see if your blending give this result.
I've been playing with OpenGL ES Android and somehow my textures are always filled with the color of the the top left-most pixel. I suppose the flags are wrong, but I've tried a many logical combinations and it does not seem to make any difference.
Why would the texture behave like so? What's the bit (flag bit indeed) that am I missing? Thanks
public void loadGLTexture(GL10 gl, Context context) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
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_REPLACE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
((GL11Ext) gl).glDrawTexfOES(position.getX(), position.getY(), 0, width, height);
}
the surface is set to
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
Obviously texture crop rectangle has to be explicitly set:
int cropWorkspace[] = new int[4];
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
cropWorkspace[0] = 0;
cropWorkspace[1] = height;
cropWorkspace[2] = width;
cropWorkspace[3] = -height;
((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropWorkspace, 0);
I've been struggling with this issue for a few weeks now, with no results. I'm sure I'm just missing something silly, so I thought I'd get an outside opinion on it.
I'm drawing a bunch of different textures in an app, and for some reason, some of them aren't showing up. I tried to figure out why only certain textures wouldn't display, and I think I've narrowed it down to textures with translucent pixels (textures that contain pixels with an alpha value that is not 0 or 255). Fully opaque textures display just fine, and textures that have either fully on or fully off pixels do as well. The problem textures display as a white square. Also, I figure I should add that everything displays fine in the emulator, it's only on my testing device (Samsung Captivate) that the textures don't display.
Here are some snippets of my code showing the important parts, as always, let me know if you need more information.
View setup (I've tried both of these, but having these lines there or not seems to make no difference):
gameView.setEGLConfigChooser(8,8,8,8,16,0);
gameView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
Renderer's onSurfaceCreated method (I've also tried enabling depth test to no avail, the lines I used are commented here, and when I tried depth testing, I did clear the depth buffer on every draw):
gl.glClearColor(0.5f, 0.5f, 0.5f, 1);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glShadeModel(GL10.GL_FLAT);
gl.glDisable(GL10.GL_DEPTH_TEST);
//gl.glEnable(GL10.GL_DEPTH_TEST);
//gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
Texture loading method (could it have something to do with GLUtils.texImage2D?):
int texId;
gl.glGenTextures(1, mTextureNameWorkspace, 0);
texId = mTextureNameWorkspace[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, texId);
if (gl instanceof GL11) {
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
}
else {
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
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_MODULATE);
InputStream is = res.openRawResource(resourceId);
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(is, null, bitmapOptions);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
if (gl instanceof GL11) {
mCropWorkspace[0] = 0;
mCropWorkspace[1] = bitmap.getHeight();
mCropWorkspace[2] = bitmap.getWidth();
mCropWorkspace[3] = -bitmap.getHeight();
((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0);
}
//Don't poke fun at my archaic error handler
int error;
String errorCodes = "";
while ((error = gl.glGetError()) != GL10.GL_NO_ERROR) {
errorCodes += error + " ";
}
if (errorCodes.length() != 0)
throw new Exception("OpenGL error while loading texture. Error codes: " + errorCodes.substring(0,errorCodes.length()-1));
textureWidth = bitmap.getWidth();
textureHeight = bitmap.getHeight();
textureId = texId;
return texId;
}
finally {
try { is.close(); } catch (IOException e) { }
try { bitmap.recycle(); } catch (Exception e) { }
}
Just to close the question in case anyone stumbles upon it:
This error was occurring because the images were saved in res/drawable. When loaded from there, the Android can do some behind-the-scenes processing, causing the resulting images to not be sized to a power of two. Store the images in res/raw to avoid this processing.
I d like to "kill" the black color of my texture. Or, I want to show png files, without background (transparent bg)
How i can do this?
Any example?
it's not that difficult. This are the main pieces:
public static Bitmap loadBitmapFromId(Context context, int bitmapId) {
InputStream is = context.getResources().openRawResource(bitmapId);
try {
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeStream(is, null, bitmapOptions);
} catch (Exception ex) {
Log.e("bitmap loading exeption", ex.getLocalizedMessage());
return null;
}
}
The Bitmap.Config.RGB_565 is important here. Then add the bitmap and get your texture id as usual.
Now in the onSurfaceCreated(GL10 gl, EGLConfig config) of your renderer add this:
// Transparancy
// important: transparent objects have to be drawn last!
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
And the drawing part (you are probably already doing this):
// first disable color_array for save:
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
// Enabled the vertices buffer for writing and to be used during
// rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
gl.glBindTexture(GL10.GL_TEXTURE_2D, myTextureId);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawArrays(drawMode, 0, verticesCount);
gl.glDisable(GL10.GL_TEXTURE_2D);
// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);