开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