Reputation: 30276
I'm coding on Android Platform. I'm trying to use texture (load image from Assets folder) for triangle. When my app run, it just blank white in triangle (not texture what I want).
I have read some other source that say image must be a power of two. And I have checked, my image is a power of two. (128 x 128). That a reason why make me headache.
Here is my code: (the main code that you should see in onDrawFrame
method, It contains code that I use for Render)
package com.test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.util.Log;
public class TextureTriangleTest extends Activity{
GLSurfaceView glView;
ByteBuffer byteBuffer;
FloatBuffer vertices;
AssetManager assets;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
assets = getAssets();
int VERTEX_SIZE = (2+2)*4;
byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
vertices = byteBuffer.asFloatBuffer();
vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f,
319.0f, 0.0f, 1.0f, 1.0f,
160.0f, 479.0f, 0.5f, 0.0f } );
vertices.flip();
glView = new GLSurfaceView(this);
glView.setRenderer(new Render());
setContentView(glView);
}
class Render implements Renderer{
@Override
public void onDrawFrame(GL10 gl) {
try {
Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png"));
int textureIds[] = new int[1];
gl.glGenTextures(1, textureIds, 0);
int textureId = textureIds[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 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_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
bitmap.recycle();
} catch (IOException e) {
Log.d("", "FAILED LOAD FILE");
throw new RuntimeException("Couldn't load asset!");
}
gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 320, 0, 480, 1, -1);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
int VERTEX_SIZE = (2+2)*4;
vertices.position(0);
gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
vertices.position(2);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
}
}
}
My code just a simple example. I have debug and all thing is true. (such as: successfully load image). But, I don't know how to debug OpenGL app. (It means : when debug, I can view parameter of variable, but I don't know how it be, because OpenGL is too complicated than Canvas- that you just use one line of code and has result :) )
thanks for help :)
Upvotes: 1
Views: 2654
Reputation: 30276
Oh. I have fixed whole my solutions, and below is my full code. I posted here for whom try to read my long post (^^) and need a real solution :) Thanks to SteveL has suggested me :)
In my solution, I have some change:
first. Performance: I put code read texture in onSurfaceCreate
.
second. As SteveL say. I'm missing gl.glEnable
and I have reseted again gl.glBindTexture
.
Thinks again, I see that those error really silly. Just because I'm a newbie of OpenGL :(
package com.test;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
public class ColorTriangleTest extends Activity{
GLSurfaceView glView;
ByteBuffer byteBuffer;
FloatBuffer vertices;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
int VERTEX_SIZE = (2+4)*4;
byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
vertices = byteBuffer.asFloatBuffer();
vertices.put(new float[] { 0.0f, 0.0f, 1, 0, 0, 1,
319.0f, 0.0f, 1, 1, 0, 1,
160.0f, 479.0f, 1, 0, 1, 1 });
vertices.flip();
glView = new GLSurfaceView(this);
glView.setRenderer(new Render());
setContentView(glView);
}
class Render implements Renderer {
@Override
public void onDrawFrame(GL10 gl) {
int VERTEX_SIZE = (2+4)*4;
gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 320, 0, 480, 10, -10);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
vertices.position(0);
gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
vertices.position(2);
gl.glColorPointer(4, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
}
}
}
Upvotes: 2
Reputation: 30276
Oh. I have fixed my problem. But I cannot explain why. (I can fixed because I do like some tutorial on the internet).
Here is my code. I have pointed some lines that I have changed. Please tell me why it works, please:
package com.test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.util.Log;
public class TextureTriangleTest extends Activity{
GLSurfaceView glView;
ByteBuffer byteBuffer;
FloatBuffer vertices;
AssetManager assets;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
assets = getAssets();
int VERTEX_SIZE = (2+2)*4;
byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
vertices = byteBuffer.asFloatBuffer();
vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f,
319.0f, 0.0f, 1.0f, 1.0f,
160.0f, 479.0f, 0.5f, 0.0f } );
vertices.flip();
glView = new GLSurfaceView(this);
glView.setRenderer(new Render());
setContentView(glView);
}
class Render implements Renderer{
@Override
public void onDrawFrame(GL10 gl) {
int a = 0;
try {
Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png"));
int textureIds[] = new int[1];
gl.glGenTextures(1, textureIds, 0);
int textureId = textureIds[0];
a= textureId;
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); //this line
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 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_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); //and this line
bitmap.recycle();
} catch (IOException e) {
Log.d("", "FAILED LOAD FILE");
throw new RuntimeException("Couldn't load asset!");
}
gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 320, 0, 480, 1, -1);
//Here two lines that I added. Two lines I have declared above in try_catch
//So, WHY I NEED TO DECLARE AGAIN ??!!!
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, a);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
int VERTEX_SIZE = (2+2)*4;
vertices.position(0);
gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
vertices.position(2);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
}
}
}
That works for me now :) Who can explain why ??!!
Upvotes: 0