0

openglを使用してAndroidで棒グラフを作成しています

レンダラーを呼び出しているアクティビティから、レンダラーからキューブを呼び出しています(バーを表示するためにキューブを使用しています)

これが私のレンダラーコードです:

public class BarRenderer implements Renderer {

int[] vals;
private float translatex, translatez, scaly;

public BarRenderer(boolean useTranslucentBackground, int[] vals) {
    mTranslucentBackground = useTranslucentBackground;
    this.vals = vals;
    for (int i = 0; i < this.vals.length; i++) {
        mcube[i] = new Cube();
    }
}

public void onDrawFrame(GL10 gl) {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    translatex = 0.5f;
    scaly = 0.8f;
    for (int i = 0; i < vals.length; i++) {
        gl.glTranslatef((-1.0f + (translatex * i)), 0.0f, translatez);
        gl.glRotatef(mAngle, 0.0f, 1.0f, 0.0f);
        gl.glScalef(0.4f, scaly * vals[i], 0.6f);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        mcube[i].draw(gl);
    }
    mTransY = .075f;
    mAngle = -60.0f;
    translatez = -7.0f;
    Log.i("Draw", "called");
}

public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    float aspectRatio;
    float zNear = .1f;
    float zFar = 1000;
    float fieldOfView = 80.0f / 57.3f;
    float size;
    gl.glEnable(GL10.GL_NORMALIZE);
    aspectRatio = (float) width / (float) height;
    gl.glMatrixMode(GL10.GL_PROJECTION);
    size = zNear * (float) (Math.tan((double) (fieldOfView / 2.0f)));
    gl.glFrustumf(-size, size, -size / aspectRatio, size / aspectRatio,
            zNear, zFar);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glDisable(GL10.GL_DITHER);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
    if (mTranslucentBackground) {
        gl.glClearColor(0, 0, 0, 0);
    } else {
        gl.glClearColor(1, 1, 1, 1);
    }
    gl.glEnable(GL10.GL_CULL_FACE);
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glEnable(GL10.GL_POINT_SMOOTH);
    gl.glEnable(GL10.GL_DEPTH_TEST);
}

private boolean mTranslucentBackground;
private Cube[] mcube = new Cube[4];
private float mTransY;
private float mAngle;

}

残念ながら、棒グラフは次のようになります。

ここに画像の説明を入力

これが棒グラフとまったく同じではないことは誰でも理解できますが、ここで私の欠点を指摘してください。どこが間違っているのでしょうか。

1>バーの高さは 4 1 2 1 ですが、正確なサイズではありません

2>バー間のスペースは.5f離れているはずですが、最初は大きなギャップがあり、バーごとに繰り返し減少します

3>1 つのベース プレーンから開始する方法

編集:

4> このバーの成長をアニメーション化できますか?どうすればいいですか?

私のキューブコード:

