OpenGL ES 2.0 Android-キューブ回転バグ

マティアス・ティエツ:

私は、Androidアプリで使用されるOpenGL ES 2.0を使用して、色付きの3Dキューブの視覚化を実装しました。私の目標:立方体はスワイプイベント(左、右、上、下)に反応し、次に立方体は対応する方向に回転する必要があります

回転:

  • if(current_angle%90 == 0)->ある面から別の面にスワイプすると停止します
  • 一度に1つの回転のみ(x軸またはy軸の周りのみ)
  • また、段階的に行う必要があります(例:5度)。そのため、すぐには行われません->ユーザーに表示されます。

私のコード:

public class Cube20 {

    private volatile int angleX;
    private volatile int angleY;

    private volatile Cube.RotateDirection rotateDirection;

    public Cube.RotateDirection getRotateDirection() {
        return rotateDirection;
    }


    public void setRotation(Cube.RotateDirection rotateDirection) {
        this.rotateDirection = Cube.RotateDirection.getDirectionForID(rotateDirection.getId());
    }

    public int getAngleX() {
        return angleX;
    }

    public void setAngleX(int angleX) {
        this.angleX = angleX;
    }

    public int getAngleY() {
        return angleY;
    }

    public void setAngleY(int angleY) {
        this.angleY = angleY;
    }

    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;" +
                    "attribute vec4 vPosition;" +
                    "void main() {" +
                    // The matrix must be included as a modifier of gl_Position.
                    // Note that the uMVPMatrix factor *must be first* in order
                    // for the matrix multiplication product to be correct.
                    "  gl_Position = uMVPMatrix * vPosition;" +
                    "}";

    private final String fragmentShaderCode =
            "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main() {" +
                    "  gl_FragColor = vColor;" +
                    "}";

    private final FloatBuffer vertexBuffer;
    //private final ShortBuffer drawListBuffer;
    private final int mProgram;
    private final ShortBuffer indexBuffer;
    private int mPositionHandle;
    private int mColorHandle;
    private int mMVPMatrixHandle;

    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;

    private float[] vertices = {  // Vertices of the 6 faces
            // FRONT
            -1.0f, -1.0f, 1.0f,  // 0. left-bottom-front (0)
            1.0f, -1.0f, 1.0f,  // 1. right-bottom-front
            -1.0f, 1.0f, 1.0f,  // 2. left-top-front
            1.0f, 1.0f, 1.0f,  // 3. right-top-front
            // BACK
            1.0f, -1.0f, -1.0f,  // 6. right-bottom-back (4)
            -1.0f, -1.0f, -1.0f,  // 4. left-bottom-back
            1.0f, 1.0f, -1.0f,  // 7. right-top-back
            -1.0f, 1.0f, -1.0f,  // 5. left-top-back
            // LEFT
            -1.0f, -1.0f, -1.0f,  // 4. left-bottom-back (8)
            -1.0f, -1.0f, 1.0f,  // 0. left-bottom-front
            -1.0f, 1.0f, -1.0f,  // 5. left-top-back
            -1.0f, 1.0f, 1.0f,  // 2. left-top-front
            // RIGHT
            1.0f, -1.0f, 1.0f,  // 1. right-bottom-front (12)
            1.0f, -1.0f, -1.0f,  // 6. right-bottom-back
            1.0f, 1.0f, 1.0f,  // 3. right-top-front
            1.0f, 1.0f, -1.0f,  // 7. right-top-back
            // TOP
            -1.0f, 1.0f, 1.0f,  // 2. left-top-front
            1.0f, 1.0f, 1.0f,  // 3. right-top-front
            -1.0f, 1.0f, -1.0f,  // 5. left-top-back
            1.0f, 1.0f, -1.0f,  // 7. right-top-back
            // BOTTOM
            -1.0f, -1.0f, -1.0f,  // 4. left-bottom-back
            1.0f, -1.0f, -1.0f,  // 6. right-bottom-back
            -1.0f, -1.0f, 1.0f,  // 0. left-bottom-front
            1.0f, -1.0f, 1.0f   // 1. right-bottom-front
    };

    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

    private float[][] colors = {  // Colors of the 6 faces
            {1.0f, 0.5f, 0.0f, 1.0f},  // 0. orange
            {1.0f, 0.0f, 1.0f, 1.0f},  // 1. violet
            {0.0f, 1.0f, 0.0f, 1.0f},  // 2. green
            {0.0f, 0.0f, 1.0f, 1.0f},  // 3. blue
            {1.0f, 0.0f, 0.0f, 1.0f},  // 4. red
            {1.0f, 1.0f, 0.0f, 1.0f}   // 5. yellow
    };

