OpenGL ES 2.0 Shader on Texture not working

2019-09-10 07:51发布

I copied the example from this site click

It is working well after fixing some minor things and extending the shader for my purpose. Now i want to move/translate the texture to the right side of the screen.

For that case i have to add a ModelViewProjection Matrix to my code and as well to the shader, right?

After doing this the Texture is not showing up anymore :-( What am I doing wrong?

So the code is working until i change in my shader gl_position from :

gl_Position= a_position to gl_Position= a_position * ModelViewProjectionMatrix

There is no error but also no texture...

The output for the ModelViewProjection is : [0.0,0.0,0.0,0.0] ... why?

This is the Source-Code :

Activity:

//Activity
public class MainActivity extends Activity {
    private MainView mView;
    //private WakeLock mWL;

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

        mView = new MainView(this);
        setContentView(mView);

    }

    @Override
    protected void onPause() {

        mView.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mView.onResume();

    }
}

SurfaceView

    //View
    class MainView extends GLSurfaceView {
        CameraRenderer mRenderer;

        MainView(Context context) {
            super(context);
            mRenderer = new CameraRenderer(this);
            setEGLContextClientVersion(2);
            setRenderer(mRenderer);
            //setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
        }

        public void surfaceCreated(SurfaceHolder holder) {
            super.surfaceCreated(holder);
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            mRenderer.close();
            super.surfaceDestroyed(holder);
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            super.surfaceChanged(holder, format, w, h);
        }
    }

