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>条之间的空间应该相距0.5f,但它们开始时有很大的差距,但在每个条之后会反复减小

3>如何从一个基本平面开始

编辑:

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(); 

在您的情况下使用 y= - Barheight/2 或更改条形的顶点坐标

于 2013-09-06T10:00:36.807 回答
0

我已经完成了 3d 条形图的创建,尽管我现在还有其他一些问题,但我相信有些人可能会对这段代码有所帮助。

Myrenderer 类:

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 回答