I am trying to do some video things on android with OpenglES,MediaCodec,SurfaceTexture,and a bunch of other things. First I decode frames from video as GL_TEXTURE_EXTERNAL_OES texture. Then I render this to framebuffer. Here is the code:
checkGlError("before renderTexture");
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mCameraFbo.frameId());
checkGlError("renderTexture 1");
GLES20.glViewport(0, 0, mInputImageWidth, mInputImageHeight);
checkGlError("renderTexture 2");
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
checkGlError("renderTexture 3");
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
checkGlError("renderTexture 4");
GLES20.glUseProgram(mProgram);
if (texid != OpenGlUtils.NO_TEXTURE) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texid);
GLES20.glUniform1i(GLES20.glGetUniformLocation(mProgram, "inputImageTexture"), 1);
}
mTriangleVertices.position(0);
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTriangleVertices);
mGLTextureBuffer.position(0);
GLES20.glEnableVertexAttribArray(maTextureHandle);
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDisableVertexAttribArray(maPositionHandle);
GLES20.glDisableVertexAttribArray(maTextureHandle);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glUseProgram(0);
It Crashes in My Nexus 5X and Nexus 6P, at this line "GLES20.glClear", with glError 1286. But It's just fine on other older devices,such as Nexus 5 and Xiaomi Note.
I've checked framebuffer state with "glCheckFramebufferStatus",I'm pretty sure it is fine.
Device info:
Nexus 5X, Android7.1.1
GPU info:
vendor : Qualcomm
renderer: Adreno (TM) 418
version : OpenGL ES 3.2 V#145.0 (GIT#If5818605d9)
Anybody have idea about this? Thanks in advance.
Figure out why...I create framebuffer with an EGL Context, use it with another,
Related
I have created 2 sphere's, and I am currently trying to texture them. However the texture coordinates seem to be a bit off.
The Texture (Just supposed to be a window or some kind of break):
The result of the texture being applied to both spheres (You can ignore the black lines not around the square, that's just the camera - yes it's an AR app):
Now I exported the Sphere using a perl script I found that converts obj files to a list of vertices and texture coords OBJ2OPENGL. And the obj file has been converted with 2160 Vertices.
When I render the sphere:
GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT,
false, 0, ufo_sphere.getVertices());
GLES20.glVertexAttribPointer(normalHandle, 3, GLES20.GL_FLOAT,
false, 0, ufo_sphere.getNormals());
GLES20.glVertexAttribPointer(textureCoordHandle, 3,
GLES20.GL_FLOAT, false, 0, ufo_sphere.getTexCoords());
GLES20.glEnableVertexAttribArray(vertexHandle);
GLES20.glEnableVertexAttribArray(normalHandle);
GLES20.glEnableVertexAttribArray(textureCoordHandle);
// activate texture 0, bind it, and pass to shader
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,
mTextures.get(textureIndex).mTextureID[0]);
GLES20.glUniform1i(texSampler2DHandle, 0);
// pass the model view matrix to the shader
GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false,
modelViewProjection, 0);
//GLES20.glDrawElements(GLES20.GL_TRIANGLES, sphere.getNumObjectVertex(), GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, sphere.getNumObjectVertex()); // I have tried TRIANGLES and TRIANGLE_FAN as well
// disable the enabled arrays
GLES20.glDisableVertexAttribArray(vertexHandle);
GLES20.glDisableVertexAttribArray(normalHandle);
GLES20.glDisableVertexAttribArray(textureCoordHandle);
I can see at least one thing which seems to be wrong...
GLES20.glVertexAttribPointer(textureCoordHandle, 3,
GLES20.GL_FLOAT, false, 0, ufo_sphere.getTexCoords());
Texture coordinates typically have a size of 2 (u, v). So you could try this instead:
GLES20.glVertexAttribPointer(textureCoordHandle, 2,
GLES20.GL_FLOAT, false, 0, ufo_sphere.getTexCoords());
Also, in the link you provided they use the GL_TRIANGLES format instead of GL_TRIANGLE_STRIP so you should switch back to that.
I'm facing a big problem. I'm using a Transformer tf101 tab with Android 4.0.3 on it.
My app is using a custom OpenGL ES 2.0 surface. I'm rendering multiple planes with textures. this textures are changing approx. 20 times per second and are updated by passing byte arrays. However, in certain cases, the screen begins flickering and does not render the new textures. Additional UI Elements are still responsive and do their work as intended. It seems the OpenGL context ignores all commands and is unresponsive.
When this happens, a few lines show up in my logCat:
08-20 10:31:15.390: D/NvOsDebugPrintf(2898): NvRmChannelSubmit: NvError_IoctlFailed with error code 1
followed by
08-20 10:31:15.390: D/NvOsDebugPrintf(2898): NvRmChannelSubmit failed (err = 13, SyncPointValue = 879005, returning = 0)
and a few of them:
08-20 10:31:15.390: D/NvOsDebugPrintf(2898): NvRmChannelSubmit failed (err = 196623, SyncPointValue = 0)
Here is how i create my Textured Plane:
m_nTextureStorage[0] = 0;
GLES20.glGenTextures( 1, m_nTextureStorage, 0);
GLES20.glActiveTexture( GLES20.GL_TEXTURE0 );
GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, m_nTextureStorage[ 0 ] );
// Set filtering
GLES20.glTexParameterf( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST );
GLES20.glTexParameterf( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST );
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 );
and here is how i draw it:
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glActiveTexture( GLES20.GL_TEXTURE0 );
//GLES20.glUniformMatrix4fv(m_HMVPMatrixUniform, 1, false, mvpMatrix, 0);
GLES20.glUseProgram( m_nProgramHandle );
ByteBuffer oDataBuf = ByteBuffer.wrap( m_sTexture );
m_HTextureUniform = GLES20.glGetUniformLocation( m_nProgramHandle, "uTexture" );
m_HTextureCoordinate = GLES20.glGetAttribLocation( m_nProgramHandle, "TexCoordinate" );
GLES20.glUniform1iv( m_HTextureUniform, 2, m_nTextureStorage, 0 );
// get handle to the vertex shader's vPosition member
m_nPositionHandle = GLES20.glGetAttribLocation( m_nProgramHandle, "vPosition" );
// Prepare the triangle data
GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 640, 480,
0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, oDataBuf );
// Prepare the triangle data
GLES20.glVertexAttribPointer( m_nPositionHandle, 3, GLES20.GL_FLOAT, false, 12, m_oVertexBuffer );
GLES20.glEnableVertexAttribArray( m_nPositionHandle );
GLES20.glVertexAttribPointer( m_HTextureCoordinate, 2, GLES20.GL_FLOAT, false, 12, m_oTextureBuffer);
GLES20.glEnableVertexAttribArray( m_HTextureCoordinate );
m_nMVPMatrixHandle = GLES20.glGetUniformLocation( m_nProgramHandle, "uMVPMatrix");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv( m_nMVPMatrixHandle, 1, false, mvpMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
The OpenGL Renderer simply calls the draw function of my TexturedPlane by passing the mvpMatrix. Im not deleting any textures since i've read that the android system will take care of that automatically.
I think it has something todo with the GPU going OOM, but im not sure since i haven't found anything related to the posted error messages.
Thanks it advance!
UPDATE:
The Rendermode was set to RENDER_WHEN_DIRTY . After Changing it to RENDERMODE_CONTINOUSLY the problem disappears.. Weird. Since this is just a workaround and no solution, I'm still asking for help ;)
Leaving the Rendermode at continuously is no option, since this consumes to much processor time and makes no sense, since rendering is only necessary when new textures a generated.
Finally found the solution.
When i call glFlush() after every rendering circle, it works fine. I no render every plane on a different texture channel, it works perfectly so far. Thanks for the help.
When you call ..:
GLES20.glUniform1iv( m_HTextureUniform, 2, m_nTextureStorage, 0 );
I think that binds a particular texture unit to the sampler uniform. But you're passing a texture name/object/handle/whatever (which is not a texture unit.) Maybe it's just coincidence, and you only ever pass in 0 (which is possibly the texture name in m_nTextureStorage,) which is coincidentally the correct/desired value?
Or maybe this results in the user-space driver crashing.
I'm rendering simple scene with library GLESv1_CM on Android with NDK.
void render(Rect viewport)
{
glViewport(viewport.left, viewport.top, viewport.Width(), viewport.Height());
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(viewport.left, viewport.right, viewport.top, viewport.bottom, -1, 1);
GLfloat points[] = { 5, 50, 1, 1, 1, 1,
7, 50, 1, 1, 1, 1,
7, 50, 1, 0, 0, 1,
7, 52, 1, 0, 0, 1,
8, 50, 0, 1, 0, 1,
10, 50, 0, 1, 0, 1};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2,GL_FLOAT,sizeof(GLfloat)*6,&points);
glColorPointer(4,GL_FLOAT,sizeof(GLfloat)*6,&points[2]);
glDrawArrays(GL_LINES,0,6);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
I wish to have 3 crossed lines, but when I run it on device with android 2.2 or 3.2 i have this:
Even more, on Android emulator with Android 4 (update: same on emulator with 2.3) i have this:
Is it possible to make it looks like on this picture on all devices with all Android versions without using opengl2?
Thank you
According to the OpenGL FAQ for this type of projection:
If exact pixelization is required, you might want to put a small
translation in the ModelView matrix, as shown below:
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0.375, 0.375, 0.);
I imagine this reduces the likelihood of rounding issues.
I have an Android app which uses a bit of OpenGL running on a Galaxy Nexus with ICS. After turning on hardware acceleration and using my OpenGL activity some of those textures are stolen by the system and now in my listviews and other UI elements. Its as if my GL pointers obtained via GLES20.glGenTextures are not actually fresh pointers but rather overwriting ones used by the window renderer.
In any case there should be some sort of firewall or sandbox between the OS screen drawing system and my app, no?
Turning off hardwareAcceleration entirely displays fine, but the UI is choppy (and buttery smooth on 2.3 and lower either way). Turning it off/on activity by activity doesn't help either.
Screenshot (before/after)
Normally a repeating bitmap drawable, now an image (from camera in this case) I loaded into OpenGL in a different activity - http://a.yfrog.com/img532/9245/t81k.png
Gen/Load texture
int[] image = new int[1];
GLES20.glGenTextures(1, image, 0);
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);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
Basic draw
GLES20.glViewport(0, 0, width, height);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(shader.program);
GLES20.glUniform1i(GLES20.glGetUniformLocation(shader.program, "imageTexture"), 0);
GLES20.glVertexAttribPointer(Attributes.VERTEX, 2, GLES20.GL_FLOAT, true, 0, squareVertices);
GLES20.glEnableVertexAttribArray(Attributes.VERTEX);
GLES20.glVertexAttribPointer(Attributes.TEXTUREPOSITON, 2, GLES20.GL_FLOAT, true, 0, textureVertices);
GLES20.glEnableVertexAttribArray(Attributes.TEXTUREPOSITON);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, image[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
Turns out I was calling GL commands on the UI thread at certain times. This interfered with the apps hardware accelerated display as suggested by Romain Guy at this post.
I use the following code to retrieve the depth buffer:
FloatBuffer pixels = ByteBuffer
.allocateDirect(4).order(ByteOrder.nativeOrder()).asFloatBuffer();
GLES20.glReadPixels(pointx, pointy, 1, 1,
GLES20.GL_DEPTH_COMPONENT16, GLES20.GL_FLOAT, pixels);
Problem is, whichever point I am requesting, the pixels is giving me 0.0;
I have enabled the following in onSurfaceCreated:
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
GLES20.glDepthMask(true);
GLES20.glClearColor(1, 1, 1, 1);
I've been struggling with this issue for days! Please help.
According to the OpenGL ES 2.0 docs, glReadPixels() doesn't support reading the depth buffer. What does glGetError() return?