0

ユーザーが赤い三角形をx軸に沿ってドラッグするだけで回転できるようにするために、OpenGL_1テクノロジーを使用してカスタムビューを作成しました。(Y軸を中心に回転します)。動作しますが、(マウス/指を離さずに)一方の方向からもう一方の方向にドラッグすると、多少の遅延が発生します。したがって、私のコードはまだ「完全な目標」ではないようです。(それ自体で完璧なコードはないと確信しています)。

クォータニオンを使用することを考えましたが、あまり役に立たないかもしれません。本当にクォータニオン(または一種のマトリックス)を使用する必要がありますか?

私はAndroid4.0.3用のアプリケーションを設計しましたが、Android api 3(Android 1.5)にも適合する可能性があります(少なくとも、それは可能だと思います)。

これが私のメインレイアウトです:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.laurent_bernabe.android.triangletournant3d.MyOpenGLView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        /> 

</LinearLayout>

これが私の主な活動です:

MainActivity.java

package com.laurent_bernabe.android.triangletournant3d;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

そして最後に、私のOpenGLビュー

MyOpenGLView.java

package com.laurent_bernabe.android.triangletournant3d;

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

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

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.util.AttributeSet;
import android.view.MotionEvent;

public class MyOpenGLView extends GLSurfaceView implements Renderer {

    public MyOpenGLView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setRenderer(this);
    }

    public MyOpenGLView(Context context) {
        this(context, null);
    }



    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int actionMasked = event.getActionMasked();
        switch(actionMasked){
        case MotionEvent.ACTION_DOWN:
            savedClickLocationX = (int) event.getX();   
            break;
        case MotionEvent.ACTION_UP:
            savedClickLocationX = null;
            break;
        case MotionEvent.ACTION_MOVE:
            Integer newClickLocationX =  (int) event.getX();
            int dx = newClickLocationX - savedClickLocationX;
            angle += dx / 180.0f * 3.14159265f;
            break;
    }
        return true;
    }



    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        GLU.gluLookAt(gl,
                0f, 0f, 5f,
                0f, 0f, 0f,
                0f, 1f, 0f
        );

        gl.glRotatef(angle, 0f, 1f, 0f);
        gl.glColor4f(1f, 0f, 0f, 0f);
        gl.glVertexPointer(2, GL10.GL_FLOAT, 0, triangleCoordsBuff);
        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 60f, (float) width / height, 0.1f, 10f);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glClearDepthf(1.0f);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        buildTriangleCoordsBuffer();
    }

    private void buildTriangleCoordsBuffer() {
        ByteBuffer buffer = ByteBuffer.allocateDirect(4*triangleCoords.length);
        buffer.order(ByteOrder.nativeOrder());
        triangleCoordsBuff = buffer.asFloatBuffer();
        triangleCoordsBuff.put(triangleCoords);
        triangleCoordsBuff.rewind();
    }

    private float [] triangleCoords = {-1f, -1f,
                                        +1f, -1f,
                                        +1f, +1f};

    private FloatBuffer triangleCoordsBuff;
    private float angle = 0f;

    private Integer savedClickLocationX;

}

(Mohamed Abdallahのおかげで変更されました)。

マニフェストファイルを実際に提供する必要はないと思います。しかし、あなたがそれが必要だと思うなら、私はそうすることができます。

エミュレータと実際のデバイスでテストしました。

私の構成

  • Android SDK 20.0.3
  • Eclipse Juno
  • Ubuntu12.1064ビット
  • OpenGLドライバーがインストールされています(Canonicalから)。

では、どうすれば反応性を向上させることができるでしょうか?

前もって感謝します。

4

1 に答える 1

1

エミュレーターは非常に遅いため(特にの場合)、パフォーマンスの基準とすべきではありませんOpenGL(実際のパフォーマンスではなく、指標を提供します)。実際のデバイスでテストします(最悪のユーザーエクスペリエンスを感じたい場合はローエンド)。

また、クラスへの呼び出しがMath少し遅れをもたらす前に、私は本を読みました。したがって、クラスを呼び出さずに手動で度をラジアンに変換することで、コードを拡張できます(実際のデバイスでテストした後に必要な場合Math) (180で除算してPiで乗算するだけです)

于 2012-11-13T10:58:20.070 に答える