0

楽しみのために、Android用のシンプルなフラクタル表示アプリを作成しています。また、OpenGLを使用したことがないので、OpenGLを学ぶ機会としても使用しています。NeHeチュートリアルのAndroidポートを出発点として使用して、私のアプローチは、フラクタルを作成するためのすべての計算を行う1つのクラス(FractalModel)と、すべてのレンダリングを行うFractalViewを持つことです。

私が抱えている問題は、レンダリングを機能させることです。基本的に、各ポイントが1ピクセルに対応するさまざまな色のポイントのグラフをプロットしているので、画面全体に1x1の長方形をレンダリングし、寸法を使用してオフセットを計算し、1が存在するようにすることでこれを処理すると思いました。長方形と物理ピクセル間の1:1の対応。各ピクセルの色は個別に計算されるため、同じレンダリングコードを再利用して、フラクタルのさまざまな部分をレンダリングできます(後でパンとズームを追加したい)。

これが私が書いたビュークラスです:

public class FractalView extends GLSurfaceView implements Renderer {

private float[] mVertices;
private FloatBuffer[][] mVBuffer;
private ByteBuffer[][] mBuffer;
private int mScreenWidth;
private int mScreenHeight;
private float mXOffset;
private float mYOffset;
private int mNumPixels;

//references to current vertex coordinates
private float xTL;
private float yTL;
private float xBL;
private float yBL;
private float xBR;
private float yBR;
private float xTR;
private float yTR;


public FractalView(Context context, int w, int h){
    super(context);
    setEGLContextClientVersion(1);
    mScreenWidth = w;
    mScreenHeight = h;
    mNumPixels = mScreenWidth * mScreenHeight;
    mXOffset = (float)1.0/mScreenWidth;
    mYOffset = (float)1.0/mScreenHeight;
    mVertices = new float[12];
    mVBuffer = new FloatBuffer[mScreenHeight][mScreenWidth];
    mBuffer = new ByteBuffer[mScreenHeight][mScreenWidth];
}


public void onDrawFrame(GL10 gl){
    int i,j;    
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
    gl.glLoadIdentity();
    mapVertices();  
    gl.glColor4f(0.0f,1.0f, 0.0f,.5f);
    for(i = 0; i < mScreenHeight; i++){
        for(j = 0; j < mScreenWidth; j++){
            gl.glFrontFace(GL10.GL_CW);
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVBuffer[i][j]);
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVertices.length / 3);
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        }
    }




}

public void onSurfaceChanged(GL10 gl, int w, int h){
    if(h == 0) {                        //Prevent A Divide By Zero By
        h = 1;                      //Making Height Equal One
    }

    gl.glViewport(0, 0, w, h);  //Reset The Current Viewport
    gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix
    gl.glLoadIdentity();                    //Reset The Projection Matrix

    //Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(gl, 45.0f, (float)w / (float)h, 0.1f, 100.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
    gl.glLoadIdentity();

}

public void onSurfaceCreated(GL10 gl, EGLConfig config){
    gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    //Black Background
    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); 
}

private void mapVertices(){
    int i,j;
    xTL = -1;
    yTL = 1;
    xTR = -1 + mXOffset;
    yTR = 1;
    xBL = -1;
    yBL = 1 - mYOffset;
    xBR = -1 + mXOffset;
    yBR = 1 - mYOffset;
    for(i = 0; i < mScreenHeight; i++){
        for (j = 0; j < mScreenWidth; j++){
            //assign coords to vertex array         
            mVertices[0] = xBL;
            mVertices[1] = yBL;
            mVertices[2] = 0f;
            mVertices[3] = xBR;
            mVertices[4] = xBR;
            mVertices[5] = 0f;
            mVertices[6] = xTL;
            mVertices[7] = yTL;
            mVertices[8] = 0f;
            mVertices[9] = xTR;
            mVertices[10] = yTR;
            mVertices[11] = 0f;
            //add doubleBuffer
            mBuffer[i][j] = ByteBuffer.allocateDirect(mVertices.length * 4);
            mBuffer[i][j].order(ByteOrder.nativeOrder());
            mVBuffer[i][j] = mBuffer[i][j].asFloatBuffer();
            mVBuffer[i][j].put(mVertices);
            mVBuffer[i][j].position(0);
            //transform right
            transformRight();
        }
        //transform down
        transformDown();
        //reset x
        xTL = -1;
        xTR = -1 + mXOffset;
        xBL = -1;
        xBR = -1 + mXOffset;
    }



}

//transform all the coordinates 1 "pixel" to the right
private void transformRight(){
    xTL = xTL + mXOffset; //TL            
    xBL = xBL + mXOffset; //BL
    xBR = xBR + mXOffset; //BR
    xTR = xTR + mXOffset; //TR;
}

//transform all of the coordinates 1 pixel down;
private void transformDown(){
    yTL = yTL - mYOffset;                        
    yBL = yBL - mYOffset;            
    yBR = yBR - mYOffset;           
    yTR = yTR - mYOffset;
}
}

基本的に、これと同じ方法(レッスン2の正方形)で実行しようとしていますが、オブジェクトがはるかに多くなっています。1と-1は画面の端にほぼ対応していると思います(これが完全に正しいわけではないことはわかっていますが、投影行列の使用方法がよくわからないため、適切なリソースがない限り、これをできるだけ単純に保ちたいと思います。そこから学ぶことができます)が、OpenGLの座標は実際の画面座標とは別のものであることを理解しています。コードを実行すると、黒い画面(緑色になっているはずです)が表示されますが、LogCatはガベージコレクターが機能していることを示しているので、何かがわかります起こっている。何かが正しく行われなかったことが原因のバグなのか、それとも本当に遅いのかはわかりません。どちらの場合でも、私は別の方法で何をすべきですか?私はこれについてすべて間違っているのではないかと感じています。私は周りを見回しましたが、チュートリアルと例のほとんどは上記のリンクに基づいています。

編集:画面全体を埋めるテクスチャを生成してそれを描画するだけでこれを実行できることはわかっていますが、私が読んだリンクでは、フレームごとにテクスチャを再描画する必要がないため、処理が遅くなると書かれていました。とはいえ、パースペクティブが変更されたときにテクスチャを再描画するだけでよいので、これを考慮してコードを記述できます。私が現在抱えている主な問題は、ビットマップを描画し、正しく表示することです。

4

1 に答える 1

1

画面が空白になるのは、バッファを何度も交換していることと、フレームごとにすべての頂点バッファを生成していることが原因だと思います。1つのフレームでの数千のバッファスワップと数千のバッファ作成は、信じられないほど遅くなります。

言及すべきことの1つは、Androidデバイスのメモリが限られているため、ガベージコレクターが機能していないことは、バッファー作成コードが使用可能なメモリの多くを消費し、デバイスが新しいメモリの作成のために一部を解放しようとしていることを示している可能性がありますバッファ。

フレームごとにピクセルデータを入力してから、画面を埋める単一の正方形にレンダリングするテクスチャを作成することをお勧めします。これにより、速度が大幅に向上し、プログラムがより柔軟になります。

編集: ここのチュートリアルを見てください:http : //www.nullterminator.net/gltexture.htmlテクスチャを作成し、それらをロードする方法についてのアイデアを得てください。基本的に、BYTE*データに独自のデータを入力する必要があります。

データを動的に変更する場合は、テクスチャデータを更新する必要があります。ここの情報を使用してください:http://www.opengl.org/wiki/Texture:テクスチャ画像の変更に関するセクション。

于 2011-11-18T05:15:23.227 に答える