2012-12-29 85 views
0

我想在android中深入學習OpenGLES 2.0。我試圖在屏幕中心繪製一個簡單的點,但不知何故,重點並未顯示。點不顯示在opengles 2.0中

public class MyRenderer implements GLSurfaceView.Renderer { 
    Context context; 

    private int mProgram; 

    private final float[] mViewMatrix=new float[16]; 
    private float[] mProjectionMatrix=new float[16]; 
    private final float[] mPointModelMatrix=new float[16]; 

    private final float[] mMVPMatrix=new float[16]; 

    private final float[] mPointPosInModelSpace = new float[] {0.0f, 0.0f, 0.0f, 1.0f}; 
    private final float[] mPointPosInWorldSpace = new float[4]; 
    private final float[] mPointPosInEyeSpace = new float[4]; 

    private int pointMVPMatrixHandle; 
    private int pointPositionHandle; 

public MyRenderer(Context context){ 
    this.context=context; 
} 


public void onDrawFrame(GL10 arg0) { 
    // TODO Auto-generated method stub 

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

    Matrix.setIdentityM(mPointModelMatrix, 0); 


    Matrix.translateM(mPointModelMatrix, 0, 0.0f, 0.0f, -3.0f); 

    Matrix.multiplyMV(mPointPosInWorldSpace, 0, mPointModelMatrix, 0, mPointPosInModelSpace, 0); 
    Matrix.multiplyMV(mPointPosInEyeSpace, 0, mViewMatrix, 0, mPointPosInWorldSpace, 0); 

    GLES20.glUseProgram(mProgram); 

    drawPoint();   
} 


private void drawPoint(){ 

    pointMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix"); 
    pointPositionHandle=GLES20.glGetAttribLocation(mProgram, "a_position"); 

    GLES20.glVertexAttrib3f(pointPositionHandle, mPointPosInEyeSpace[0], mPointPosInEyeSpace[1], mPointPosInEyeSpace[2]); 
    GLES20.glDisableVertexAttribArray(pointPositionHandle); 

    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mPointModelMatrix, 0); 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); 
    GLES20.glUniformMatrix4fv(pointMVPMatrixHandle, 1, false, mMVPMatrix, 0); 

    // Draw the point. 
    GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1); 


} 

public void onSurfaceChanged(GL10 gl, int width, int height) { 
    // TODO Auto-generated method stub 
GLES20.glViewport(0, 0, width, height); 

final float ratio=(float)width/height; 
    Log.d("Ratio is", " "+ratio); 
    Log.d("Width is"," "+width+" and "+height); 
final float left = -ratio; 
final float right = ratio; 
final float bottom= -1.0f; 
final float top = 1.0f; 
final float near = 1.0f; 
final float far = 10.0f; 


Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far); 
} 

public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    // TODO Auto-generated method stub 
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 

    GLES20.glEnable(GLES20.GL_CULL_FACE); 
    GLES20.glEnable(GLES20.GL_DEPTH_TEST); 

    float eyeX=0.0f; 
    float eyeY=0.0f; 
    float eyeZ=-0.5f; 

    float centerX=0.0f; 
    float centerY=0.0f; 
    float centerZ=-5.0f; 

    float upX=0.0f; 
    float upY=1.0f; 
    float upZ=0.0f; 

    Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); 

    final String vertexShader=this.getVertexShader(); 
    final String fragmentShader=this.getFragmentShader(); 

    final int vertexShaderHandle=ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader); 
    final int fragmentShaderHandle=ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader); 


    mProgram=ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, new String[]{"a_position"});  
} 

private String getVertexShader(){ 
    final String vertexShader="uniform mat4 u_MVPMatrix;  \n"  
       + "attribute vec4 a_Position;  \n"  
       + "void main()     \n" 
       + "{        \n" 
       + " gl_Position = u_MVPMatrix \n" 
       + "    * a_Position; \n" 
       + " gl_PointSize = 10.0;   \n" 
       + "}        \n"; 

    return vertexShader; 

} 

private String getFragmentShader(){ 
    final String fragmentShader="precision mediump float;  \n"       
       + "void main()     \n" 
       + "{        \n" 
       + " gl_FragColor = vec4(1.0, \n" 
       + " 1.0, 1.0, 1.0);    \n" 
       + "}        \n"; 
    return fragmentShader; 
} 

}

我非常肯定,我指着兩個眼點在負Z方向(遠離觀衆)。該點應該顯示在頂點着色器中,點大小爲10.0,但不知何故,沒有運氣。

注意:ShaderHelper是一個靜態方法compileShader和createAndLinkProgram的類,其中編譯着色器,檢查錯誤的代碼被寫入。 (程序中沒有錯誤)

回答

3

這是一個基於您的代碼顯示點的基礎上構建的類。由於您最終可能會使用多個點,因此最好將點推入頂點數組中,如圖所示。

package point.example.point; 

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

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 
import android.opengl.GLES20; 
import android.opengl.GLSurfaceView; 
import android.opengl.Matrix; 

public class PointRenderer implements GLSurfaceView.Renderer 
{ 
    private float[] mModelMatrix = new float[16]; 
    private float[] mViewMatrix = new float[16]; 
    private float[] mProjectionMatrix = new float[16]; 
    private float[] mMVPMatrix = new float[16]; 
    private int mMVPMatrixHandle; 
    private int mPositionHandle; 