    short[] indices = {
            0, 1, 2, 2, 1, 3, // FRONT
            4, 5, 6, 6, 5, 7, // BACK
            8, 9, 10, 10, 9, 11, // LEFT
            12, 13, 14, 14, 13, 15, // RIGHT
            16, 17, 18, 18, 17, 19, // TOP
            20, 21, 22, 22, 21, 23, // BOTTOM

    };
    private int numFaces = 6;

    /**
     * Sets up the drawing object data for use in an OpenGL ES context.
     */
    public Cube20() {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 4 bytes per float)
                vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        // initialize byte buffer for the draw list
        indexBuffer = ByteBuffer.allocateDirect(indices.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
        indexBuffer.put(indices).position(0);

        // prepare shaders and OpenGL program
        int vertexShader = RenderUtils.loadShader(
                GLES20.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader = RenderUtils.loadShader(
                GLES20.GL_FRAGMENT_SHADER,
                fragmentShaderCode);

        mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
        GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables

        this.rotateDirection = Cube.RotateDirection.NONE;
    }

    /**
     * Encapsulates the OpenGL ES instructions for drawing this shape.
     *
     * @param mvpMatrix - The Model View Project matrix in which to draw
     *                  this shape.
     */
    public void draw(float[] mvpMatrix) {
        // Add program to OpenGL environment
        GLES20.glUseProgram(mProgram);

        GLES20.glFrontFace(GLES20.GL_CCW);
        GLES20.glEnable(GLES20.GL_CULL_FACE);
        GLES20.glCullFace(GLES20.GL_BACK);

        // scale
        float scale_matrix[] = new float[16];
        Matrix.setIdentityM(scale_matrix, 0);
        Matrix.scaleM(scale_matrix, 0, 0.5f, 0.5f, 1);
        Matrix.multiplyMM(mvpMatrix, 0, scale_matrix, 0, mvpMatrix, 0);

        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(
                mPositionHandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                vertexStride, vertexBuffer);

        // get handle to fragment shader's vColor member
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

        // Set color for drawing the triangle
        //GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        // get handle to shape's transformation matrix
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        RenderUtils.checkGlError("glGetUniformLocation");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
        RenderUtils.checkGlError("glUniformMatrix4fv");

        // Render all the faces
        for (int face = 0; face < numFaces; face++) {
            // Set the color for each of the faces
            GLES20.glUniform4fv(mColorHandle, 1, colors[face], 0);
            indexBuffer.position(face * 6);
            GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
        }

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisable(GLES20.GL_CULL_FACE);
    }
}

public class MyGLSurfaceView extends GLSurfaceView {
    private volatile MyGLRenderer myGLRenderer;

    public MyGLSurfaceView(Context context) {
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        myGLRenderer = new MyGLRenderer(context);
        setRenderer(myGLRenderer); // Use a custom renderer
        setOnTouchListener(new OnSwipeListener(context));

        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    class OnSwipeListener implements View.OnTouchListener {

        private final GestureDetector gestureDetector;

        public OnSwipeListener(Context context) {
            this.gestureDetector = new GestureDetector(context, new OnFlingListener());
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return this.gestureDetector.onTouchEvent(event);
        }

        private class OnFlingListener extends GestureDetector.SimpleOnGestureListener {
            private final Object LOCK = new Object();

            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }

            /**
             * @return true if the event is consumed, else false
             */
            @Override
            public boolean onFling(MotionEvent down, MotionEvent up, float velocityX, float velocityY) {
                //super.onFling(down, up, velocityX, velocityY);

                float distanceX = up.getX() - down.getX();
                float distanceY = up.getY() - down.getY();

                final Cube20 cube = myGLRenderer.getCube();
                if (!cube.getRotateDirection().equals(Cube.RotateDirection.NONE)) {
                    return false;
                }

                if (Math.abs(distanceX) > Math.abs(distanceY)) {
                    if (distanceX > 0) {
                        // RIGHT
                        cube.setRotation(Cube.RotateDirection.RIGHT);
                    } else {
                        // LEFT
                        cube.setRotation(Cube.RotateDirection.LEFT);
                    }
                } else {
                    if (distanceY < 0) {
                        // TOP
                        cube.setRotation(Cube.RotateDirection.UP);
                    } else {
                        // DOWN
                        cube.setRotation(Cube.RotateDirection.DOWN);
                    }
                }
                //requestRender();
                return true;
            }
        }
    }
}

public class MyGLRenderer implements GLSurfaceView.Renderer {
    Context context;   // Application's context
    private volatile int rotationAngle;
    private volatile float rotateX;
    private volatile float rotateY;
    private boolean firstRotation = true;
    private Cube20 cube;

