OpenGL ES实例3:3维翻转的球体

最近迫于生存压力,不得不给人兼职打工。故在博文中加了个求点击的链接。麻烦有时间的博友们帮我点击一下。没时间的不用勉强啊。不过请放心,我是做技术的,肯定链接没病毒,就是我打工的淘宝店铺。嘻嘻。http://shop108130013.taobao.com。谢谢捧场。以后就每周写篇原创的技术博客回报大家,实在是迫于生计,无所不用其极。请谅解。


同实例2的原理,在<Pro OpenGL ES for Android (2012)>一书第二章的第二个例子,3D翻转的球体。

学了几天,发现opengl这东西跟别的没什么两样,就是要多练。除此以外,还要多看看算法。这个对我来说,真的需要下苦功夫啊。

对应这个例子的完整代码已经上传到CSDN的资源页:http://download.csdn.net/download/fener10289/5265380

代码如下:

package book.SolarSystem;

import book.SolarSystem.SolarSystemRenderer;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.WindowManager;

public class SolarSystemActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
     		GLSurfaceView view = new GLSurfaceView(this);
       		view.setRenderer(new SolarSystemRenderer());
       		setContentView(view);
    }
}


 

package book.SolarSystem;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;
import java.lang.Math;

class SolarSystemRenderer implements GLSurfaceView.Renderer 
{
    public SolarSystemRenderer() 
    {
    	mPlanet=new Planet(10,10,1.0f, 1.0f);
    }
    
    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();
    	
         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;
    }

	
	public void onSurfaceChanged(GL10 gl, int width, int height) {
	     gl.glViewport(0, 0, width, height);
	
	     /*
	      * Set our projection matrix. This doesn't have to be done
	      * each time we draw, but usually a new projection needs to
	      * be set when the viewport is resized.
	      */
	     
	 	float aspectRatio;
		float zNear =.1f;
		float zFar =1000f;
		float fieldOfView = 30.0f/57.3f;
		float	size;
		
		gl.glEnable(GL10.GL_NORMALIZE);
		
		aspectRatio=(float)width/(float)height;				//h/w clamps the fov to the height, flipping it would make it relative to the width
		
		//Set the OpenGL projection matrix
		
		gl.glMatrixMode(GL10.GL_PROJECTION);
		
		size = zNear * (float)(Math.tan((double)(fieldOfView/2.0f)));
		gl.glFrustumf(-size, size, -size/aspectRatio, size /aspectRatio, zNear, zFar);
		
		//Make the OpenGL modelview matrix the default
		
		gl.glMatrixMode(GL10.GL_MODELVIEW);
	}
	
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
	    /*
	     * By default, OpenGL enables features that improve quality
	     * but reduce performance. One might want to tweak that
	     * especially on software renderer.
	     */
	    gl.glDisable(GL10.GL_DITHER);
	
	    /*
	     * Some one-time OpenGL initialization can be made here
	     * probably based on features of this particular context
	     */
	     gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
	             GL10.GL_FASTEST);
	
	     gl.glEnable(GL10.GL_CULL_FACE);
	     gl.glCullFace(GL10.GL_BACK);
	     gl.glShadeModel(GL10.GL_SMOOTH);
	     gl.glEnable(GL10.GL_DEPTH_TEST);
	}

	private Planet mPlanet;
	private float mTransY;
	private float mAngle;
}


 

package book.SolarSystem;

import java.util.*;
import java.nio.*;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES11;


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;
        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;                              
         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_Stacks = stacks;
	    	m_Slices = slices;
    		    				
	    	//vertices
    		
            vertexData = new float[ 3*((m_Slices*2+2) * m_Stacks)];	      
    		
            //color data
    		
            colorData = new float[ (4*(m_Slices*2+2) * m_Stacks)];      	
		
            int phiIdx, thetaIdx;
    		
            //latitude
    		
            for(phiIdx=0; phiIdx < m_Stacks; phiIdx++)	               		
            {
            	//starts at -90 degrees (-1.57 radians) goes up to +90 degrees (or +1.57 radians)
    			
            	//the first circle
     	             	             	             	             	             	             	       
            	float phi0 = (float)Math.PI * ((float)(phiIdx+0) * (1.0f/(float)(m_Stacks)) - 0.5f);	
    			
            	//the next, or second one.
	             	             	             	             	             	             	      
            	float phi1 = (float)Math.PI * ((float)(phiIdx+1) * (1.0f/(float)(m_Stacks)) - 0.5f);	

            	float cosPhi0 = (float)Math.cos(phi0);	                     
            	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++)               
            	{
	    	         //increment along the longitude circle each "slice"
	    				                                                                   
	    	         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; 	
	         	     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;			  	
	    	         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; 	             	             	             	             	             	
	          	     vIndex+=2*3; 				           
	            }
    			
            	blue+=colorIncrement;				         
            	red-=colorIncrement;
		    			
		    	// create a degenerate triangle to connect stacks and maintain winding order
			     	           	             	             	             	             	             
		    	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); 	             
         m_ColorData = makeFloatBuffer(colorData);
    }


    public void draw(GL10 gl) 
    {
 	
    	gl.glFrontFace(GL10.GL_CW);					
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_VertexData);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	
    	gl.glColorPointer(4, GL10.GL_FLOAT, 0, m_ColorData);		

        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, (m_Slices+1)*2*(m_Stacks-1)+2);
    }
    
    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;
    }
}


 

package book.SolarSystem;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

/**
 * A vertex shaded cube.
 */
class Cube
{
    public Cube()
    {
        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
        	};

        	
        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);
        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( GL11.GL_TRIANGLE_FAN, 6 * 3, GL11.GL_UNSIGNED_BYTE, mTfan1);
    	gl.glDrawElements( GL11.GL_TRIANGLE_FAN, 6 * 3, GL11.GL_UNSIGNED_BYTE, mTfan2);
    }

    private FloatBuffer mFVertexBuffer;
    private ByteBuffer  mColorBuffer;
    private ByteBuffer  mIndexBuffer;
    private ByteBuffer  mTfan1;
    private ByteBuffer  mTfan2;

}


 




你可能感兴趣的:(OpenGL ES实例3:3维翻转的球体)