球体、材质、光照

今天我们将实现绘制一个球体,并为其添加材质效果。

效果图:

下面是我在网上找的代码,稍微有改动一下的。

Sphere.java

 

package test.Sphere;

 

import android.app.Activity;

import android.opengl.GLSurfaceView;

import android.os.Bundle;

import android.view.Window;

import android.view.WindowManager;

 

public class Sphere extends Activity {

    /** Calledwhen the activity is first created. */

    private GLSurfaceView mGLSurfaceView;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

       getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

               WindowManager.LayoutParams.FLAG_FULLSCREEN);

 

        mGLSurfaceView=new GLSurfaceView(this);

        mGLSurfaceView.setRenderer(new Renderer());

        setContentView(mGLSurfaceView);

    }

    protected void onResume() {

        // Ideally a game should implement onResume() andonPause()

        // to take appropriate action when the activity loosesfocus

        super.onResume();

        mGLSurfaceView.onResume();

    }

    @Override

    protected void onPause() {

        // Ideally a game should implement onResume() andonPause()

        // to take appropriate action when the activity loosesfocus

        super.onPause();

        mGLSurfaceView.onPause();

    }

}

Renderer.java

 

package test.Sphere;

 

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

 

import android.opengl.GLSurfaceView;

import android.opengl.GLU;

 

public class Renderer implementsGLSurfaceView.Renderer{

    DrawSphere mSphere;

    public void onSurfaceChanged(GL10 gl, int width, int height){

       // Setsthe current view port to the new size.

       gl.glViewport(0, 0, width, height);

       // Selectthe projection matrix

       gl.glMatrixMode(GL10.GL_PROJECTION);

       // Resetthe projection matrix

       gl.glLoadIdentity();

       //Calculate the aspect ratio of the window

       GLU.gluPerspective(gl, 45.0f,

                                   (float) width / (float) height,

                                   0.1f, 100.0f);

       // Selectthe modelview matrix

       //gl.glMatrixMode(GL10.GL_MODELVIEW);

       // Resetthe modelview matrix

       //gl.glLoadIdentity();

    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config){

      

       gl.glClearColor(0.0f, 0.0f,0.0f, 0.5f); 

       // EnableSmooth Shading, default not really needed.

       gl.glShadeModel(GL10.GL_SMOOTH);

       // Depthbuffer setup.

       gl.glClearDepthf(1.0f);

       // Enablesdepth testing.

       gl.glEnable(GL10.GL_DEPTH_TEST);

      

      

      

       // Thetype of depth testing to do.

       gl.glDepthFunc(GL10.GL_LEQUAL);

       // Reallynice perspective calculations.

       gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,

                          GL10.GL_NICEST);

    }

    @Override

    public void onDrawFrame(GL10 gl) {

      

       // TODO Auto-generated method stub

       //gl.glClearColor(0.0f, 0.0f, 0.0f,0.0f);

      

       //gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);

       gl.glMatrixMode(GL10.GL_MODELVIEW);

       gl.glLoadIdentity();

       gl.glClearColor(0.0f, 0.0f,0.0f, 0.0f); 

       // Clearsthe screen and depth buffer.

       gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

       //gl.glTranslatef(0,0, -3.0f);

       mSphere=new DrawSphere();

       mSphere.initSphere(gl);

       mSphere.draw(gl);

    }

   

}

 

 

DrawSphere.java

 

package test.Sphere;

import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import java.nio.FloatBuffer;

 

import javax.microedition.khronos.opengles.GL10;

 

import android.opengl.GLU;

 

public class DrawSphere{

   

    /** Calledwhen the activity is first created. */

