10

SpriteMethodTest が言うように、スプライトを描画するには多くの方法があります。まず、キャンバスを試してみましたが、パフォーマンスの問題がいくつかありました。次に、opengl を学ぶことにしました。GL11Ext 拡張機能を使用して初めて成果を上げました。ただし、デフォルトでは、テクスチャを描画すると反転し、x 軸と y 軸がデバイス画面の左下隅 (横向きモード) でゼロになり、キャンバスとは異なり、スプライトを回転させることはできません。

次に、GLU look at を使用してこの軸ビューに影響を与えようとしましたが、効果がありませんでした。次に、スプ​​ライトを回転させたいと思ったのですが、GL11Ext のせいで効果がありませんでした。

したがって、現在、主要なスタックオーバーフロー状態があり、基本的な質問は次のとおりです。

  1. スプライトでズーム、回転、バウンス効果を達成するため、および昔ながらの方法で X 軸と Y 軸を見る [(0,0) はランドスケープ モードで左上にある] ために使用する方法はどれですか?**

  2. そして、スプライトレンダリングの唯一の良い方法を使用する宇宙にいくつかのスプライトクラスの例がありますか? (SpriteMethodTest は私を大いに混乱させます)

4

1 に答える 1

10

エブリカ!!!

私はほとんど自殺していた!Canvas を離れて OpenGL メソッドを学習し、ゲーム エンジンを実装してから 3 日後。

Web にはごみだらけの OpenGL チュートリアルがあふれており、その多くは未完成であり、その多くは 2D OpenGL ゲーム エンジンの実装方法の間違った方法につながっています。大きな間違いは、G11Ext をゲームの作成に使用することです。回転しないので : D

その後、YouTube ゲームのサンプル ビデオ リンクから見つけた他のチュートリアルからこのチュートリアルを見つけました笑:

ここで視聴者を混乱させないために

第1章: http://obviam.net/index.php/opengl-es-with-android-switching-from-canvas-to-opengl/

第2章: http://obviam.net/index.php/opengl-es-android-displaying-graphical-elements-primitives/

第3章: http://obviam.net/index.php/texture-mapping-opengl-android-displaying-images-using-opengl-and-squares/

ちょうど 15 分前に、スプライトを使用して図形を回転、移動、およびサイズ変更できる方法を発見しました。! ! ハハハ

この素晴らしいチュートリアルを読んだ後、多くの読者がスプライトの移動、サイズ変更、回転の方法を尋ねています。だから私は、この混乱した例とチュートリアルからいくつかのコードを作成しました:

このクラスは、いくつかの頂点操作に使用されます

public class Vertex
{
    public FloatBuffer buffer; // buffer holding the vertices
    public float vertex[];
    public Vertex (float[] vertex)
    {
        this.vertex = vertex;
        this.prepare ();
    }
    private void prepare ()
    {
        // a float has 4 bytes so we allocate for each coordinate 4 bytes
        ByteBuffer factory = ByteBuffer.allocateDirect (vertex.length * 4);
        factory.order (ByteOrder.nativeOrder ());
        // allocates the memory from the byte buffer
        buffer = factory.asFloatBuffer ();
        // fill the vertexBuffer with the vertices
        buffer.put (vertex);
        // set the cursor position to the beginning of the buffer
        buffer.position (0);        
    }
}

このクラスは、回転と位置を移動できるテクスチャで形状を描画するために使用されます

public class Square
{
    Vertex shape,texture;
    int corner=0;
    float x=0;

    public Square()
    {
        shape = new Vertex (new float[]
                {
                1f,1f,0f,
                0f,1f,0f,
                1f,0f,0f,
                0f,0f,0f,
                });

        texture = new Vertex (new float[]
                {
                1.0f, 0.0f,
                0.0f, 0.0f,
                1.0f, 1.0f,
                0.0f, 1.0f,
                });     
    }

    /** The draw method for the square with the GL context */
    public void draw (GL10 gl, int image, float x, float y, float width, float height, float corner)
    {
        if (corner>=0)
        {
            corner += 1;    
        }
        if (corner>360)
        {
            corner = -1;
        }
        gl.glPushMatrix();

        x += 1f;
        if (x>800)
        {
            x = 0;
        }

        position (gl, 0, 0, width, height, corner);

        // bind the previously generated texture
        gl.glBindTexture(GL10.GL_TEXTURE_2D, image);

        // Point to our buffers
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // set the colour for the square
        gl.glColor4f (0.0f, 1.0f, 0.0f, 0.5f);

        // Set the face rotation
        gl.glFrontFace(GL10.GL_CW);     

        // Point to our vertex buffer
        gl.glVertexPointer (3, GL10.GL_FLOAT, 0, shape.buffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture.buffer);

        // Draw the vertices as triangle strip
        gl.glDrawArrays (GL10.GL_TRIANGLE_STRIP, 0, shape.vertex.length / 3);

        // Disable the client state before leaving
        gl.glDisableClientState (GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glPopMatrix();       
    }

    public void position (GL10 gl, float x, float y, float width, float height, float corner)
    {
        gl.glTranslatef (x, y, 0f); //MOVE !!! 1f is size of figure if called after scaling, 1f is pixel if called before scaling

        if (corner>0)
        {
            gl.glTranslatef (width/2, height/2, 0f);
            gl.glRotatef (corner, 0f, 0f, 1f); // ROTATE !!!
            gl.glTranslatef (-width/2, -height/2, 0f);          

        }

        gl.glScalef (width, height, 0f); // ADJUST SIZE !!!

    }
}

主なことは、1つのopengl単位== 1ピクセルになるようにカメラを設定する方法と、テクスチャをロードする方法です

public class Scene implements Renderer
{
    public Context context;
    public Resources resources;
    public SparseIntArray images = new SparseIntArray ();
    public float width;
    public float height;

