2D rendering with VBO in lwjgl won't draw - java
I'm working on a 2D game in LWJGL. I have successfully rendered QUADS with textures using glBegin but moving to VBOs turned out to be a big undertaking. At the moment I can switch between the vbo and non-vbo rendering with a boolean, both using the same vertex- and texture coordinates. The VBO-implementation won't draw anything onto the screen. Can anyone point me in the right direction?
This is my initialization:
public void init() {
VBOID = VBOHandler.createVBOID();
TBOID = VBOHandler.createVBOID();
float[] vdata = {0, 0,
width, 0,
width, height,
0, height};
float[] tdata = {sx, sy,
ex, sy,
ex, ey,
sx, ey};
//Texture coordinates: (0,0)(1,0)(1,1) and (0,1)
FloatBuffer fb = BufferUtils.createFloatBuffer(8);
fb.put(vdata);
VBOHandler.bufferData(VBOID, fb);
fb = BufferUtils.createFloatBuffer(8);
fb.put(tdata);
VBOHandler.bufferData(TBOID, fb);
}
And here is my rendering code:
private void render() {
texture.bind();
if(vbo) {
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
VBOHandler.bindBuffer(VBOID);
GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
VBOHandler.bindBuffer(TBOID);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
VBOHandler.bindElementBuffer(VBOHandler.getDefaultIBOID());
// I figured why not use a standard IBO for all my sprite drawing
// The default IBO ID is initialized earlier in the program, not shown in this code
GL12.glDrawRangeElements(GL11.GL_TRIANGLE_FAN, 0, 3, 4, GL11.GL_UNSIGNED_SHORT, 0);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
} else {
GL11.glBegin(GL11.GL_TRIANGLE_FAN);
GL11.glTexCoord2f(sx, sy);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(ex, sy);
GL11.glVertex2f(width,0);
GL11.glTexCoord2f(ex, ey);
GL11.glVertex2f(width, height);
GL11.glTexCoord2f(sx, ey);
GL11.glVertex2f(0, height);
GL11.glEnd();
}
}
And the VBOHandler class, for those interested
public class VBOHandler {
private static int IBOID;
public static void initDefaultIBO() {
IBOID = createVBOID();
short[] indexdata = {0, 1, 2, 3};
ShortBuffer shortBuffer = BufferUtils.createShortBuffer(4);
shortBuffer.put(indexdata);
VBOHandler.bufferElementData(IBOID, shortBuffer);
}
public static int getDefaultIBOID() {
return IBOID;
}
public static int createVBOID() {
if(GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
return ARBVertexBufferObject.glGenBuffersARB();
}
return 0;
}
public static void bufferData(int id, FloatBuffer buffer) {
if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
}
public static void bufferElementData(int id, ShortBuffer buffer) {
if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
}
public static void bindBuffer(int id) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
}
public static void bindElementBuffer(int id) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
}
}
The above render-function lies within my Sprite class. It is called by my GameView every frame as so:
public void renderGame() {
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
sprite.render();
}
The GameView is initialized with the following code:
Display.setDisplayMode(new DisplayMode(1024, 768));
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glEnable(GL11.GL_BLEND); // enable alpha blending
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(x - width/2, x + width/2, y + height / 2, y - height / 2, -1, 1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
You did not call 'flip' on the FloatBuffers before passing them to OpenGL. You need to call 'flip()' on FloatBuffers before you pass them to OpenGL, or it will not be able to read them. It is worth noting that you cannot read the FloatBuffers after you call 'flip()' yourself.
Related
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);
VBO with textures, without deprecated functions
I am trying to write a basic Quad-renderer, using VBO, VAO, IBO and shaders. I am trying to use mainly only one VBO, VAO, IBO and rebuffer the data when an element is added/removed. Mostly everything worked fine, until I decided to implement textures, instead of color gradings. It just doesn't draw anyhting, no matter what I try, because I want to avoid using deprecated functions like ClientStates and maybe use the textures inside the shaders. Next to the problem, that nothing is being drawn, I have the problem that the Textures are saved inside the BRectangle class, and now I don't know, how to access them while using DrawElements. And can I reuse my IBO, so I don't have to add the additional indices? My current approach: The Renderer, you can add a Rectangle atm and it will buffer the needed data. public class ShaderRenderer { public static final int POSITION_INDEX = 0; // index of vertex attribute "in_Position" public static final int TEXTURE_INDEX = 1; // index of vertex attribute "in_Texture" public static final int FLOAT_NUM_BYTES; // sizeof(float) in bytes public static final int INT_NUM_BYTES; // sizeof(int) in bytes public static final int VEC4_BYTES; // sizeof(vec4) in bytes static { FLOAT_NUM_BYTES = Float.SIZE / Byte.SIZE; INT_NUM_BYTES = Integer.SIZE / Byte.SIZE; VEC4_BYTES = 4 * FLOAT_NUM_BYTES; } private VAO vao = new VAO(); private VBO vbo = new VBO(); private IBO ibo = new IBO(); private int elements = 0; public ShaderRenderer() { try { ShaderUtilities.compileShader("shaders/screen.vert", "shaders/screen.frag", POSITION_INDEX, TEXTURE_INDEX); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void add( BRectangle rect ) { // Bind the VAO // This OpenGL-object groups the "in_Position" and "in_Color" // vertex attributes. vao.bind(); // Bind the VBO and add the FloatBuffer from the Rect vbo.bind(); vbo.addBuffer(rect.vertexData); ibo.bind(); ibo.addIndices(generateIndices()); ibo.buffer(); //============================================================== // Now we tell OpenGL that we will use POSITION_INDEX and COLOR_INDEX // to communicate respectively the vertex positions and vertex colors // to our shaders. { // First we enable the indices. This will affect the vertex // array object from above. glEnableVertexAttribArray(POSITION_INDEX); Util.checkGLError(); // Then we tell OpenGL how it should read the GL_ARRAY_BUFFER // (to which we have bound our vertex data, see above). // The position data starts at the beginning of the vertex data glVertexAttribPointer(POSITION_INDEX, 4, GL_FLOAT, false, 2 * VEC4_BYTES, 0); Util.checkGLError(); // The color data starts after the first 4 floats of position data glVertexAttribPointer(TEXTURE_INDEX, 2, GL_FLOAT, false, 0, VEC4_BYTES); Util.checkGLError(); } vbo.bufferData(); // Just to be VERY clean, we will unbind the vertex attribute object // and only bind it when we render. This way we cannot accidentally modify // it anymore. vao.unbind(); // Only after the vertex array is disabled, we unbind the buffers // to the GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER targets, because // otherwise the vertex array object would become invalid again. vbo.unbind(); ibo.unbind(); } void DestroyVBO() { glDisableVertexAttribArray(POSITION_INDEX); Util.checkGLError(); glDisableVertexAttribArray(TEXTURE_INDEX); Util.checkGLError(); glBindBuffer(GL_ARRAY_BUFFER, 0); Util.checkGLError(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); Util.checkGLError(); glDeleteBuffers(ibo.id); Util.checkGLError(); glDeleteBuffers(vbo.id); Util.checkGLError(); glBindVertexArray(0); Util.checkGLError(); glDeleteVertexArrays(vao.id); Util.checkGLError(); } private int[] generateIndices() { int c = elements * 3; int v[] = { c, c+1, c+2, c, c+3, c+2}; elements++; return v; } public void render () { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Util.checkGLError(); vao.bind(); glDrawElements( GL_TRIANGLES, ibo.size, GL_UNSIGNED_INT, 0); Util.checkGLError(); vao.unbind(); } } My basic Rectangle class public class BRectangle { final int amountOfVertices = 8; final int vertexSize = 3; final int textureSize = 2; public FloatBuffer vertexData; Texture texture; public BRectangle(float x, float y ) { float[] VerticesArray = new float[]{ -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.1f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, -0.1f, 0.4f, 0.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.4f, 0.0f, 1.0f, 0.0f, 1.0f }; vertexData = BufferUtils.createFloatBuffer(24); vertexData.put(VerticesArray); try { texture = Textures.loadTexture("data/floor.jpg"); } catch (IOException e) { e.printStackTrace(); } glBindTexture(GL_TEXTURE_2D, texture.getTextureID()); } } The test with main[] public class ShaderTest { ShaderRenderer sr; FpsCounter c; public ShaderTest() { } public void create() throws LWJGLException, Exception { new SimpleDisplay(800, 600, "test", false, false); glOrtho(0, 800, 0, 600, 1, -1); //Keyboard Keyboard.create(); c = new FpsCounter(); Textures.setUpTextureLoader(); //Mouse Mouse.setGrabbed(false); Mouse.create(); sr = new ShaderRenderer(); //OpenGL initGL(); } public void destroy() { Mouse.destroy(); Keyboard.destroy(); Display.destroy(); } public void initGL() throws IOException { ShaderUtilities.compileShader("shaders/screen.vert", "shaders/screen.frag", ShaderRenderer.POSITION_INDEX, ShaderRenderer.TEXTURE_INDEX); sr.add(new BRectangle(0f, 0f)); } public void processKeyboard() { } public void processMouse() { } public void render() throws LWJGLException { sr.render(); } public void run() throws LWJGLException { while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { if (Display.isVisible()) { processKeyboard(); processMouse(); update(); render(); } else { if (Display.isDirty()) { render(); } try { Thread.sleep(100); } catch (InterruptedException ex) { } } Display.update(); //Display.sync(60); } } public void update() { c.updateFPS(); } public static void main(String[] args) { ShaderTest main = null; try { main = new ShaderTest(); main.create(); main.run(); } catch (Exception ex) { ex.printStackTrace(); } finally { if (main != null) { main.destroy(); } } } } and the openglinit public static void initGLSlim() { glClearColor(0, 0, 0, 0); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glEnable(GL11.GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, 800, 600, 0, 1, -1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } vertex shader #version 140 in vec4 in_Position; in vec2 in_Texture; out vec2 out_Texture; void main(void) { gl_Position = vec4(in_Position.x *0.75 ,in_Position.y, in_Position.z, in_Position.w); out_Texture = in_Texture; } fragment shader #version 140 in vec2 out_Texture; uniform sampler2D mytexture; out vec4 fragColor; void main(void) { fragColor = texture2D(mytexture, out_Texture); }
Your stride parameters are not correct. Here's what you have: glVertexAttribPointer(POSITION_INDEX, 4, GL_FLOAT, false, 2 * VEC4_BYTES, 0); glVertexAttribPointer(TEXTURE_INDEX, 2, GL_FLOAT, false, 0, VEC4_BYTES); You're telling the position index that it has 8 float stride, which is not correct. As far as I can tell you're uploading 4 vertices, with 6 floats per vertex (4x position + 2x texture). That means your POSITION stride should be 6 * FLOAT_NUM_BYTES. Your texture stride should be the same, as it's packed into the same array. Here you're telling it that the texcoords are tightly packed, but in reality theres only one pair of texcoords per 6 floats. So again you need 6 * FLOAT_NUM_BYTES here. And can I reuse my IBO, so I don't have to add the additional indices? Yes, you can use an IBO to draw as many objects as you want, provided that they all want the same indices. Other less serious comments: You don't need to clearColor to zero in initialization, it's zero by default. You don't need to disable depth_test/lighting in initialization, they are off by default. Don't call glEnable(GL_TEXTURE_2D) when you're using shaders. This switch only enables texturing for the fixed pipeline, and it has no effect on shader programs. This will generate an error if you ever move to a core profile, so just get rid of it.
openGL texturing is running on emulator but not on real device
I'm trying to show textures by openGL. In following code I want to draw simple square with texture. When I run it on android emulator, everything is OK, but when I run it on real device, I can see only white square without any texture. There is similar problem, but I don't use NDK. I use only Java. public class MainActivity extends Activity { public static TextView t; #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout l = new LinearLayout(this); t = new TextView(this); l.addView(t); l.setOrientation(1); l.addView(new ImageView(this)); setContentView(l); } long last = System.currentTimeMillis(); int FPS = 0; //Show FPS(+ some extraData) public void FPS(final String extraData) { if(System.currentTimeMillis()<last+1000) { FPS++; } else { runOnUiThread(new Runnable(){#Override public void run(){ t.setText((double)FPS/(((double)System.currentTimeMillis()-last)/1000)+";"+extraData); }}); FPS = 0; last = System.currentTimeMillis(); } } public class ImageView extends GLSurfaceView implements GLSurfaceView.Renderer { MainActivity thiz; public ImageView(MainActivity thiz) { super(thiz); this.thiz = thiz; setRenderer(this); } FloatBuffer vertex; ShortBuffer texture; int[] textureID = new int[1]; public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertex); gl.glTexCoordPointer(2, GL10.GL_SHORT, 0, texture); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); thiz.FPS(""); } public void onSurfaceCreated(GL10 gl, EGLConfig arg1) { vertex = FloatBuffer.wrap(new float[]{-0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f}); texture = ShortBuffer.wrap(new short[]{0, 1, 1, 1, 0, 0, 1, 0}); Bitmap b = BitmapFactory.decodeResource(thiz.getResources(), R.drawable.nex2); gl.glGenTextures(1, textureID, 0); gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID[0]); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, b, 0); b.recycle(); gl.glClearColor(0.1f, 0.5f, 1f, 1f); gl.glEnable(GL10.GL_TEXTURE_2D); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); } public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); } Can someone look at my code and tell me where is the problem?
Do you remember to set the minification filter to not use mipmaps? I'm kind of surprised this would work on the emulator if you didn't, but maybe it allows it for some reason. E.g. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); http://www.opengl.org/wiki/Common_Mistakes#Creating_a_Texture
The emulator does NOT run OpenGL ES afaik, it runs off of the desktop driver. Meaning it can support textures are not 2^n, where your phone only supports textures that are 2^n(aka square). I would check this, it is most likely your issue if you are getting no errors. Grab a 2^n image and see if it works for you.
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.
Java OpenGL Vertex Buffer Objects not working
I tried to implement Open GLs Vertex Buffer Objects the first time, and all i get is a black screen. I tried it with glOrtho instead of glPerspective, but it didnt work as well. thanks for helping Heres my code: public class VBufferTest { public static final int WIN_WIDTH = 640; public static final int WIN_HEIGHT = 480; public int vBufferId; public static void main(String args[]){ VBufferTest foo = new VBufferTest(); foo.initLWJGLFrame(); foo.initBuffer(); while (!Display.isCloseRequested()){ foo.render(); } } public void initLWJGLFrame(){ try { DisplayMode[] possible = Display.getAvailableDisplayModes(); DisplayMode chosen = null; for (int i = 0; i < possible.length; i += 1){ if (possible[i].getWidth() == WIN_WIDTH && possible[i].getHeight() == WIN_HEIGHT){ chosen = possible[i]; break; } } if (chosen != null){ Display.setDisplayMode(chosen); Display.setTitle("TestFrame1"); Display.create(); } else { throw new LWJGLException("Couldn't find the appropriate display mode."); } } catch (LWJGLException e){ } } public void initGL(){ GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY); GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY); GL11.glClearColor(104.f/255.0f, 136.0f/255.0f, 252.0f/255.0f, 1.0f); GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); GLU.gluPerspective(50.0f, Display.getDisplayMode().getWidth()/Display.getDisplayMode().getHeight(), 0.5f, 1000.0f); GL11.glViewport(0, 0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight()); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glLoadIdentity(); } public void initBuffer(){ FloatBuffer vertices = BufferUtils.createFloatBuffer(4*3); vBufferId = genNewId(); vertices.put(new float[]{-1.0f, -1.0f, 0.0f}); vertices.put(new float[]{1.0f, -1.0f, 0.0f}); vertices.put(new float[]{1.0f, 1.0f, 0.0f}); vertices.put(new float[]{-1.0f, 1.0f, 0.0f}); vertices.flip(); bufferData(vBufferId, vertices); } public void render(){ GL11.glColor3f(1.0f, 0.0f, 1.0f); ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.vBufferId); GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0); GL11.glDrawArrays(GL11.GL_QUADS, 0, 4); Display.update(); } public static int genNewId(){ IntBuffer buffer = BufferUtils.createIntBuffer(1); ARBVertexBufferObject.glGenBuffersARB(buffer); return buffer.get(0); } public static void bufferData(int id, FloatBuffer buffer){ ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id); ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB); } }
You have depth-testing enabled, but you don't clear the z-buffer once per frame using glClear (at the beginning of your render method). Same for clearing the color buffer. EDIT: Also, initGl() seems to be never called?