2016-08-01 6 views
0

enter image description hereは、デバイスからAndroidのOpenGLの円(球)楕円..

も添付のスクリーンショットは、 uはplsは... そのAndroidのキットカットの問題を解決する私を助けることができていない投影/カメラのように見えますデバイスからのバージョン

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

も添付のスクリーンショットは、 uはplsは私が問題を解決することができます...Xその規模によって座標その後、あなたのドローの時間を掛け

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

を:フロートを追加し、バルーンは、円のように見えるようにするには、そのAndroidのキットカット版

答えて

0

描画するパラメータとして(のはそれX_SCALEを呼びましょう) FillBaloonの要因(...):

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

そして、あなたのレンダラのドローにスケールファクタを設定する(X_SCALE)コール:

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

onSurfaceCreated(...)で一度だけX_SCALEを設定し、サーフェスのサイズをonSurfaceChanged(...)に変更するたびに設定することをお勧めします。

最後の一つです:あなたは、明示的な初期化で「F」接尾辞を使用して浮動小数点数として鋳造ダブルスを避けることができます。

float twicePI = 6.28318530717959f; 
+0

これは私に後ろ向きです。アスペクト比の逆数をスケーリング係数として使用したいと思います。または、この値をxの値ではなくyのスケールに使用します。 –

+0

ありがとうレトコラディ、リチャードKlaassen ...アスペクトのXの逆数またはYのファクターはうまくいきます...あなたはpplが私の日を作ったのです...ありがとうございました。 – murty

+0

@RetoKoradi良いコール、私はコードの定義を修正しました。 –

1

は、これは正常な動作です。 OpenGLのデフォルトの座標系は、すべての軸で[-1、1]です。つまり、左端のポイントはx=-1、右端のx=1、最上位のy=1、最下部のy=-1となります。あなたの画面比率に応じて、結果は同じ伸張率になります。

あなたが好きなように形を描くためにシーンを操作するのはあなた次第です。 1つの方法は、頂点データを生成するときにその頂点データを拡大することですが、モデル頂点データが意図されたとおりになるようにすることを強くお勧めします。もう一つの方法は、単純に四角いサーフェスビューを作成してから、描画面を制限して、再び最良のアプローチではないようにすることです。さらに別の方法は、ビューポートを使用して形状を描画したい矩形を設定することですが、その形状は全幅と高さに戻すように覚えておく必要があります。そして、行列があります。

座標系を定義するために行列を使います。 2Dの場合、最も良い方法は通常境界パラメータ(左、上、下、右)を使用するOrthoを使用することです。例えばビュー座標(left = 0right = viewWidthtop = 0bottom = viewHeight)を使用することができるか、ゼロの周りにシステムを正常化し、1.0の値を有するべき境界選ぶことができる:あなたが持つ水平正規化(left = -1right = 1top = viewHeight/viewWidthbottom = -viewHeight/viewWidth)垂直(left = -viewWidth/viewHeight,right = viewWidth/viewHeight,top = 1.0,bottom = -1.0)です。