    float[] vertices = { 
       0.0f,0.0f,0.0f 
      }; 
    FloatBuffer vertexBuf; 

    @Override 
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
    {  
     vertexBuf = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     vertexBuf.put(vertices).position(0);   

     // Set the background clear color to gray. 
     GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f); 

     float eyeX=0.0f; 
     float eyeY=0.0f; 
     float eyeZ=0.0f; 

     float centerX=0.0f; 
     float centerY=0.0f; 
     float centerZ=-5.0f; 

     float upX=0.0f; 
     float upY=1.0f; 
     float upZ=0.0f; 

     // Set the view matrix. This matrix can be said to represent the camera position. 
     // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and 
     // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose. 
     Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); 

     final String vertexShader = 
          "uniform mat4 u_MVPMatrix;  \n"  
          + "attribute vec4 a_Position;  \n"  
          + "void main()     \n" 
          + "{        \n" 
          + " gl_Position = u_MVPMatrix \n" 
          + "    * a_Position; \n" 
          + " gl_PointSize = 10.0;  \n" 
          + "}        \n"; 

     final String fragmentShader = 
          "precision mediump float;  \n"       
          + "void main()     \n" 
          + "{        \n" 
          + " gl_FragColor = vec4(1.0, \n" 
          + " 1.0, 1.0, 1.0);    \n" 
          + "}        \n";  

     // Load in the vertex shader. 
     int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); 

     if (vertexShaderHandle != 0) 
     { 
      // Pass in the shader source. 
      GLES20.glShaderSource(vertexShaderHandle, vertexShader); 

      // Compile the shader. 
      GLES20.glCompileShader(vertexShaderHandle); 

      // Get the compilation status. 
      final int[] compileStatus = new int[1]; 
      GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0); 

      // If the compilation failed, delete the shader. 
      if (compileStatus[0] == 0) 
      {    
       GLES20.glDeleteShader(vertexShaderHandle); 
       vertexShaderHandle = 0; 
      } 
     } 

     if (vertexShaderHandle == 0) 
     { 
      throw new RuntimeException("Error creating vertex shader."); 
     } 

     // Load in the fragment shader shader. 
     int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); 

     if (fragmentShaderHandle != 0) 
     { 
      // Pass in the shader source. 
      GLES20.glShaderSource(fragmentShaderHandle, fragmentShader); 

      // Compile the shader. 
      GLES20.glCompileShader(fragmentShaderHandle); 

      // Get the compilation status. 
      final int[] compileStatus = new int[1]; 
      GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0); 

      // If the compilation failed, delete the shader. 
      if (compileStatus[0] == 0) 
      {    
       GLES20.glDeleteShader(fragmentShaderHandle); 
       fragmentShaderHandle = 0; 
      } 
     } 

     if (fragmentShaderHandle == 0) 
     { 
      throw new RuntimeException("Error creating fragment shader."); 
     } 

     // Create a program object and store the handle to it. 
     int programHandle = GLES20.glCreateProgram(); 

     if (programHandle != 0) 
     { 
      // Bind the vertex shader to the program. 
      GLES20.glAttachShader(programHandle, vertexShaderHandle);   
      // Bind the fragment shader to the program. 
      GLES20.glAttachShader(programHandle, fragmentShaderHandle); 
      // Bind attributes 
      GLES20.glBindAttribLocation(programHandle, 0, "a_Position"); 
      // Link the two shaders together into a program. 
      GLES20.glLinkProgram(programHandle); 
      // Get the link status. 
      final int[] linkStatus = new int[1]; 
      GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0); 
      // If the link failed, delete the program. 
      if (linkStatus[0] == 0) 
      {    
       GLES20.glDeleteProgram(programHandle); 
       programHandle = 0; 
      } 
     } 

     if (programHandle == 0) 
     { 
      throw new RuntimeException("Error creating program."); 
     } 

     // Set program handles. These will later be used to pass in values to the program. 
     mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");   
     mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position"); 

     // Tell OpenGL to use this program when rendering. 
     GLES20.glUseProgram(programHandle);   
    } 

    @Override 
    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
    { 
     // Set the OpenGL viewport to the same size as the surface. 
     GLES20.glViewport(0, 0, width, height); 

     // Create a new perspective projection matrix. The height will stay the same 
     // while the width will vary as per aspect ratio. 
     final float ratio = (float) width/height; 
     final float left = -ratio; 
     final float right = ratio; 
     final float bottom = -1.0f; 
     final float top = 1.0f; 
     final float near = 1.0f; 
     final float far = 100.0f; 

     Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far); 
    } 

    @Override 
    public void onDrawFrame(GL10 glUnused) 
    { 
     GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);      

     Matrix.setIdentityM(mModelMatrix, 0); 
     //Push to the distance - note this will have no effect on a point size 
     Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -5.0f); 
     Matrix.multiplyMV(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); 
     Matrix.multiplyMV(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); 
     GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0); 

     //Send the vertex 
     GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuf); 
     GLES20.glEnableVertexAttribArray(mPositionHandle); 

     //Draw the point 
     GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1);   

    } 
}