2012-04-20 23 views
1

Android用OpenGLの学習を始めたばかりです。円を描くときに奇妙な問題が発生しています。頂点のいくつかは左と上の壁に張り付いていて、円から少しランダムに出ています。私はアプリを再起動するたびに、彼らは別の位置を持っています。円が描かれAndroidでgles20 circleを描画するときのランダムな線

マイDrawScreenクラス:

public class DrawScreen implements GLSurfaceView.Renderer { 

Ball ball; 

public float mAngle; 

private int mProgram; 
private int maPositionHandle; 

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 muMVPMatrixHandle; 
private float[] mMVPMatrix = new float[16]; 
private float[] mVMatrix = new float[16]; 
private float[] mProjMatrix = new float[16]; 


public void onSurfaceCreated(GL10 unused, EGLConfig config) { 

    ball = new Ball(); 

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

    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 

    ball.initShapes(240, 360, 50); 

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

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

    // Prepare the circle data 
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 0, ball.ballVB); 
    GLES20.glEnableVertexAttribArray(maPositionHandle); 

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

    // Draw the circle 
    GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, (int) (ball.getNumSeg() * 3)); 

} 

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

    float ratio = (float) width/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 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 class Ball { 

public FloatBuffer ballVB; 

private float cx, cy, r; 

float numSegments = 360; 

public void initShapes(float tx, float ty, float tr){ 

    cx = (tx/240.f) - 1.f; 
    cy = (ty/360.f) - 1.f; 
    r = (tr/240.f); 

    float ballCoords[] = new float[(int) (numSegments * 3)]; 

    double theta = (2 * 3.1415926/numSegments); 
    float c = (float) Math.cos(theta);//precalculate the sine and cosine 
    float s = (float) Math.sin(theta); 
    float t; 

    float x = r;//we start at angle = 0 
    float y = 0; 

    for(int i = 0; i < (numSegments * 3); i = i + 3) { 

     ballCoords[i] = (x + cx); 
     ballCoords[i + 1] = (y + cy); 
     ballCoords[i + 2] = (0); 

     //apply the rotation matrix 
     t = x; 
     x = c * x - s * y; 
     y = s * t + c * y; 

    } 

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

} 

public float getNumSeg(){ 

    return numSegments; 

} 

}私がきた

何時間もインターネットを掃除していたが、何も見つけられなかった。あなたたちが私を助けてくれることを願っています。

+0

こんにちは、このコードを使用して円を描いていますが、代わりに楕円が表示されます。それはサークルに近いですが、あなたはそれがそうでないと見ることによって伝えることができます。私は間違って何をしているのだろうか? –

+0

私はこの問題の質問をしました[ここ](http://stackoverflow.com/questions/26287598/stretched-image-when-drawn-on-the-screen) –

答えて

1

GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, (int) (ball.getNumSeg() * 3));

私はこれの不審なんだが、個々の頂点を参照セグメントですか?

glDrawArraysの最後の引数は、浮動小数点数ではなく、頂点の数です。おそらく、* 3の乗数をglDrawArraysから削除する必要があります。

余分な線は、実際に割り当てた頂点の3倍の図を描画している可能性があります。

+0

ありがとうございました!それは後天的にはかなり明白でした...>、< –

関連する問題