Android OpenGL ES... Why does the tutorial always render correctly, while my version randomly does not?
I'm following the tutorial set found at insanitydesign.com, which is an Android port of the NeHe tutorials on OpenGL. I'm having a lot of problems understanding why the tutorial version appears to render correctly at all times while my modified version randomly renders completely incorrectly. Occasionally, the problem is evident immediately when the program loads, but sometimes I have to rotate the screen before it appears. You can download a zip file containing screengrabs where I've rotated the screen 12 times from filedropper. As you can see, the triangle usually renders but on occasion appears completely distorted and smudged. Here is a link to my entire Eclipse project if you're curious.
I suspect the problem is in my Shape.draw() method, but I can't know for sure.
This is, I believe, the relevant code:
GLRenderer.java
private Shape shape;
public GLRenderer(){
Log.i(this.toString(),"ctor");
shape = Shape.makeTriangle();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
speedPerSecond = SystemClock.uptimeMillis();
Log.d(this.toString(), ".onSurfaceCreated");
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(1.0f, 0.0f, 0.0f, 0.5f);
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
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
shape.setX(0.0f);
shape.setY(0.0f);
shape.setZ(-6.0f);
shape.draw(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0){
height = 1;
}
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 50.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
Shape.java package com.smashing.test;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.util.Log;
public class Shape implements IGLShape {
public float getX(){
return x;
}
public float getY(){
return y;
}
public float getZ(){
return z;
}
public void setX(float pX){
x = pX;
}
public void setY(float pY){
y = pY;
}
public void setZ(float pZ){
z = pZ;
}
public static Shape makeTriangle(){
Shape s = new Shape();
/*
* Is this correct? I want to create a right triangle on screen like this
* |\
* | \
* | \
* | \
* |____\ though with a 90/45/45 degree spread rather than this poor representation.
*/
float v[] = {
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f
};
s.setVertices(v);
return s;
}
public static Shape makeShapeFromVertices(float pVerts[]){
Shape s = new Shape();
s.setVertices(pVerts);
return s;
}
private float x = 0.0f;
private float y = 0.0f;
private float z = 0.0f;
private float[] mVertices;
private FloatBuffer mVertexBuffer;
public void setVertices(float pVerts[]){
mVertices = pVerts;
ByteBuffer bb = ByteBuffer.allocateDirect(mVertices.length * 4);
bb.order(ByteOrder.nativeOrder());
mVertexBuffer = bb.asFloatBuffer();
mVertexBuffer.put(mVertices);
mVertexBuffer.position(0);
}
public float[] getVertices(){
return mVertices;
}
private Shape(){
}
@Override
public void draw(GL10 gl) {
/*
* I believe the problem is here... but I don't understand how or why?
*/
gl.glTranslatef(x, y, z);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVertices.length);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glTranslatef(-x, -y, -z);
}
}
EDIT: I am aware that the tutorial is a little different than my version. I'm attempting to extrapolate from it and experiment... I'm just completely surprised and astounded at the differences and would like to know why they exist, and how I can avoid such an unpleasant outcome as I've found with my rendering scheme.
you should replace
glDrawArrays(GL10.GL_TRIANGLE_STRIP, ...)
with
glDrawArrays(GL10.GL_TRIANGLES, ...)
I think that as you're drawing a simple triangle and not a quad, that is the cause of the trouble.
Regards
精彩评论