opengl es2を勉強する。その10 表示用にクラスを作る。

利用をしやすいように、クラスを作って見ました。

一応、3Dは自分で実装してはいないので、2Dに特化してる作りかもしれません。

deleteTextireは一応いれてるのだけど、捨てた後も参照できてしまうので、消せないのかもしれません。

public class ShaderUtil {

    public static final String simpleVertexShaderCode =
                    "uniform mat4 uMVPMatrix;" +
                    "attribute  vec4 vPosition;" +
                    "void main() {" +
                    "gl_Position = uMVPMatrix*vPosition;" +
                    "}";

    public static final String simpleFragmentShaderCode =
                    "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main() {" +
                        "  gl_FragColor = vColor;" +
                    "}";


    public static final String vertexShaderCode =
            "attribute vec4 vPosition;" +
                    "uniform mat4 uMVPMatrix;" +
                    "attribute vec2 a_texCoord;" +
                    "varying vec2 v_texCoord;" +
                    "void main() {" +
                    "  gl_Position = uMVPMatrix*vPosition;" +
                    "  v_texCoord = a_texCoord;" +
                    "}";

    public static final String fragmentShaderCode =
            "precision mediump float;" +
                    "varying vec2 v_texCoord;" +
                    "uniform sampler2D s_texture;" +
                    "uniform float Opacity;" +
                    "void main() {" +
                    "lowp vec4 textureColor = texture2D( s_texture, v_texCoord );" +
                    "gl_FragColor = vec4(textureColor.rgb, textureColor.w*Opacity);" +
                    "}";

    public static int loadShader(int type, String shaderCode){
        int[] compiled = new int[1];
        int iShader = GLES20.glCreateShader(type);
        GLES20.glShaderSource(iShader, shaderCode);
        GLES20.glCompileShader(iShader);
        GLES20.glGetShaderiv(iShader, GLES20.GL_COMPILE_STATUS, compiled, 0);
        if (compiled[0] == 0) {
            Log.e("Load Shader Failed", "Compilation\n" + GLES20.glGetShaderInfoLog(iShader));
            return 0;
        }
        return iShader;
    }

    public static void setBitmapShaderFilter(){
        // 拡大縮小の時のフィルターの設定
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
    }

    public static int getTextureLocation(int uniq){
        if(uniq == 0){
            return GLES20.GL_TEXTURE0;
        }else if(uniq == 1){
            return GLES20.GL_TEXTURE1;
        }else if(uniq == 2){
            return GLES20.GL_TEXTURE2;
        }else if(uniq == 3){
            return GLES20.GL_TEXTURE3;
        }else if(uniq == 4){
            return GLES20.GL_TEXTURE4;
        }else if(uniq == 5){
            return GLES20.GL_TEXTURE5;
        }else if(uniq == 6){
            return GLES20.GL_TEXTURE6;
        }else if(uniq == 7){
            return GLES20.GL_TEXTURE7;
        }else if(uniq == 8){
            return GLES20.GL_TEXTURE8;
        }else if(uniq == 9){
            return GLES20.GL_TEXTURE9;
        }else if(uniq == 10){
            return GLES20.GL_TEXTURE10;
        }else if(uniq == 11){
            return GLES20.GL_TEXTURE11;
        }else if(uniq == 12){
            return GLES20.GL_TEXTURE12;
        }else if(uniq == 13){
            return GLES20.GL_TEXTURE13;
        }else if(uniq == 14){
            return GLES20.GL_TEXTURE14;
        }else if(uniq == 15){
            return GLES20.GL_TEXTURE15;
        }else if(uniq == 16){
            return GLES20.GL_TEXTURE16;
        }else if(uniq == 17){
            return GLES20.GL_TEXTURE17;
        }else if(uniq == 18){
            return GLES20.GL_TEXTURE18;
        }else if(uniq == 19){
            return GLES20.GL_TEXTURE19;
        }else if(uniq == 20){
            return GLES20.GL_TEXTURE20;
        }else if(uniq == 21){
            return GLES20.GL_TEXTURE21;
        }else if(uniq == 22){
            return GLES20.GL_TEXTURE22;
        }else if(uniq == 23){
            return GLES20.GL_TEXTURE23;
        }else if(uniq == 24){
            return GLES20.GL_TEXTURE24;
        }else if(uniq == 25){
            return GLES20.GL_TEXTURE25;
        }else if(uniq == 26){
            return GLES20.GL_TEXTURE26;
        }else if(uniq == 27){
            return GLES20.GL_TEXTURE27;
        }else if(uniq == 28){
            return GLES20.GL_TEXTURE28;
        }else if(uniq == 29){
            return GLES20.GL_TEXTURE29;
        }else if(uniq == 30){
            return GLES20.GL_TEXTURE30;
        }else if(uniq == 31){
            return GLES20.GL_TEXTURE31;
        }
        return GLES20.GL_TEXTURE0;
    }

    private static float xRotate(float _width,float _height,float rotate){
        return _width/2f* (float)Math.cos(Math.PI * 2f * rotate / 360f) - _height/2f* (float)Math.sin(Math.PI * 2f * rotate / 360f);
    }
    private static float yRotate(float _width,float _height,float rotate){
        return _width / 2f * (float)Math.sin(Math.PI * 2f * rotate / 360f) + _height / 2f * (float)Math.cos(Math.PI * 2f * rotate / 360f);
    }


