Android OpenGL ES 2.0基于运动绘制直线,直线始终从原点开始

Android OpenGL ES 2.0基于运动绘制直线,直线始终从原点开始,android,opengl-es-2.0,Android,Opengl Es 2.0,我刚刚开始学习Android版的OpenGL,我在画线时遇到了一个奇怪的问题。我想做的就是根据手指的运动画一条线。现在,只要我开始刷卡,我总是会得到一条线,从原点(0,0)跟随我的运动 这是一张照片: 箭头表示我的手指运动,从原点开始的线(红色圆圈)是我整个运动的后续线 不要为Coords阵列烦恼我知道这不是最佳实践,但我调试了整个程序,没有发现任何与此阵列有关的bug 我可能应该提到ArrayList points包含我生成的所有点 我现在正想弄明白这一点,但我真的被卡住了,任何建议都会有帮

我刚刚开始学习Android版的OpenGL,我在画线时遇到了一个奇怪的问题。我想做的就是根据手指的运动画一条线。现在,只要我开始刷卡,我总是会得到一条线,从原点(0,0)跟随我的运动

这是一张照片:

箭头表示我的手指运动,从原点开始的线(红色圆圈)是我整个运动的后续线

不要为Coords阵列烦恼我知道这不是最佳实践,但我调试了整个程序,没有发现任何与此阵列有关的bug

我可能应该提到ArrayList points包含我生成的所有点

我现在正想弄明白这一点,但我真的被卡住了,任何建议都会有帮助

这是我的整个渲染类

公共类HelloOpenGLES20Renderer实现GLSurfaceView.Renderer{

private FloatBuffer triangleVB;
private int mProgram;
private int maPositionHandle;
public ArrayList<PointWrapper> points;

private int muMVPMatrixHandle;
private float[] mMVPMatrix = new float[16];
private float[] mMMatrix = new float[16];
private float[] mVMatrix = new float[16];
private float[] mProjMatrix = new float[16];
private int[] viewport = new int[4];

private ArrayList<Float> coordinates;

float[] Coords = new float[100000];

boolean first;
private int counter;
private PointWrapper last;

private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;   \n" +

"attribute vec4 vPosition;  \n" + "void main(){               \n" +

// the matrix must be included as a modifier of gl_Position
        " gl_Position = uMVPMatrix * vPosition; \n" +
        "}  \n";

private final String fragmentShaderCode = "precision mediump float;  \n"
        + "void main(){              \n"
        + " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n"
        + "}                         \n";

private int loadShader(int type, String shaderCode) {

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type);

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
}

public HelloOpenGLES20Renderer() {
    points = new ArrayList<PointWrapper>();
    first = true;
    this.counter = 0;
    last = new PointWrapper();

    coordinates = new ArrayList<Float>();
}

private float[] convertCoordinates(PointWrapper f) {
    float[] vector = new float[4];
    GLU.gluUnProject(f.point.x, f.point.y, 0.0f, mVMatrix, 0, mProjMatrix,
            0, viewport, 0, vector, 0);

    return vector;
}

private void initShapes() {
    ArrayList<PointWrapper> points2 = new ArrayList<PointWrapper>(points);
    float[] vector;


    if (!points2.isEmpty()) {
        if(points2.size()%2==1){
            points2.remove(points2.size()-1);
        }

        for (int i = counter/2; i < points2.size(); i++) {

            vector = convertCoordinates(points2.get(i));
            Coords[counter] = vector[0] / vector[3];
            Coords[counter+1] = -1 * (vector[1] / vector[3]);

            counter= counter+2;
        }


    }

    // initialize vertex Buffer for triangle
    ByteBuffer vbb = ByteBuffer.allocateDirect(
    // (# of coordinate values * 4 bytes per float)
            Coords.length * 4);
    vbb.order(ByteOrder.nativeOrder());// use the device hardware's native
    // byte order
    triangleVB = vbb.asFloatBuffer(); // create a floating point buffer from
    // the ByteBuffer
    triangleVB.put(Coords); // add the coordinates to the
    // FloatBuffer
    triangleVB.position(0); // set the buffer to read the first coordinate

}

