OPENGL-ES画圆球体

来源:互联网 发布:微信一键转发软件 编辑:程序博客网 时间:2024/04/26 07:19

球体数据结构

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


原创粉丝点击