2011-12-18 17 views
9

Androidでは、頂点バッファオブジェクトを使用する単純なOpenGL ES 2.0アプリケーションを実行しようとしていますが失敗しました。GLES20を使用して、Android 2.3.3で頂点バッファオブジェクト(VBO)が動作しない

私はこのプロジェクトを開始しました:説明したよう

​​

すべてがうまく説明して動作します。ファイン。

glDrawArraysの代わりにglDrawElementsコマンドを使用してレンダリングを行うコードをいくつか追加しました。 私は成功しました。

次のステップ:同じことをするためにVertex Buffer Objectを使用したいと思います。

だから私はこの追加:

  1. 新しいVARS:

    民間のint [] mVBOid =新しいint型[2]。 // VBOとインデックスバッファに必要な2 ids private ShortBuffer mIndices; //インデックスは

  2. を使用VBOを作成するためのコードを追加:

    ByteBuffer vbb = ByteBuffer.allocateDirect(
          triangleCoords.length * SIZEOF_FLOAT); 
        vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order 
        mTriangleVB = vbb.asFloatBuffer(); // create a floating point buffer from the ByteBuffer 
        mTriangleVB.put(triangleCoords); // add the coordinates to the FloatBuffer 
        mTriangleVB.position(0);   // set the buffer to read the first coordinate 
    
        ByteBuffer ibb = ByteBuffer.allocateDirect(
          indices.length * SIZEOF_SHORT); 
        ibb.order(ByteOrder.nativeOrder()); // use the device hardware's native byte order 
        mIndices = ibb.asShortBuffer();  // create a short buffer from the ByteBuffer 
        mIndices.put(indices);    // add the indices to the Buffer 
        mIndices.position(0);    // set the buffer to read the first index 
    
        GLES20.glGenBuffers(2, mVBOid, 0); 
    
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVBOid[0]); 
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 
          numComponentsPerVertex * SIZEOF_FLOAT, 
          mTriangleVB, 
          GLES20.GL_STATIC_DRAW); 
    
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mVBOid[1]); 
        GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 
          mNumIndices * SIZEOF_SHORT, 
          mIndices, 
          GLES20.GL_STATIC_DRAW); 
    
  3. ジオメトリを描画するためのコードを追加:

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVBOid[0]); 
        GLES20.glVertexAttribPointer(maPositionHandle, nc, GLES20.GL_FLOAT, false, stride, 0); 
        GLES20.glEnableVertexAttribArray(maPositionHandle); 
    
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mVBOid[1]); 
        GLES20.glDrawElements(GLES20.GL_TRIANGLE_FAN, mNumIndices, GLES20.GL_UNSIGNED_SHORT, 0); 
    

注:に最初に実装された新しい機能としてVBOを使用せずにglDrawElementsを使用してジオメトリをレンダリングすると、mTriangleVBおよびmIndices変数が必要なデータで正しく埋められていることがわかります。 また、maPositionHandleとmuMVPMatrixHandleも正しいです。 私のコードでGLエラーをチェックします - 見つからないものがあります

