Guest User

Untitled

a guest
Aug 19th, 2012
689
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 64.32 KB | None | 0 0
  1. package com.atonea.SpaceRisk;
  2.  
  3. import java.nio.ByteBuffer;
  4. import java.nio.ByteOrder;
  5. import java.nio.FloatBuffer;
  6. import java.nio.ShortBuffer;
  7.  
  8. import javax.microedition.khronos.egl.EGLConfig;
  9. import javax.microedition.khronos.opengles.GL10;
  10.  
  11. import android.opengl.GLES20;
  12. import android.opengl.GLSurfaceView;
  13. import android.opengl.Matrix;
  14. import android.os.SystemClock;
  15. import android.util.Log;
  16.  
  17. public class SRTrenderer implements GLSurfaceView.Renderer {
  18.     /** Used for debug logs. */
  19.     private static final String TAG = "LessonTwoRenderer";
  20.  
  21.     /**
  22.      * Store the model matrix. This matrix is used to move models from object space (where each model can be thought
  23.      * of being located at the center of the universe) to world space.
  24.      */
  25.     private float[] mModelMatrix = new float[16];
  26.  
  27.     /**
  28.      * Store the view matrix. This can be thought of as our camera. This matrix transforms world space to eye space;
  29.      * it positions things relative to our eye.
  30.      */
  31.     private float[] mViewMatrix = new float[16];
  32.  
  33.     /** Store the projection matrix. This is used to project the scene onto a 2D viewport. */
  34.     private float[] mProjectionMatrix = new float[16];
  35.  
  36.     /** Allocate storage for the final combined matrix. This will be passed into the shader program. */
  37.     private float[] mMVPMatrix = new float[16];
  38.  
  39.     /**
  40.      * Stores a copy of the model matrix specifically for the light position.
  41.      */
  42.     private float[] mLightModelMatrix = new float[16]; 
  43.  
  44.     /** Store our model data in a float buffer. */
  45.     private final FloatBuffer mCubePositions;
  46.     private final FloatBuffer mCubeColors;
  47.     private final FloatBuffer mCubeNormals;
  48.     private final FloatBuffer mSpherePositions;
  49.     private final ShortBuffer drawListBuffer;
  50.     short[] sphereDrawOrder;
  51.    
  52.  
  53.     /** This will be used to pass in the transformation matrix. */
  54.     private int mMVPMatrixHandle;
  55.  
  56.     /** This will be used to pass in the modelview matrix. */
  57.     private int mMVMatrixHandle;
  58.  
  59.     /** This will be used to pass in the light position. */
  60.     private int mLightPosHandle;
  61.  
  62.     /** This will be used to pass in model position information. */
  63.     private int mPositionHandle;
  64.  
  65.     /** This will be used to pass in model color information. */
  66.     private int mColorHandle;
  67.  
  68.     /** This will be used to pass in model normal information. */
  69.     private int mNormalHandle;
  70.  
  71.     /** How many bytes per float. */
  72.     private final int mBytesPerFloat = 4;  
  73.  
  74.     /** Size of the position data in elements. */
  75.     private final int mPositionDataSize = 3;   
  76.  
  77.     /** Size of the color data in elements. */
  78.     private final int mColorDataSize = 4;  
  79.  
  80.     /** Size of the normal data in elements. */
  81.     private final int mNormalDataSize = 3;
  82.  
  83.     /** Used to hold a light centered on the origin in model space. We need a 4th coordinate so we can get translations to work when
  84.      *  we multiply this by our transformation matrices. */
  85.     private final float[] mLightPosInModelSpace = new float[] {0.0f, 0.0f, 0.0f, 1.0f};
  86.  
  87.     /** Used to hold the current position of the light in world space (after transformation via model matrix). */
  88.     private final float[] mLightPosInWorldSpace = new float[4];
  89.  
  90.     /** Used to hold the transformed position of the light in eye space (after transformation via modelview matrix) */
  91.     private final float[] mLightPosInEyeSpace = new float[4];
  92.  
  93.     /** This is a handle to our per-vertex cube shading program. */
  94.     private int mPerVertexProgramHandle;
  95.  
  96.     /** This is a handle to our light point program. */
  97.     private int mPointProgramHandle;   
  98.  
  99.     /**
  100.      * Initialize the model data.
  101.      */
  102.     public SRTrenderer()
  103.     {  
  104.         // Define points for a cube.       
  105.  
  106.         // X, Y, Z
  107. // In OpenGL counter-clockwise winding is default. This means that when we look at a triangle,
  108.                 // if the points are counter-clockwise we are looking at the "front". If not we are looking at
  109.                 // the back. OpenGL has an optimization where all back-facing triangles are culled, since they
  110.                 // usually represent the backside of an object and aren't visible anyways.
  111.  
  112.                 // Front face
  113.                 -1.0f, 1.0f, 1.0f,             
  114.                 -1.0f, -1.0f, 1.0f,
  115.                 1.0f, 1.0f, 1.0f,
  116.                 -1.0f, -1.0f, 1.0f,                
  117.                 1.0f, -1.0f, 1.0f,
  118.                 1.0f, 1.0f, 1.0f,
  119.  
  120.                 // Right face
  121.                 1.0f, 1.0f, 1.0f,              
  122.                 1.0f, -1.0f, 1.0f,
  123.                 1.0f, 1.0f, -1.0f,
  124.                 1.0f, -1.0f, 1.0f,             
  125.                 1.0f, -1.0f, -1.0f,
  126.                 1.0f, 1.0f, -1.0f,
  127.  
  128.                 // Back face
  129.                 1.0f, 1.0f, -1.0f,             
  130.                 1.0f, -1.0f, -1.0f,
  131.                 -1.0f, 1.0f, -1.0f,
  132.                 1.0f, -1.0f, -1.0f,            
  133.                 -1.0f, -1.0f, -1.0f,
  134.                 -1.0f, 1.0f, -1.0f,
  135.  
  136.                 // Left face
  137.                 -1.0f, 1.0f, -1.0f,            
  138.                 -1.0f, -1.0f, -1.0f,
  139.                 -1.0f, 1.0f, 1.0f,
  140.                 -1.0f, -1.0f, -1.0f,               
  141.                 -1.0f, -1.0f, 1.0f,
  142.                 -1.0f, 1.0f, 1.0f,
  143.  
  144.                 // Top face
  145.                 -1.0f, 1.0f, -1.0f,            
  146.                 -1.0f, 1.0f, 1.0f,
  147.                 1.0f, 1.0f, -1.0f,
  148.                 -1.0f, 1.0f, 1.0f,             
  149.                 1.0f, 1.0f, 1.0f,
  150.                 1.0f, 1.0f, -1.0f,
  151.  
  152.                 // Bottom face
  153.                 1.0f, -1.0f, -1.0f,            
  154.                 1.0f, -1.0f, 1.0f,
  155.                 -1.0f, -1.0f, -1.0f,
  156.                 1.0f, -1.0f, 1.0f,             
  157.                 -1.0f, -1.0f, 1.0f,
  158.                 -1.0f, -1.0f, -1.0f,
  159.         }; 
  160.  
  161.         // R, G, B, A
  162.         final float[] cubeColorData =
  163.         {              
  164.                 // Front face (red)
  165.                 1.0f, 0.0f, 0.0f, 1.0f,            
  166.                 1.0f, 0.0f, 0.0f, 1.0f,
  167.                 1.0f, 0.0f, 0.0f, 1.0f,
  168.                 1.0f, 0.0f, 0.0f, 1.0f,            
  169.                 1.0f, 0.0f, 0.0f, 1.0f,
  170.                 1.0f, 0.0f, 0.0f, 1.0f,
  171.  
  172.                 // Right face (green)
  173.                 0.0f, 1.0f, 0.0f, 1.0f,            
  174.                 0.0f, 1.0f, 0.0f, 1.0f,
  175.                 0.0f, 1.0f, 0.0f, 1.0f,
  176.                 0.0f, 1.0f, 0.0f, 1.0f,            
  177.                 0.0f, 1.0f, 0.0f, 1.0f,
  178.                 0.0f, 1.0f, 0.0f, 1.0f,
  179.  
  180.                 // Back face (blue)
  181.                 0.0f, 0.0f, 1.0f, 1.0f,            
  182.                 0.0f, 0.0f, 1.0f, 1.0f,
  183.                 0.0f, 0.0f, 1.0f, 1.0f,
  184.                 0.0f, 0.0f, 1.0f, 1.0f,            
  185.                 0.0f, 0.0f, 1.0f, 1.0f,
  186.                 0.0f, 0.0f, 1.0f, 1.0f,
  187.  
  188.                 // Left face (yellow)
  189.                 1.0f, 1.0f, 0.0f, 1.0f,            
  190.                 1.0f, 1.0f, 0.0f, 1.0f,
  191.                 1.0f, 1.0f, 0.0f, 1.0f,
  192.                 1.0f, 1.0f, 0.0f, 1.0f,            
  193.                 1.0f, 1.0f, 0.0f, 1.0f,
  194.                 1.0f, 1.0f, 0.0f, 1.0f,
  195.  
  196.                 // Top face (cyan)
  197.                 0.0f, 1.0f, 1.0f, 1.0f,            
  198.                 0.0f, 1.0f, 1.0f, 1.0f,
  199.                 0.0f, 1.0f, 1.0f, 1.0f,
  200.                 0.0f, 1.0f, 1.0f, 1.0f,            
  201.                 0.0f, 1.0f, 1.0f, 1.0f,
  202.                 0.0f, 1.0f, 1.0f, 1.0f,
  203.  
  204.                 // Bottom face (magenta)
  205.                 1.0f, 0.0f, 1.0f, 1.0f,            
  206.                 1.0f, 0.0f, 1.0f, 1.0f,
  207.                 1.0f, 0.0f, 1.0f, 1.0f,
  208.                 1.0f, 0.0f, 1.0f, 1.0f,            
  209.                 1.0f, 0.0f, 1.0f, 1.0f,
  210.                 1.0f, 0.0f, 1.0f, 1.0f
  211.         };
  212.  
  213.         // X, Y, Z
  214.         // The normal is used in light calculations and is a vector which points
  215.         // orthogonal to the plane of the surface. For a cube model, the normals
  216.         // should be orthogonal to the points of each face.
  217.         final float[] cubeNormalData =
  218.         {                                              
  219.                 // Front face
  220.                 0.0f, 0.0f, 1.0f,              
  221.                 0.0f, 0.0f, 1.0f,
  222.                 0.0f, 0.0f, 1.0f,
  223.                 0.0f, 0.0f, 1.0f,              
  224.                 0.0f, 0.0f, 1.0f,
  225.                 0.0f, 0.0f, 1.0f,
  226.  
  227.                 // Right face
  228.                 1.0f, 0.0f, 0.0f,              
  229.                 1.0f, 0.0f, 0.0f,
  230.                 1.0f, 0.0f, 0.0f,
  231.                 1.0f, 0.0f, 0.0f,              
  232.                 1.0f, 0.0f, 0.0f,
  233.                 1.0f, 0.0f, 0.0f,
  234.  
  235.                 // Back face
  236.                 0.0f, 0.0f, -1.0f,             
  237.                 0.0f, 0.0f, -1.0f,
  238.                 0.0f, 0.0f, -1.0f,
  239.                 0.0f, 0.0f, -1.0f,             
  240.                 0.0f, 0.0f, -1.0f,
  241.                 0.0f, 0.0f, -1.0f,
  242.  
  243.                 // Left face
  244.                 -1.0f, 0.0f, 0.0f,             
  245.                 -1.0f, 0.0f, 0.0f,
  246.                 -1.0f, 0.0f, 0.0f,
  247.                 -1.0f, 0.0f, 0.0f,             
  248.                 -1.0f, 0.0f, 0.0f,
  249.                 -1.0f, 0.0f, 0.0f,
  250.  
  251.                 // Top face
  252.                 0.0f, 1.0f, 0.0f,          
  253.                 0.0f, 1.0f, 0.0f,
  254.                 0.0f, 1.0f, 0.0f,
  255.                 0.0f, 1.0f, 0.0f,              
  256.                 0.0f, 1.0f, 0.0f,
  257.                 0.0f, 1.0f, 0.0f,
  258.  
  259.                 // Bottom face
  260.                 0.0f, -1.0f, 0.0f,         
  261.                 0.0f, -1.0f, 0.0f,
  262.                 0.0f, -1.0f, 0.0f,
  263.                 0.0f, -1.0f, 0.0f,             
  264.                 0.0f, -1.0f, 0.0f,
  265.                 0.0f, -1.0f, 0.0f
  266.         };
  267.  
  268.         // Initialize the buffers.
  269.         mCubePositions = ByteBuffer.allocateDirect(cubePositionData.length * mBytesPerFloat)
  270.         .order(ByteOrder.nativeOrder()).asFloatBuffer();                           
  271.         mCubePositions.put(cubePositionData).position(0);
  272.        
  273.         mSpherePositions = ByteBuffer.allocateDirect(spherePositionData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
  274.         mSpherePositions.put(spherePositionData).position(0);
  275.        
  276.         ByteBuffer dlb = ByteBuffer.allocateDirect(sphereDrawOrder.length * 2).order(ByteOrder.nativeOrder());
  277.         drawListBuffer = dlb.asShortBuffer();
  278.         drawListBuffer.put(sphereDrawOrder);
  279.         drawListBuffer.position(0);
  280.  
  281.  
  282.         mCubeColors = ByteBuffer.allocateDirect(cubeColorData.length * mBytesPerFloat)
  283.         .order(ByteOrder.nativeOrder()).asFloatBuffer();                           
  284.         mCubeColors.put(cubeColorData).position(0);
  285.  
  286.         mCubeNormals = ByteBuffer.allocateDirect(cubeNormalData.length * mBytesPerFloat)
  287.         .order(ByteOrder.nativeOrder()).asFloatBuffer();                           
  288.         mCubeNormals.put(cubeNormalData).position(0);
  289.        
  290.     }
  291.  
  292.     protected String getVertexShader()
  293.     {
  294.         // TODO: Explain why we normalize the vectors, explain some of the vector math behind it all. Explain what is eye space.
  295.         final String vertexShader =
  296.             "uniform mat4 u_MVPMatrix;      \n"     // A constant representing the combined model/view/projection matrix.
  297.           + "uniform mat4 u_MVMatrix;       \n"     // A constant representing the combined model/view matrix. 
  298.           + "uniform vec3 u_LightPos;       \n"     // The position of the light in eye space.
  299.  
  300.           + "attribute vec4 a_Position;     \n"     // Per-vertex position information we will pass in.
  301.           + "attribute vec4 a_Color;        \n"     // Per-vertex color information we will pass in.
  302.           + "attribute vec3 a_Normal;       \n"     // Per-vertex normal information we will pass in.
  303.  
  304.           + "varying vec4 v_Color;          \n"     // This will be passed into the fragment shader.
  305.  
  306.           + "void main()                    \n"     // The entry point for our vertex shader.
  307.           + "{                              \n"    
  308.         // Transform the vertex into eye space.
  309.           + "   vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);              \n"
  310.         // Transform the normal's orientation into eye space.
  311.           + "   vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));     \n"
  312.         // Will be used for attenuation.
  313.           + "   float distance = length(u_LightPos - modelViewVertex);             \n"
  314.         // Get a lighting direction vector from the light to the vertex.
  315.           + "   vec3 lightVector = normalize(u_LightPos - modelViewVertex);        \n"
  316.         // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
  317.         // pointing in the same direction then it will get max illumination.
  318.           + "   float diffuse = max(dot(modelViewNormal, lightVector), 0.1);       \n"                                                               
  319.         // Attenuate the light based on distance.
  320.           + "   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));  \n"
  321.         // Multiply the color by the illumination level. It will be interpolated across the triangle.
  322.           + "   v_Color = a_Color * diffuse;                                       \n"  
  323.         // gl_Position is a special variable used to store the final position.
  324.         // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.      
  325.           + "   gl_Position = u_MVPMatrix * a_Position;                            \n"    
  326.           + "}                                                                     \n";
  327.  
  328.         return vertexShader;
  329.     }
  330.  
  331.     protected String getFragmentShader()
  332.     {
  333.         final String fragmentShader =
  334.             "precision mediump float;       \n"     // Set the default precision to medium. We don't need as high of a
  335.                                                     // precision in the fragment shader.               
  336.           + "varying vec4 v_Color;          \n"     // This is the color from the vertex shader interpolated across the
  337.                                                     // triangle per fragment.            
  338.           + "void main()                    \n"     // The entry point for our fragment shader.
  339.           + "{                              \n"
  340.           + "   gl_FragColor = v_Color;     \n"     // Pass the color directly through the pipeline.         
  341.           + "}                              \n";
  342.  
  343.         return fragmentShader;
  344.     }
  345.  
  346.     @Override
  347.     public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
  348.     {
  349.         // Set the background clear color to black.
  350.         GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  351.  
  352.         // Use culling to remove back faces.
  353.         GLES20.glEnable(GLES20.GL_CULL_FACE);
  354.  
  355.         // Enable depth testing
  356.         GLES20.glEnable(GLES20.GL_DEPTH_TEST);
  357.  
  358.         // Position the eye in front of the origin.
  359.         final float eyeX = 0.0f;
  360.         final float eyeY = 0.0f;
  361.         final float eyeZ = -0.5f;
  362.  
  363.         // We are looking toward the distance
  364.         final float lookX = 0.0f;
  365.         final float lookY = 0.0f;
  366.         final float lookZ = -5.0f;
  367.  
  368.         // Set our up vector. This is where our head would be pointing were we holding the camera.
  369.         final float upX = 0.0f;
  370.         final float upY = 1.0f;
  371.         final float upZ = 0.0f;
  372.  
  373.         // Set the view matrix. This matrix can be said to represent the camera position.
  374.         // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and
  375.         // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose.
  376.         Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);       
  377.  
  378.         final String vertexShader = getVertexShader();         
  379.         final String fragmentShader = getFragmentShader();         
  380.  
  381.         final int vertexShaderHandle = compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);       
  382.         final int fragmentShaderHandle = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);     
  383.  
  384.         mPerVertexProgramHandle = createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle,
  385.                 new String[] {"a_Position",  "a_Color", "a_Normal"});                                                                                                  
  386.        
  387.         // Define a simple shader program for our point.
  388.         final String pointVertexShader =
  389.             "uniform mat4 u_MVPMatrix;      \n"    
  390.           + "attribute vec4 a_Position;     \n"    
  391.           + "void main()                    \n"
  392.           + "{                              \n"
  393.           + "   gl_Position = u_MVPMatrix   \n"
  394.           + "               * a_Position;   \n"
  395.           + "   gl_PointSize = 5.0;         \n"
  396.           + "}                              \n";
  397.        
  398.         final String pointFragmentShader =
  399.             "precision mediump float;       \n"                          
  400.           + "void main()                    \n"
  401.           + "{                              \n"
  402.           + "   gl_FragColor = vec4(1.0,    \n"
  403.           + "   1.0, 1.0, 1.0);             \n"
  404.           + "}                              \n";
  405.        
  406.         final int pointVertexShaderHandle = compileShader(GLES20.GL_VERTEX_SHADER, pointVertexShader);
  407.         final int pointFragmentShaderHandle = compileShader(GLES20.GL_FRAGMENT_SHADER, pointFragmentShader);
  408.         mPointProgramHandle = createAndLinkProgram(pointVertexShaderHandle, pointFragmentShaderHandle,
  409.                 new String[] {"a_Position"});                
  410.     }  
  411.  
  412.     @Override
  413.     public void onSurfaceChanged(GL10 glUnused, int width, int height)
  414.     {
  415.         // Set the OpenGL viewport to the same size as the surface.
  416.         GLES20.glViewport(0, 0, width, height);
  417.  
  418.         // Create a new perspective projection matrix. The height will stay the same
  419.         // while the width will vary as per aspect ratio.
  420.         final float ratio = (float) width / height;
  421.         final float left = -ratio;
  422.         final float right = ratio;
  423.         final float bottom = -1.0f;
  424.         final float top = 1.0f;
  425.         final float near = 1.0f;
  426.         final float far = 10.0f;
  427.  
  428.         Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
  429.     }  
  430.  
  431.     @Override
  432.     public void onDrawFrame(GL10 glUnused)
  433.     {
  434.         GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);                   
  435.                
  436.         // Do a complete rotation every 10 seconds.
  437.         long time = SystemClock.uptimeMillis() % 10000L;        
  438.         float angleInDegrees = (360.0f / 10000.0f) * ((int) time);
  439.         float cuberotate = (720.0f / 10000.0f) * ((int) time);
  440.        
  441.         // Set our per-vertex lighting program.
  442.         GLES20.glUseProgram(mPerVertexProgramHandle);
  443.        
  444.         // Set program handles for cube drawing.
  445.         mMVPMatrixHandle = GLES20.glGetUniformLocation(mPerVertexProgramHandle, "u_MVPMatrix");
  446.         mMVMatrixHandle = GLES20.glGetUniformLocation(mPerVertexProgramHandle, "u_MVMatrix");
  447.         mLightPosHandle = GLES20.glGetUniformLocation(mPerVertexProgramHandle, "u_LightPos");
  448.         mPositionHandle = GLES20.glGetAttribLocation(mPerVertexProgramHandle, "a_Position");
  449.         mColorHandle = GLES20.glGetAttribLocation(mPerVertexProgramHandle, "a_Color");
  450.         mNormalHandle = GLES20.glGetAttribLocation(mPerVertexProgramHandle, "a_Normal");
  451.        
  452.         // Calculate position of the light. Rotate and then push into the distance.
  453.         Matrix.setIdentityM(mLightModelMatrix, 0);
  454.         Matrix.translateM(mLightModelMatrix, 0, 0.0f, 0.0f, -5.0f);      
  455.         Matrix.rotateM(mLightModelMatrix, 0, angleInDegrees, 0.0f, 1.0f, 0.0f);
  456.         Matrix.translateM(mLightModelMatrix, 0, 0.0f, 0.0f, 2.0f);
  457.                
  458.         Matrix.multiplyMV(mLightPosInWorldSpace, 0, mLightModelMatrix, 0, mLightPosInModelSpace, 0);
  459.         Matrix.multiplyMV(mLightPosInEyeSpace, 0, mViewMatrix, 0, mLightPosInWorldSpace, 0);                        
  460.        
  461.         // Draw some cubes.        
  462.        
  463.         Matrix.setIdentityM(mModelMatrix, 0);
  464.         Matrix.rotateM(mModelMatrix, 0, cuberotate, 1.0f, 1.0f, 0.0f);        
  465.         drawSphere();    
  466.        
  467.        
  468.         // Draw a point to indicate the light.
  469.         GLES20.glUseProgram(mPointProgramHandle);        
  470.         drawLight();
  471.     }                  
  472.    
  473.    
  474.     private void drawCube()
  475.     {      
  476.         // Pass in the position information
  477.         mCubePositions.position(0);    
  478.         GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
  479.                 0, mCubePositions);        
  480.                
  481.         GLES20.glEnableVertexAttribArray(mPositionHandle);        
  482.        
  483.         // Pass in the color information
  484.         mCubeColors.position(0);
  485.         GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
  486.                 0, mCubeColors);        
  487.        
  488.         GLES20.glEnableVertexAttribArray(mColorHandle);
  489.        
  490.         // Pass in the normal information
  491.         mCubeNormals.position(0);
  492.         GLES20.glVertexAttribPointer(mNormalHandle, mNormalDataSize, GLES20.GL_FLOAT, false,
  493.                 0, mCubeNormals);
  494.        
  495.         GLES20.glEnableVertexAttribArray(mNormalHandle);
  496.        
  497.         // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
  498.         // (which currently contains model * view).
  499.         Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);  
  500.        
  501.         // Pass in the modelview matrix.
  502.         GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);                
  503.        
  504.         // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
  505.         // (which now contains model * view * projection).
  506.         Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
  507.  
  508.         // Pass in the combined matrix.
  509.         GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
  510.        
  511.         // Pass in the light position in eye space.        
  512.         GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
  513.        
  514.         // Draw the cube.
  515.         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36);                              
  516.     }  
  517.    
  518.     private void drawSphere()
  519.     {      
  520.         // Pass in the position information
  521.         mSpherePositions.position(0);      
  522.         GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
  523.                 0, mSpherePositions);        
  524.                
  525.         GLES20.glEnableVertexAttribArray(mPositionHandle);        
  526.        
  527.         // Pass in the color information
  528.  
  529.        
  530.         // Pass in the normal information
  531.  
  532.        
  533.         // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
  534.         // (which currently contains model * view).
  535.         Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);  
  536.        
  537.         // Pass in the modelview matrix.
  538.         GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);                
  539.        
  540.         // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
  541.         // (which now contains model * view * projection).
  542.         Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
  543.  
  544.         // Pass in the combined matrix.
  545.         GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
  546.        
  547.         // Pass in the light position in eye space.        
  548.         GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
  549.        
  550.         // Draw the sphere.
  551.         GLES20.glDrawElements(GLES20.GL_TRIANGLES, sphereDrawOrder.length,
  552.                 GLES20.GL_UNSIGNED_SHORT, drawListBuffer);                              
  553.     }  
  554.  
  555.     /**
  556.      * Draws a point representing the position of the light.
  557.      */
  558.     private void drawLight()
  559.     {
  560.         final int pointMVPMatrixHandle = GLES20.glGetUniformLocation(mPointProgramHandle, "u_MVPMatrix");
  561.         final int pointPositionHandle = GLES20.glGetAttribLocation(mPointProgramHandle, "a_Position");
  562.        
  563.         // Pass in the position.
  564.         GLES20.glVertexAttrib3f(pointPositionHandle, mLightPosInModelSpace[0], mLightPosInModelSpace[1], mLightPosInModelSpace[2]);
  565.  
  566.         // Since we are not using a buffer object, disable vertex arrays for this attribute.
  567.         GLES20.glDisableVertexAttribArray(pointPositionHandle);  
  568.  
  569.         // Pass in the transformation matrix.
  570.         Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mLightModelMatrix, 0);
  571.         Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
  572.         GLES20.glUniformMatrix4fv(pointMVPMatrixHandle, 1, false, mMVPMatrix, 0);
  573.  
  574.         // Draw the point.
  575.         GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1);
  576.     }
  577.  
  578.     /**
  579.      * Helper function to compile a shader.
  580.      *
  581.      * @param shaderType The shader type.
  582.      * @param shaderSource The shader source code.
  583.      * @return An OpenGL handle to the shader.
  584.      */
  585.     private int compileShader(final int shaderType, final String shaderSource)
  586.     {
  587.         int shaderHandle = GLES20.glCreateShader(shaderType);
  588.  
  589.         if (shaderHandle != 0)
  590.         {
  591.             // Pass in the shader source.
  592.             GLES20.glShaderSource(shaderHandle, shaderSource);
  593.  
  594.             // Compile the shader.
  595.             GLES20.glCompileShader(shaderHandle);
  596.  
  597.             // Get the compilation status.
  598.             final int[] compileStatus = new int[1];
  599.             GLES20.glGetShaderiv(shaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
  600.  
  601.             // If the compilation failed, delete the shader.
  602.             if (compileStatus[0] == 0)
  603.             {
  604.                 Log.e(TAG, "Error compiling shader: " + GLES20.glGetShaderInfoLog(shaderHandle));
  605.                 GLES20.glDeleteShader(shaderHandle);
  606.                 shaderHandle = 0;
  607.             }
  608.         }
  609.  
  610.         if (shaderHandle == 0)
  611.         {          
  612.             throw new RuntimeException("Error creating shader.");
  613.         }
  614.  
  615.         return shaderHandle;
  616.     }  
  617.  
  618.     /**
  619.      * Helper function to compile and link a program.
  620.      *
  621.      * @param vertexShaderHandle An OpenGL handle to an already-compiled vertex shader.
  622.      * @param fragmentShaderHandle An OpenGL handle to an already-compiled fragment shader.
  623.      * @param attributes Attributes that need to be bound to the program.
  624.      * @return An OpenGL handle to the program.
  625.      */
  626.     private int createAndLinkProgram(final int vertexShaderHandle, final int fragmentShaderHandle, final String[] attributes)
  627.     {
  628.         int programHandle = GLES20.glCreateProgram();
  629.  
  630.         if (programHandle != 0)
  631.         {
  632.             // Bind the vertex shader to the program.
  633.             GLES20.glAttachShader(programHandle, vertexShaderHandle);          
  634.  
  635.             // Bind the fragment shader to the program.
  636.             GLES20.glAttachShader(programHandle, fragmentShaderHandle);
  637.  
  638.             // Bind attributes
  639.             if (attributes != null)
  640.             {
  641.                 final int size = attributes.length;
  642.                 for (int i = 0; i < size; i++)
  643.                 {
  644.                     GLES20.glBindAttribLocation(programHandle, i, attributes[i]);
  645.                 }                      
  646.             }
  647.  
  648.             // Link the two shaders together into a program.
  649.             GLES20.glLinkProgram(programHandle);
  650.  
  651.             // Get the link status.
  652.             final int[] linkStatus = new int[1];
  653.             GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);
  654.  
  655.             // If the link failed, delete the program.
  656.             if (linkStatus[0] == 0)
  657.             {              
  658.                 Log.e(TAG, "Error compiling program: " + GLES20.glGetProgramInfoLog(programHandle));
  659.                 GLES20.glDeleteProgram(programHandle);
  660.                 programHandle = 0;
  661.             }
  662.         }
  663.  
  664.         if (programHandle == 0)
  665.         {
  666.             throw new RuntimeException("Error creating program.");
  667.         }
  668.  
  669.         return programHandle;
  670.     }
  671. }
Advertisement
Add Comment
Please, Sign In to add comment