OPENGL-ES画圆球体

球体数据结构
public class Planet {

    FloatBuffer m_VertexData;
    FloatBuffer m_NormalData;
    FloatBuffer m_ColorData;
    float m_Scale;// 比例
    float m_Squash;// 挤入
    float m_Radius; // 半径
    int m_Stacks, m_Slices; // 部分

    public Planet(int stacks, int slices, float radius, float squash) {
        this.m_Stacks = stacks; // 1
        this.m_Slices = slices;
        this.m_Radius = radius;
        this.m_Squash = squash;
        init(m_Stacks, m_Slices, radius, squash, "dummy");
    }

    private void init(int stacks, int slices, float radius, float squash,
            String textureFile) {
        float[] vertexData;
        float[] colorData; // 2
        float colorIncrement = 0f;
        float blue = 0f;
        float red = 1.0f;
        int vIndex = 0; // vertex index
        int cIndex = 0; // color index
        m_Scale = radius;
        m_Squash = squash;
        colorIncrement = 1.0f / (float) stacks;

        m_Scale = radius;
        m_Squash = squash;

        colorIncrement = 1.0f / (float) stacks;

        m_Stacks = stacks;
        m_Slices = slices;
        // vertices
        vertexData = new float[3 * ((m_Slices * 2 + 2) * m_Stacks)]; // 4
        // color data
        colorData = new float[(4 * (m_Slices * 2 + 2) * m_Stacks)]; // 5
        int phiIdx, thetaIdx;
        // latitude 纬度
        for (phiIdx = 0; phiIdx < m_Stacks; phiIdx++) {
            // 从 -90度 - +90度(-1.57-+1.57弧度)
            // 第一个圆
            float phi0 = (float) Math.PI
                    * ((float) (phiIdx + 0) * (1.0f / (float) (m_Stacks)) - 0.5f);
            // the next, or second one.
            // 8
            float phi1 = (float) Math.PI
                    * ((float) (phiIdx + 1) * (1.0f / (float) (m_Stacks)) - 0.5f);

            float cosPhi0 = (float) Math.cos(phi0); // 9
            float sinPhi0 = (float) Math.sin(phi0);
            float cosPhi1 = (float) Math.cos(phi1);
            float sinPhi1 = (float) Math.sin(phi1);

            float cosTheta, sinTheta;
            // longitude经度

            for (thetaIdx = 0; thetaIdx < m_Slices; thetaIdx++) {

                float theta = (float) (-2.0f * (float) Math.PI
                        * ((float) thetaIdx) * (1.0 / (float) (m_Slices - 1)));
                cosTheta = (float) Math.cos(theta);
                sinTheta = (float) Math.sin(theta);
                // we're generating a vertical pair of points, such
                // as the first point of stack 0 and the first point of
                // stack 1
                // above it. This is how TRIANGLE_STRIPS work,
                // taking a set of 4 vertices and essentially drawing two
                // triangles
                // at a time. The first is v0-v1-v2 and the next is
                // v2-v1-v3. Etc.
                // get x-y-z for the first vertex of stack
                vertexData[vIndex + 0] = m_Scale * cosPhi0 * cosTheta; // 11
                vertexData[vIndex + 1] = m_Scale * (sinPhi0 * m_Squash);
                vertexData[vIndex + 2] = m_Scale * (cosPhi0 * sinTheta);
                vertexData[vIndex + 3] = m_Scale * cosPhi1 * cosTheta;
                vertexData[vIndex + 4] = m_Scale * (sinPhi1 * m_Squash);
                vertexData[vIndex + 5] = m_Scale * (cosPhi1 * sinTheta);
                colorData[cIndex + 0] = (float) red; // 12
                colorData[cIndex + 1] = (float) 0f;
                colorData[cIndex + 2] = (float) blue;
                colorData[cIndex + 4] = (float) red;
                colorData[cIndex + 5] = (float) 0f;
                colorData[cIndex + 6] = (float) blue;
                colorData[cIndex + 3] = (float) 1.0;
                colorData[cIndex + 7] = (float) 1.0;
                cIndex += 2 * 4; // 13
                vIndex += 2 * 3; // 14
            }
            blue += colorIncrement; // 15
            red -= colorIncrement;
            // create a degenerate triangle to connect stacks and maintain
            // winding order
            // 16
            Log.i("hello", "vIndex:" + vIndex);
            vertexData[vIndex + 0] = vertexData[vIndex + 3] = vertexData[vIndex - 3];
            vertexData[vIndex + 1] = vertexData[vIndex + 4] = vertexData[vIndex - 2];
            vertexData[vIndex + 2] = vertexData[vIndex + 5] = vertexData[vIndex - 1];
        }
        m_VertexData = makeFloatBuffer(vertexData); // 17
        m_ColorData = makeFloatBuffer(colorData);
    }

