基于运动的OpenGL ES 2.0绘制线,Line总是从原点开始

时间:2012-06-13 12:59:15

标签: android opengl-es-2.0

我刚刚开始学习Android的OpenGL,我在绘制线条时遇到了一个奇怪的问题。我想做的就是根据手指动作绘制一条线。现在,一旦我开始滑动,我总是从原点(0,0)得到一条线。

这是一张图片:

http://imageshack.us/photo/my-images/137/screenshot2012061312174.jpg/

我手指动作的箭头符号和原点(红色圆圈)开始的线是我整个动作中提到的线。

不要对Coords数组感到困扰我知道这不是最佳实践,但我对整个程序进行了调试,无法找到任何涉及此数组的错误。

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

我现在试图解决这个问题,但是我真的卡住任何建议可能会有所帮助

这是我的整个渲染类。

公共类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);
}

}

我提前感谢

1 个答案:

答案 0 :(得分:0)

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

你已经初始化了Coords来保存100000个浮点数并将它们初始化为0.在这个循环中,最后一次迭代具有'counter',其中包含你在数组中设置的浮点数。

传递给glDrawArrays的内容应该是要绘制的VERTICES的数量。所以在这种情况下,“反击”的一半。

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

你的for循环在数组的末尾添加'counter'/ 2额外量的(0,0)顶点。最快的方法是将'counter'/ 2传递给glDrawArrays,但我建议采用更清晰的方法。

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