テクスチャあり描画

テクスチャあり描画




テクスチャを付けて描画するメソッドを実装します。

テクスチャあり用の描画パラメータ作成メソッドを用意します。
テクスチャなしと同じくアプリケーション側ではこのメソッドを叩いて作られたパラメータを変更して
描画メソッドに渡します。

    //  描画パラメータ作成
    public DrawParam    CreateDrawParam( Texture image )
    {
        return new DrawParam( image );
    }

そして描画メソッド本体です。

    //  描画
    public void Draw( DrawParam param )
    {
        if( !_IsDrawEnable( param ))
            return;

        GL10    gl  = m_DrawDevice.GetGl();

        final Texture   image       = param.m_Image;
        final Rect      imageRect   = param.m_ImageRect;
        final PointF    imageCenter = param.m_ImageCenter;
        final Color     color       = param.m_Color;
        final float imageWidth  = image.GetWidth();
        final float imageHeight = image.GetHeight();

        //  表示用行列設定
        _UpdateWorldMatrix( gl, param );

        //  テクスチャ設定
        gl.glEnable( GL10.GL_TEXTURE_2D );
        gl.glBindTexture( GL10.GL_TEXTURE_2D, param.m_Image.GetTextureBindID());

        //  頂点の位置設定
        {
            final float leftPos     = -imageCenter.x;
            final float topPos      = -imageCenter.y;
            final float rightPos    = leftPos + imageRect.width();
            final float bottomPos   = topPos + imageRect.height();
            final float aVerticalPos[]  =
            {
                    leftPos,    topPos,
                    rightPos,   topPos,
                    leftPos,    bottomPos,
                    rightPos,   bottomPos,
            };

            m_VertexPos.SetArray( aVerticalPos );
            gl.glVertexPointer( VERTEX_POS_ELEMENT_NUM, GL10.GL_FLOAT, 0, m_VertexPos.GetFloatBuffer());
        }

        //  テクスチャ領域設定
        {
            final float imageWidthInv   = 1.0f / imageWidth;
            final float imageHeightInv  = 1.0f / imageHeight;
            final float leftImagePos    = ( imageRect.left      + 0.5f )    * imageWidthInv;
            final float topImagePos     = ( imageRect.top       + 0.5f )    * imageHeightInv;
            final float rightImagePos   = ( imageRect.right     - 0.5f )    * imageWidthInv;
            final float bottomImagePos  = ( imageRect.bottom    - 0.5f )    * imageHeightInv;
            final float aImageRect[]    =
            {
                    leftImagePos,   topImagePos,
                    rightImagePos,  topImagePos,
                    leftImagePos,   bottomImagePos,
                    rightImagePos,  bottomImagePos,
            };

            //  テクスチャ座標有効化
            gl.glEnableClientState( GL10.GL_TEXTURE_COORD_ARRAY );

            m_ImageRect.SetArray( aImageRect );
            gl.glTexCoordPointer( IMAGE_POS_ELEMENT_NUM, GL10.GL_FLOAT, 0, m_ImageRect.GetFloatBuffer());
        }

        //  色設定
        m_DrawColor.set( m_ScaleColor );
        m_DrawColor.Mul( color );
        if( !m_PrevDrawColor.equals( m_DrawColor ))
        {
            final float colorR      = m_DrawColor.GetR();
            final float colorG      = m_DrawColor.GetG();
            final float colorB      = m_DrawColor.GetB();
            final float colorA      = m_DrawColor.GetA();
            final float aColor[]    =
            {
                    colorR, colorG, colorB, colorA,
                    colorR, colorG, colorB, colorA,
                    colorR, colorG, colorB, colorA,
                    colorR, colorG, colorB, colorA,
            };

            m_VertexColor.SetArray( aColor );
            gl.glColorPointer( VERTEX_COLOR_ELEMET_NUM, GL10.GL_FLOAT, 0, m_VertexColor.GetFloatBuffer());

            m_PrevDrawColor.set( m_DrawColor );
        }

        //  描画
        gl.glDrawArrays( GL10.GL_TRIANGLE_STRIP, 0, VERTEX_NUM );
    }

基本的にはテクスチャなしとそれほど変わりません。
では変わったところを詳しく見てみましょう。

        //  テクスチャ設定
        gl.glEnable( GL10.GL_TEXTURE_2D );
        gl.glBindTexture( GL10.GL_TEXTURE_2D, param.m_Image.GetTextureBindID());

テクスチャを使うのでテクスチャを有効化します。
さらに、テクスチャのIDをOpenGLに設定してテクスチャを使えるようにします。

        //  テクスチャ領域設定
        {
            final float imageWidthInv   = 1.0f / imageWidth;
            final float imageHeightInv  = 1.0f / imageHeight;
            final float leftImagePos    = ( imageRect.left      + 0.5f )    * imageWidthInv;
            final float topImagePos     = ( imageRect.top       + 0.5f )    * imageHeightInv;
            final float rightImagePos   = ( imageRect.right     - 0.5f )    * imageWidthInv;
            final float bottomImagePos  = ( imageRect.bottom    - 0.5f )    * imageHeightInv;
            final float aImageRect[]    =
            {
                    leftImagePos,   topImagePos,
                    rightImagePos,  topImagePos,
                    leftImagePos,   bottomImagePos,
                    rightImagePos,  bottomImagePos,
            };

            //  テクスチャ座標有効化
            gl.glEnableClientState( GL10.GL_TEXTURE_COORD_ARRAY );

            m_ImageRect.SetArray( aImageRect );
            gl.glTexCoordPointer( IMAGE_POS_ELEMENT_NUM, GL10.GL_FLOAT, 0, m_ImageRect.GetFloatBuffer());
        }

テクスチャの表示領域を設定します。
特に大したことはやってないです。。。

なお、テクスチャなしと共通の部分が多くありますが
高速化のためにメソッドには抜いてないです。
管理のしやすさと相談しつつメソッドに抜き出すのはありだと思います。
(C++のinline関数みたいに出来ればこんな面倒なことをしなくてもいいのだが……)



<前のページ
次のページ>