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,
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 had a canvas that was correctly displayed on older APIs. However, when I ran it on my newer tablet, the graphics weren't being drawn.
Here is a minimal test example:
protected void onDraw(Canvas canvas) {
// .....
// skipped paint initialization code ...
canvas.drawRect(0, 0, 100, 100, redPaint);
canvas.drawRect(100, 100, 200, 0, greenPaint);
canvas.drawRect(200, 0, 300, 100, bluePaint);
canvas.drawRect(300, 0, 400, 100, redPaint);
canvas.drawRect(500, 0, 400, 100, bluePaint);
canvas.drawRect(500, 0, 600, 100, greenPaint);
}
Running this on older and new tablets will give very different results.
Older devices:
[RED][GREEN][BLUE][RED][BLUE][GREEN]
Newer devices:
[RED][SPACE][BLUE][RED][SPACE][GREEN]
It seems that drawRect no longer works with negative values in newer APIs. To fix the problem, make sure values always go from lower to higher unless you have a specific reason for not wanting them to draw on new APIs.
I have a tetrahedron object created in openGL ES 2.0. What I'm trying to achieve is to show the actual wireframe of the polygon over its base color. Is there a method for achieving this effect?
Also, my tetrahedron is pink. How can I change its color?
1: First draw your object as usual, then draw it again (with a different shader, or it will be the same color as the object and thus invisible), using GLES20.GL_LINES, GL_LINE_LOOP or GL_LINE_STRIP.
You might want to scale the object up slightly when drawing the lines so that the depth-testing don't decides that the lines are behind the object and ignores them.
2: This is done in your shader, set gl_FragColor to a vec4 containing your wanted rgba-values for a solid color.
In addition to what Jave said. Instead of enlarging the whole object (whose optimal amount always depends on the object and the current view) to prevent z-fighting artefacts, you can also use the polygon offset (using glPolygonOffset), whose major application are indeed wireframe overlays.
It basically works by slightly adjusting the depth values of the resulting fragments, which you cannot achieve differently in ES, since you cannot write to the depth buffer (which I guess is the reason they didn't drop it from ES, like they did in desktop GL 3+). So you basically render your solid object and your line-version of the object using the same vertices, but using a polygon offset configuration for the solid object that slightly increases the resulting fragments' depth values (pushes them away from the viewer), thus placing the triangles always behind the lines in view space (or window space actually). See here for further information.
Though the case of a tetrahedron might make some problems because of its very sharp edges.
Although this has been here a little while (over a year now), this may also help: Note that you may not need to use another shader to achieve the desired result. You can disable the vertex attribute array then specify and load the constant vertex attribute data (the wireframe line color) to draw the wire frame. For example:
float coloredcube[] = { 2, 2, 2, 1, 0, 0, -2, 2, 2, 0, 1, 0, -2, -2, 2, 0,
0, 1, 2, -2, 2, 1, 1, 0, 2, 2, -2, 1, 0, 1, -2, 2, -2, 0, 1, 1, -2,
-2, -2, 1, 1, 1, 2, -2, -2, 0, 0, 0
};
short indices[] = { 0, 1, 2, 0, 2, 3, //back
0, 4, 7, //right
0, 7, 3,
7, 6, 2, //bottom
7, 2, 3,
4, 5, 6, //front
4, 6, 7,
5, 1, 2, //left
5, 2, 6,
0, 1, 5, 0, 5, 4 //top
};
short lineindices[] = { 0, 1, 1, 2, 0, 2, 2, 3,
0, 4, 4, 7, 0, 7, 7, 3,
7, 6, 6, 2, 7, 2, 4, 5,
5, 6, 4, 6, 5, 2, 1, 5, 0, 5, 0, 3 };
glVertexAttribPointer(iPosition, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),coloredcube);
glEnableVertexAttribArray(iPosition);
glVertexAttribPointer(iColor, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),coloredcube + 3);
glEnableVertexAttribArray(iColor);
// offset the filled object to avoid the stitching that can arise when the wireframe lines are drawn
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(2.0f, 2.0f);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, indices);
glDisable(GL_POLYGON_OFFSET_FILL);
//Then disable the vertex colors and draw the wire frame with one constant color
glDisableVertexAttribArray(iColor);
glLineWidth(1.0f);
GLfloat color[4] = { 1.0f, 0.0f, 0.0f, 0.5f };
glVertexAttrib4fv(iColor, color);
glDrawElements(GL_LINES, 36, GL_UNSIGNED_SHORT, lineindices);
A similar example can be found in "The OpenGL ES 2.0 programming guide" pp 109,110.
I am trying to load a texture on to my android app display, where I am using code from this github.
I get my pixels messed up completely on the screen, And I have no idea, what's going on. The only thing I change in that code is I have memcpy, which copied uint8_t buffer into s_pixels instead of render_pixels in glbuffer.c file. My frame pixels are in rgb565 format.
Is it somekind of configuration problem or any problem with the way I copy pixels?
EDIT
Below is the code :
pictureQ is as below
pictureQ {
uint8_t *data;
int size;
}
memcpy(s_pixels,&(pictureQ[qFirst].data[0]) , 307200);
//render_pixels(s_pixels);
glClear(GL_COLOR_BUFFER_BIT);
// glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 480, 320, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, &(pictureRGBQ[qFirst].data[0]));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 480, 320, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, s_pixels);
check_gl_error("glTexSubImage2D");
glDrawTexiOES(0, 0, 0, s_w, s_h);
check_gl_error("glDrawTexiOES");
memset(s_pixels, 0, 307200);
Ok, It was my mistake, I was passing the data for the pixels instead of the data. Thanks for your response Reuben Scatton.