0

我正在尝试深入学习android中的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 的类,其中编写了用于编译着色器、检查错误的代码。(程序中没有错误)

4

1 回答 1

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);        

    }   
}
于 2013-02-14T21:54:06.260 回答