OpenGL ES : Using Texture: Blank White instead of Texture Image - java
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 :)
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
}
}
}
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 ??!!
Related
JavaVM crashing when drawing using OpenGL
I've got the folowing code: package test.opengl; import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL30; import com.badlogic.gdx.utils.BufferUtils; import java.io.IOException; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.file.Files; import java.nio.file.Paths; import static com.badlogic.gdx.graphics.GL20.*; public class GLClass extends ApplicationAdapter { private int shaderProgram; private GL30 gl; FloatBuffer vertices; IntBuffer vao = BufferUtils.newIntBuffer(1); IntBuffer vbo = BufferUtils.newIntBuffer(1); #Override public void create() { gl = Gdx.gl30; compileShaders(); vertices = BufferUtils.newFloatBuffer(9); vertices.put(new float[] { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f }); gl.glEnable(GL_DEPTH_TEST); gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); gl.glGenVertexArrays(1, vao); gl.glGenBuffers(1, vbo); gl.glBindVertexArray(vao.get(0)); gl.glBindBuffer(GL_ARRAY_BUFFER, vbo.get(0)); gl.glBufferData(GL_ARRAY_BUFFER, 9, vertices, GL_STATIC_DRAW); gl.glVertexAttribPointer(0, 3, GL_FLOAT, false, 3, 0); gl.glEnableVertexAttribArray(0); gl.glBindVertexArray(0); } #Override public void render() { gl.glClearColor(0.2f, 0.2f, 0.2f, 1); gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl.glUseProgram(shaderProgram); gl.glBindVertexArray(vao.get(0)); gl.glDrawArrays(GL_TRIANGLES, 0, 3); gl.glBindVertexArray(0); int err = gl.glGetError(); if (err != 0) System.err.println("ERROR: " + err); } #Override public void resize(int width, int height) { gl.glViewport(0, 0, width, height); } private void compileShaders() { String vsSource; String fsSource; try { vsSource = new String(Files.readAllBytes(Paths.get("shaders/shader.vert"))); fsSource = new String(Files.readAllBytes(Paths.get("shaders/shader.frag"))); } catch (IOException e) { throw new RuntimeException(e); } shaderProgram = gl.glCreateProgram(); int vertexShader = gl.glCreateShader(GL_VERTEX_SHADER); gl.glShaderSource(vertexShader, vsSource); gl.glCompileShader(vertexShader); System.err.println(gl.glGetShaderInfoLog(vertexShader)); gl.glAttachShader(shaderProgram, vertexShader); int fragmentShader = gl.glCreateShader(GL_FRAGMENT_SHADER); gl.glShaderSource(fragmentShader, fsSource); gl.glCompileShader(fragmentShader); System.err.println(gl.glGetShaderInfoLog(fragmentShader)); gl.glAttachShader(shaderProgram, fragmentShader); gl.glLinkProgram(shaderProgram); gl.glDeleteShader(vertexShader); gl.glDeleteShader(fragmentShader); } } The code for shader.vert: #version 330 core layout (location = 0) in vec3 position; void main() { gl_Position = vec4(position.x, position.y, position.z, 1.0); } The code for shader.frag: #version 330 out vec4 out_Color; void main() { out_Color = vec4(1.0f, 0.5f, 0.2f, 1.0f); } It is running on desktop and the program crashes as soon as the first call of render() is completed, without a stacktrace and a segfault log. config.useGL30 is set to true. Why is it crashing? Am I doing anything wrong?
Android OpenGL ES Polygon Tutorial Assistance
I have followed some Android tutorials and have this Triangle program that works and runs and creates a filled Triangle successfully. I am now trying to follow several different Polygon tutorials but none seem to help translating my code to a polygon. I have scoured stack and everywhere else, so I know this may seem repetitive. I want to be able to enter the number of sides and have the program generate the polygon with that many sides. I can sort of hard code in vertices in order to generate a polygon but cannot make this a polygon of n sides. Would anyone be able to guide me in the right direction or provide some examples? I am lost. Triangle.java import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.opengles.GL10; public class Triangle{ private FloatBuffer vertexBuffer; private int vSize = 7; public Triangle(){ float vertices[] = { -.5f, -.433f, 0, 1, 0, 0, 1, .5f, -.433f, 0, 0, 1, 0, 1, 0, .433f, 0, 0, 0, 1, 1 }; ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length*4); byteBuffer.order(ByteOrder.nativeOrder()); vertexBuffer = byteBuffer.asFloatBuffer(); vertexBuffer.put(vertices); } public void onDrawFrame(GL10 gl) { vertexBuffer.position(0); gl.glVertexPointer(3, GL10.GL_FLOAT, vSize*4, vertexBuffer); vertexBuffer.position(3); gl.glColorPointer(4, GL10.GL_FLOAT, vSize*4, vertexBuffer); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); // GL_TRAINGLEFAN for polygon? gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); } } MyRenderer.java import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; public class MyRenderer implements Renderer { private Triangle triangle; #Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT); triangle.onDrawFrame(gl); } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { if(width<height){ gl.glViewport(0, 0, width, width); }else{ gl.glViewport(0, 0, height, height); } gl.glMatrixMode(GL10.GL_PROJECTION); //to work with the projection matrix //to do: set up ortho projection gl.glLoadIdentity(); gl.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, -0.1f, 0.1f); gl.glMatrixMode(GL10.GL_MODELVIEW);//methods should restore model view matrix mode } #Override public void onSurfaceCreated(GL10 gl, EGLConfig arg1) { gl.glClearColor(0.8f, 0.8f, 0.8f, 1); triangle = new Triangle(); } } MainActivity.java import android.opengl.GLSurfaceView; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { private GLSurfaceView view; private MyRenderer renderer; #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); view = new GLSurfaceView(this); renderer = new MyRenderer(); view.setRenderer(renderer); setContentView(view); } #Override protected void onPause() { view.onPause(); super.onPause(); } #Override protected void onResume() { view.onResume(); super.onResume(); } #Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
Sample a circle every (2 * pi) / n radians: void glPolygon( unsigned int sides ) { glBegin( GL_TRIANGLE_FAN ); glVertex2f( 0, 0 ); for( unsigned int i = 0; i <= sides; i++ ) { const float u = ( i / (float)sides ); const float a = ( 2 * 3.14159 ) * u; glVertex2f( cos( a ), sin( a ) ); } glEnd(); }
Why glTranslatef?
I just don't understand why in this case if I get rid of this stroke gl.glTranslatef(0.0f,(float)Math.sin(mTransY), -3.0f); square just not drawing? Full code here (and ignore those cyrillic comments - i just wrote for myself what each func does ) MainActivity class package opengl.tutorial.one; import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.view.WindowManager; public class MainActivity extends Activity { /** Called when the activity is first created. */ #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new SquareRenderer(true)); setContentView(view); } } Square class package opengl.tutorial.one; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.microedition.khronos.opengles.GL10; //1 import javax.microedition.khronos.opengles.GL11; public class Square { private FloatBuffer mFVertexBuffer; private ByteBuffer mColorBuffer; private ByteBuffer mIndexBuffer; public Square(){ float vertices[] = { -1.0f, -1.0f,//0 1.0f, -1.0f, //1 -1.0f, 1.0f, //2 1.0f, 1.0f //3 };//задали положение веришн квадрата по координатам byte maxColor=(byte)255; byte colors[] = //задали цвет веришнам { maxColor,maxColor, 0,maxColor, maxColor,maxColor, 0,maxColor, maxColor,maxColor, 0,maxColor, maxColor,maxColor, 0,maxColor, }; byte indices[] = //порядок построения треугольников вершинами { 0, 3, 1, //первый 0, 2, 3 //второй }; ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); //5 vbb.order(ByteOrder.nativeOrder()); mFVertexBuffer = vbb.asFloatBuffer(); mFVertexBuffer.put(vertices); mFVertexBuffer.position(0); mColorBuffer = ByteBuffer.allocateDirect(colors.length); mColorBuffer.put(colors); mColorBuffer.position(0); mIndexBuffer = ByteBuffer.allocateDirect(indices.length); mIndexBuffer.put(indices); mIndexBuffer.position(0); } public void draw(GL10 gl) //6 { gl.glFrontFace(GL11.GL_CW); //выводит полигон по заданной ориентации к экрану. CW - по часовой gl.glVertexPointer(2, GL11.GL_FLOAT, 0, mFVertexBuffer); //Установка массива для вершинных координат gl.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 0, mColorBuffer); //9 gl.glDrawElements(GL11.GL_TRIANGLES, 6,GL11.GL_UNSIGNED_BYTE, mIndexBuffer); gl.glFrontFace(GL11.GL_CCW); //выводит полигон по заданной ориентации к экрану. СCW - против часовой } } class SquareRenderer package opengl.tutorial.one; import javax.microedition.khronos.egl.EGL10; //1 import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; import java.lang.Math; public class SquareRenderer implements Renderer { private boolean mTranslucentBackground; private Square mSquare; private float mTransY; private float mAngle; public SquareRenderer(boolean useTranslucentBackground) { mTranslucentBackground = useTranslucentBackground;//прозрачный фон mSquare = new Square(); //новый объект типа квадрат } public void onDrawFrame(GL10 gl) //4 { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); //5 gl.glMatrixMode(GL10.GL_MODELVIEW); //6 gl.glLoadIdentity(); //7 gl.glTranslatef(0.0f,(float)Math.sin(mTransY), -3.0f); //8 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //9 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); mSquare.draw(gl); //10 mTransY += 0f; } public void onSurfaceChanged(GL10 gl, int width, int height) //11 { gl.glViewport(0, 0, width, height); //12 float ratio = (float) width / height; gl.glMatrixMode(GL10.GL_PROJECTION); //13 gl.glLoadIdentity(); gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //14 } public void onSurfaceCreated(GL10 gl, EGLConfig config) //15 { gl.glDisable(GL10.GL_DITHER); //16 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); if (mTranslucentBackground) //18 { } else { gl.glClearColor(1,1,1,1); } gl.glEnable(GL10.GL_CULL_FACE); //19 gl.glShadeModel(GL10.GL_SMOOTH); //20 gl.glEnable(GL10.GL_DEPTH_TEST); //21 } }
The whole square is at z=0 plane. glTranslatef defines point of view 3.0 by z axis. Without this call, the point of view has z=0 coordinate, so you are looking at the square inside of the square itself. Play with glTranslatef coordinates to see what happens. The best way to understand the meaning of every OpenGL function is to exclude/include it (well, you have already done this...) and to set different parameter values. y parameter of glTranslatef gives rotation effect around y-axis.
OpenGL ES Object is Displaying Strangely / Distorted - Android
EDIT OK - I grabbed a device and..guess what...it displays correctly ? Does anyone know why this would be happening on the simulator only ? Thank you. I am trying to draw an object using glDrawElements on Android. I am using the code below to read in my vertice and indice data and then draw the object in my render method. I am testing this on the simulator rather than a real device. This is my scene object code : import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; import javax.microedition.khronos.opengles.GL10; public class SceneObject { public FloatBuffer mVertexBuffer; public FloatBuffer mTextureBuffer; public ShortBuffer indexBuffer; public FloatBuffer mMatriceBuffer; public FloatBuffer mPivotBuffer; public short[] indicesTest = {0,1,2,3,4,5,3,5,6,7,5,8,7,8,9,10,7,9,11,10,9,12,1,0,13,12,14,15,13,14,14,10,11,15,14,11,0,14,12,16,17,18,19,16,18,18,20,19,21,16,19,22,21,19,22,19,23,4,24,25,25,26,27,25,27,28,4,25,28,5,4,28,5,28,8,29,30,31,29,31,19,29,19,20,32,33,31,32,31,30,32,34,33,35,22,23,36,35,23,37,36,23,37,23,38,39,37,38,40,39,38,41,40,38,41,38,1,42,41,1,12,43,1,42,1,43,17,27,26,26,18,17,44,45,46,46,47,44,48,49,50,51,52,53,53,54,51,55,51,54,54,56,55,57,48,50,50,58,57,52,59,60,60,53,52,59,44,47,47,60,59,61,62,63,63,64,61,65,66,67,67,68,65,69,70,71,71,72,69,66,69,72,72,67,66,73,65,68,68,74,73,70,75,76,76,71,70,75,61,64,64,76,75,77,78,79,79,80,77,81,82,62,62,61,81,83,81,61,61,75,83,84,63,62,62,82,84,63,84,85,86,87,88,89,90,91,92,93,87,87,86,92,94,95,96,96,97,94,98,99,100,100,101,98,102,103,104,104,105,102,106,107,108,108,109,106,110,111,112,78,77,113,114,115,78,112,111,116,117,118,115,119,116,120,121,122,123,123,124,121,125,126,127,127,128,125,129,130,131,132,133,5,5,133,6,5,134,135,135,134,136,134,137,136,137,138,136,129,139,130,139,140,141,140,142,141,137,141,138,141,142,138,141,130,139,143,144,145,144,146,145,147,145,146,144,148,146,148,149,146,146,149,150,151,132,152,153,152,154,154,152,155,152,132,155,132,5,155,155,5,135,156,157,158,158,157,146,146,157,147,159,160,158,158,160,156,34,160,159,149,161,150,161,162,150,162,163,150,150,163,164,163,165,164,165,166,164,166,167,164,164,167,129,167,168,129,169,139,129,129,168,169,154,143,153,145,153,143,170,171,172,173,172,171,174,175,176,177,178,179,180,179,178,178,181,180,182,180,181,175,183,176,184,176,183,185,177,186,179,186,177,171,185,173,186,173,185,187,188,189,190,189,188,191,192,193,194,193,192,195,196,197,198,197,196,196,191,198,193,198,191,192,199,194,200,194,199,201,195,202,197,202,195,188,201,190,202,190,201,203,204,205,206,205,204,207,208,187,188,187,208,208,209,188,201,188,209,189,210,187,207,187,210,210,189,211,212,213,214,215,216,217,218,219,220,221,220,219,222,223,224,225,226,227,228,229,230,231,230,229,232,233,234,235,236,237,238,239,240,241,242,243,123,244,124,245,246,203,204,203,246,247,248,203,249,250,251,252,253,247,248,247,253,159,33,34,254,255,256,256,257,254,255,244,123,123,256,255,244,258,121,121,124,244,259,260,125,125,128,259}; public float[] verticeTest = {20360.8f,20679.5f,611.547f,24248.7f,13527f,1074.93f,24207.4f,23005.5f,1503.19f,9819.59f,14845.7f,8.81875f,11126.3f,13982.2f,32.0718f,8379.01f,17678.5f,0.00115749f,8379.01f,15141.6f,0.00111471f,12137.8f,17973.8f,60.0461f,14591.9f,14509.2f,164.113f,15621.5f,15846.6f,223.075f,15136.7f,18549.5f,194.186f,16918.2f,16705.3f,310.215f,21081.8f,15846.6f,687.576f,19789f,16705.3f,554.435f,18467.9f,19868.7f,433.258f,18354.3f,17001.2f,423.539f,14591.9f,7402.34f,164.113f,13930.5f,9087.62f,131.015f,13039.7f,9096.18f,92.3283f,19110.4f,-8011.43f,490.311f,12811.7f,7228.03f,83.5128f,15621.5f,6064.9f,223.074f,16918.2f,5206.21f,310.215f,21807.5f,-426.492f,768.658f,11221.5f,13854f,34.3347f,12150f,12649.6f,60.4329f,12811.7f,10964.3f,83.513f,13702.6f,10955.8f,120.472f,13930.5f,12823.9f,131.015f,12150f,5542.76f,60.4327f,11119f,4205.31f,31.902f,15341.7f,-15792.9f,206.155f,9819.59f,3346.62f,8.81857f,10735.6f,-21752.5f,23.5976f,8379.01f,3050.73f,0.000981022f,18354.3f,4910.32f,423.538f,19789f,5206.21f,554.434f,21081.8f,6064.9f,687.576f,23336.1f,6399.27f,954.364f,22106.6f,7402.34f,803.393f,22764f,9087.62f,882.485f,22990.5f,10955.8f,910.595f,22764f,12823.9f,882.485f,22106.6f,14509.2f,803.393f,24248.7f,8492.36f,-3249.03f,24207.4f,17415.3f,-3297.97f,24207.4f,23005.5f,1503.19f,24248.7f,13527f,1074.93f,12728.3f,-24463.4f,-4243.56f,15341.7f,-20827.5f,-4117.81f,15341.7f,-15792.9f,206.155f,19110.4f,-13046f,-3833.65f,21807.5f,-5461.09f,-3555.3f,21807.5f,-426.492f,768.658f,19110.4f,-8011.43f,490.311f,15341.7f,-20827.5f,-4117.81f,15341.7f,-15792.9f,206.155f,10735.6f,-26787.1f,-4300.36f,10735.6f,-21752.5f,23.5976f,23336.1f,1364.68f,-3369.59f,23336.1f,6399.27f,954.364f,24883.8f,8123.11f,-2819.08f,24859.5f,16025.8f,-2803.12f,24207.4f,17415.3f,-3297.97f,24248.7f,8492.36f,-3249.03f,13363.4f,-24832.7f,-3813.62f,15976.8f,-21196.8f,-3687.86f,15341.7f,-20827.5f,-4117.81f,12728.3f,-24463.4f,-4243.56f,19745.5f,-13415.3f,-3403.7f,22442.7f,-5830.35f,-3125.36f,21807.5f,-5461.09f,-3555.3f,19110.4f,-13046f,-3833.65f,10915.8f,-27847.5f,-3863.23f,10735.6f,-26787.1f,-4300.36f,23222.6f,-2518.03f,-3057.67f,23336.1f,1364.68f,-3369.59f,10301.8f,-40240.8f,-15469.8f,10482f,-40907.1f,-14694f,10915.8f,-27847.5f,-3863.23f,10735.6f,-26787.1f,-4300.36f,25648.8f,8121.58f,-2817.31f,25624.5f,16024.2f,-2801.34f,24056.1f,-2550.94f,-3019.36f,25678.7f,16560.2f,-2907.29f,25594.2f,17951.2f,-3237.71f,25624.5f,-88046.9f,-92182.7f,25678.7f,-87767f,-92508.6f,25678.7f,16560.2f,-2907.29f,25678.7f,16560.2f,-2907.29f,25624.5f,16024.2f,-2801.34f,25624.5f,-88046.9f,-92182.7f,25624.5f,-88413.1f,-92497.2f,25678.7f,-88133.2f,-92823.1f,24765.7f,-88413.1f,-92497.2f,24820f,-88133.2f,-92823.1f,25678.7f,-88133.2f,-92823.1f,25624.5f,-88413.1f,-92497.2f,24765.7f,-89895.8f,-93770.7f,24820f,-89615.9f,-94096.6f,24820f,-88133.2f,-92823.1f,24765.7f,-88413.1f,-92497.2f,25678.7f,-89596.5f,-94079.9f,25678.7f,-88133.2f,-92823.1f,24820f,-88133.2f,-92823.1f,24820f,-89615.9f,-94096.6f,23222.6f,-93458.9f,-81162.2f,24056.1f,-93491.8f,-81123.9f,24056.1f,-2550.94f,-3019.36f,23222.6f,-2518.03f,-3057.67f,10579.6f,-102089f,-68973.2f,10579f,-102925f,-68042.7f,10482f,-40907.1f,-14694f,10579.6f,-102089f,-68973.2f,10579f,-102925f,-68042.7f,10482f,-41291.8f,-14246f,10579f,-102925f,-68042.7f,10489f,-103571f,-67018.6f,10482f,-41713.9f,-13886.7f,10482f,-41291.8f,-14246f,10489f,-103571f,-67018.6f,8379.01f,-102145f,-69021.7f,10579.6f,-102089f,-68973.2f,10301.8f,-40240.8f,-15469.8f,8379.01f,-68082.6f,-39554.7f,8379.01f,-101057f,-70411.1f,10735.6f,-101057f,-70411.1f,10579.6f,-102089f,-68973.2f,8379.01f,-102145f,-69021.7f,-7490.7f,13527f,1074.93f,-3602.79f,20679.5f,611.547f,-7449.35f,23005.5f,1503.19f,5631.77f,13982.2f,32.0718f,6938.43f,14845.7f,8.81875f,4620.19f,17973.8f,60.0461f,2166.16f,14509.2f,164.113f,1136.48f,15846.6f,223.075f,1621.29f,18549.5f,194.186f,-160.178f,16705.3f,310.215f,-4323.73f,15846.6f,687.576f,-3030.97f,16705.3f,554.435f,-1709.92f,19868.7f,433.258f,-1596.32f,17001.2f,423.539f,2827.51f,9087.62f,131.015f,2166.16f,7402.34f,164.113f,3718.3f,9096.18f,92.3283f,-2352.36f,-8011.43f,490.311f,3946.3f,7228.03f,83.5128f,1136.48f,6064.9f,223.074f,-160.182f,5206.21f,310.215f,-5049.53f,-426.492f,768.658f,5536.51f,13854f,34.3347f,4608.07f,12649.6f,60.4329f,3946.3f,10964.3f,83.513f,3055.44f,10955.8f,120.472f,2827.51f,12823.9f,131.015f,5639.04f,4205.31f,31.902f,4608.07f,5542.76f,60.4327f,1416.3f,-15792.9f,206.155f,6022.45f,-21752.5f,23.5976f,6938.43f,3346.62f,8.81857f,-1596.32f,4910.32f,423.538f,-3030.97f,5206.21f,554.434f,-4323.73f,6064.9f,687.576f,-6578.08f,6399.27f,954.364f,-5348.56f,7402.34f,803.393f,-6006f,9087.62f,882.485f,-6232.44f,10955.8f,910.595f,-6006f,12823.9f,882.485f,-5348.57f,14509.2f,803.393f,-7449.35f,17415.3f,-3297.97f,-7490.7f,8492.36f,-3249.03f,-7449.35f,23005.5f,1503.19f,-7490.7f,13527f,1074.93f,1416.3f,-20827.5f,-4117.81f,4029.77f,-24463.4f,-4243.56f,1416.3f,-15792.9f,206.155f,-5049.53f,-5461.09f,-3555.3f,-2352.36f,-13046f,-3833.65f,-5049.53f,-426.492f,768.658f,-2352.36f,-8011.43f,490.311f,1416.3f,-20827.5f,-4117.81f,1416.3f,-15792.9f,206.155f,6022.45f,-26787.1f,-4300.36f,6022.45f,-21752.5f,23.5976f,-6578.08f,1364.68f,-3369.59f,-6578.08f,6399.27f,954.364f,-8101.47f,16025.8f,-2803.12f,-8125.81f,8123.11f,-2819.08f,-7449.35f,17415.3f,-3297.97f,-7490.7f,8492.36f,-3249.03f,781.19f,-21196.8f,-3687.86f,3394.66f,-24832.7f,-3813.62f,1416.3f,-20827.5f,-4117.81f,4029.77f,-24463.4f,-4243.56f,-5684.64f,-5830.35f,-3125.36f,-2987.47f,-13415.3f,-3403.7f,-5049.53f,-5461.09f,-3555.3f,-2352.36f,-13046f,-3833.65f,5842.26f,-27847.5f,-3863.23f,6022.45f,-26787.1f,-4300.36f,-6464.54f,-2518.03f,-3057.67f,-6578.08f,1364.68f,-3369.59f,6276.06f,-40907.1f,-14694f,6456.25f,-40240.8f,-15469.8f,5842.26f,-27847.5f,-3863.23f,6022.45f,-26787.1f,-4300.36f,-8866.45f,16024.2f,-2801.34f,-8890.79f,8121.58f,-2817.31f,-7298.12f,-2550.94f,-3019.36f,-8920.72f,16560.2f,-2907.29f,-8836.13f,17951.2f,-3237.71f,-8920.72f,-87767f,-92508.6f,-8866.45f,-88046.9f,-92182.7f,-8920.72f,16560.2f,-2907.29f,-8866.45f,16024.2f,-2801.34f,-8920.72f,16560.2f,-2907.29f,-8866.45f,-88046.9f,-92182.7f,-8920.72f,-88133.2f,-92823.1f,-8866.45f,-88413.1f,-92497.2f,-8920.72f,-87767f,-92508.6f,-8866.45f,-88046.9f,-92182.7f,-8061.98f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8866.45f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8061.98f,-89615.9f,-94096.6f,-8007.72f,-89895.8f,-93770.7f,-8061.98f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8920.72f,-89596.5f,-94079.9f,-8061.98f,-88133.2f,-92823.1f,-8061.98f,-89615.9f,-94096.6f,-8061.98f,-88133.2f,-92823.1f,-8920.72f,-89596.5f,-94079.9f,-7298.12f,-93491.8f,-81123.9f,-6464.54f,-93458.9f,-81162.2f,-7298.12f,-2550.94f,-3019.36f,-6464.54f,-2518.03f,-3057.67f,-7298.12f,-2550.94f,-3019.36f,-6464.54f,-93458.9f,-81162.2f,6456.25f,-40240.8f,-15469.8f,6179.01f,-102925f,-68042.7f,6178.41f,-102089f,-68973.2f,6276.06f,-41291.8f,-14246f,6179.01f,-102925f,-68042.7f,6179.01f,-102925f,-68042.7f,6276.06f,-40907.1f,-14694f,6179.01f,-102925f,-68042.7f,6276.06f,-41713.9f,-13886.7f,6269.01f,-103571f,-67018.6f,6022.45f,-21752.5f,23.5976f,6022.45f,-26787.1f,-4300.36f,10735.6f,-26787.1f,-4300.36f,10735.6f,-21752.5f,23.5976f,6178.41f,-102089f,-68973.2f,6178.41f,-102089f,-68973.2f,6022.45f,-101057f,-70411.1f }; public String objectName; public int triangleCount; public int verticeCount; public float[] vertices; public float[] normals; public float[] textures; public short[] indices; public float[] matrices; public float[] pivots; public float[] animations; public void awake() { ByteBuffer vbb = ByteBuffer.allocateDirect(verticeTest.length * 4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asFloatBuffer(); mVertexBuffer.put(verticeTest); mVertexBuffer.position(0); ByteBuffer tbb = ByteBuffer.allocateDirect(textures.length * 4); tbb.order(ByteOrder.nativeOrder()); mTextureBuffer = tbb.asFloatBuffer(); mTextureBuffer.put(textures); mTextureBuffer.position(0); //short has 2 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(indicesTest.length*2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indicesTest); indexBuffer.position(0); verticeCount = (triangleCount*3); } public void draw(GL10 gl) { System.out.println("Draw Method Called in Object"); gl.glEnable(GL10.GL_TEXTURE_2D); //workaround bug 3623 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); System.out.println("Triangle Vertice Count is "+verticeCount); int x = vertices.length; System.out.println("Rendering following number of vertices "+x); int y = indices.length; System.out.println("Rendering following number of indices "+y); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); } } And here is the code where I call the draw method : import java.nio.FloatBuffer; import java.util.ArrayList; import java.util.Iterator; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLSurfaceView; import android.opengl.GLU; class GLRenderer implements GLSurfaceView.Renderer { private static final String TAG = "GLRenderer"; private final Context context; private final GLCube cube = new GLCube(); private long startTime; private long fpsStartTime; private long numFrames; SceneObject drawObject; SceneObject object; //Used for object position and rotation. float zRotation; float xRotation; float yRotation; float kxRotation = 0.0f; float kyRotation = 0.0f; ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); boolean SEE_THRU = false; GLRenderer(Context context) { this.context = context; } public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Setup any OpenGL Options that are required. gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnable(GL10.GL_TEXTURE_2D); if (SEE_THRU) { gl.glDisable(GL10.GL_DEPTH_TEST); gl.glEnable(GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE); } //Optional - disable dither to boost peformance. //gl.glDisable(GL10.GL_DITHER); //Dithering enabled by default. //Turn on the lights. float lightAmbient[] = new float[] { 0.2f, 0.2f, 0.2f, 1}; float lightDiffuse[] = new float[] {1, 1, 1, 1}; float[] lightPos = new float[] {1 ,1 ,1 , 1}; gl.glEnable(GL10.GL_LIGHTING); gl.glEnable(GL10.GL_LIGHT0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0); //Specify which materials we should use. float matAmbient[] = new float[] {1, 1, 1, 1}; float matDiffuse[] = new float[] {1, 1, 1, 1}; gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0); } public void onSurfaceChanged(GL10 gl, int width, int height) { //Define the view frustrum gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); float ratio = (float)width/height; gl.glLoadIdentity(); //gl.glOrthof(0, 480f, 800f, 0, 0, 1); GLU.gluPerspective(gl, 45.0f, ratio, 1.0f, 100f); } public void onDrawFrame (GL10 gl) { //Defs for rotation of object. float kzRotation = 0.0f; kyRotation +=1.0f; kxRotation =280.0f; gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); SceneObject object = sceneObjects.get(13); //Get the object //Position the model. gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -30.0f); gl.glScalef(0.0001f, 0.0001f, 0.0001f); zRotation = kzRotation; xRotation = kxRotation; yRotation = kyRotation; gl.glRotatef(yRotation, 0.0f, 1.0f, 0.0f); gl.glRotatef(xRotation, 1.0f, 0.0f, 0.0f); gl.glRotatef(zRotation, 0.0f, 0.0f, 1.0f); object.draw(gl); } } } The problem is that the object is not displaying as it should, but instead looks warped and squashed. Can anyone spot what might be wrong ? EDIT - Changed the onSufaceChanged method as per Tim's answer below, however no improvement. I've added an image of how the object is rendering on Android and the same object rendering correct on the iPhone. The most noticeable problem is that the "legs" should be straight and not bend and overall the object should be much longer. I'm sure the vertices and indices in the code above are correct (they are exactly the same as the iPhone ones). In case it is relevant here is how I am setting up the surfaceview / view: public class SaxParserActivity extends Activity { /** Called when the activity is first created. */ ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.main); GLView view; view = new GLView(this, sceneObjects); //Pass down our sceneObjects into the view class. //view.sceneObjects = sceneObjects; setContentView(view); } } class GLView extends GLSurfaceView { private final GLRenderer renderer; ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); GLView(Context context, ArrayList<SceneObject> sceneObjects) { super (context); //Uncomment this to turn on error-checking and logging. //setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS); renderer = new GLRenderer(context); //Pass down our sceneObjects. renderer.sceneObjects = sceneObjects; setRenderer(renderer); } }
I'm a bit confused by what you're doing. Why do you wipe on the projection matrix in onDrawFrame, after setting it in onSurfaceChanged? You should set projection in onSurfaceChanged like so: public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); //make sure to reset before glOrthof gl.glOrthof(0, 320f, 480f, 0, 0, 1); } And then change back to modelview and don't disturb the projection matrix during onDrawFrame. You'll probably need to recalibrate your scale and translate in onDrawFrame as well after doing this.
OpenGL ES texture won't draw
I have followed a tutorial on how to display an image in OpenGL, and I first had to make a square and then texture it. I have tried gl.glColor4f(0f,0f,0f,1f); and that works, I can see the square. But then when I try to texture it, the screen just stays white. What did I do wrong? Here is the screen with the gl.glColor4f(0f,0f,0f,1f); : If I apply the texture (using the custom Texture class that the tutorial suggested), the screen is completely white. Here is my code: Square.java: package com.chrypthic.android.reference; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import javax.microedition.khronos.opengles.GL10; import android.content.Context; public class Square { final int VERTEX_SIZE = (2+2) *4; FloatBuffer vertices; ShortBuffer indices; Texture texture; GL10 gl; Context c; public Square(GL10 gl, Context context) { this.gl = gl; this.c = context; ByteBuffer byteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * 4); byteBuffer.order(ByteOrder.nativeOrder()); vertices = byteBuffer.asFloatBuffer(); vertices.put(new float[]{ 10.0f, 10.0f, 0.0f, 0.0f, //bl 160.0f, 10.0f, 1.0f, 0.0f, //br 160.0f, 160.0f, 1.0f, 1.0f, //tr 10.0f, 160.0f, 1.0f, 0.0f, //tl }); vertices.flip(); byteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * 4); byteBuffer.order(ByteOrder.nativeOrder()); indices = byteBuffer.asShortBuffer(); indices.put(new short[]{ 0, 1, 2, 2, 3, 0 }); indices.flip(); texture = new Texture("image/picture.png", c, gl); } public void draw() { gl.glEnable(GL10.GL_TEXTURE_2D); texture.bind(); //gl.glColor4f(0f, 0f, 0f, 1f); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 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.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_SHORT, indices); } } Texture.java package com.chrypthic.android.reference; import java.io.InputStream; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLUtils; public class Texture { String texturePath; Context context; GL10 gl; int textureId; int minFilter; int magFilter; Bitmap texture; public Texture(String texturePath, Context context, GL10 gl) { this.gl = gl; this.texturePath = texturePath; this.context = context; } public void load() { try{ AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open(texturePath); texture = BitmapFactory.decodeStream(is); gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0); setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); }catch(Exception e) { e.printStackTrace(); } } public void reload() { load(); bind(); setFilters(minFilter, magFilter); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); } public void setFilters(int minFilter, int magFilter) { this.minFilter = minFilter; this.magFilter = magFilter; gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilter); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, magFilter); } public void bind() { gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); } public void dispose() { gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); int[] textureIds = {textureId}; gl.glDeleteTextures(1, textureIds, 0); } } OpenGLRenderer.java package com.chrypthic.android.reference; import java.util.Random; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLSurfaceView.Renderer; public class OpenGLRenderer implements Renderer { Random rand = new Random(); int mWidth = 0; int mHeight = 0; Context c; Square square; public OpenGLRenderer(Context c) { this.c = c; } #Override public void onDrawFrame(GL10 gl) { gl.glClearColor(1, 1, 1, 1); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glViewport(0, 0, mWidth, mHeight); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0, mWidth, 0, mHeight, -1, 1); if(square != null)square.draw(); } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { mWidth = width; mHeight = height; } #Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { square = new Square(gl, c); } } I hope you can help me, if you need even more information just tell me. Thanks in advance. I did't post the white screen as a screenshot, because it seems kind of pointless with the white background that stackoverflow have.
You never create the texture! public void load() { try{ int []texture = new int[1]; gl.glGenTextures(1, texture,0);//the missing method textureId = texture[0]; //now you can call AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open(texturePath); texture = BitmapFactory.decodeStream(is); gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);/*this fails if textureId is a 'random' number. You must/should generate a valid id. */ GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0); setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); It is exactly the opposite of your dispose() method.
Going from a comment to an answer. (Comment): Why are you using glVertexPointer twice rather that glVertexPointer and then glTexCoordPointer? Also there seems to be a typo in that line that says GL_FLAT instead of GL_FLOAT. Are you sure you're giving us your actual code? -Answer starts here- It looks like you aren't using texture coordinates at all. You have to specify which corner of the texture you'd like to assign to which corner of the triangle/quad. For example, I see that you've got a "tl" comment next to the top left vertex. You similarly need to supply a texture coordinate that says "use the top left corner of the image with this vertex" and then OpenGL figures out the rest. Then when you go to pass the vertex pointer, you also have to pass a texture coordinate pointer that contains those texture coordinates I were just talking about in the previous paragraph. You do this with glTexCoordPointer in the exact same fashion as glVertexPointer. You can also load texture coordinates into a VBO (in fact, into the same VBO as the vertices, then you can call glTexCoordPointer with the offset into the VBO to where the tex coords start). Let me know (via comment) if you need more elaboration/code examples or more explanation anywhere. Edit 1: See these links for information about texture mapping: gamedev, nehe Edit 2: Okay, stupid me. I didn't notice that you've actually got the texture coordinate data in with the vertex data. Try changing your second call to glVertexPointer to glTexCoordPointer. This might fix your problem entirely.