OpenGl ES texture(纹理)绘制为单一纯色bug - 1

纹理单一颜色

English describe : android opengl textureview solid color

StackOverFlow推荐的错误排查
PS:(声明了属性,但没使用,debug时position为-1(测试时注意))

直接原因

纹理坐标赋值没有起效,实际上一直在重复纹理0,0坐标上的颜色

可能代码原因
  1. stackoverflow那个是属性赋值没有glEnableVertexAttribArray
  2. 对属性赋值时 VBO和FloatBuffer作为实参 两种方式不能混合使用
针对2的实验代码如下:
public class Triangle {

    private final String vertexShaderCode =
            // This matrix member variable provides a hook to manipulate
            // the coordinates of the objects that use this vertex shader
            "uniform mat4 uMVPMatrix;" +
                    "attribute vec4 vPosition;" +
                    "attribute vec2 a_TexCoordinate;" +
                    "varying vec2 v_TexCoordinate;" +
                    "void main() {" +
                    // the matrix must be included as a modifier of gl_Position
                    // Note that the uMVPMatrix factor *must be first* in order
                    // for the matrix multiplication product to be correct.
                    "  v_TexCoordinate = a_TexCoordinate;" +
                    "  gl_Position = uMVPMatrix * vPosition;" +
                    "}";

    private final String fragmentShaderCode =
            "precision highp float;" +
                    "uniform vec4 vColor;" +
                    "uniform sampler2D u_Texture;" +
                    "varying vec2 v_TexCoordinate;" +

                    "void main() {" +
                    "    gl_FragColor = texture2D(u_Texture, v_TexCoordinate);" +
//                    "  gl_FragColor = vColor;" +
                    "}";
    private final int mProgram;
    private int vbo_vertex_box;
    private int vbo_coord_box;
    private int mTextureDataHandle;

    // Use to access and set the view transformation
    private int mMVPMatrixHandle;

    private FloatBuffer vertexBuffer;

    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float triangleCoords[] = {   // in counterclockwise order:
            -0.5f, 0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, 0.5f, 0.0f,
            0.5f, 0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f
    };

    // Set color with red, green, blue and alpha (opacity) values
    float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 1.0f};


    final float[] cubeTextureCoordinateData = {
            0f, 0f,
            0f, 1f,
            1f, 0f,

            1f, 0f,
            0f, 1f,
            1f, 1f
    };
    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;

    /**
     * Store our model data in a float buffer.
     */
    private FloatBuffer mTextureBuffer;
    private int mBytesPerFloat = 4;
    private boolean useVbo = false;

    public Triangle(Context context) {
        // initialize vertex byte buffer for shape coordinates
        int vertexShader = GlUtils.loadShader(GLES20.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader = GlUtils.loadShader(GLES20.GL_FRAGMENT_SHADER,
                fragmentShaderCode);

        // create empty OpenGL ES Program
        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        GLES20.glLinkProgram(mProgram);

        mTextureDataHandle = GlUtils.loadTexture(context, R.drawable.real_solid);

        if (useVbo) {
            vbo_vertex_box = generateOneBuffer();
            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo_vertex_box);
            FloatBuffer cube_vertices_buffer = FloatBuffer.wrap(triangleCoords);
            GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, cube_vertices_buffer.limit() * 4,
                    cube_vertices_buffer, GLES20.GL_DYNAMIC_DRAW);

            vbo_coord_box = generateOneBuffer();
            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo_coord_box);
            FloatBuffer coord_buffer = FloatBuffer.wrap(cubeTextureCoordinateData);
            GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, coord_buffer.limit() * 4,
                    coord_buffer, GLES20.GL_DYNAMIC_DRAW);
        } else {
            vertexBuffer = (FloatBuffer) ByteBuffer.allocateDirect(triangleCoords.length * 4)
                    .order(ByteOrder.nativeOrder())
                    .asFloatBuffer().put(triangleCoords).position(0);

            mTextureBuffer = (FloatBuffer) ByteBuffer.allocateDirect(cubeTextureCoordinateData.length * 4)
                    .order(ByteOrder.nativeOrder())
                    .asFloatBuffer().put(cubeTextureCoordinateData).position(0);
        }
    }

    public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
        GLES20.glUseProgram(mProgram);

        int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        int textureHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");

        if (useVbo) {
            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo_vertex_box);
            GLES20.glEnableVertexAttribArray(mPositionHandle);
            GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT,
                    false, 3 * 4, 0);

            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo_coord_box);
            GLES20.glEnableVertexAttribArray(textureHandle);
            GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT,
                    false, 2 * 4, 0);
        } else {
            GLES20.glEnableVertexAttribArray(mPositionHandle);
            GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                    GLES20.GL_FLOAT, false,
                    COORDS_PER_VERTEX * 4, vertexBuffer);

            GLES20.glEnableVertexAttribArray(textureHandle);
            GLES20.glVertexAttribPointer(textureHandle, 2,
                    GLES20.GL_FLOAT, false,
                    2 * 4, mTextureBuffer);
        }


        // get handle to fragment shader's vColor member
        int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);


        // get handle to shape's transformation matrix
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

        // Pass the projection and view transformation to the shader
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

        // Draw the triangle
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
    
    private int generateOneBuffer() {
        int[] buffer = {0};
        GLES20.glGenBuffers(1, buffer, 0);
        return buffer[0];
    }
    
}
public class MyGlRenderer implements GLSurfaceView.Renderer {
    private Triangle mTriangle;

    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    Context mContext;

    public MyGlRenderer(Context context) {
        mContext = context;
    }


    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        mTriangle = new Triangle(mContext);
    }

    @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, -1f, 1f, 3f, 7f);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        // Set the camera position (View matrix)
        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        // Calculate the projection and view transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
//        mTriangle.draw();
        mTriangle.draw(mMVPMatrix);
    }

}

public class MyGlSurfaceView extends GLSurfaceView {

    private MyGlRenderer mRender;

    public MyGlSurfaceView(Context context) {
        super(context);
        init(context);
    }

    public MyGlSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        setEGLContextClientVersion(2);
        mRender = new MyGlRenderer(context);
        setRenderer(mRender);
        setRenderMode(RENDERMODE_WHEN_DIRTY);
    }
}
    private GLSurfaceView mGlSurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_surface_view);
        initView();
    }


    private void initView() {
        mGlSurfaceView = (GLSurfaceView) findViewById(R.id.surface_gl_view);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值