    // mMVPMatrix is an abbreviation for "Model View Projection Matrix"
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];

    // Constructor with global application context
    public MyGLRenderer(Context context) {
        this.context = context;
    }


    public float getRotateX() {
        return rotateX;
    }

    public void setRotateX(float rotateX) {
        this.rotateX = rotateX;
    }

    public float getRotateY() {
        return rotateY;
    }

    public void setRotateY(float rotateY) {
        this.rotateY = rotateY;
    }

    public float getAngle() {
        return rotationAngle;
    }

    public void setAngle(int angle) {
        rotationAngle = angle;
    }


    // Call back when the surface is first created or re-created
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        this.cube = new Cube20();
    }

    // Call back to draw the current frame.
    @Override
    public void onDrawFrame(GL10 gl) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        // Set the camera position (View matrix)
        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -1, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        // Calculate the projection and view transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

        // zoom out a bit
        Matrix.translateM(mMVPMatrix, 0, 0, 0, 4.5f);


        int angleOffset = 5;
        // update the angles for the x and y rotation
        if (cube.getRotateDirection().equals(Cube.RotateDirection.LEFT)) {
            cube.setAngleY(cube.getAngleY() - angleOffset);
        } else if (cube.getRotateDirection().equals(Cube.RotateDirection.RIGHT)) {
            cube.setAngleY(cube.getAngleY() + angleOffset);
        } else if (cube.getRotateDirection().equals(Cube.RotateDirection.UP)) {
            cube.setAngleX(cube.getAngleX() + angleOffset);
        } else if (cube.getRotateDirection().equals(Cube.RotateDirection.DOWN)) {
            cube.setAngleX(cube.getAngleX() - angleOffset);
        }
        firstRotation = false;

        // rotate and draw
        rotate();
        cube.draw(mMVPMatrix);


        // test if rotation should be stopped (lock in each 90° step)
        if (cube.getRotateDirection().equals(Cube.RotateDirection.LEFT) ||
                cube.getRotateDirection().equals(Cube.RotateDirection.RIGHT)) {
            if (!firstRotation && cube.getAngleY() % 90 == 0) {
                cube.setRotation(Cube.RotateDirection.NONE);
            }
        }
        if (cube.getRotateDirection().equals(Cube.RotateDirection.UP) ||
                cube.getRotateDirection().equals(Cube.RotateDirection.DOWN)) {
            if (!firstRotation && cube.getAngleX() % 90 == 0) {
                cube.setRotation(Cube.RotateDirection.NONE);
            }
        }

        Log.i("MyGLRENDER~ ", cube.getRotateDirection().toString());
    }

    private void rotate() {
        float[] rotationMatrix = new float[16];
        Matrix.setIdentityM(rotationMatrix, 0);

        // rotate in x and y direction, apply that to the intermediate matrix
        Matrix.rotateM(rotationMatrix, 0, cube.getAngleX(), 1, 0, 0);
        Matrix.rotateM(rotationMatrix, 0, cube.getAngleY(), 0, 1, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mMVPMatrix, 0, rotationMatrix, 0);
    }

    // Call back after onSurfaceCreated() or whenever the window's size changes
    @Override
    public void onSurfaceChanged(GL10 gl, 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(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
    }

    public Cube20 getCube() {
        return cube;
    }
}

public class MyGLActivity extends Activity {

    private GLSurfaceView glView;   // Use GLSurfaceView

    // Call back when the activity is started, to initialize the view
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        glView = new MyGLSurfaceView(this); // Allocate a GLSurfaceView
        this.setContentView(glView); // This activity sets to GLSurfaceView
    }

    // Call back when the activity is going into the background
    @Override
    protected void onPause() {
        super.onPause();
        glView.onPause();
    }

    // Call back after onPause()
    @Override
    protected void onResume() {
        super.onResume();
        glView.onResume();
    }
}

私が期待する行動:

  • 成功したスワイプ反応とx軸を中心とした回転
    (中間のスクリーンショット)

  • 成功したスワイプ反応とy軸を中心とした回転
    (中間のスクリーンショット)