    public static float[] getVertices(float _centerX, float _centerY, float width,float height,float rotate){
        float uvs[] = new float[]{
                _centerX + xRotate(-width, -height, rotate),    _centerY + yRotate(-width, -height, rotate),    0.0f,
                _centerX + xRotate(-width, height, rotate),     _centerY + yRotate(-width, height, rotate),     0.0f,
                _centerX + xRotate(width, -height, rotate),     _centerY + yRotate(width, -height, rotate),     0.0f,
                _centerX + xRotate(-width, height, rotate),     _centerY + yRotate(-width, height, rotate),     0.0f,
                _centerX + xRotate(width, -height, rotate),     _centerY + yRotate(width, -height, rotate),     0.0f,
                _centerX + xRotate(width, height, rotate),      _centerY + yRotate(width, height, rotate),      0.0f
        };
        return uvs;
    }

    public static float[] getUvs(int _num,int _x,int _y){
        float num = _num;
        float x = _x;
        float y = _y;
        float size = 1f/num;
        float uvs[] = new float[]{
                x*size,         y*size,
                x*size,         y*size+size,
                x*size+size,    y*size,
                x*size,         y*size+size,
                x*size+size,    y*size,
                x*size+size,    y*size+size
        };
        return uvs;
    }
}

ただ、使い方は、

public class Sprite {
    
    private int shaderProgram;
    private int uniq = 0;

    public Sprite(Bitmap bitmap,int _uniq){
        uniq = _uniq;
        shaderProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(shaderProgram, ShaderUtil.loadShader(GLES20.GL_VERTEX_SHADER, ShaderUtil.vertexShaderCode));
        GLES20.glAttachShader(shaderProgram, ShaderUtil.loadShader(GLES20.GL_FRAGMENT_SHADER, ShaderUtil.fragmentShaderCode));
        GLES20.glLinkProgram(shaderProgram);
        setupImage(bitmap);
    }


    int[] texture;
    private void setupImage(Bitmap bitmap) {

        texture = new int[1];

        GLES20.glGenTextures(1, texture, 0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);
        GLES20.glActiveTexture(ShaderUtil.getTextureLocation(uniq));
        ShaderUtil.setBitmapShaderFilter();

        // 画像をテクスチャに登録
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);



    }

    public void draw(float[] m){
        //8等分した、左から[5]上から[0]の画像を取得
        float uvs[] = ShaderUtil.getUvs(8, 5, 0);
        //(210,220)を中心点 横幅230 縦幅240 角度は45度
        float vertices[] = ShaderUtil.getVertices(210, 220, 230, 240, 45);

        GLES20.glEnable(GLES20.GL_BLEND);
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);


        GLES20.glUseProgram(shaderProgram);
        // シェーダーの準備(図形側)
        int mPositionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
        // シェーダー:ON
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        //シェーダーの準備(テクスチャ側)
        int mTexCoordLoc = GLES20.glGetAttribLocation(shaderProgram, "a_texCoord");
        // シェーダー:ON
        GLES20.glEnableVertexAttribArray(mTexCoordLoc);

        //////////////////////////////////START
        //////////////////////////////////START
        //////////////////////////////////START

        //頂点座標をバッファーに変換
        ByteBuffer bb1 = ByteBuffer.allocateDirect(vertices.length * 4);
        bb1.order(ByteOrder.nativeOrder());
        FloatBuffer vertexBuffer = bb1.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        //画像側の頂点座標をバッファーに変換
        ByteBuffer bb2 = ByteBuffer.allocateDirect(uvs.length * 4);
        bb2.order(ByteOrder.nativeOrder());
        FloatBuffer uvBuffer = bb2.asFloatBuffer();
        uvBuffer.put(uvs);
        uvBuffer.position(0);

        //vertexBufferをデータ列から頂点データという解釈に変換
        GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
        //uvBufferをデータ列から頂点データという解釈に変換
        GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, uvBuffer);

        // 描画に利用をする画像のデータをする
        GLES20.glUniform1i(GLES20.glGetUniformLocation(shaderProgram, "s_texture"), uniq);
        GLES20.glUniform1f(GLES20.glGetUniformLocation(shaderProgram, "Opacity"), 1.0f);
        GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix"), 1, false, m, 0);

        // 描画に利用をする画像のデータをする
        //GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);

        // 描画する。何で描くのかは、「関数内で登録してある」という暗黙の了解的な。
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);

        //////////////////////////////////END
        //////////////////////////////////END
        //////////////////////////////////END
        // シェーダー:OFF
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTexCoordLoc);
        GLES20.glDisable(GLES20.GL_BLEND);
        GLES20.glUseProgram(0);
    }

    public void dispose(){
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
        GLES20.glDeleteTextures(1, texture, 0);
    }
}

前後の記事

前の記事:

次の記事:

関連の記事

コメントの投稿

  • サイト内検索

新作アプリの紹介

関連サイトの紹介

アンドロイドアプリ開発TIPS
きぐるみカメラ
ふらいぱん
アンドロイドのデザイン集
Page top↑