Android Open Source - AndroidGLViewer Sphere






From Project

Back to project page AndroidGLViewer.

License

The source code is released under:

GNU General Public License

If you think the Android project AndroidGLViewer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package graphics.bradley.androidglviewer;
/* w w w .  j av a 2  s. c  om*/
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import android.opengl.GLES20;
import android.util.Log;

// square shape to be drawn in the context of an OpenGL ES view
public class Sphere {

  private final String vertexShaderCode =
      "uniform mat4 uMVPMatrix, uMVMatrix, uNormalMat;" +
      "attribute vec4 vPosition;" +
      "attribute vec4 vColor;" +
      "attribute vec3 vNormal;" + 
      "varying vec4 varyingColor; varying vec3 varyingNormal; " +
      "varying vec3 varyingPos; " + 
      "void main() {" +
      "  varyingColor = vColor;" +
      "  vec4 t = uNormalMat*vec4(vNormal, 0.0);" +
      "   varyingNormal.xyz = t.xyz; "+
      "   t = uMVMatrix*vPosition;"+ 
      "   varyingPos.xyz = t.xyz; "+
      "   gl_Position =    uMVPMatrix  * vPosition ;" +
      "}";
  // fragment code to perform diffuse + specular shading; 
  private final String fragmentShaderCode =
      "precision mediump float;" +
      "varying vec4 varyingColor; varying vec3 varyingNormal;" +
      "varying vec3 varyingPos;" +    
      "uniform vec3 lightDir; " +
      "void main() {" +
      "  float Ns = 100.0;  "+ // for shiness; 
      "   float kd = 0.9, ks = 0.9; " +
      "   vec4 light = vec4(1.0, 1.0, 1.0, 1.0); " +
      "   vec4 lightS = vec4(1.0, 1.0, 1.0, 1.0); " + // the specular highlight is redish
      "   vec3 Nn = normalize(varyingNormal); " +
      "   vec3 Ln = normalize(lightDir); " +
      "   vec4 diffuse = kd* light * max(dot(Nn, Ln), 0.0); " +
      "   vec3 Ref = reflect(Nn, Ln); " + // get the reflectance vector; 
      "   float dotV = max(dot(Ref, normalize(varyingPos)), 0.0); " + // since we are in eye space, the eye position is at 0, 0, 0, so the view direction is simply (varyingPos- (0, 0, 0))
      "   vec4 specular = lightS*ks*pow(dotV, Ns); " +
      "  gl_FragColor = varyingColor*diffuse + specular; " +
      //"   gl_FragColor = varyingColor*diffuse + specular; " +
      "}";
  
  private FloatBuffer vertexBuffer;
  private FloatBuffer colorBuffer; 
  private FloatBuffer normalBuffer; 
  private ShortBuffer drawListBuffer;
  
  private final int mProgram;
  private int mPositionHandle;
  private int mColorHandle, mNormalHandle;
  private int mMVPMatrixHandle, mNormalMatHandle;
  
  // number of coordinates per vertex in this array
  static final int COORDS_PER_VERTEX = 3;
  
  // vertex coords array for glDrawArrays() =====================================
  // A cube has 6 sides and each side has 2 triangles, therefore, a cube consists
  // of 36 vertices (6 sides * 2 tris * 3 vertices = 36 vertices). And, each
  // vertex is 3 components (x,y,z) of floats, therefore, the size of vertex
  // array is 108 floats (36 * 3 = 108).
  private float [] vertices; 

  // normal array
  private float [] normals; 
  // color array
  static float [] colors; 
  
  
  private short drawOrder[] = { 0, 1, 2, 0, 2, 3 };  // order to draw vertices
  
  private int vertexCount; 
  private final int vertexStride = COORDS_PER_VERTEX * 4;  // bytes per vertex
  
  // set the light direction in the eye coordinate; 
  float lightDir[] = {0.0f, 1.0f, 8.0f}; 
  
  public static int checkShaderError(int shader) {
    

    final int[] compileStatus = new int[1];

                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);

