2013-08-25 3 views
2

Хорошо, прежде всего, я полностью согласен с тем, что учебники «TheNewBoston» очень ... неправильны временами. Однако это то, что я следовал, чтобы попытаться сделать куб в OpenGL на Android.Почему это не делает красивый квадрат?

В любом случае, я не могу сказать, что нашел отличный материал на OpenGL, если честно. Я прочитал OpenGL Superbible ... все было нормально.

Так вот код, который у меня есть.

GLRenderer.java

package android.gem.opengltest; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.opengl.GLU; 
import android.opengl.GLSurfaceView.Renderer; 
import android.os.SystemClock; 

public class GLRenderer implements Renderer { 

    private GLCube cube; 

    public GLRenderer() { 
     cube = new GLCube(); 
    } 

    @Override 
    public void onDrawFrame(GL10 gl) { 
     // TODO Auto-generated method stub 
     gl.glDisable(GL10.GL_DITHER); 
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT); 

     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
     GLU.gluLookAt(gl, 0, 0, -5, 0, 0, 0, 0, 2, 0); 

     long time = SystemClock.uptimeMillis() % 4000L; 
     float angle = .09f * ((int) time); 

     gl.glRotatef(angle, 1, 1.5f, 2); 

     cube.draw(gl); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     // TODO Auto-generated method stub 
     float ratio = (float) width/height; 

     gl.glViewport(0, 0, width, height); 
     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     gl.glFrustumf(-ratio, ratio, -1, 1, 1, 25); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) { 
     // TODO Auto-generated method stub 

     // START OF PERFORMANCE // 
     gl.glDisable(GL10.GL_DITHER); 
     gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); 
     // END OF PERFORMANCE // 

     gl.glClearColor(.8f, 0, .2f, 1f); // Red, Green, Blue, Alpha (0 - 1) 
     gl.glClearDepthf(1f); 
    } 

}

GLCube.java

package android.gem.opengltest; 

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import java.nio.ShortBuffer; 

import javax.microedition.khronos.opengles.GL10; 

public class GLCube { 

    private float verticies[] = { 
      1, 1, -1, // point 0 - topFrontRight 
      1, -1, -1, // point 1 - bottomFrontRight 
      -1, -1, -1, // point 2 - bottomFrontLeft 
      -1, 1, -1, // point 3 - frontTopLeft 
      1, 1, 1, // point 4 - topBackRight 
      1, -1, 1, // point 5 - bottomBackRight 
      -1, -1, 1, // point 6 - bottomBackLeft 
      -1, 1, 1 // point 7 - frontBackLeft 
    }; 

    private float rgbaValues[] = { 
      1, 1, 0, 1, 
      .25f, 0, .85f, 1, 
      0, 1, 1, 1, 
      1, 1, 0, 1, 
      .25f, 0, .85f, 1, 
      0, 1, 1, 1, 
      .5f, .5f, .2f, 1, 
      .3f, .3f, .3f, 1 
    }; 

    private FloatBuffer vertBuff, colorBuff; 

    private short[] pIndex = { // Indicies 
      3, 4, 0, 0, 4, 1, 3, 0, 1, 
      3, 7, 4, 7, 6, 4, 7, 3, 6, 
      3, 1, 2, 1, 6, 2, 6, 3, 2, 
      1, 4, 5, 5, 6, 1, 6, 5, 4 
    }; 

    private ShortBuffer pBuffer; 

    public GLCube() { 
     ByteBuffer bBuff = ByteBuffer.allocateDirect(this.verticies.length * 4); 
     bBuff.order(ByteOrder.nativeOrder()); 
     vertBuff = bBuff.asFloatBuffer(); 
     vertBuff.put(this.verticies); 
     vertBuff.position(0); 

     ByteBuffer pbBuff = ByteBuffer.allocateDirect(this.pIndex.length * 2); 
     pbBuff.order(ByteOrder.nativeOrder()); 
     pBuffer = pbBuff.asShortBuffer(); 
     pBuffer.put(pIndex); 
     pBuffer.position(0); 

     ByteBuffer cBuff = ByteBuffer.allocateDirect(this.rgbaValues.length * 4); 
     cBuff.order(ByteOrder.nativeOrder()); 
     colorBuff = cBuff.asFloatBuffer(); 
     colorBuff.put(rgbaValues); 
     colorBuff.position(0); 
    } 

    public void draw(GL10 gl) { 
     gl.glFrontFace(GL10.GL_CW); // Clock Wise 
     gl.glEnable(GL10.GL_CULL_FACE); // Removes back end of cube 
     gl.glCullFace(GL10.GL_BACK); 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 

     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, this.vertBuff); 
     gl.glColorPointer(4, GL10.GL_FLOAT, 0, this.colorBuff); 
     gl.glDrawElements(GL10.GL_TRIANGLES, this.pIndex.length, GL10.GL_UNSIGNED_SHORT, this.pBuffer); 

     gl.glDisableClientState(GL10.GL_COLOR_ARRAY); 
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glDisable(GL10.GL_CULL_FACE); 
    } 

} 

Я получаю куб, который выглядит следующим образом ...

enter image description here

Что я делаю неправильно? Что делать, чтобы он выглядел как настоящий куб?

Кроме того, если он помогает весь мой код по следующему адресу: https://github.com/gemurdock/OpenGlTest/tree/alpha.0.1.0

ответ

2

Прежде всего, это (ужасно деформированной) куб, не квадрат. Если вы не посмотрите на него лицом к лицу, он никогда не будет выглядеть как «хороший квадрат» :)

Выбрав полигональную грань, кажется, отбраковывает неправильную сторону ваших поверхностей куба. Он по-прежнему выглядит как куб, просто куб изнутри.

Это, скорее всего, потому, что вы переопределили направление обмотки OpenGL по умолчанию (GL_CCW).

+0

Плохо, я имею тенденцию менять квадрат и куб. - Кроме того, вы были совершенно правы. Огромное спасибо. Просто интересно ... почему это имеет значение, если вы идете CCW или CW? Было бы достаточно исследовать Google на «Culling», чтобы учиться? – Zeveso

+1

CCW и CW - это схема, которую OpenGL использует для идентификации передней и задней части лица. Обычно лица не имеют фронтов или спинок, они всего лишь заполненная коллекция очков. Есть несколько способов идентифицировать фронт и спину, можно было бы использовать вектор, который является нормальным к поверхности, а другой - просто определить, в каком направлении наматываются вершины. GL выбирает позже для простоты и скорости. Многие двигатели предварительно обрабатывают треугольники на процессоре, прежде чем отправлять их в OpenGL, используя обычный треугольник и точечный продукт для раннего отбраковки; поэтому они не являются взаимоисключающими. –

+1

Это может быть интересно прочитать, если вам все еще интересно, как это работает: http://www.sumantaguha.com/files/materials/chapter9.pdf –

Смежные вопросы