With this setup i encounter the following problems:

  1. Sometimes the rotation is done about the z-axis
    (中間のスクリーンショット)
    I never implemented a rotation about the z-axis for the cube, i am not sure why this rotation is done. I could only imagine that there is maybe a threading problem between the swipe listener at MyGLSurfaceView and MyGLRenderer (which holds the reference to the cube).

The rotation is done at MyGLRenderer.rotate. The cube uses separate angles (x/y) and also there is a property for which rotation is currently done (LEFT, RIGHT, UP, DOWN, NONE), which is updated in OnSwipeListener.

  1. Also if the bug with the z-rotation (1.) happened, the rotation about the x or y axis is done in the wrong direction (left/right, up/down swapped)

My guess is that either the angles or the RotateDirection is not updated correctly. The app is tested on a OnePlus 3T @ Android 8.0, IDE is Android Studio 3.2.1.

Rabbid76 :

If you have rotated a cube by 90° around the X-axis, then of course a rotation on around the Y-axis of the cube is a rotation around the Z-axis in the world. You have to rotate around the Y-axis of the world, not around the Y-axis of the cube.
To do so you have to store the concatenated rotations of the cube in a rotation matrix and to apply the new rotation to this matrix.

Create a member for rotation matrix:

private final float[] mRotationMatrix = new float[16];

Initialize it by the identity matrix:

Matrix.setIdentityM(mRotationMatrix, 0);

この方法でrotateは、現在のアニメーションを回転行列に適用する必要があります。注文はでなければなりませんanimationMatrix * mRotationMatrix行列の乗算は可換ではありません乗算の順序を尊重しない場合、以前と同じ結果が得られ、回転はワールドの軸ではなく、キューブの軸の周りになります。

private void rotate() {
    float[] animationMatrix = new float[16];
    Matrix.setIdentityM(animationMatrix, 0);

    // rotate in x and y direction, apply that to the intermediate matrix
    Matrix.rotateM(animationMatrix, 0, cube.getAngleX(), 1, 0, 0);
    Matrix.rotateM(animationMatrix, 0, cube.getAngleY(), 0, 1, 0);

    // concatenate the animation and the rotation matrix; the order is important
    Matrix.multiplyMM(animationMatrix, 0, animationMatrix, 0, mRotationMatrix, 0); 

    Matrix.multiplyMM(mMVPMatrix, 0, mMVPMatrix, 0, animationMatrix, 0);
}

アニメーションが完全な90°に達したら、回転行列を変更して回転角度をリセットする必要があります。

if (cube.getRotateDirection().equals(Cube.RotateDirection.LEFT) ||
    cube.getRotateDirection().equals(Cube.RotateDirection.RIGHT)) {
        if (!firstRotation && cube.getAngleY() % 90 == 0) {

            float[] newRotationMatrix = new float[16];
            Matrix.setIdentityM(newRotationMatrix, 0);
            Matrix.rotateM(newRotationMatrix, 0, cube.getAngleY(), 0, 1, 0);

            // concatenate the new 90 rotation to the rotation matrix
            Matrix.multiplyMM(mRotationMatrix, 0, newRotationMatrix, 0, mRotationMatrix, 0);

            // reset the angle
            cube.setAngleY(0);
            cube.setRotation(Cube.RotateDirection.NONE);
        }
    }
    if (cube.getRotateDirection().equals(Cube.RotateDirection.UP) ||
        cube.getRotateDirection().equals(Cube.RotateDirection.DOWN)) {
        if (!firstRotation && cube.getAngleX() % 90 == 0) {

            float[] newRotationMatrix = new float[16];
            Matrix.setIdentityM(newRotationMatrix, 0);
            Matrix.rotateM(newRotationMatrix, 0, cube.getAngleX(), 1, 0, 0);

            // concatenate the new 90 rotation to the rotation matrix
            Matrix.multiplyMM(mRotationMatrix, 0, newRotationMatrix, 0, mRotationMatrix, 0);

            // reset the angle
            cube.setAngleX(0);
            cube.setRotation(Cube.RotateDirection.NONE);
        }
    }

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Android OpenGL ES 2. 0VBOがレンダリングされない

分類Dev

Android openGL ES2rotateMMフリップ回転角度

分類Dev

Android OpenGL ES 2 Texture Quadrants Rotated

分類Dev

Android Surfaceflinger and openGL ES

分類Dev

