问题
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;
}
}
回答1:
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
回答2:
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);
....
来源:https://stackoverflow.com/questions/28250867/opengl-es-2-0-shader-on-texture-not-working