4

我刚刚开始学习适用于 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);
}

}

预先感谢

4

1 回答 1

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。在此循环中,最后一次迭代具有“计数器”,其中包含您在数组中设置的浮点数。

你传递给 glDrawArrays 的应该是要绘制的顶点数。所以在这种情况下是“计数器”的一半。

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);
于 2013-04-29T18:24:00.063 回答