CameraRenderer:

    public class CameraRenderer  implements GLSurfaceView.Renderer,
        SurfaceTexture.OnFrameAvailableListener {

    private final String vss = "uniform mat4 uMVPMatrix;\n"
            + "attribute vec2 vPosition;\n"
            + "attribute vec2 vTexCoord;\n"
            + ""
            + "varying vec2 texCoord;\n"
            + "vec4 Distort(vec4 p){                    \n"
            + " float BarrelPower = 1.0;            \n"
            + " vec2 v = p.xy / p.w;                \n"
            + "     float radius = length(v);           \n"
            + " if (radius > 0.0){                  \n"
            + "     float theta = atan(v.y,v.x);    \n"
            + "         radius = pow(radius, BarrelPower);\n"
            + "         v.x = radius * cos(theta);      \n"
            + "         v.y = radius * sin(theta);      \n"
            + "         p.xy = v.xy * p.w;              \n"
            + " }"
            + "                                         \n"
            + " return p;                               \n"
            + " }                                       \n"
            + "void main() {\n"

            +" vec4 a_position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );"
            + "vec4 test = uMVPMatrix * a_position; \n"
            + "texCoord = vTexCoord;\n"
            + "gl_Position = test;\n"
            + "}";

    private final String fss = "#extension GL_OES_EGL_image_external : require\n"
            + "precision mediump float;\n"
            + "uniform samplerExternalOES sTexture;\n"
            + "varying vec2 texCoord;\n" + "void main() {\n"
            + "  gl_FragColor = texture2D(sTexture,texCoord);\n" + "}";

    private int[] hTex;
    private FloatBuffer pVertexRight;
    private FloatBuffer pTexCoordRight;

    private int hProgram;

    private Camera mCamera;
    private SurfaceTexture mSTexture;

    private boolean mUpdateST = false;

    private MainView mView;

    private float[] mMVPMatrix = new float[16];
    private float[] mProjMatrix = new float[16];
    private float[] mMMatrix = new float[16];
    private float[] mVMatrix = new float[16];

    private int muMVPMatrixHandle;
    private int maPositionHandle;
    private int maTextureHandle;

    CameraRenderer(MainView view) {

        mView = view;

        float[] vtmpRight = { 0.35f, -0.35f, -0.35f, -0.35f, 0.35f, 0.35f,
                -0.35f, 0.35f };
        float[] ttmpRight = { 0.35f, 0.35f, 0.0f, 0.35f, 0.35f, 0.0f, 0.0f,
                0.0f };

        pVertexRight = ByteBuffer.allocateDirect(8 * 4)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        pVertexRight.put(vtmpRight);
        pVertexRight.position(0);
        pTexCoordRight = ByteBuffer.allocateDirect(8 * 4)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        pTexCoordRight.put(ttmpRight);
        pTexCoordRight.position(0);

    }

    public void close() {
        mUpdateST = false;
        mSTexture.release();
        mCamera.stopPreview();

        mCamera = null;
        deleteTex();
    }

    public void onSurfaceCreated(GL10 unused,
            javax.microedition.khronos.egl.EGLConfig config) {
        // String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS);
        // Log.i("mr", "Gl extensions: " + extensions);
        // Assert.assertTrue(extensions.contains("OES_EGL_image_external"));

        initTex();
        mSTexture = new SurfaceTexture(hTex[0]);
        mSTexture.setOnFrameAvailableListener(this);

        mCamera = Camera.open();
        try {
            mCamera.setPreviewTexture(mSTexture);

            Log.i("GLES20", "setPreviewTexture success");

        } catch (IOException ioe) {
        }

        GLES20.glClearColor(1.0f, 1.0f, 0.0f, 1.0f);

        hProgram = loadShader(vss, fss);



    }

    public void onDrawFrame(GL10 unused) {

        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        synchronized (this) {
            if (mUpdateST) {
                mSTexture.updateTexImage();
                mUpdateST = false;
            }
        }

        GLES20.glUseProgram(hProgram);

        int ph = GLES20.glGetAttribLocation(hProgram, "vPosition");



        int tch = GLES20.glGetAttribLocation(hProgram, "vTexCoord");
        int th = GLES20.glGetUniformLocation(hProgram, "sTexture");

        muMVPMatrixHandle = GLES20.glGetUniformLocation(hProgram, "uMVPMatrix");



        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]);
        GLES20.glUniform1i(th, 0);

        GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 4 * 2,
                pVertexRight);

        GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 4 * 2,
                pTexCoordRight);
        GLES20.glEnableVertexAttribArray(ph);
        GLES20.glEnableVertexAttribArray(tch);

        Matrix.setRotateM(mMMatrix, 0, 0, 0, 0, 1.0f);
        Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv( muMVPMatrixHandle, 1, false, mMVPMatrix, 0 );
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

        // right
        GLES20.glFlush();

    }

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

        Camera.Parameters param = mCamera.getParameters();

        List<Size> psize = param.getSupportedPreviewSizes();
        if (psize.size() > 0) {
            int i;
            for (i = 0; i < psize.size(); i++) {
                if (psize.get(i).width < width || psize.get(i).height < height)
                    break;
            }
            if (i > 0)
                i--;

            param.setPreviewSize(psize.get(i).width, psize.get(i).height);
            Log.i("mr", "ssize: " + psize.get(i).width + ", "
                    + psize.get(i).height);
        }



        mCamera.setParameters(param);
        mCamera.startPreview();



    }

    private void initTex() {
        hTex = new int[1];
        GLES20.glGenTextures(1, hTex, 0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
                GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
    }

    private void deleteTex() {
        GLES20.glDeleteTextures(1, hTex, 0);
    }

    public synchronized void onFrameAvailable(SurfaceTexture st) {

        mUpdateST = true;
        // mView.requestRender();
    }

    private static int loadShader(String vss, String fss) {
        int vshader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        GLES20.glShaderSource(vshader, vss);
        GLES20.glCompileShader(vshader);
        int[] compiled = new int[1];
        GLES20.glGetShaderiv(vshader, GLES20.GL_COMPILE_STATUS, compiled, 0);
        if (compiled[0] == 0) {
            Log.e("Shader", "Could not compile vshader");
            Log.v("Shader",
                    "Could not compile vshader:"
                            + GLES20.glGetShaderInfoLog(vshader));
            GLES20.glDeleteShader(vshader);
            vshader = 0;
        } else {

            Log.i("GLES20", "compile vertex success");

        }

        int fshader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fshader, fss);
        GLES20.glCompileShader(fshader);
        GLES20.glGetShaderiv(fshader, GLES20.GL_COMPILE_STATUS, compiled, 0);
        if (compiled[0] == 0) {
            Log.e("Shader", "Could not compile fshader");
            Log.v("Shader",
                    "Could not compile fshader:"
                            + GLES20.glGetShaderInfoLog(fshader));
            GLES20.glDeleteShader(fshader);
            fshader = 0;
        } else {
            Log.i("GLES20", "compile fragment success");

        }

        int program = GLES20.glCreateProgram();
        GLES20.glAttachShader(program, vshader);
        GLES20.glAttachShader(program, fshader);
        GLES20.glLinkProgram(program);

        return program;
    }


}

2条回答
姐就是有狂的资本
2楼-- · 2019-09-10 08:31

I cant's see where you set the values from the matrix mMVPMatrix to the uniform uMVPMatrix. You should do something like this before drawing the arrays:

GLES20.glUniformMatrix4fv( muMVPMatrixHandle, 1, false, mMVPMatrix, 0 );

EDIT: @derhass @reto-koradi thank you for correcting my answer

查看更多
老娘就宠你
3楼-- · 2019-09-10 08:36

Last Post and additionally defining the viewFrustum did it. Thanks a lot ! :-)

onSurfaceChange(width,height){
...
float ratio = (float) width / height;

Matrix.frustumM(mProjectionMatrix, 0, ratio, -ratio, -1, 1, 3, 7);
....
查看更多
登录 后发表回答