                if (compileStatus[0] == 0) {

                        Log.e("GLES Error:", "Error compiling shader: " + GLES20.glGetShaderInfoLog(shader));
                        GLES20.glDeleteShader(shader);
                        return 1; 

                }
                return 0; 
  }
  
  
  private void createSphere(double r, int lats, int longs) {
            int i, j;
            
            
            // there are lats*longs number of quads, each requires two triangles with six vertices, each vertex takes 3 floats; 
            vertices = new float[lats*longs*6*3];
            normals = new float[lats*longs*6*3]; 
            colors = new float[lats*longs*6*3]; 
            
            vertexCount = vertices.length / COORDS_PER_VERTEX;
            int triIndex = 0; 
            for(i = 0; i < lats; i++) {
                double lat0 = Math.PI * (-0.5 + (double) (i) / lats);
               double z0  = Math.sin(lat0);
               double zr0 =  Math.cos(lat0);
        
               double lat1 = Math.PI * (-0.5 + (double) (i+1) / lats);
               double z1 = Math.sin(lat1);
               double zr1 = Math.cos(lat1);
        
               
               //glBegin(GL_QUAD_STRIP);
               for(j = 0; j < longs; j++) {
                   double lng = 2 * Math.PI * (double) (j - 1) / longs;
                   double x = Math.cos(lng);
                   double y = Math.sin(lng);
        
                   
                   lng = 2 * Math.PI * (double) (j) / longs;
                   double x1 = Math.cos(lng);
                   double y1 = Math.sin(lng);
                   
                   //glNormal3f(x * zr0, y * zr0, z0);
                   //glVertex3f(x * zr0, y * zr0, z0);
                   //glNormal3f(x * zr1, y * zr1, z1);
                   //glVertex3f(x * zr1, y * zr1, z1);
                   
                   // the first triangle
                   vertices[triIndex*9 + 0 ] = (float)(x * zr0);    vertices[triIndex*9 + 1 ] = (float)(y * zr0);   vertices[triIndex*9 + 2 ] = (float) z0;
                   vertices[triIndex*9 + 3 ] = (float)(x * zr1);    vertices[triIndex*9 + 4 ] = (float)(y * zr1);   vertices[triIndex*9 + 5 ] = (float) z1;
                   vertices[triIndex*9 + 6 ] = (float)(x1 * zr0);   vertices[triIndex*9 + 7 ] = (float)(y1 * zr0);  vertices[triIndex*9 + 8 ] = (float) z0;
                   
                   triIndex ++; 
                   vertices[triIndex*9 + 0 ] = (float)(x1 * zr0);   vertices[triIndex*9 + 1 ] = (float)(y1 * zr0);    vertices[triIndex*9 + 2 ] = (float) z0;
                   vertices[triIndex*9 + 3 ] = (float)(x * zr1);    vertices[triIndex*9 + 4 ] = (float)(y * zr1);     vertices[triIndex*9 + 5 ] = (float) z1;  
                   vertices[triIndex*9 + 6 ] = (float)(x1 * zr1);    vertices[triIndex*9 + 7 ] = (float)(y1 * zr1);   vertices[triIndex*9 + 8 ] = (float) z1;
                   
                   // in this case, the normal is the same as the vertex, plus the normalization; 
                   for (int kk = -9; kk<9 ; kk++) {
                     normals[triIndex*9 + kk] = vertices[triIndex*9+kk];
                     if((triIndex*9 + kk)%3 == 2)
                       colors[triIndex*9 + kk] = 1;
                     else
                       colors[triIndex*9 + kk] = 0;                     
                   }                   
                   triIndex ++; 
               }
               //glEnd();
           }
  }
  
  public Sphere(double r, int lats, int longs) {
    
    // first create the sphere data; 
    createSphere(r, lats, longs); 
    
    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
        // (# of coordinate values * 4 bytes per float
        vertices.length * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());
    
    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    vertexBuffer.put(vertices);
    // set the buffer to read the first coordinate
    vertexBuffer.position(0);
    
    
    ByteBuffer bb2 = ByteBuffer.allocateDirect(
        // (# of color values * 4 bytes per float
        colors.length * 4);
    bb2.order(ByteOrder.nativeOrder());
    
    // create a floating point buffer from the ByteBuffer
    colorBuffer = bb2.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    colorBuffer.put(colors);
    // set the buffer to read the first coordinate
    colorBuffer.position(0);
    
    // normal buffer; 
    ByteBuffer bb3 = ByteBuffer.allocateDirect(normals.length * 4);
    bb3.order(ByteOrder.nativeOrder());
        
    normalBuffer = bb3.asFloatBuffer();
    normalBuffer.put(normals);
    normalBuffer.position(0);
        
    // initialize byte buffer for the draw list
    ByteBuffer dlb = ByteBuffer.allocateDirect(
        // (# of coordinate values * 2 bytes per short
        drawOrder.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(drawOrder);
    drawListBuffer.position(0);
    
    int vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    checkShaderError(vertexShader);
    int fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
    checkShaderError(fragmentShader);
    mProgram = GLES20.glCreateProgram();        // create empty OpenGL ES program
    GLES20.glAttachShader(mProgram,  vertexShader);    // add the vertex shader to program
    GLES20.glAttachShader(mProgram, fragmentShader);  // add the fragment shader to program
    GLES20.glLinkProgram(mProgram);            // creates OpenGL ES program executables
    
  }
  
  
  
  public void draw(float[] mvpMatrix, float [] normalMat, float [] mvMat) {  // pass in the calculated transformation matrix
    
    //
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram);
    
    //GLES20.glPolygonMode(GLES20.GL_FRONT,GLES20.GL_LINE);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    
    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    
    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                  GLES20.GL_FLOAT, false,
                  vertexStride, vertexBuffer);
    
    // get handle to fragment shader's light direction
    int light = GLES20.glGetUniformLocation(mProgram, "lightDir");
    
    // Set color for drawing the triangle
    GLES20.glUniform3fv(light, 1, lightDir, 0);
    
    mColorHandle = GLES20.glGetAttribLocation(mProgram, "vColor");
    
    GLES20.glEnableVertexAttribArray(mColorHandle);
        
    // Prepare the color data
    GLES20.glVertexAttribPointer(mColorHandle, COORDS_PER_VERTEX,
                      GLES20.GL_FLOAT, false,
                      vertexStride, colorBuffer);
    
    // now deal with normals
    mNormalHandle = GLES20.glGetAttribLocation(mProgram, "vNormal");  
    GLES20.glEnableVertexAttribArray(mNormalHandle);
    // Prepare the normal data
    GLES20.glVertexAttribPointer(mNormalHandle, COORDS_PER_VERTEX,
                              GLES20.GL_FLOAT, false,
                              vertexStride, normalBuffer);    
    
    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    mNormalMatHandle = GLES20.glGetUniformLocation(mProgram, "uNormalMat");
    
    int MVMatHandle = GLES20.glGetUniformLocation(mProgram, "uMVMatrix");
    
    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
    GLES20.glUniformMatrix4fv(mNormalMatHandle, 1, false, normalMat, 0);
    GLES20.glUniformMatrix4fv(MVMatHandle, 1, false, mvMat, 0);
    
    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
    //GLES20.glDrawArrays(GLES20.GL_POINTS, 0, vertexCount);
    
    //for (int i = 0; i< vertexCount; i+=3) 
      //GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, i, 3);
    
    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
    GLES20.glDisableVertexAttribArray(mColorHandle);
    GLES20.glDisableVertexAttribArray(mNormalHandle);
  }
}




Java Source Code List

graphics.bradley.androidglviewer.Cube.java
graphics.bradley.androidglviewer.MainGLActivity.java
graphics.bradley.androidglviewer.MyGL20Renderer.java
graphics.bradley.androidglviewer.MyGLSurfaceView.java
graphics.bradley.androidglviewer.Sphere.java