OpenGL es2の頂点。Android用Java

分類Dev

OpenGL ES 2.0のAndroidライブ壁紙?

分類Dev

OpenGL ES ANDROID C++ エラー

分類Dev

Android OpenGL ES2-ブレンディングは常に相加的であるようです

分類Dev

Opengl ES glGetAttribLocation問題!0x0502エラー

分類Dev

opengl es 2.0 android c ++ glGetTexImage代替

分類Dev

Model not visible android OpenGL ES 2.0

分類Dev

Model not visible android OpenGL ES 2.0

分類Dev

OpenGL ES2を使用する場合のAndroidのテクスチャのブラックアルファ

分類Dev

Android OpenGL ES 2:メインアクティビティのフラグメントとしてOpenGLアクティビティを使用する方法

分類Dev

OpenGL-ES2を使用してAndroidで.objファイルをロードして表示する方法

分類Dev

gluUnProjectを使用して、Android OpenGL ES 2.0のz = 0平面上のx、yコードにタッチをマッピングします

分類Dev

Android-opengl-esを使用して3Dキューブでビデオテクスチャをレンダリングする方法は?

分類Dev

Android OpenGL ES 2.0:テキストが表示されない

分類Dev

Android OpenGL camera2 texture resolution

分類Dev

Android OpenGL Es3.0サークルの作成

分類Dev

Android OpenGL Es3.0サークルの作成

分類Dev

OpenGL ES2を使用したBox2Dデバッグ描画

分類Dev

Box2D debug draw with OpenGL ES 2

分類Dev

Android-OpenGL ES 2.0:エミュレーター(動作)-デバイス(動作しない)

分類Dev

android opengl-es-2.0-rotateMの説明

分類Dev

OpenGL ES 単一ピクセル描画 android

分類Dev

Android4.4 hwuiで、openglエラー0x0506を取得します

分類Dev

Android上のOpenGL-ESゲームのチュートリアルとライブラリ

分類Dev

OpenGL ES 2.0 2D(Marmalade SDK)

Related 関連記事

  1. 1

    Android OpenGL ES 2. 0VBOがレンダリングされない

  2. 2

    Android openGL ES2rotateMMフリップ回転角度

  3. 3

    Android OpenGL ES 2 Texture Quadrants Rotated

  4. 4

    Android Surfaceflinger and openGL ES

  5. 5

    OpenGL es2の頂点。Android用Java

  6. 6

    OpenGL ES 2.0のAndroidライブ壁紙?

  7. 7

    OpenGL ES ANDROID C++ エラー

  8. 8

    Android OpenGL ES2-ブレンディングは常に相加的であるようです

  9. 9

    Opengl ES glGetAttribLocation問題!0x0502エラー

  10. 10

    opengl es 2.0 android c ++ glGetTexImage代替

  11. 11

    Model not visible android OpenGL ES 2.0

  12. 12

    Model not visible android OpenGL ES 2.0

  13. 13

    OpenGL ES2を使用する場合のAndroidのテクスチャのブラックアルファ

  14. 14

    Android OpenGL ES 2:メインアクティビティのフラグメントとしてOpenGLアクティビティを使用する方法

  15. 15

    OpenGL-ES2を使用してAndroidで.objファイルをロードして表示する方法

  16. 16

    gluUnProjectを使用して、Android OpenGL ES 2.0のz = 0平面上のx、yコードにタッチをマッピングします

  17. 17

    Android-opengl-esを使用して3Dキューブでビデオテクスチャをレンダリングする方法は?

  18. 18

    Android OpenGL ES 2.0:テキストが表示されない

  19. 19

    Android OpenGL camera2 texture resolution

  20. 20

    Android OpenGL Es3.0サークルの作成

  21. 21

    Android OpenGL Es3.0サークルの作成

  22. 22

    OpenGL ES2を使用したBox2Dデバッグ描画

  23. 23

    Box2D debug draw with OpenGL ES 2

  24. 24

    Android-OpenGL ES 2.0:エミュレーター(動作)-デバイス(動作しない)

  25. 25

    android opengl-es-2.0-rotateMの説明

  26. 26

    OpenGL ES 単一ピクセル描画 android

  27. 27

    Android4.4 hwuiで、openglエラー0x0506を取得します

  28. 28

    Android上のOpenGL-ESゲームのチュートリアルとライブラリ

  29. 29

    OpenGL ES 2.0 2D(Marmalade SDK)

ホットタグ

アーカイブ