    public void initSphere(GL10 gl){

        float[] mat_amb = {0.2f* 1.0f, 0.2f * 0.4f, 0.2f* 0.4f, 1.0f,};

       float[] mat_diff= {1.0f, 0.4f, 0.4f, 1.0f,};

       float[] mat_spec= {1.0f, 1.0f, 1.0f, 1.0f,};   

      

        ByteBuffer mabb = ByteBuffer.allocateDirect(mat_amb.length*4);

       mabb.order(ByteOrder.nativeOrder());

       FloatBuffer mat_ambBuf =mabb.asFloatBuffer();

       mat_ambBuf.put(mat_amb);

       mat_ambBuf.position(0);     

      

       ByteBuffer mdbb = ByteBuffer.allocateDirect(mat_diff.length*4);

       mdbb.order(ByteOrder.nativeOrder());

       FloatBuffer mat_diffBuf =mdbb.asFloatBuffer();

       mat_diffBuf.put(mat_diff);

       mat_diffBuf.position(0);   

      

       ByteBuffer msbb = ByteBuffer.allocateDirect(mat_spec.length*4);

       msbb.order(ByteOrder.nativeOrder());

       FloatBuffer mat_specBuf =msbb.asFloatBuffer();

       mat_specBuf.put(mat_spec);

       mat_specBuf.position(0);

      

      

       

        gl.glClearColor(0.8f, 0.8f, 0.8f,0.0f);

        gl.glEnable(GL10.GL_DEPTH_TEST);

        gl.glEnable(GL10.GL_CULL_FACE);

        gl.glShadeModel(GL10.GL_SMOOTH);

 

        gl.glEnable(GL10.GL_LIGHTING); 

        gl.glEnable(GL10.GL_LIGHT0);   

 

        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT,mat_ambBuf);

        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE,mat_diffBuf);

        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR,mat_specBuf);

        gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 64.0f);

       

        gl.glLoadIdentity();

        GLU.gluLookAt(gl,0.0f, 0.0f, 10.0f,

               0.0f, 0.0f, 0.0f,

               0.0f, 1.0f, 0.0f);

       

    }

    public void draw(GL10 gl) {

       float  theta, pai;

        float  co, si;

        float  r1, r2;

        float  h1, h2;

        float  step = 2.0f;

        float[][] v = new float[32][3];

        ByteBuffervbb;

        FloatBuffervBuf;

       

       vbb = ByteBuffer.allocateDirect(v.length * v[0].length * 4);

        vbb.order(ByteOrder.nativeOrder());

        vBuf = vbb.asFloatBuffer();

 

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

       

        for (pai = -90.0f;pai < 90.0f; pai +=step) {

       

           int n = 0;

 

            r1 = (float)Math.cos(pai* Math.PI / 180.0);

           r2= (float)Math.cos((pai + step) * Math.PI / 180.0);

           h1= (float)Math.sin(pai * Math.PI / 180.0);

           h2= (float)Math.sin((pai + step) * Math.PI / 180.0);

 

           for (theta = 0f;theta <= 360.0f; theta+= step) {

               co= (float)Math.cos(theta * Math.PI / 180.0);

               si= -(float)Math.sin(theta * Math.PI / 180.0);

 

               v[n][0]= (r2 * co);

               v[n][1]= (h2);

               v[n][2]= (r2 * si);

               v[n+ 1][0] = (r1 * co);

               v[n+ 1][1] = (h1);

               v[n+ 1][2] = (r1 * si);

 

               vBuf.put(v[n]);

               vBuf.put(v[n+ 1]);

 

               n+= 2; 

              

               if(n>31){

                  vBuf.position(0);

 

                   gl.glVertexPointer(3,GL10.GL_FLOAT, 0, vBuf);

                   gl.glNormalPointer(GL10.GL_FLOAT, 0, vBuf);

                  gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);

                 

                  n= 0;

                  theta-= step;

               }

              

           }

           vBuf.position(0);

 

           gl.glVertexPointer(3,GL10.GL_FLOAT, 0, vBuf);

           gl.glNormalPointer(GL10.GL_FLOAT, 0, vBuf);

           gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);

        }

       

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

        gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

    }

}

 

这里的注释比较少,相关的方法可以参照我gl10方法解析中的内容。

下面主要讲一下球体的绘制方法。

由于在OpenGL ES中并没有可供直接绘制球体的方法,所以我们需要绘制一个很多面对多面体,它看起来像是一个球。

我们这里draw方法就是用来画这个多面体的。它主要由两层循环。它绘制的顺序是自底向上一层一层绘制的。第一层循环就是确定要绘制的是哪一层。

第二层循环是在确定的层上绘制多个三角形。

值得注意的是这些三角形并不在同一个平面上。它们共同组成这个多面体。

我将在下篇中讲下gl.glDrawArrays。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值