public void onSurfaceCreated(GL10 unused, EGLConfig config) {

    // Set the background frame color
    GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

    // initialize the triangle vertex array
    // initShapes();

    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
            fragmentShaderCode);

    mProgram = GLES20.glCreateProgram(); // create empty OpenGL 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 program executables

    // get handle to the vertex shader's vPosition member
    maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
}

public void onDrawFrame(GL10 unused) {

    // Redraw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    initShapes();

    // Add program to OpenGL environment
    GLES20.glUseProgram(mProgram);

    // Prepare the triangle data
    GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT,
            false, 0, triangleVB);
    GLES20.glEnableVertexAttribArray(maPositionHandle);

    // Apply a ModelView Projection transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    GLES20.glLineWidth(5f);

    GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, counter);


}

public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;
    viewport[0] = 0;
    viewport[1] = 0;
    viewport[2] = width;
    viewport[3] = height;

    // this projection matrix is applied to object coodinates
    // in the onDrawFrame() method
    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
}
private-FloatBuffer-triangleVB;
私人内部程序;
私有int-maPositionHandle;
公共阵列列表点;
私有int MUMPMATRIXHANDLE;
私有浮点[]mMVPMatrix=新浮点[16];
私有浮动[]mMMatrix=新浮动[16];
私有浮动[]mVMatrix=新浮动[16];
私有浮动[]mProjMatrix=新浮动[16];
私有int[]视口=新int[4];
私有数组列表坐标;
浮动[]坐标=新浮动[100000];
布尔优先;
专用int计数器;
私有点包装器;
私有最终字符串vertexShaderCode=
//这个矩阵成员变量提供了一个钩子来操作
//使用此顶点着色器的对象的坐标
“统一mat4 uMVPMatrix;\n”+
属性vec4 vPosition;\n“+”void main(){\n”+
//矩阵必须包含为gl_位置的修改器
“gl_Position=uMVPMatrix*vpposition;\n”+
“}\n”;
私有最终字符串fragmentShaderCode=“precision mediump float;\n”
+“void main(){\n”
+“gl_FragColor=vec4(0.63671875,0.76953125,0.22265625,1.0);\n”
+“}\n”;
私有int loadShader(int类型,字符串shaderCode){
//创建顶点着色器类型(GLES20.GL_vertex_着色器)
//或片段着色器类型(GLES20.GL_fragment_着色器)
int shader=GLES20.glCreateShader(类型);
//将源代码添加到着色器并编译它
glShaderSource(着色器,着色器代码);
GLES20.glCompileShader(着色器);
返回着色器;
}
公共HelloOpenGLES20Renderer(){
points=新的ArrayList();
第一个=正确;
这个计数器=0;
last=新的PointWrapper();
坐标=新的ArrayList();
}
专用浮点[]转换坐标(点包装器f){
浮点[]向量=新浮点[4];
GLU.glunproject(f.point.x,f.point.y,0.0f,mVMatrix,0,mProjMatrix,
0,视口,0,向量,0);
返回向量;
}
私有void initShapes(){
ArrayList points2=新的ArrayList(点);
浮点[]向量;
如果(!points2.isEmpty()){
if(points2.size()%2==1){
points2.remove(points2.size()-1);
}
对于(int i=counter/2;ifor (int i = counter/2; i < points2.size(); i++) {

        vector = convertCoordinates(points2.get(i));
        Coords[counter] = vector[0] / vector[3];
        Coords[counter+1] = -1 * (vector[1] / vector[3]);

        counter= counter+2;
    }
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, counter);
numOfVertices = points2.size(); //make field 
int counter = 0; //make local
for (int i = 0; i < numOfVertices; i++) {
        vector = convertCoordinates(points2.get(i));
        Coords[counter] = vector[0] / vector[3];
        Coords[counter+1] = -1 * (vector[1] / vector[3]);
        counter= counter+2;
    }
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, numOfVertices);