2012-06-13 30 views
4

我剛開始學習OpenGL for Android,繪製線條時出現奇怪的問題。我想要做的就是根據手指動作繪製一條線。現在,只要我開始刷卡,我總是會從原點(0,0)開始出現一條線條。基於運動的OpenGL ES 2.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); 
} 

}

我在此先感謝

+0

你能告訴'Coords'的內容? –

回答

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

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