2016-08-01 36 views
0

enter image description hereAndroid OpenGL Kreis (Kugel) wie Ellipse .. keine Projektion/Kamera

auch angebracht Screenshot aus dem Gerät, kann u pls mir helfen, das Problem zu lösen ... seine Android KitKat Version

public class Balloon 
{ 
    private final String vertexShaderCode = 
      // This matrix member variable provides a hook to manipulate 
      // the coordinates of the objects that use this vertex shader 
        "attribute vec4 vPosition;" + 
        "void main() {" + 
        "gl_PointSize = 5.0;     "+ 
        " gl_Position = vPosition;" + 
        "}"; 

    private final String fragmentShaderCode = 
      "precision mediump float;" + 
        "uniform vec4 vColor;" + 
        "void main() {" + 
        " gl_FragColor = vColor;" + 
        "}"; 

    private FloatBuffer vertexBuffer; 
    private final int mProgram; 
    private int mPositionHandle; 
    private int mColorHandle; 
    private int mMVPMatrixHandle; 

    private float[] data = new float[126]; 

    // number of coordinates per vertex in this array 
    static final int COORDS_PER_VERTEX = 3; 

    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex 

    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 0.0f }; 

    /** 
    * Sets up the drawing object data for use in an OpenGL ES context. 
    */ 
    public Balloon() { 

     // prepare shaders and OpenGL program 
     int vertexShader = MyGLRenderer.loadShader(
       GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
     int fragmentShader = MyGLRenderer.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);     
     // create OpenGL program executables 

    } 

    private void FillBalloon(float x1,float y1,float r1) 
    { 
     int i=0,j=0; 
     float angle = 0; 

     float twicePI = (float)2.0 * (float)3.1415926; 


     float angle_stepsize = 0.1f; 

     // go through all angles from 0 to 2 * PI radians 
     for(;angle < twicePI;angle = (angle + angle_stepsize)) 
     { 
      // calculate x, y from a vector with known length and angle 
      data[j++] = x1 + r1 * (float)Math.cos(angle); 
      data[j++] = y1 + r1 * (float)Math.sin(angle); 

     } 

     // initialize vertex byte buffer for shape coordinates 
     ByteBuffer bb = ByteBuffer.allocateDirect(
       // (number of coordinate values * 4 bytes per float) 
       j * 4); 
     // use the device hardware's native byte order 
     bb.order(ByteOrder.nativeOrder()); 

     // create a floating point buffer from the ByteBuffer 
     vertexBuffer = bb.asFloatBuffer(); 
     // add the coordinates to the FloatBuffer 
     vertexBuffer.put(data); 
     // set the buffer to read the first coordinate 
     vertexBuffer.position(0); 

    } 


    /** 
    * Encapsulates the OpenGL ES instructions for drawing this shape. 
    * 
    */ 
    public void draw() { 
     // Add program to OpenGL environment 
     GLES20.glUseProgram(mProgram); 

     float posX = 0.0f,posY = 0.0f,radius =0.2f; 

     FillBalloon(posX, posY, radius); 

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

     // Enable a handle to the triangle vertices 
     GLES20.glEnableVertexAttribArray(mPositionHandle); 

     // Prepare the balloon coordinate data 

     GLES20.glVertexAttribPointer(mPositionHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer); 

     // get handle to fragment shader's vColor member 
     mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); 

     // Set color for drawing the triangle 
     GLES20.glUniform4fv(mColorHandle, 1, color, 0); 
     MyGLRenderer.checkGlError("mColorHandle"); 


     GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 63); 

     // Disable vertex array 
     GLES20.glDisableVertexAttribArray(mPositionHandle); 
    } 
} 

auch Screenshot aus dem Gerät angebracht ist, u kann mir pls helfen, das Problem zu lösen ... seine Android KitKat Version

Antwort

0

Um die Ballons aussehen wie Kreise, fügen Sie einen Schwimmer zu machen (lassen Sie sie es X_SCALE nennen) als Parameter zu ziehen:

von dieser Skala
public void draw(float X_SCALE) { 
    ... 
    FillBaloon(posX, posY, radius, X_SCALE); 
    ... 
} 

Dann x Ihren Einzug Zeit multiplizieren koordinieren Faktor in FillBaloon (...):

data[j++] = x1 + X_SCALE * r1 * (float)Math.cos(angle); 

und legen Sie den Skalierungsfaktor in Ihrem Renderer draw (X_SCALE) Aufruf:

X_SCALE = (float)MyGLSurfaceView.getHeight()/(float)MyGLSurfaceView.getWidth(); 
myBaloon.draw(X_SCALE); 

Noch besser wäre es, X_SCALE einmal in onSurfaceCreated (...) zu setzen und jedes Mal, wenn die Oberfläche in onSurfaceChanged geändert wird (...).

Eine letzte Sache: Sie vermeiden können, indem ein „f“ Suffix in expliziten Initialisierung verdoppelt sich als Schwimmer Gießen:

float twicePI = 6.28318530717959f; 
+0

Das sieht für mich rückwärts. Ich denke, Sie möchten das Inverse des Seitenverhältnisses als Skalierungsfaktor verwenden. Oder verwenden Sie diesen Wert, um y und nicht x zu skalieren. –

+0

Danke Reto Koradi und Richard Klaassen ...Umkehrung von Aspekt auf X oder Faktor auf Y funktioniert gut ... Sie ppl machte meinen Tag ... Danke eine Tonne .. – murty

+0

@RetoKoradi guten Ruf, habe ich die Definition in den Code. –

1

Dies ist das erwartete Verhalten. Das Standardkoordinatensystem für die openGL ist [-1, 1] in jeder Achse. Das bedeutet, dass der am weitesten links gelegene Punkt x=-1, am weitesten rechts x=1, am weitesten oben y=1 und am untersten y=-1 hat. Abhängig von Ihrem Bildschirmverhältnis wird das Ergebnis das gleiche gestreckte Verhältnis haben.

Es liegt an Ihnen, mit der Szene umzugehen, um die Form nach Belieben zu zeichnen. Eine Möglichkeit besteht darin, die Scheitelpunktdaten zu skalieren, wenn sie erzeugt werden, aber ich rate Ihnen dringend davon ab, da die Modellscheitelpunktdaten so sein sollten, wie sie sein sollen. Ein anderer Weg besteht darin, einfach eine quadratische Oberflächenansicht zu erstellen, die dann Ihre Zeichenfläche begrenzt, so dass es nicht wieder der beste Ansatz ist. Eine andere Möglichkeit besteht darin, das Ansichtsfenster zu verwenden und ein Rechteck zu setzen, in dem Sie Ihre Form zeichnen möchten, die zwar in Ordnung ist, aber Sie müssen daran denken, sie auf die volle Breite und Höhe zurückzusetzen. Und dann gibt es Matrizen ...

Verwenden Sie eine Matrix, um Ihr Koordinatensystem zu definieren. Für 2D ist die beste Methode normalerweise Ortho zu verwenden, die Randparameter (links, oben, unten, rechts) verwendet, die dann beliebig gesetzt werden können. Zum Beispiel können Sie Ansicht Koordinaten (left = 0, right = viewWidth, top = 0, bottom = viewHeight) oder Sie können das System um den Nullpunkt, und wählen Sie normalisieren die Grenze einen Wert von 1.0 haben sollte: Für die horizontale Normalisierung haben Sie (left = -1, right = 1, top = viewHeight/viewWidth, bottom = -viewHeight/viewWidth) und für die Vertikale (left = -viewWidth/viewHeight, right = viewWidth/viewHeight, top = 1.0, bottom = -1.0).