    protected static FloatBuffer makeFloatBuffer(float[] arr) {
        ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
        bb.order(ByteOrder.nativeOrder());
        FloatBuffer fb = bb.asFloatBuffer();
        fb.put(arr);
        fb.position(0);
        return fb;
    }

    public void draw(GL10 gl) {
        gl.glFrontFace(GL10.GL_CW); // 1
        // 第一个参数表示坐标的维数,可以是2或者3,如果是2,则坐标为(x,y),z轴默认为0;如果是3,则坐标为(x,y,z)
        // 第二个参数可以是GL10.GL_FIXED或者GL10.GL_FLOAT,如果是GL10.GL_FIXED,则第四个参数为IntBuffer类
        // 型,如果为GL10.GL_FLOAT,则第四个参数为FloatBuffer类型
        // 第三个参数表示步长
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_VertexData); // 2
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, m_ColorData);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        // 3
        // GL10.GL_LINE_STRIP 显示线条
        // 第一个参数有三种类型GL10.GL_TRIANGLES、GL10.GL_TRIANGLE_FAN、GL10.GL_TRIANGLE_STRIP
        // GL_TRIANGLES:每三个顶之间绘制三角形,之间不连接
        // GL_TRIANGLE_FAN:以V0V1V2,V0V2V3,V0V3V4,……的形式绘制三角形
        // GL_TRIANGLE_STRIP:顺序在每三个顶点之间均绘制三角形。这个方法可以保证从相同的方向上所有以三角形均被绘制。以V0V1V2,V1V2V3,V2V3V4……的形式绘制三角形
        gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, (m_Slices + 1) * 2
                * (m_Stacks - 1) + 2);
    }
}
renderer
public class SolarSystemRenderer implements GLSurfaceView.Renderer {
    private Planet mPlanet;
    private float mAngle;
    private float mTransY;

    public SolarSystemRenderer() {
        mPlanet = new Planet(10, 10, 1.0f, 1.0f);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        // (x,y,z)
        gl.glTranslatef(0.0f, (float) Math.sin(mTransY), -4.0f);
        gl.glRotatef(mAngle, 1, 0, 0);
        gl.glRotatef(mAngle, 0, 1, 0);
        mPlanet.draw(gl);
        mTransY += .075f;
        mAngle += .4;

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 设置OpenGL场景的大小
        gl.glViewport(0, 0, width, height); // 12
        float ratio = (float) width / height;
        // 设置投影矩阵
        gl.glMatrixMode(GL10.GL_PROJECTION); // 13
        gl.glLoadIdentity();
        // 设置视图的大小
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glDisable(GL10.GL_DITHER); // 16
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // 17
                GL10.GL_FASTEST);
        gl.glClearColor(1, 1, 1, 1);
        gl.glEnable(GL10.GL_CULL_FACE); // 19
        gl.glShadeModel(GL10.GL_SMOOTH); // 20
        gl.glEnable(GL10.GL_DEPTH_TEST);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值