public class Cube {
private ByteBuffer mTfan1;
private ByteBuffer mTfan2;
private int bar;

public Cube(int i) {
    
    this.bar = i;
    
    float vertices[] = { 
            
            -1.0f, 1.0f, 1.0f,
            1.0f, 1.0f, 1.0f,
            1.0f, -1.0f,1.0f,
            -1.0f, -1.0f, 1.0f,

            -1.0f, 1.0f, -1.0f,
            1.0f, 1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f, -1.0f 
    };

    byte maxColor = (byte) 255;
    byte colors[][] =
    {   
            {maxColor,maxColor, 0,maxColor},
            {0, maxColor,maxColor,maxColor},
            {0, 0, 0,maxColor},
            {maxColor, 0,maxColor,maxColor},
            {maxColor, 0, 0,maxColor},
            {0, maxColor, 0,maxColor},
            {0, 0,maxColor,maxColor},
            {0, 0, 0,maxColor} 
    };

    byte tfan1[] =
    {
            1,0,3,
            1,3,2,
            1,2,6,
            1,6,5,
            1,5,4,
            1,4,0
    };
    byte tfan2[] =
    {
                7,4,5,
                7,5,6,
                7,6,2,
                7,2,3,
                7,3,0,
                7,0,4
    };
        
    byte indices[] =
    { 0, 3, 1, 0, 2, 3 };

    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    
    mFVertexBuffer = vbb.asFloatBuffer();
    mFVertexBuffer.put(vertices);
    mFVertexBuffer.position(0);
    
    mColorBuffer = ByteBuffer.allocateDirect(colors.length);
    mColorBuffer.put(colors[bar]);
    mColorBuffer.position(0);
    
    mTfan1 = ByteBuffer.allocateDirect(tfan1.length);
    mTfan1.put(tfan1);
    mTfan1.position(0);
    
    mTfan2 = ByteBuffer.allocateDirect(tfan2.length);
    mTfan2.put(tfan2);
    mTfan2.position(0);
}

public void draw(GL10 gl)
{
    gl.glVertexPointer(3, GL11.GL_FLOAT, 0, mFVertexBuffer);
    gl.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 0, mColorBuffer);
    gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan1);
    gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan2);
}

private FloatBuffer mFVertexBuffer;
private ByteBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}

draw メソッドで何かをしなければならないと思いますが、ここでアニメーション化する方法は?

助けてくださいありがとう

4

2 に答える 2

2

2 glTranslate と rotate 呼び出しの前に glPushMatrix を使用し、その後 glPopMatrix 関数を使用するか、インクリメントなしで glTranslate を呼び出す必要があります。glTranslate は glTranslate パラメータから新しい行列に既存の射影行列を乗算するため

3

gl.glPushMatrix() ;
gl.glTranslate(0,y,0);
mcube[i].draw(gl);
gl.glPopMatrix(); 

with y= - Barheight/2 の場合、またはバーの頂点座標を変更します

于 2013-09-06T10:00:36.807 に答える
0

現在、他の問題がいくつかありますが、3D 棒グラフの作成は完了していますが、このコードで役立つ可能性があると思います。

マイレンダラー クラス:

public class BarRenderer implements GLSurfaceView.Renderer {

int[] vals;
private float translatex, scaly;
// For controlling cube's z-position, x and y angles and speeds (NEW)
float angleX = 0; // (NEW)
float angleY = 0; // (NEW)
float speedX = 0; // (NEW)
float speedY = 0; // (NEW)
float translatez;

public BarRenderer(Context context, boolean useTranslucentBackground,
        int[] vals) {
    mTranslucentBackground = useTranslucentBackground;
    mfloor = new Cube(0);
    mwall = new Cube(0);

    this.vals = vals;
    for (int i = 0; i < this.vals.length; i++) {
        mcube[i] = new Cube(i);
    }
}

public void onDrawFrame(GL10 gl) {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();

    translatex = 2.0f;
    scaly = 0.8f;
    for (int i = 0; i < vals.length; i++) {
        gl.glPushMatrix();
        mTransY = -5 + (scaly * vals[i]);
        gl.glTranslatef((-3.0f + (translatex * i)), mTransY, translatez);
        gl.glRotatef(mAngleX, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(mAngleY, 0.0f, 1.0f, 0.0f);
        gl.glScalef(0.4f, scaly * vals[i], 0.4f);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        mcube[i].draw(gl);
        gl.glPopMatrix();
    }
     mTransY = .075f;
//      mAngleX = -90.0f;
//      mAngleY = -0.01f;
    mAngleX += speedX;
    mAngleY += speedY;
    translatez = -6.0f;
}

public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    float aspectRatio;
    float zNear = .1f;
    float zFar = 1000;
    float fieldOfView = 80.0f / 57.3f;
    float size;
    gl.glEnable(GL10.GL_NORMALIZE);
    aspectRatio = (float) width / (float) height;
    gl.glMatrixMode(GL10.GL_PROJECTION);
    size = zNear * (float) (Math.tan((double) (fieldOfView / 2.0f)));
    gl.glFrustumf(-size, size, -size / aspectRatio, size / aspectRatio,
            zNear, zFar);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glDisable(GL10.GL_DITHER);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
    if (mTranslucentBackground) {
        gl.glClearColor(0, 0, 0, 0);
    } else {
        gl.glClearColor(1, 1, 1, 1);
    }
    gl.glEnable(GL10.GL_CULL_FACE);
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glEnable(GL10.GL_POINT_SMOOTH);
    gl.glEnable(GL10.GL_DEPTH_TEST);
}

private boolean mTranslucentBackground;
private Cube[] mcube = new Cube[4];
private Cube mfloor, mwall;
private float mTransY;
private float mAngleX,mAngleY;

}