私の問題:VBOテクニックは動作しません。透明な色を除いて、画面に何も表示されません。私は多くの問題を得るより複雑なアプリケーションで :正しくレンダリングされたVBOsを使用せずに

  • 他の形状は、目に見えないVBOベースのジオメトリが導入されたときに

  • セグメンテーションフォールトがoccasionaly報告されています。正確な原因を取得しようとすると、多くのコードがコメントアウトされ、ジオメトリがまったくレンダリングされない場合でもクラッシュが発生することがわかりました。 クラッシュの理由は、VBOの初期化でなければなりません。ただし、クラッシュはすぐには発生しませんが、後で発生します。
    しかし、私はまだそれが動作していない理由を把握することはできません。

    1. 私の環境:

    2. 2.3.3
      • Androidのビルドターゲット:アンドロイド2.3

      ここではいくつかのより多くの情報があります。3

    3. のAndroid SDKツール:
    4. のAndroid SDK Platformツール牧師15:牧師9
    5. デバイス:Huawei社IDEOS X3スマートフォン
  • SimpleOpenGLES20Rendererクラスの完全なソース。
    コードは、このサンプルに基づいている:
    http://developer.android.com/resources/tutorials/opengl/opengl-es20.html

  • package com.hugo.simplegles20; 
    
    import java.nio.ByteBuffer; 
    import java.nio.ByteOrder; 
    import java.nio.FloatBuffer; 
    import java.nio.ShortBuffer; 
    
    import javax.microedition.khronos.egl.EGLConfig; 
    import javax.microedition.khronos.opengles.GL10; 
    
    import android.opengl.GLES20; 
    import android.opengl.GLSurfaceView; 
    import android.opengl.Matrix; 
    import android.util.Log; 
    
    
    public class SimpleOpenGLES20Renderer implements GLSurfaceView.Renderer { 
    
        public float mAngle; 
    
        static String TAG = "SimpleTest"; 
    
        final int SIZEOF_FLOAT = Float.SIZE/8; 
        final int SIZEOF_SHORT = Short.SIZE/8; 
    
    
        private int[] mVBOid = new int[2];  // 2 ids needed for VBO and index buffer oject 
    
    
        enum TestType { 
         USE_ARRAY,   // (almost) the original code 
         USE_ELEMENTS,  // rendering, using glDrawElements call 
         USE_VBO_ELEMENTS // using a vertex buffer object (VBO) 
        } 
        private TestType mUsage = TestType.USE_VBO_ELEMENTS; 
    
    
        private boolean mFourComponents = true; 
    
        private int mNumIndices = 0; 
    
        private FloatBuffer mTriangleVB; 
        private ShortBuffer mIndices; 
        private final String vertexShaderCode = 
         // This matrix member variable provides a hook to manipulate 
         // the coordinates of the objects that use this vertex shader 
         "uniform mat4 uMVPMatrix; \n" + 
    
         "attribute vec4 vPosition; \n" + 
         "void main(){    \n" + 
    
         // the matrix must be included as a modifier of gl_Position 
         " gl_Position = uMVPMatrix * vPosition; \n" + 
    
         "} \n"; 
    
        private final String fragmentShaderCode = 
         "precision mediump float; \n" + 
         "void main(){    \n" + 
         " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n" + 
         "}       \n"; 
    
        private int mProgram; 
    
        private int maPositionHandle; 
    
        private int muMVPMatrixHandle; 
    
        private float[] mMVPMatrix = new float[16]; 
        private float[] mMMatrix = new float[16]; 
        private float[] mVMatrix = new float[16]; 
        private float[] mProjMatrix = new float[16]; 
    
        public static void checkGLError(String msg) { 
         int e = GLES20.glGetError(); 
         if (e != GLES20.GL_NO_ERROR) { 
          Log.d(TAG, "GLES20 ERROR: " + msg + " " + e); 
          Log.d(TAG, errString(e)); 
         } 
        } 
        public static String errString(int ec) { 
         switch (ec) { 
         case GLES20.GL_NO_ERROR: 
          return "No error has been recorded."; 
         case GLES20.GL_INVALID_ENUM: 
          return "An unacceptable value is specified for an enumerated argument."; 
         case GLES20.GL_INVALID_VALUE: 
          return "A numeric argument is out of range."; 
         case GLES20.GL_INVALID_OPERATION: 
          return "The specified operation is not allowed in the current state."; 
         case GLES20.GL_INVALID_FRAMEBUFFER_OPERATION: 
          return "The command is trying to render to or read from the framebuffer" + 
          " while the currently bound framebuffer is not framebuffer complete (i.e." + 
          " the return value from glCheckFramebufferStatus is not" + 
          " GL_FRAMEBUFFER_COMPLETE)."; 
         case GLES20.GL_OUT_OF_MEMORY: 
          return "There is not enough memory left to execute the command." + 
            " The state of the GL is undefined, except for the state" + 
            " of the error flags, after this error is recorded."; 
         default : 
          return "UNKNOW ERROR"; 
         } 
        } 
    
        @Override 
        public void onSurfaceCreated(GL10 uu, EGLConfig config) { 
         // Set the background frame color 
         GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
         checkGLError("onSurfaceCreated 1"); 
    
         initShapes(); 
    
         Log.d(TAG, "load vertex shader"); 
         int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
         Log.d(TAG, "load fragment shader"); 
         int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 
    
         mProgram = GLES20.glCreateProgram();    // create empty OpenGL Program 
         checkGLError("onSurfaceCreated 2"); 
         GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program 
         checkGLError("onSurfaceCreated 3"); 
         GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program 
         checkGLError("onSurfaceCreated 4"); 
         GLES20.glLinkProgram(mProgram);     // creates OpenGL program executables 
         checkGLError("onSurfaceCreated 5"); 
    
         // get handle to the vertex shader's vPosition member 
         maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 
         checkGLError("onSurfaceCreated 6"); 
         muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
         checkGLError("onSurfaceCreated 7"); 
        } 
    
        @Override 
        public void onSurfaceChanged(GL10 unused, int width, int height) { 
         GLES20.glViewport(0, 0, width, height); 
    
         float ratio = (float) width/height; 
    
         // this projection matrix is applied to object coordinates 
         // in the onDrawFrame() method 
         Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 
         Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 
        } 
        @Override 
        public void onDrawFrame(GL10 uu) { 
         GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
         checkGLError("onDrawFrame 1"); 
    
         // Add program to OpenGL environment 
         GLES20.glUseProgram(mProgram); 
         checkGLError("onDrawFrame 2"); 
    
         // Use the mAngle member as the rotation value 
         Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f); 
    
         // Apply a ModelView Projection transformation 
         Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); 
         Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); 
    
         GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); 
         checkGLError("onDrawFrame 3"); 
    
         int nc = mFourComponents ? 4 : 3; 
         int stride = nc * SIZEOF_FLOAT; 
    
         switch (mUsage) { 
         case USE_ARRAY: 
          // Prepare the triangle data 
          GLES20.glVertexAttribPointer(maPositionHandle, nc, GLES20.GL_FLOAT, false, stride, mTriangleVB); 
          checkGLError("onDrawFrame 4"); 
          GLES20.glEnableVertexAttribArray(maPositionHandle); 
          checkGLError("onDrawFrame 5"); 
    
          // Draw the triangle 
          GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, mNumIndices); 
          checkGLError("onDrawFrame 6"); 
          break; 
         case USE_ELEMENTS: 
          // Prepare the triangle data 
          GLES20.glVertexAttribPointer(maPositionHandle, nc, GLES20.GL_FLOAT, false, stride, mTriangleVB); 
          checkGLError("onDrawFrame 7"); 
          GLES20.glEnableVertexAttribArray(maPositionHandle); 
          checkGLError("onDrawFrame 8"); 
    
          // Draw the triangle 
          // int indicesSizeInBytes = SIZEOF_SHORT * mNumIndices; 
          GLES20.glDrawElements(GLES20.GL_TRIANGLE_FAN, mNumIndices, GLES20.GL_UNSIGNED_SHORT, mIndices); 
          checkGLError("onDrawFrame 9"); 
          break; 
         case USE_VBO_ELEMENTS: 
          GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVBOid[0]); 
          checkGLError("onDrawFrame 14"); 
          GLES20.glVertexAttribPointer(maPositionHandle, nc, GLES20.GL_FLOAT, false, stride, 0); 
          checkGLError("onDrawFrame 15"); 
          GLES20.glEnableVertexAttribArray(maPositionHandle); 
          checkGLError("onDrawFrame 16"); 
    
          GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mVBOid[1]); 
          checkGLError("onDrawFrame 17"); 
          GLES20.glDrawElements(GLES20.GL_TRIANGLE_FAN, mNumIndices, GLES20.GL_UNSIGNED_SHORT, 0); 
          checkGLError("onDrawFrame 18"); 
          break; 
         } 
        } 
    
        private void initShapes(){ 
    
         float triangleCoords3[] = { 
           // X, Y, Z 
           -0.5f, -0.5f, 0, 
           -0.5f, 0.5f, 0, 
           -0.2f, -0.2f, 0, 
           0.5f, -0.5f, 0 
          }; 
         float triangleCoords4[] = { 
           // X, Y, Z, W 
           -0.5f, -0.5f, 0, 1, 
           -0.5f, 0.5f, 0, 1, 
           -0.2f, -0.2f, 0, 1, 
           0.5f, -0.5f, 0, 1 
          }; 
    
         short[] indices = {0,1,2,3}; 
    
         float[] triangleCoords; 
    
         int numComponentsPerVertex; 
         if (mFourComponents) { 
          triangleCoords = triangleCoords4; 
          numComponentsPerVertex = 4; 
         } else { 
          triangleCoords = triangleCoords3; 
          numComponentsPerVertex = 3; 
         } 
    
         mNumIndices = triangleCoords.length/numComponentsPerVertex; 
    
         Log.d(TAG, "Components per Vertex: " + numComponentsPerVertex); 
         Log.d(TAG, "Number of Indices : " + mNumIndices); 
    
         switch (mUsage) { 
         case USE_ARRAY: 
         { 
          Log.d(TAG, "using array"); 
          // initialize vertex Buffer for triangle 
          ByteBuffer vbb = ByteBuffer.allocateDirect(
            // (# of coordinate values * 4 bytes per float) 
            triangleCoords.length * SIZEOF_FLOAT); 
          vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order 
          mTriangleVB = vbb.asFloatBuffer(); // create a floating point buffer from the ByteBuffer 
          mTriangleVB.put(triangleCoords); // add the coordinates to the FloatBuffer 
          mTriangleVB.position(0);   // set the buffer to read the first coordinate 
          break; 
         } 
         case USE_ELEMENTS: 
         { 
          Log.d(TAG, "using VBO elements"); 
          // initialize vertex Buffer for triangle 
          ByteBuffer vbb = ByteBuffer.allocateDirect(
            // (# of coordinate values * 4 bytes per float) 
            triangleCoords.length * SIZEOF_FLOAT); 
          vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order 
          mTriangleVB = vbb.asFloatBuffer(); // create a floating point buffer from the ByteBuffer 
          mTriangleVB.put(triangleCoords); // add the coordinates to the FloatBuffer 
          mTriangleVB.position(0);   // set the buffer to read the first coordinate 
    
          vbb = ByteBuffer.allocateDirect(
            // (# of coordinate values * 2 bytes per short) 
            indices.length * SIZEOF_SHORT); 
          vbb.order(ByteOrder.nativeOrder()); // use the device hardware's native byte order 
          mIndices = vbb.asShortBuffer();  // create a short buffer from the ByteBuffer 
          mIndices.put(indices);    // add the indices to the Buffer 
          mIndices.position(0);    // set the buffer to read the first index 
          break; 
         } 
         case USE_VBO_ELEMENTS: 
         { 
          Log.d(TAG, "using VBO elements"); 
          ByteBuffer vbb = ByteBuffer.allocateDirect(
            // (# of coordinate values * 4 bytes per float) 
            triangleCoords.length * SIZEOF_FLOAT); 
          vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order 
          mTriangleVB = vbb.asFloatBuffer(); // create a floating point buffer from the ByteBuffer 
          mTriangleVB.put(triangleCoords); // add the coordinates to the FloatBuffer 
          mTriangleVB.position(0);   // set the buffer to read the first coordinate 
    
          ByteBuffer ibb = ByteBuffer.allocateDirect(
            indices.length * SIZEOF_SHORT); 
          ibb.order(ByteOrder.nativeOrder()); // use the device hardware's native byte order 
          mIndices = ibb.asShortBuffer();  // create a short buffer from the ByteBuffer 
          mIndices.put(indices);    // add the indices to the Buffer 
          mIndices.position(0);    // set the buffer to read the first index 
    
          GLES20.glGenBuffers(2, mVBOid, 0); 
          checkGLError("initShapes 4"); 
    
          GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVBOid[0]); 
          checkGLError("initShapes 5"); 
          GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 
            numComponentsPerVertex * SIZEOF_FLOAT, 
            mTriangleVB, 
            GLES20.GL_STATIC_DRAW); 
          checkGLError("initShapes 6"); 
    
          GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mVBOid[1]); 
          checkGLError("initShapes 7"); 
          GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 
            mNumIndices * SIZEOF_SHORT, 
            mIndices, 
            GLES20.GL_STATIC_DRAW); 
          checkGLError("initShapes 8"); 
          break; 
         } 
         } 
        } 
    
        private int loadShader(int type, String shaderCode){ 
    
         // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 
         // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 
         int shader = GLES20.glCreateShader(type); 
         checkGLError("loadShader 1"); 
    
         // add the source code to the shader and compile it 
         GLES20.glShaderSource(shader, shaderCode); 
         checkGLError("loadShader 2"); 
         GLES20.glCompileShader(shader); 
         checkGLError("loadShader 3"); 
    
         // Get the compilation status. 
         final int[] compileStatus = new int[1]; 
         GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); 
         checkGLError("loadShader 4"); 
    
         // If the compilation failed, delete the shader. 
         if (compileStatus[0] == 0) 
         { 
          Log.e(TAG, "Error compiling shader: " + GLES20.glGetShaderInfoLog(shader)); 
          GLES20.glDeleteShader(shader); 
          checkGLError("loadShader 5"); 
          shader = 0; 
         } 
    
         return shader; 
        } 
    } 
    

    1. クラッシュダンプ: 12-18 14:59:02.790:I/DEBUG(85): * * * * * * * * * * * * * * * *

      12-18 14:59:02.790:I/DEBUG(85):ビルドの指紋:「華為/ U8510/hwu8510:2.3.3/HuaweiU8510/C169B831:ユーザー/ ota-rel-keys、リリースキー '

      12-18 14:59:02.790:I/DEBUG(85):pid:1638、tid: 1646 >>> com.gles20.step1 < < < 12 -18 14:59:02.790:I/DEBUG(85):シグナル11(SIGSEGV)、コード1(SEGV_MAPERR)、フォールトaddr 00368000 12-18 14:59:02.790:I/DEBUG(85):r0 44affc80 r1 00367ff0r2 0004f03cr3 00000000 12-18 14:59:02.790:I/DEBUG(85):r4 00000000 r5 00000000 r6 00000000 r7 00000028 12-18 14:59:02.790:I/DEBUG(85):r8 00000000 r9 00000000 10 00000000 fp 00000000 12-18 14:59:02.790:I/DEBUG(85):IP 00368000 sp 443ef9d0 lr 80e02a08 pc afd0cd7c cpsr 20000010 12-18 14:59:02.790:I/DEBUG(85):d0 c420e36a40000000さd1 3f800000c4a0e36a 12-18 14:59:02.790:I/DEBUG(85):D2 000000003f800000 D3 000000003f800000 12-18 14:59:02.790:I/DEBUG(85):D4 D5 0000000000000000 0000000000000000 12-18 14 :59:02.790:I/DEBUG(85):d6 3f80000000000000 d7 3f8000003f800000 12-18 14:59:02.790:I/DEBUG(85):D8 D9 0000000000000000 0000000000000000 12-18 14:59:02.800:I/DEBUG(85):D10 D11 0000000000000000 0000000000000000 12-18 14時59分: I/DEBUG(85):d12 0000000000000000 d13 0000000000000000 12-18 14:59:02.800:I/DEBUG(85):d14 0000000000000000 d15 0000000000000000 12-18 14:59:02.800:I/DEBUG(85) :scr 20000010 12-18 14:59:02.860:I/DEBUG(85):#00 pc 0000cd7c /system/lib/libc.so 12-18 14:59:02.860:I/DEBUG(85):# 01 pc 00002a04 /system/lib/libgsl.so 12-18 14:59:02.860:I/DEBUG(85):#02 pc 00089de0 /system/lib/egl/libGLESv2_adreno200.so 12-18 14:59: 02.860:I/DEBUG(85):#03 pc 00091a4a /system/lib/egl/libGLESv2_adreno200.so 12-18 14:59:02.860:I/DEBUG(85): #04 pc 000612ca /system/lib/egl/libGLESv2_adreno200.so 12-18 14:59:02.860:I/DEBUG(85):#05 pc 0006138a /system/lib/egl/libGLESv2_adreno200.so 12-18 14 :59:02.860:I/DEBUG(85):#06 pc 00063d94 /system/lib/egl/libGLESv2_adreno200.so 12-18 14:59:02860:I/DEBUG(85):#07 pc 000836aa /system/lib/egl/libGLESv2_adreno200.so 12-18 14:59:02.860:I/DEBUG(85):#08 pc 0003fd66/system/lib/libandroid_runtime .so 12-18 14:59:02.860:I/DEBUG(85):#09 pc 00012174 /system/lib/libdvm.so 12-18 14:59:02.860:I/DEBUG(85):コードの前後PC: 12-18 14:59:02.860:I/DEBUG(85):afd0cd5c e0422003 e2522020 3a000008 e3c1c01f 12-18 14:59:02.860:I/DEBUG(85):afd0cd6c e28cc040 e8b10ff0 f5dcf040 e2522020 12~18 (85):afd0cd8c e312001f 0a00000c e1b0ce02 28b100f0 12-18 14:59:02.860:I/I/DEBUG(85):afd0cd9c 48b10300 28a000f0 48a00300 e1b0cf02 12-18 14:59:02.860:I/DEBUG(85):code ar ound LR: 12-18 14:59:02.860:I/DEBUG(85):80e029e8 e5906008 e0831001 e1510006 8a000006 12-18 14:59:02.860:I/DEBUG(85):80e029f8 e5903000 e1a0100e e0830005 eb000a13 12- 18:14:59:02.860:I/DEBUG(85):80e02a08e1a00004e28dd008e8bd8070e59f104c 12-18 14:59:02.860:I/DEBUG(85):80e02a18 e59fe04c e1a02005 e79c0001 e08f100e 12-18 14:59:02.860 I/DEBUG(85):スタック: 12-18 14:59:02.860:I/DEBUG(85):443ef990:I/DEBUG(85):80e02a28 e58d6000 e28000a8 ebfffef8 e3e00000 12-18 14:59:02.860:I/DEBUG 0000018c
      12-18 14:59:02.860:I/DEBUG(85):443ef994 811bd8b0
      12-18 14:59:02.860:I/DEBUG(85):443ef998 000000c6
      12-18 14:59:02.860:I/DEBUG(85):443ef99c 443efb68
      12-18 14:59:02.860:I/DEBUG(85):443ef9a0 4360beb4
      12-18 14:59:02.860: I/DEBUG(85):443ef9a4 4360bea0
      12-18 14:59:02.860:I/DEBUG(85):443ef9a8 428da7b4
      12-18 14:59:02.870:I/DEBUG(85):443ef9ac 81089e25 /システム/ LIB/EGL/libGLESv2_adreno200.so 12-18 14:59:02.870:I/DEBUG(85):443ef9b0 001e8cc8
      12-18 14:59:02.870:I/DEBUG(85):443ef9b4 443efa6c
      12/18 14:59:02.870:I/DEBUG(85):443ef9b8 00000001
      12-18 14:59:02.870:I/DEBUG(85):443ef9bc 00000001
      12-18 14:59:02.870:I/DEBUG(85):443ef9c0 0000018c
      12-18 14:59:02.870:I/DEBUG(85):443ef9c4 afd10f08 /system/lib/libc.so 12- 18:14:59:02.870:I/DEBUG(85):443ef9c8 df002777
      12-18 14:59:02.870:I/DEBUG(85):443ef9cc e3a070ad
      12-18 14:59:02.870:I/DEBUG (85):#00 443ef9d0 00000000
      12-18 14:59:02.870:I/DEBUG(85):443ef9d4 000a3000
      12-18 14:59:02.870:I/DEBUG(85):443ef9d8 0018b834
      I/DEBUG(85):443ef9dc 443efb68
      12-18 14:59:02.870:I/DEBUG(85):443ef9e0 4360beb4
      12-18 14:59:02.870:I/DEBUG(85):443ef9e4 4360bea0
      12-18 14:59:02.870:I/DEBUG(85):443ef9e8 428da7b4
      12-18 14:59:02.870 :I/DEBUG(85):443ef9ec 44aac000
      12-18 14:59:02.870:I/DEBUG(85):443ef9f0 00000000
      12-18 14:59:02.870:I/DEBUG(85):443ef9f4 80e02a08 /system/lib/libgsl.so 12-18 14:59:02.870:I/DEBUG(85):#01 443ef9f8 001e9320
      12-18 14:59:02.870:I/DEBUG(85):443ef9fc 00000001
      12-18 14:59:02.870:I/DEBUG(85):443efa00 001e9320
      12-18 14:59:02I/DEBUG(85):443efa04 00000001
      12-18 14:59:02.870:I/DEBUG(85):443efa08 001e9328
      12-18 14:59:02.870:I/DEBUG(85):443efa0c私は私のコードのいくつかの問題発見の調査の別の日の後81089de3 /system/lib/egl/libGLESv2_adreno200.so

    答えて

    16

    • 中古バッファをバインド解除するのを忘れ。これらの呼び出しは、データでバッファを充填した後、プリミティブを描画するためにそれらを使用した後に欠落していた。

      GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mArray); 
      GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndices); 
      // fill or draw 
      // ... 
      // unbind: 
      GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 
      GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); 
      
    • glBindAttribLocationは、適切な時期に発生する必要があります呼び出し:シェーダをコンパイルした後、しかし、プログラム

      // load and compile shaders ... 
      mProgramId = loadProgram(vertexShaderSource, fragmentShaderSource); 
      
      // Bind the locations 
      GLES20.glBindAttribLocation(mProgramId, Shader.VERTEX_POS, "position"); 
      GLES20.glBindAttribLocation(mProgramId, Shader.NORMAL_POS, "normal"); 
      
      // finally link program 
      GLES20.glLinkProgram(mProgramId); 
      
      をリンクする前に、
    • GLES20.glBindAttribLocation 
      GLES20.glEnableVertexAttribArray 
      GLES20.glVertexAttribPointer 
      

      通話のインデックスパラメータの誤解。スペックのより深い一見は私を助けます。これは常に良いアイデアのようです。

    VBOのセットアップと使用に関するいくつかの問題を持っている他の人が出発点としてシンプルですが、完全にOpenGL ES 2.0のアプリを持っていることは役に立つかもしれませんので、私はここにコードを掲載します。

    https://code.google.com/p/gdc2011-android-opengl、VBO関連のコード以外のすべてを削除しました。 は、いくつかのクラスをカプセル化機能に設定し、Android/VBOスターターキットの作成に成功しました。
    このパッケージはActivity、いくつかのヘルパークラス、基本シェーダ、カメラクラス、そして最も重要なのは のVBOクラスで、頂点バッファオブジェクトを作成、使用、破壊するためのすべての機能をラップしています。
    アプリはない:のOpenGL ES 2.0環境

  • を設定

    • レンダリング点灯/消灯ジオメトリ
    • が可能なシェーダを作成
    • インスタンス化3つのVBOベースジオメトリ固定カメラを作成します一つは、Uへ

    着色ジオメトリレンダリングワイヤフレームグリッド

  • あります単純に新しいAndroidプロジェクトを作成し、アクティビティ 'GLES20VBOTest'を作成し、次のファイルを使用します。

    package com.example.vbo; 
    
    /* 
    Note: these not exist or not work before Android 2.3 
    
    GLES20.glVertexAttribPointer 
    GLES20.glDrawElements 
    */ 
    
    import java.nio.Buffer; 
    import java.nio.ByteBuffer; 
    import java.nio.ByteOrder; 
    import java.nio.FloatBuffer; 
    import java.nio.ShortBuffer; 
    
    import javax.microedition.khronos.egl.EGLConfig; 
    import javax.microedition.khronos.opengles.GL10; 
    
    import android.app.Activity; 
    import android.opengl.GLES20; 
    import android.opengl.GLSurfaceView; 
    import android.opengl.Matrix; 
    import android.os.Bundle; 
    import android.util.Log; 
    
    
    public class GLES20VBOTest extends Activity { 
    
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
    
         GLSurfaceView view = new GLSurfaceView(this); 
         view.setEGLContextClientVersion(2); 
         view.setRenderer(new GDC11Renderer()); 
    
         setContentView(view); 
        } 
    
    } 
    
    // Helper class to create some different geometries 
    class GeoData { 
    
        public float[] mVertices; 
        public short[] mIndices; 
    
        private GeoData() {} 
    
        static public GeoData halfpipe() { 
         GeoData creator = new GeoData(); 
         creator.mVertices = createVertices1(44); 
         creator.mIndices = createIndices1(44); 
         return creator; 
        } 
    
        static public GeoData circle() { 
         GeoData creator = new GeoData(); 
         creator.mVertices = createVertices2(32); 
         creator.mIndices = createIndices2(32); 
         return creator; 
        } 
    
        static public GeoData grid() { 
         GeoData creator = new GeoData(); 
         creator.mVertices = createGridVertices(30,30); 
         creator.mIndices = createGridIndices(30,30); 
         return creator; 
        } 
    
        static float[] createGridVertices(int m, int n) { 
         float[] vertices = new float[3*(2*m + 2*n + 4)]; 
    
         float y = 0.1f; 
         float S = 2.8f; 
         for (int i=0; i<=m; i++) { 
          float x = S*(float) (-0.5 + (1.0*i)/m); 
          float z = S*0.5f; 
          vertices[6*i + 0] = x; 
          vertices[6*i + 1] = y; 
          vertices[6*i + 2] = z; 
          vertices[6*i + 3] = x; 
          vertices[6*i + 4] = y; 
          vertices[6*i + 5] = -z; 
         } 
    
         int start = 3*(2*m + 2); 
         // start = 0; 
         for (int i=0; i<=n; i++) { 
          float z = S*(float) (-0.5 + (1.0*i)/n); 
          float x = S*0.5f; 
          vertices[start + 6*i + 0] = x; 
          vertices[start + 6*i + 1] = y; 
          vertices[start + 6*i + 2] = z; 
          vertices[start + 6*i + 3] = -x; 
          vertices[start + 6*i + 4] = y; 
          vertices[start + 6*i + 5] = z; 
         } 
    
         float[] M = new float[16]; 
         Matrix.setIdentityM(M, 0); 
         Matrix.rotateM(M, 0, 27, 0.76f, -0.9f, 1.5f); 
         int count = (2*m + 2*n + 4); 
         Log.d("MKZ", "A: " + count); 
         Log.d("MKZ", "B: " + vertices.length/3); 
         for (int i=0; i<count-1; i++) { 
          int offset = 3*i; 
          Log.d("MKZ", "offset: " + offset); 
          Matrix.multiplyMV(vertices, offset, M, 0, vertices, offset); 
         } 
    
         return vertices; 
        } 
    
        static short[] createGridIndices(int m, int n) { 
         int N = 2*(m+n+2); 
         short[] indices = new short[N]; 
         for (int i=0; i<N; i++) { 
          indices[i] = (short)i; 
         } 
         return indices; 
        } 
    
        static float[] createVertices1(int n) { 
         int NUM_COMPONENTS = 6; 
         float S = 0.75f; 
         float X = 1f; 
         float z0 = 1.3f; 
         float z1 = 1.1f; 
         float dx = 2*X/n; 
         float[] vertices = new float[NUM_COMPONENTS*(n+1)*2]; 
         for (int i=0; i<(n+1); i++) { 
          int I0 = 2*NUM_COMPONENTS*i; 
          int I1 = 2*NUM_COMPONENTS*i + NUM_COMPONENTS; 
          float x = -X + dx*i; 
          float y = -(float) Math.sqrt(1.0 - x*x); 
          vertices[I0 + 0] = S*x; 
          vertices[I0 + 1] = S*y; 
          vertices[I0 + 2] = S*z0; 
          vertices[I0 + 3] = x; 
          vertices[I0 + 4] = y; 
          vertices[I0 + 5] = 0; 
    
          vertices[I1 + 0] = S*x; 
          vertices[I1 + 1] = S*y; 
          vertices[I1 + 2] = S*z1; 
          vertices[I1 + 3] = x; 
          vertices[I1 + 4] = y; 
          vertices[I1 + 5] = 0; 
         } 
         return vertices; 
        } 
        static short[] createIndices1(int n) { 
         short[] indices = new short[(n+1)*2]; 
         for (short i=0; i<(n+1)*2; i++) { 
          indices[i] = i; 
         } 
         return indices; 
        } 
    
        static float[] createVertices2(int n) { 
         int NUM_COMPONENTS = 6; 
         float[] vertices = new float[NUM_COMPONENTS*(n+2)]; 
         final float S = 0.9f; 
         final float Y = -0.0f; 
         vertices[0] = 0; 
         vertices[1] = Y; 
         vertices[2] = 0; 
         vertices[3] = 0; 
         vertices[4] =-1; 
         vertices[5] = 0; 
         for (int i=0; i<=n; i++) { 
          int I = 6 + 6*i; 
          float a = (float) (0.75*2*Math.PI*i/n); 
          float x = (float) (S*Math.cos(a)); 
          float z = (float) (S*Math.sin(a)); 
          vertices[I+0] = x; 
          vertices[I+1] = Y; 
          vertices[I+2] = z; 
          vertices[I+3] = 0; 
          vertices[I+4] =-1; 
          vertices[I+5] = 0; 
         } 
         return vertices; 
        } 
        static short[] createIndices2(int n) { 
         short[] indices = new short[(n+2)]; 
         for (short i=0; i<(n+2); i++) { 
          indices[i] = i; 
         } 
         return indices; 
        } 
    } 
    
    // all GLES20 calls are made here 
    class Shader { 
        // THESE ARE ARBITRARY VALUES, the only constraints are 
        // - must be different 
        // - must be less than a maximum value 
        static final int VERTEX_POS = 3; 
        static final int NORMAL_POS = 4; 
        static final int TEX_POS = 5; 
        static final String TAG = "VBOTest"; 
    
        private int mProgramId; 
        private int mViewProjectionLoc; 
        private int mLightVectorLoc; 
        private int mColorLoc; 
        private int mEnableLightLoc; 
    
    
        Shader() { 
         mProgramId = loadProgram(kVertexShader, kFragmentShader); 
         GLES20.glBindAttribLocation(mProgramId, Shader.VERTEX_POS, "position"); 
         GLES20.glBindAttribLocation(mProgramId, Shader.NORMAL_POS, "normal"); 
         GLES20.glLinkProgram(mProgramId); 
         mViewProjectionLoc = 
          GLES20.glGetUniformLocation(mProgramId, "worldViewProjection"); 
         mLightVectorLoc = 
          GLES20.glGetUniformLocation(mProgramId, "lightVector"); 
         mColorLoc = 
          GLES20.glGetUniformLocation(mProgramId, "color"); 
         mEnableLightLoc = 
          GLES20.glGetUniformLocation(mProgramId, "enableLight"); 
    
         // Other state. 
         GLES20.glClearColor(0.7f, 0.7f, 0.7f, 1.0f); 
         GLES20.glEnable(GLES20.GL_CULL_FACE); 
         GLES20.glEnable(GLES20.GL_DEPTH_TEST); 
        } 
    
        public void use() { 
         GLES20.glUseProgram(mProgramId); 
        } 
        public void setCamera(float[] viewProjectionMatrix) { 
         GLES20.glUniformMatrix4fv(mViewProjectionLoc, 
           1, 
           false, // transpose isn't supported 
           viewProjectionMatrix, 0); 
        } 
        public void setLight(float[] transformedLightVector) { 
         GLES20.glUniform3fv(mLightVectorLoc, 1, transformedLightVector, 0); 
        } 
        public void setColor(float[] color) { 
         GLES20.glUniform3fv(mColorLoc, 1, color, 0); 
        } 
        public void enableLight(boolean val) { 
         GLES20.glUniform1i(mEnableLightLoc, val ? 1 : 0); 
        } 
    
        static public void setViewPort(int width, int height) { 
         GLES20.glViewport(0, 0, width, height); 
        } 
    
    
    
        private static String kLogTag = "GDC11"; 
    
        private static int getShader(String source, int type) { 
         int shader = GLES20.glCreateShader(type); 
         if (shader == 0) return 0; 
    
         GLES20.glShaderSource(shader, source); 
         GLES20.glCompileShader(shader); 
         int[] compiled = { 0 }; 
         GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 
         if (compiled[0] == 0) { 
          Log.e(kLogTag, GLES20.glGetShaderInfoLog(shader)); 
         } 
         return shader; 
        } 
    
        public static int loadProgram(String vertexShader, 
          String fragmentShader) { 
         int vs = getShader(vertexShader, GLES20.GL_VERTEX_SHADER); 
         int fs = getShader(fragmentShader, GLES20.GL_FRAGMENT_SHADER); 
         if (vs == 0 || fs == 0) return 0; 
    
         int program = GLES20.glCreateProgram(); 
         GLES20.glAttachShader(program, vs); 
         GLES20.glAttachShader(program, fs); 
         GLES20.glLinkProgram(program); 
    
         int[] linked = { 0 }; 
         GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linked, 0); 
         if (linked[0] == 0) { 
          Log.e(kLogTag, GLES20.glGetProgramInfoLog(program)); 
          return 0; 
         } 
         return program; 
        } 
    
    
        private static final String kVertexShader = 
         "precision mediump float;         \n" + 
         "uniform mat4 worldViewProjection;       \n" + 
         "uniform vec3 lightVector;         \n" + 
         "attribute vec3 position;         \n" + 
         "attribute vec3 normal;          \n" + 
         "varying float light;          \n" + 
         "void main() {            \n" + 
         // |lightVector| is in the model space, so the model 
         // doesn't have to be transformed. 
         " light = max(dot(normal, lightVector), 0.0) + 0.2;  \n" + 
         " gl_Position = worldViewProjection * vec4(position, 1.0); \n" + 
         "}"; 
    
        private static final String kFragmentShader = 
         "precision mediump float;         \n" + 
         "uniform sampler2D textureSampler;       \n" + 
         "uniform vec3 color;          \n" + 
         "uniform int enableLight;         \n" + 
         "varying float light;          \n" + 
         "void main() {            \n" + 
         " if (1 == enableLight) {         \n" + 
         " gl_FragColor = light * vec4(color,1);     \n" + 
         " } else {             \n" + 
         " gl_FragColor = vec4(color,1);       \n" + 
         " }              \n" + 
         // " gl_FragColor = light * vec4(0.1,0.7,0.0,1);    \n" + 
         "}"; 
    
    
        public void clearView() { 
         int clearMask = GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT; 
         GLES20.glClear(clearMask); 
        } 
    } 
    
    // view matrices 
    class Camera { 
        private float mPhi, mZ = 3.5f; 
        private float[] mProjectionMatrix = new float[16]; 
        private float[] mViewMatrix = new float[16]; 
        private float[] mViewProjectionMatrix = new float[16]; 
    
    
        // Updates mViewProjectionMatrix with the current camera position. 
        public void updateMatrices() { 
         Matrix.setIdentityM(mViewMatrix, 0); 
         Matrix.translateM(mViewMatrix, 0, 0, 0, -mZ); 
         Matrix.rotateM(mViewMatrix, 0, mPhi, 0, 1, 0); 
         Matrix.rotateM(mViewMatrix, 0, -90, 1, 0, 0); 
         Matrix.multiplyMM(
           mViewProjectionMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0); 
        } 
    
        public float[] viewMatrix() { 
         return mViewMatrix; 
        } 
    
        public void perspective(int width, int height) { 
         float aspect = width/(float)height; 
         perspectiveM(
           mProjectionMatrix, 
           (float)Math.toRadians(45), 
           aspect, 0.1f, 15.f); 
         // aspect, 0.5f, 5.f); 
         updateMatrices(); 
        } 
    
        // Like gluPerspective(), but writes the output to a Matrix. 
        static private void perspectiveM(
          float[] m, float angle, float aspect, float near, float far) { 
         float f = (float)Math.tan(0.5 * (Math.PI - angle)); 
         float range = near - far; 
    
         m[0] = f/aspect; 
         m[1] = 0; 
         m[2] = 0; 
         m[3] = 0; 
    
         m[4] = 0; 
         m[5] = f; 
         m[6] = 0; 
         m[7] = 0; 
    
         m[8] = 0; 
         m[9] = 0; 
         m[10] = far/range; 
         m[11] = -1; 
    
         m[12] = 0; 
         m[13] = 0; 
         m[14] = near * far/range; 
         m[15] = 0; 
        } 
    
        public void use(Shader shader) { 
         shader.setCamera(mViewProjectionMatrix); 
        } 
    } 
    
    // The renderer object. 
    // Manages the graphic view/content 
    class GDC11Renderer implements GLSurfaceView.Renderer { 
    
        // OpenGL state stuff. 
        private Shader mShader; 
        private Camera mCamera; 
    
        VBO mVBO1, mVBO2, mVBO3; 
    
        private float[] mLightVector = { 2/3.f, 1/3.f, 2/3.f }; // Needs to be normalized 
        private float[] mTransformedLightVector = new float[3]; 
    
        private void updateLightVector() { 
    
         // Transform the light vector into model space. Since mViewMatrix 
         // is orthogonal, the reverse transform can be done by multiplying 
         // with the transpose. 
    
         float[] viewMatrix = mCamera.viewMatrix(); 
    
         mTransformedLightVector[0] = 
          viewMatrix[0] * mLightVector[0] + 
          viewMatrix[1] * mLightVector[1] + 
          viewMatrix[2] * mLightVector[2]; 
         mTransformedLightVector[1] = 
          viewMatrix[4] * mLightVector[0] + 
          viewMatrix[5] * mLightVector[1] + 
          viewMatrix[6] * mLightVector[2]; 
         mTransformedLightVector[2] = 
          viewMatrix[8] * mLightVector[0] + 
          viewMatrix[9] * mLightVector[1] + 
          viewMatrix[10] * mLightVector[2];    
        } 
    
        // This is called continuously to render. 
        @Override 
        public void onDrawFrame(GL10 unused) { 
    
         mShader.use(); 
         mShader.clearView(); 
         mCamera.use(mShader); 
         mShader.setLight(mTransformedLightVector); 
    
         // VBO 
         mShader.enableLight(true); 
    
         mShader.setColor(red); 
         mVBO1.draw(); 
    
         mShader.setColor(gold); 
         mVBO2.draw(); 
    
         mShader.enableLight(false); 
         mShader.setColor(brown); 
         mVBO3.draw(); 
    
        } 
        static float[] green = {0.2f,1,0.2f}; 
        static float[] brown = {0.7f,0.4f,0.2f}; 
        static float[] red = {0.9f,0,0}; 
        static float[] gold = {0.9f,0.8f,0.1f}; 
        static float[] black = {0,0,0}; 
    
    
        @Override 
        public void onSurfaceCreated(GL10 unused, EGLConfig config) { 
         // CREATE GEOMETRY 
         // NEVER load stuff on the render thread in real life! 
         // You'd call fc.map() and b.load() on a loader thread, and 
         // only then upload that to GL once it's done. 
    
         mShader = new Shader(); 
         mCamera = new Camera(); 
    
         GeoData data = GeoData.halfpipe(); 
         mVBO1 = new VBO(data.mVertices, data.mIndices, GLES20.GL_TRIANGLE_STRIP, true, false, -1); 
    
         data = GeoData.circle(); 
         mVBO2 = new VBO(data.mVertices, data.mIndices, GLES20.GL_TRIANGLE_FAN, true, false, -1); 
    
         data = GeoData.grid(); 
         mVBO3 = new VBO(data.mVertices, data.mIndices, GLES20.GL_LINES, false, false, -1); 
        } 
    
        // This is called when the surface changes, e.g. after screen rotation. 
        @Override 
        public void onSurfaceChanged(GL10 unused, int width, int height) { 
         mCamera.perspective(width, height); 
    
         updateLightVector(); 
    
         // Necessary if the manifest contains |android:configChanges="orientation"|. 
         Shader.setViewPort(width, height); 
        } 
    } 
    
    
    class VBO { 
        int mNumIndices; 
    
        int mIndexBufferId; 
        int mVertexBufferId; 
        boolean mUseNormals; 
        boolean mUseTexCoords; 
    
        int mType; 
        int mNumComponents; 
        int mStride; 
    
        VBO(float[] vertices,    // array of vertex data 
          short[] indices,   // indices 
          int type,     // GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, 
          // GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, and GL_TRIANGLES 
          boolean vertexNormals,  // normals used ? 
          boolean vertexTexCoords, // texCoords used ? 
          int stride) {    // struct size in bytes; if stride <= 0 -> stride will be calculated 
    
    
         mType = type; 
         mUseNormals = vertexNormals; 
         mUseTexCoords = vertexTexCoords; 
    
         mNumComponents = 3; 
         if (mUseNormals) { 
          mNumComponents += 3; 
         } 
         if (mUseTexCoords) { 
          mNumComponents += 2; 
         } 
    
         if (stride <= 0) { 
          mStride = 4 * mNumComponents; 
         } else { 
          mStride = stride; 
         } 
    
         int[] buffers = {0,0}; 
         GLES20.glGenBuffers(2, buffers, 0); 
    
         mVertexBufferId = buffers[0]; 
         mIndexBufferId = buffers[1]; 
    
         createVertexBuffer(GLES20.GL_ARRAY_BUFFER, vertices, mVertexBufferId); 
         createIndexBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indices, mIndexBufferId); 
         mNumIndices = indices.length; 
        } 
    
        void deleteBuffers() { 
         int[] buffers = {mVertexBufferId, mIndexBufferId}; 
         GLES20.glDeleteBuffers(2, buffers, 0); 
         mVertexBufferId = 0; 
         mIndexBufferId = 0; 
        } 
    
        void draw() { 
         if (0 == mVertexBufferId) { 
          return; 
         } 
         GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferId); 
    
         GLES20.glEnableVertexAttribArray(Shader.VERTEX_POS); 
         if (mUseNormals) { 
          GLES20.glEnableVertexAttribArray(Shader.NORMAL_POS); 
         } 
         if (mUseTexCoords) { 
          GLES20.glEnableVertexAttribArray(Shader.TEX_POS); 
         } 
    
         int offset = 0; 
    
         GLES20.glVertexAttribPointer(
           Shader.VERTEX_POS,  // generic id 
           3,      // vertex has 3 components 
           GLES20.GL_FLOAT,  // data type 
           false,     // no normalizing 
           mStride,    // stride: sizeof(float) * number of components 
           offset);    // offset 0; vertex starts at zero 
         offset += 4 * 3; 
    
         if (mUseNormals) { 
    
          GLES20.glVertexAttribPointer(
            Shader.NORMAL_POS, 
            3, 
            GLES20.GL_FLOAT, 
            false, 
            mStride, 
            offset); 
          offset += 4 * 3; 
         } 
    
         if (mUseTexCoords) { 
    
          GLES20.glVertexAttribPointer(
            Shader.TEX_POS, 
            2,      // texCoord has 2 components 
            GLES20.GL_FLOAT, 
            false, 
            mStride, 
            offset); 
          offset += 4 * 3; 
         } 
    
         GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferId); 
         GLES20.glDrawElements(mType, mNumIndices, GLES20.GL_UNSIGNED_SHORT, 0); 
    
         GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 
         GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); 
    
         GLES20.glDisableVertexAttribArray(Shader.VERTEX_POS); 
         GLES20.glDisableVertexAttribArray(Shader.NORMAL_POS); 
         GLES20.glDisableVertexAttribArray(Shader.TEX_POS); 
        } 
        static void createVertexBuffer(int target, float[] vertices, int bufferId) { 
         int size = vertices.length * 4; 
         FloatBuffer fb = ByteBuffer.allocateDirect(4*vertices.length).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
         fb.put(vertices); 
         fb.position(0); 
    
         createBuffer(target, fb, size, bufferId); 
        } 
        static void createIndexBuffer(int target, short[] indices, int bufferId) { 
         int size = indices.length * 2; 
         ShortBuffer sb = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asShortBuffer(); 
         sb.put(indices); 
         sb.position(0); 
    
         createBuffer(target, sb, size, bufferId); 
        } 
        static void createBuffer(int target, Buffer buf, int size, int bufferId) { 
         GLES20.glBindBuffer(target, bufferId); 
         GLES20.glBufferData(target, size, buf, GLES20.GL_STATIC_DRAW); 
         GLES20.glBindBuffer(target, 0); 
        } 
    } 
    
  • +0

    これを投稿していただきありがとうございます。また、VBOs.defenitlyに問題があります。これは私に役立つでしょう –

    関連する問題