    public Scene (Context context)
    {
        this.context = context;
        this.resources = context.getResources ();
    }

    @Override
    public void onDrawFrame (GL10 gl)
    {
//      // clear Screen and Depth Buffer
        gl.glClear (GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
//      // Reset the Modelview Matrix
        gl.glLoadIdentity ();
        draw (gl);

    }

    @Override
    public void onSurfaceChanged (GL10 gl, int width, int height)
    {
        this.width = width;
        this.height = height;

        gl.glViewport (0, 0, width, height); // Reset The Current Viewport
        gl.glMatrixMode (GL10.GL_PROJECTION); // Select The Projection Matrix
        gl.glLoadIdentity (); // Reset The Projection Matrix

        gl.glOrthof (0, width, 0, height, -1f, 1f);
        //gl.glTranslatef (0f, -height/2, 0.0f); // move the camera !!


        gl.glMatrixMode (GL10.GL_MODELVIEW); // Select The Modelview Matrix
        gl.glLoadIdentity (); // Reset The Modelview Matrix

        load (gl);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) 
    {
        gl.glEnable(GL10.GL_TEXTURE_2D);            //Enable Texture Mapping ( NEW )
        gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    //Black Background
        gl.glClearDepthf(1.0f);                     //Depth Buffer Setup
        gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
        gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do

        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        gl.glEnable(GL10.GL_BLEND);


        //Really Nice Perspective Calculations
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

        init (gl);
    }


    public void init (GL10 gl)
    {

    }

    public void load (GL10 gl)
    {

    }

    public void draw (GL10 gl)
    {

    }

    private static int next (GL10 gl)
    {
        int[] temp = new int[1];
        gl.glGenTextures (1, temp, 0);
        return temp[0];
    }   

    public int image (GL10 gl, int resource)
    {
        int id = next (gl);
        images.put (resource, id);

        gl.glBindTexture (GL10.GL_TEXTURE_2D, id);

        gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

        gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

        gl.glTexEnvf (GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);

        BitmapFactory.Options options = new BitmapFactory.Options ();
        options.inScaled = false;

        InputStream input = resources.openRawResource (resource);
        Bitmap bitmap;
        try
        {
            bitmap = BitmapFactory.decodeStream (input, null, options);
        }
        finally
        {
            try
            {
                input.close ();
            }
            catch (IOException e)
            {
                // Ignore.
            }
        }

//       Matrix flip = new Matrix ();
//       flip.postScale (1f, -1f);
//       bitmap = Bitmap.createBitmap (bitmap, 0, 0, bitmap.getWidth (), bitmap.getHeight (), flip, true);

        GLUtils.texImage2D (GL10.GL_TEXTURE_2D, 0, bitmap, 0);      
        return id;
    }

}

そしていくつかの使用法

public class Scene2 extends Scene
{
    Square square1, square2;

    public Scene2(Context context)
    {
        super (context);
        // TODO Auto-generated constructor stub
    }

    public void init (GL10 gl)
    {
        square1 = new Square ();
        square2 = new Square ();
    }

    public void load (GL10 gl)
    {
        image (gl, R.drawable.s1_clouds);
        image (gl, R.drawable.s1_ground);
    }

    public void draw (GL10 gl)
    {
        square1.draw (gl, images.get(R.drawable.s1_clouds), 0, 0, width, height, 0);
        square1.draw (gl, images.get(R.drawable.s1_ground), 0, 0, width, height, 0);
    }

}

ここで実装して実装したかった主なことは、X 軸と Y 軸がキャンバスに似ていることです。

(0,0)
 --------------------------------- X axis
|
|
|
|
|
|
|
|
Y axis

この後にいくつかの完全なチュートリアルを書きます。達成したいすべての目標を達成したことを発表したいと思います。つまり、X 軸を上に、Y 軸を左に、opengl 単位 = ピクセル、オブジェクトのサイズをピクセルで設定、オブジェクトを回転、移動します。すべてをピクセル単位でオブジェクト化します。今、私はスプライトのアニメーションを処理し、それらをより細かいクラスにします。それが新しい 2D OpenGL ゲーム フレームワークの基礎です...

この関数を発見すると、チュートリアルが役立ちましたhttp://www.morrowland.com/apron/tutorials/gl/gl_matrix.php

唯一の本当の方法を教えてくれたこのブログにとても感謝しています...

+1 android 最も単純な 2D OpenGL ゲーム エンジンを 1 週間で...

幸せな心が吹いています...

:P

編集: 1 年後、ここで説明されている概念を使用した素晴らしいフレームワークhttps://github.com/hazardland/game.androidと、考えられるフレームワークの使用例を含むサンプル ゲームがhttps://github.com/hazardland/ferry.android (市場で画面を見るhttps://play.google.com/store/apps/details?id=hazardland.borani )

于 2012-07-06T14:45:46.297 に答える