および myGLsurfaceview クラス:

public class MyBarGLSurfaceView extends GLSurfaceView {

BarRenderer renderer; // Custom GL Renderer

// For touch event
private final float TOUCH_SCALE_FACTOR = 180.0f / 320.0f;
private float previousX;
private float previousY;

public MyBarGLSurfaceView(Context context,
        boolean useTranslucentBackground, int[] vals) {
    super(context);
    renderer = new BarRenderer(context, useTranslucentBackground, vals);
    this.setRenderer(renderer);
    // Request focus, otherwise key/button won't react
    this.requestFocus();
    this.setFocusableInTouchMode(true);
}

// Handler for key event
@Override
public boolean onKeyUp(int keyCode, KeyEvent evt) {
    switch (keyCode) {
    case KeyEvent.KEYCODE_DPAD_LEFT: // Decrease Y-rotational speed
        renderer.speedY -= 01.1f;
        break;
    case KeyEvent.KEYCODE_DPAD_RIGHT: // Increase Y-rotational speed
        renderer.speedY += 01.1f;
        break;
    case KeyEvent.KEYCODE_DPAD_UP: // Decrease X-rotational speed
        renderer.speedX -= 01.1f;
        break;
    case KeyEvent.KEYCODE_DPAD_DOWN: // Increase X-rotational speed
        renderer.speedX += 01.1f;
        break;
    case KeyEvent.KEYCODE_A: // Zoom out (decrease z)
        renderer.translatez -= 0.2f;
        break;
    case KeyEvent.KEYCODE_Z: // Zoom in (increase z)
        renderer.translatez += 0.2f;
        break;
    }
    return true; // Event handled
}

// Handler for touch event
@Override
public boolean onTouchEvent(final MotionEvent evt) {
    float currentX = evt.getX();
    float currentY = evt.getY();
    float deltaX, deltaY;
    switch (evt.getAction()) {
    case MotionEvent.ACTION_MOVE:
        // Modify rotational angles according to movement
        deltaX = currentX - previousX;
        deltaY = currentY - previousY;
        renderer.angleX += deltaY * TOUCH_SCALE_FACTOR;
        renderer.angleY += deltaX * TOUCH_SCALE_FACTOR;
    }
    // Save current x, y
    previousX = currentX;
    previousY = currentY;
    return true; // Event handled
}
}

それはまだ行われていますが、誰かが私に答えてくれるならお願いします

1>この棒グラフをアニメーションで成長させる方法、現在、この棒グラフアクティビティが開始されると棒グラフが表示されますが、棒グラフを表示するだけでなくアニメーションで成長させたい

2>このリンクのように棒グラフにベースと背景の壁を作成する方法http://www.fusioncharts.com/demos/gallery/#column-and-bar

3>そして、ユーザーのタッチの動きに応じて棒グラフを回転または移動しようとしましたが、別の例のようにコードを試しました。そのコードも表示されるため、このglsurfaceviewクラスを独自に作成しましたが、何らかの理由で機能していません。どこで何を見逃したのかわかりません。何か考えがあれば教えてください。

ありがとう

于 2013-09-07T14:02:11.043 に答える