OpenGL ES texture won't draw - java
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.
Related
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(); }
GLSurfaceView working on Android < 4.2 but Black Screen on > 4.2
Following code works perfectly on older Android versions, but only shows a black screen on newer versions (I guess 4.2 and higher). Im very new to OpenGL and I used to work with Canvas/SurfaceView, but now I need GLSurfaceView for the performance, so I leeched some code from here and there without exactly knowing what it does. I didnt start a whole new project, I just rewrote some of my "Canvas-Code" to a GLSurfaceView loop. Thats why it might look strange and inefficient. Explanation for the code: The class "Sprite" contains a Bitmap, xPos and yPos. In "defineStuff();" I append a few different "Sprites" to a List and the GLSurfaceView draws everything from the List. This is not the whole code, I removed pretty much to make it more clear. #Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //so its Fullscreen defineStuff(); glSurfaceView = new GLSurfaceView(this); glSurfaceView.setRenderer(new GlRenderer()); glSurfaceView.setOnTouchListener(this); setContentView(glSurfaceView); } The Sprite class: public class Sprite { private FloatBuffer vertexBuffer; // buffer holding the vertices private FloatBuffer textureBuffer; // buffer holding the texture coordinates private float texture[]; private float vertices[]; public Bitmap bmp; public boolean visible; public String name; public float posX; public float posY; public Sprite(String name, Bitmap bitmap, float posX, float posY, boolean visible) { this.name = name; this.visible = visible; setBuffers(bitmap, posX, posY); } public void setBuffers(Bitmap bitmap, float posX, float posY) { bmp = bitmap; } this.posX = posX; this.posY = posY; float tempVertices[] = { posX, posY + bitmap.getHeight(), 0.0f, // V1 - bottom left posX, posY, 0.0f, // V2 - top left posX + bitmap.getWidth(), posY + bitmap.getHeight(), 0.0f, // V3 - bottom right posX + bitmap.getWidth(), posY, 0.0f // V4 - top right }; vertices = new float[tempVertices.length]; System.arraycopy(tempVertices, 0, vertices, 0, tempVertices.length); // a float has 4 bytes so we allocate for each coordinate 4 bytes ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4); byteBuffer.order(ByteOrder.nativeOrder()); // allocates the memory from the byte buffer vertexBuffer = byteBuffer.asFloatBuffer(); // fill the vertexBuffer with the vertices vertexBuffer.put(vertices); // set the cursor position to the beginning of the buffer vertexBuffer.position(0); float tempTexture[] = { // Mapping coordinates for the vertices 0.0f, 1.0f, // top left (V2) 0.0f, 0.0f, // bottom left (V1) 1.0f, 1.0f, // top right (V4) 1.0f, 0.0f // bottom right (V3) }; texture = new float[tempTexture.length]; System.arraycopy(tempTexture, 0, texture, 0, tempTexture.length); byteBuffer = ByteBuffer.allocateDirect(texture.length * 4); byteBuffer.order(ByteOrder.nativeOrder()); textureBuffer = byteBuffer.asFloatBuffer(); textureBuffer.put(texture); textureBuffer.position(0); } /** The texture pointer */ private int[] textures = new int[1]; public void loadGLTexture(GL10 gl) { // every Sprite has to be loaded before being drawn // generate one texture pointer gl.glGenTextures(1, textures, 0); // ...and bind it to our array gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); // create nearest filtered texture 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); // Use Android GLUtils to specify a two-dimensional texture image from our bitmap GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0); } public void draw(GL10 gl, float interpolation) { gl.glPushMatrix(); gl.glTranslatef (speedInX * interpolation, speedInY * interpolation, 0f); // bind the previously generated texture gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); // Point to our buffers gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Set the face rotation gl.glFrontFace(GL10.GL_CW); // Point to our vertex buffer gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); // Draw the vertices as triangle strip gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3); //Disable the client state before leaving gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glPopMatrix(); } } My renderer: public class GlRenderer implements Renderer { #Override public void onDrawFrame(GL10 gl) { // clear Screen and Depth Buffer gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // Reset the Modelview Matrix gl.glLoadIdentity(); // Drawing gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen // is the same as moving the camera 5 units away updateLogic(gl); //there was very much code around this but I removed it to make it more clear float interpolation = (float) (SystemClock.uptimeMillis() + SKIP_TICKS - nextGameTick) / SKIP_TICKS; spriteList.toFirst(); while (spriteList.getObject() != null) { ((Sprite) spriteList.getObject()).draw(gl, interpolation); spriteList.next(); } } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); // or some matrix uniform if using shaders gl.glLoadIdentity(); gl.glOrthof(0, width, height, 0, -1, 1); // this will allow to pass vertices in 'canvas pixel' coordinates gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } #Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glDisable(GL10.GL_DITHER); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW ) gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Set Background gl.glClearDepthf(1.0f); //Depth Buffer Setup gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do gl.glEnable(GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); // So alpha works, but it still doesnt work everytime :) spriteList.toFirst(); while (spriteList.getObject() != null) { ((Sprite) spriteList.getObject()).loadGLTexture(gl); spriteList.next(); } } }
brecause you have gl.glOrthof(0,width,height,0,-1,1); your code doesnt require depth testing, try getting rid of | GL10.GL_DEPTH_BUFFER_BIT gl.glClearDepthf(1.0f); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glTranslatef(0.0f, 0.0f, -5.0f);
lwjgl glDrawArrays gives Invalid operation error
When learning how to use OpenGL 3.2 through lwjgl, i followed the tutorial at here. I keep getting invalid operation error on the method call glDrawArrays. This error even occurs if I copy the source code from the tutorial. My operating system is Mac OS X 10.8.3 and after a quick search do not turn up anything. My Code(Adapted code from tutorial): render method: public void render() { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); // Bind to the VAO that has all the information about the quad vertices GL30.glBindVertexArray(vaoId); GL20.glEnableVertexAttribArray(0); this.exitOnGLError("Error before DrawArrays"); // Draw the vertices GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCount); this.exitOnGLError("Error in DrawArrays"); // Put everything back to default (deselect) GL20.glDisableVertexAttribArray(0); GL30.glBindVertexArray(0); this.exitOnGLError("Error in render"); } Rest of code: import java.nio.FloatBuffer; import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.ContextAttribs; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.PixelFormat; import org.lwjgl.util.glu.GLU; public class TestOpenGL { // Entry point for the application public static void main(String[] args) { new TestOpenGL(); } // Setup variables private final String WINDOW_TITLE = "The Quad: glDrawArrays"; private final int WIDTH = 320; private final int HEIGHT = 240; // Quad variables private int vaoId = 0; private int vboId = 0; private int vertexCount = 0; public TestOpenGL() { // Initialize OpenGL (Display) this.setupOpenGL(); this.setupQuad(); while (!Display.isCloseRequested()) { // Do a single loop (logic/render) render(); // Force a maximum FPS of about 60 Display.sync(60); // Let the CPU synchronize with the GPU if GPU is tagging behind Display.update(); } // Destroy OpenGL (Display) this.destroyOpenGL(); } public void setupOpenGL() { // Setup an OpenGL context with API version 3.2 try { PixelFormat pixelFormat = new PixelFormat(); ContextAttribs contextAtrributes = new ContextAttribs(3, 2) .withForwardCompatible(true) .withProfileCore(true); Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); Display.setTitle(WINDOW_TITLE); Display.create(pixelFormat, contextAtrributes); System.out.println(GL11.glGetString(GL11.GL_VERSION)); GL11.glViewport(0, 0, WIDTH, HEIGHT); } catch (LWJGLException e) { e.printStackTrace(); System.exit(-1); } // Setup an XNA like background color GL11.glClearColor(0.4f, 0.6f, 0.9f, 0f); // Map the internal OpenGL coordinate system to the entire screen GL11.glViewport(0, 0, WIDTH, HEIGHT); this.exitOnGLError("Error in setupOpenGL"); } public void setupQuad() { // OpenGL expects vertices to be defined counter clockwise by default float[] vertices = { // Left bottom triangle -0.5f, 0.5f, 0f, -0.5f, -0.5f, 0f, 0.5f, -0.5f, 0f, // Right top triangle 0.5f, -0.5f, 0f, 0.5f, 0.5f, 0f, -0.5f, 0.5f, 0f }; // Sending data to OpenGL requires the usage of (flipped) byte buffers FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length); verticesBuffer.put(vertices); verticesBuffer.flip(); vertexCount = 6; // Create a new Vertex Array Object in memory and select it (bind) // A VAO can have up to 16 attributes (VBO's) assigned to it by default vaoId = GL30.glGenVertexArrays(); GL30.glBindVertexArray(vaoId); // Create a new Vertex Buffer Object in memory and select it (bind) // A VBO is a collection of Vectors which in this case resemble the location of each vertex. vboId = GL15.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW); // Put the VBO in the attributes list at index 0 GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0); // Deselect (bind to 0) the VBO GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); // Deselect (bind to 0) the VAO GL30.glBindVertexArray(0); this.exitOnGLError("Error in setupQuad"); } public void destroyOpenGL() { // Disable the VBO index from the VAO attributes list GL20.glDisableVertexAttribArray(0); // Delete the VBO GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); GL15.glDeleteBuffers(vboId); // Delete the VAO GL30.glBindVertexArray(0); GL30.glDeleteVertexArrays(vaoId); Display.destroy(); } public void exitOnGLError(String errorMessage) { int errorValue = GL11.glGetError(); if (errorValue != GL11.GL_NO_ERROR) { String errorString = GLU.gluErrorString(errorValue); System.err.println("ERROR - " + errorMessage + ": " + errorString); if (Display.isCreated()) Display.destroy(); System.exit(-1); } } } The output is 3.2 INTEL-8.10.44 ERROR - Error in DrawArrays: Invalid operation
You're code appears not be to using shaders entirely. As you are requesting a forward compatible OpenGL context there is no support for the fixed function pipeline therefor shaders are neccessary. You will have to either use shaders to proccess your vertices or use a compatibility context in order to have OpenGl do you vertex and fragment processing.
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 : Using Texture: Blank White instead of Texture Image
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 ??!!