Android OpenGl 2.0使用着色器进行纹理处理

时间:2014-07-11 00:24:25

标签: java android opengl-es textures

所以,我从另一篇文章收到了这个代码。它似乎是在Android中使用着色器在openGl 2.0中添加纹理的最完整的工作代码。他如何知道要传递给textureResourceId的整数,以及如何将资源ID设置为我放入项目的.png文件?

这是我正在努力的SO帖子的链接:

Android OpenGL|ES 2.0 Texturing

这是Square Code:

 public class Square{

private static final String TAG = "Square";

public float[] rotation = {0.0f,0.0f,45.0f};
public float[] scale = {100.0f,100f,100f};
public float[] position = {0.0f,0.0f,100f};
public float[] color = { 0.0f, 0.0f, 1.0f, 1.0f };

private int textureRef = -1;

private int mMVPMatrixHandle;

protected int DRAW_MODE = GLES20.GL_TRIANGLES;
protected int mProgram; 
protected int mPositionHandle;
protected Vertex vertices;
protected Vertex texture;

private int mColorHandle;

private int vsTextureCoord;
private int fsTexture;  

protected float[] result_matrix = new float[16];    

private final String vertexShaderCode =
        "uniform mat4 uMVPMatrix;" +
                "attribute vec3 vPosition;" +
                "attribute vec2 TexCoordIn;" +
                "varying vec2 TexCoordOut;" +
                "void main() {" +
                //the matrix must be included as a modifier of gl_Position
                "  gl_Position = uMVPMatrix * vec4(vPosition,1.0);" +
                "  TexCoordOut = TexCoordIn;" +
                "}";

private final String fragmentShaderCode =
        "precision mediump float;" +
                "uniform vec4 vColor;" +
                "uniform sampler2D Texture;" +
                "varying lowp vec2 TexCoordOut;" +                             
                "void main() {" +                   
                "  gl_FragColor = vColor*TexCoordOut*Texture;" +
                "}";    
//I am fully aware that I am not using the texture by assigning the colour, but until I can actually SEND the texture through, there would be no point.
static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // top left
                                -0.5f, -0.5f, 0.0f,   // bottom left
                                 0.5f, -0.5f, 0.0f,   // bottom right
                                 0.5f,  0.5f, 0.0f }; // top right


private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices

public Square(int textureResourceId) {

    int vertexShader = GFXUtils.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    int fragmentShader = GFXUtils.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

    mProgram = GLES20.glCreateProgram();             // create empty OpenGL ES Program
    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
    GLES20.glLinkProgram(mProgram);                  // creates OpenGL ES program executables
    textureRef = GFXUtils.textures.get(textureResourceId);

    // initialize vertex byte buffer for shape coordinates
    vertices = new Vertex(squareCoords, drawOrder, GFXUtils.COORDS_PER_VERTEX);

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

    DRAW_MODE = GLES20.GL_TRIANGLE_FAN;
}

private void getHandles()
{

    //get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    if (mPositionHandle == -1) Log.e(TAG, "vPosition not found");
    //get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
    if (mColorHandle == -1) Log.e(TAG, "vColor not found");

    //get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    if (mMVPMatrixHandle == -1) Log.e(TAG, "uMVPMatrix not found");

    //get handle to texture coordinate variable
    vsTextureCoord = GLES20.glGetAttribLocation(mProgram, "TexCoordIn");
    if (vsTextureCoord == -1) Log.e(TAG, "TexCoordIn not found");

    //get handle to shape's texture reference
    fsTexture = GLES20.glGetUniformLocation(mProgram, "Texture");
    if (fsTexture == -1) Log.e(TAG, "Texture not found");

}

private void translateRotateScale(float[] matrix, float[] perspectiveMatrix)
{       
    for (int i= 0; i < perspectiveMatrix.length;i++)
        matrix[i] = perspectiveMatrix[i];

    Matrix.translateM(matrix, 0, position[0], position[1], position[2]);
    Matrix.rotateM(matrix, 0, rotation[0], 1.0f, 0.0f, 0.0f);
    Matrix.rotateM(matrix, 0, rotation[1], 0.0f, 1.0f, 0.0f);
    Matrix.rotateM(matrix, 0, rotation[2], 0.0f, 0.0f, 1.0f);
    Matrix.scaleM(matrix, 0, scale[0], scale[1], scale[2]);            
}

public void draw(float[] mvpMatrix) {
    rotation[2]+=0.5;
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram);
    GFXUtils.checkGlError("using program");

    //Housekeeping
    getHandles();
    translateRotateScale(result_matrix, mvpMatrix);
    //end housekeeping

    // Set color for drawing the shape
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);     

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, result_matrix, 0);
    GFXUtils.checkGlError("glUniformMatrix4fv");

    // Prepare the shape coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, GFXUtils.COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false,
            GFXUtils.vertexStride, vertices.floatBuffer);
    GFXUtils.checkGlError("load vertex buffer");

    GLES20.glVertexAttribPointer(vsTextureCoord, GFXUtils.COORDS_PER_TEXTURE,
            GLES20.GL_FLOAT, false, 
            GFXUtils.textureStride, texture.floatBuffer);
    GFXUtils.checkGlError("load texture buffer - " + vsTextureCoord);

    // Enable a handle to the shape vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GFXUtils.checkGlError("enable position handle");
    GLES20.glEnableVertexAttribArray(vsTextureCoord);
    GFXUtils.checkGlError("enable texture handle");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GFXUtils.checkGlError("activtexture");
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureRef);
    GFXUtils.checkGlError("bindtexture");
    GLES20.glUniform1i(fsTexture, 0);
    GFXUtils.checkGlError("uniformi");
    //Draw the shape
    GLES20.glDrawElements(DRAW_MODE, vertices.numIndeces, GLES20.GL_UNSIGNED_SHORT, vertices.indexBuffer);
    GFXUtils.checkGlError("glDrawArrays with " + vertices.numVertices + " vertices");

    //Disable vertex array
    GLES20.glDisableVertexAttribArray(vsTextureCoord);
    GLES20.glDisableVertexAttribArray(mPositionHandle);
    GFXUtils.checkGlError("glDisableVertexAttribArray for position");

}

}

我的主要活动类:

public class MainActivity extends ActionBarActivity {

GLSurfaceView myGL;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myGL=new MySurface(this);   
    setContentView(myGL);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);
        return rootView;
    }
}

//---------------------------------Open GL-------------------------------------------------------
class MySurface extends GLSurfaceView
{
    private MyRenderer myRend;

    public MySurface(Context context)
    {
        super(context);

        myRend=new MyRenderer();
        setEGLContextClientVersion(2);
        setRenderer(myRend);
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
}


Square mSquare;
float [] mViewMatrix=new float[16];
float [] mMVPMatrix=new float[16];
float [] mProjectionMatrix=new float[16];
private float[] mRotationMatrix=new float[16];

class MyRenderer implements GLSurfaceView.Renderer
{
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1f);

            mSquare=new Square(R.drawable.brick_texture);

    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

        mSquare.draw(mMVPMatrix);


    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        float ratio = (float) width / height;
        Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 2, 50);

    }   

}

}

0 个答案:

没有答案