OpenGL ES 2.0 Scaling not working - android

I need to scale an object in OpenGL|ES 2.0. Shaders:
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
//the matrix must be included as a modifier of gl_Position
" gl_Position = vPosition * uMVPMatrix;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
Projection:
Matrix.orthoM(mProjMatrix,0,
-1.0f, // Left
1.0f, // Right
-1.0f / ratio, // Bottom
1.0f / ratio, // Top
0.01f, // Near
10000.0f);
Drawing setup:
// Set the camera position (View matrix)
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
Actual render:
float[] scale = {5f,5f,1f};
Matrix.scaleM(scale_matrix, 0, scale[0], scale[1], scale[2]);
Matrix.multiplyMM(r_matrix, 0, scale_matrix, 0, mMVPMatrix, 0);
// Combine the rotation matrix with the projection and camera view
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, r_matrix, 0);
And it will not scale. I can see the triangle and I can rotate it. But scaling does not work.

Since vectors are column vectors in OpenGL you have to change the order of the matrix multiplication in your vertex shader:
gl_Position = uMVPMatrix*vPosition;

Related

Overlay texture using GLES20 and apply rotation

I am working on a project in which I am using GLES20 to render a texture. I used GLUtils.texImage2D() to draw 2d texture image from the bitmap.
What do I need to implement to make these changes:
Place the texture to the right corner of the screen instead of stretching it to the full screen.
Provide incremental rotation frame by frame to the texture.
Shaders
private final static String FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"uniform lowp sampler2D oTexture;\n" +
"void main() {\n" +
" lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" +
" lowp vec4 textureColor2 = texture2D(oTexture, vTextureCoord);\n" +
" \n" +
" gl_FragColor = mix(textureColor, textureColor2, textureColor2.a);\n" +
"}\n";
protected static final String DEFAULT_VERTEX_SHADER =
"attribute highp vec4 aPosition;\n" +
"attribute highp vec4 aTextureCoord;\n" +
"varying highp vec2 vTextureCoord;\n" +
"void main() {\n" +
"gl_Position = aPosition;\n" +
"vTextureCoord = aTextureCoord.xy;\n" +
"}\n";
Texture Generation
int[] textures = new int[1];
#Override
public void setup() {
super.setup();// 1
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
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);
}
#Override
public void onDraw() {
if (bitmap == null) {
return;
}
int offsetDepthMapTextureUniform = getHandle("oTexture");
GLES20.glActiveTexture(GLES20.GL_TEXTURE3);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
if (bitmap != null && !bitmap.isRecycled()) {
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap, 0);
}
GLES20.glUniform1i(offsetDepthMapTextureUniform, 3);
// Recycle the bitmap, since its data has been loaded into OpenGL.
releaseBitmap();
}
UPDATED
I added the mMVPMatrix for the texture transformation as suggested by alexrnov. Both, camera feed and overlay texture are rotating now.
protected static final String VERTEX_SHADER ="attribute highp vec4 aPosition;\n" +
"uniform mat4 uMVPMatrix;\n" +
"attribute highp vec4 aTextureCoord;\n" +
"varying highp vec2 vTextureCoord;\n" +
"void main() {\n" +
"gl_Position = uMVPMatrix * aPosition;\n" +
"vTextureCoord = aTextureCoord.xy;\n" +
"}\n";
#Override
public void onDraw() {
....
Matrix.setIdentityM(mvpMatrix, 0);
Matrix.rotateM(mvpMatrix, 0, rotation, 0.0f, 0.0f, 1.0f);
rotation++;
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, getMVPMatrixAsFloatBuffer(mvpMatrix));
...
}
The project structure is quite complicated. I can't write all the code here. Please refer the Github Project
Maybe there is another way, but you can overlay the texture on the rectangle, and apply transformations (movement/rotate) to this rectangle:
Vertex shader:
#version 100
uniform mat4 u_mvpMatrix; // MVP-matrix for moving and rotating texture
attribute vec4 a_position; // data of vertices rectangle
attribute vec2 a_textureCoordinates;
varying vec2 v_textureCoordinates;
void main() {
v_textureCoordinates = a_textureCoordinates;
gl_Position = u_mvpMatrix * a_position;
}
Fragment shader:
#version 100
varying vec2 v_textureCoordinates;
uniform sampler2D s_texture;
void main() {
gl_FragColor = texture2D(s_texture, v_textureCoordinates);
}
Approximate Java-code:
private final int textureID;
...
textureID = loadTexture(R.raw.texture);
...
#Override
public void draw() {
GLES20.glUseProgram(programObject);
GLES20.glEnableVertexAttribArray(positionLink);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[0]);
GLES20.glVertexAttribPointer(positionLink, VERTEX_COMPONENT,
GLES20.GL_FLOAT, false, VERTEX_STRIDE, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glEnableVertexAttribArray(textureCoordinatesLink);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[1]);
GLES20.glVertexAttribPointer(textureCoordinatesLink, TEXTURE_COMPONENT,
GLES20.GL_FLOAT, false, TEXTURE_STRIDE, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
GLES20.glUniform1i(samplerLink, 0);
GLES20.glUniformMatrix4fv(mvpMatrixLink, 1, false,
RectangleObject3D.getMVPMatrixAsFloatBuffer());
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, VBO[2]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, NUMBER_INDICES,
GLES20.GL_UNSIGNED_INT, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
GLES20.glDisableVertexAttribArray(positionLink);
GLES20.glDisableVertexAttribArray(textureCoordinatesLink);
}
MVP-matrix:
import android.opengl.Matrix
protected val viewMatrix = FloatArray(16)
protected val projectionMatrix = FloatArray(16)
protected val modelMatrix = FloatArray(16)
protected val modelViewMatrix = FloatArray(16)
protected val mvpMatrix = FloatArray(16)
...
Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 0f,
0f, 0f, -4f, 0f, 1.0f, 0.0f) // camera
...
// parameters different for portrait and landscape orientation screen android
Matrix.frustumM(projectionMatrix, 0, left, right, bottom, top, near, far)
...
fun spotPosition() { // invoke on every frame
Matrix.setIdentityM(modelMatrix, 0)
Matrix.translateM(modelMatrix, 0, x, y, z) // move object
Matrix.rotateM(modelMatrix, 0, angleX, 0.0f, 1.0f, 0.0f) // rotate object
Matrix.scaleM(modelMatrix, 0, 4f, 4f, 4f) // scale object
Matrix.multiplyMM(modelViewMatrix, 0, viewMatrix, 0, modelMatrix, 0)
Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, modelViewMatrix, 0)
}
fun getMVPMatrixAsFloatBuffer(): FloatBuffer = floatBuffer(mvpMatrix)
get FloatBuffer (essential in Java SDK):
public static FloatBuffer floatBuffer(float[] data) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * 4)
.order(ByteOrder.nativeOrder());
FloatBuffer returnBuffer = byteBuffer.asFloatBuffer();
returnBuffer.put(data).position(0);
return returnBuffer;
}

Android/OpenGles drawing 2 external texture each taking half of the screen. Left and right half

I have successfully bind 2 external OES texture to my shader. Now I want each texture to take 1/2 of the screen(Left for one texture right for another). How do I go about doing it? Example:
http://vicceskep.hu/kepek/vicces_funny_007445.jpg
random image from google
Showing a full picture of each picture. It will be nice to have an efficient method to do it. The code that I am currently referencing from is the bikflake/ grafika code from github.
Visit http://bigflake.com/mediacodec/CameraToMpegTest.java.txt
To check the code out.
Okay I think i will really give in depth clarification for my question as I do not have much knowledge about 3d projections in open GL. Sorry for the numerous edits on the question.
This is my Vertex Shader code currently
private static final String VERTEX_SHADER =
// UMVPMATRIX IS AN IDENTITY MATRIX
"uniform mat4 uMVPMatrix;\n" +
//These are surfacetexture.getTransformationMatrix
"uniform mat4 uSTMatrixOne;\n" +
"uniform mat4 uSTMatrixTwo;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"varying vec2 vTextureCoordTwo;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
" vTextureCoordTwo = (uSTMatrixTwo* aTextureCoord).xy ;\n" +
"}\n";
This is my Fragment Shader code currently which does a overlay currently.
private static final String FRAGMENT_SHADER =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" + // highp here doesn't seem to matter
"varying vec2 vTextureCoord;\n" +
"varying vec2 vTextureCoordTwo;\n" +
"uniform samplerExternalOES sTextureOne;\n" +
"uniform samplerExternalOES sTextureTwo;\n" +
"void main() {\n" +
" lowp vec4 pixelTop = texture2D(sTextureOne, vTextureCoord);\n" +
" lowp vec4 pixelBot = texture2D(sTextureTwo, vTextureCoordTwo);" +
" gl_FragColor = pixelTop + pixelBot;\n" +
"}\n";
As for the aPosition and the a texture coordinate it is currently referenced from. It would be nice if someone explained how mTraingleVerticesData works too.
private final float[] mTriangleVerticesData = {
// X, Y, Z, U, V
-1.0f, -1.0f, 0, 0.f, 0.f,
1.0f, -1.0f, 0, 1.f, 0.f,
-1.0f, 1.0f, 0, 0.f, 1.f,
1.0f, 1.0f, 0, 1.f, 1.f,
};
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
checkGlError("glVertexAttribPointer maPosition");
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
My 2 external projection binding currently
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
//Cam Code
//Set texture to be active
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTwoTextureID);
You can do it the way #Sung suggested but conditional statements and loops in shaders, especialy fragment, are slow. It's better to render 2 different polygons.
Yea I finally got it.I used 2 different programs to draw and used mTriangleVerticesData to edit the image proportions and use gl_position to shift the image.

Draw an Image based texture in openGl android(Wear)

I am drawing an image based texture using opengl in android, But the image is drawn partially only shown below
my coding
#Override
public void onGlContextCreated() {
super.onGlContextCreated();
shaders = new ShadersDla();
float[] vts = { // x, y, s, t.
-1, 1, 1, 1, -1, 1, 0, 0, 1, -1, 1, 1, 1, 1, 1, 0
};
// AllocateDirect prevents the GC moving this memory.
vtBuffer = ByteBuffer.allocateDirect(vts.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
vtBuffer.put(vts);
}
#Override
public void onGlSurfaceCreated(int width, int height) {
super.onGlSurfaceCreated(width, height);
float aspectRatio = (float) width / height;
float dist = .001f;
Matrix.frustumM(projectionMatrix, 0,
-aspectRatio * dist, aspectRatio * dist, // Left, right.
-dist, dist, // Bottom, top.
dist, 100); // Near, far.
makeTexture();
}
Shader
private static final String VERTEX_SHADER =
// Pass in the modelview matrix as a constant.
"uniform mat4 u_mvpMatrix; \n"
// Pass in the position and texture coordinates per vertex.
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
// Varyings are sent on to the fragment shader.
+ "varying vec2 v_texCoord; \n"
+ "void main() { \n"
// Transform the vertex coordinate into clip coordinates.
+ " gl_Position = u_mvpMatrix * a_position; \n"
// Pass through the texture coordinate.
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
Need some help to do this stuff.kindly guide me a easy way i'm new to android and opengl....
Change the texture coordinates as
{-1.0f, 1.0f, 0,0 ,
1.0f, 1.0f, 1,0,
-1.0f,-1.0f, 0,1 ,
1.0f, -1.0f, 1,1

Android OpenGLES Brown square

So I'm trying to learn openGLES 2.0 and create a textured rectangle. Apparently I didn't follow all the instructions and now I've ended up with just a odd color square.
heres my shaders.
final String vertexShader =
"uniform mat4 u_MVPMatrix; \n" // A constant representing the combined model/view/projection matrix.
+ "attribute vec2 a_TexCoordinate;\n" // Per-vertex texture coordinate information we will pass in.
+ "attribute vec4 a_Position; \n" // Per-vertex position information we will pass in.
// + "attribute vec4 a_Color; \n" // Per-vertex color information we will pass in.
// + "varying vec4 v_Color; \n" // This will be passed into the fragment shader.
+ "varying vec2 v_TexCoordinate; \n" // This will be passed into the fragment shader.
+ "void main() \n" // The entry point for our vertex shader.
+ "{ \n"
+ " v_TexCoordinate = a_TexCoordinate;\n" // Pass the texture coordinate through to the fragment shader.
// It will be interpolated across the triangle.
+ " gl_Position = u_MVPMatrix \n" // gl_Position is a special variable used to store the final position.
+ " * a_Position; \n" // Multiply the vertex by the matrix to get the final point in
+ "} \n";
final String fragmentShader =
"precision mediump float; \n" // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
+ "uniform sampler2D u_Texture; \n" // The input texture.
+ "uniform vec4 u_Color; \n" // This is the color from the vertex shader interpolated across the
// triangle per fragment.
+ "varying vec2 v_TexCoordinate; \n" // Interpolated texture coordinate per fragment.
+ "void main() \n" // The entry point for our fragment shader.
+ "{ \n"
+ " gl_FragColor = texture2D(u_Texture, v_TexCoordinate); \n"
+ "} \n";
Here is the load texture function
public static int loadTexture(final Context context, final int resourceId)
{
final int[] textureHandle = new int[1];
GLES20.glGenTextures(1, textureHandle, 0);
if (textureHandle[0] != 0)
{
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false; // No pre-scaling
// Read in the resource
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);
// Bind to the texture in OpenGL
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Recycle the bitmap, since its data has been loaded into OpenGL.
bitmap.recycle();
}
if (textureHandle[0] == 0)
{
throw new RuntimeException("Error loading texture.");
}
return textureHandle[0];
}
And here is the drawFrame
#Override
public void onDrawFrame(GL10 gl) {
// Set the background clear color to gray.
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
mTextureUniformHandle = GLES20.glGetUniformLocation(programHandle, "u_Texture");
mTextureCoordinateHandle = GLES20.glGetAttribLocation(programHandle, "a_TexCoordinate");
// Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
// Draw the triangle facing straight on.
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, Fields.screen_width / 2, Fields.screen_height / 2, 0);
Matrix.scaleM(mModelMatrix, 0, Fields.screen_width / 4, Fields.screen_width / 4, 0);
drawTriangle(mTriangle1Vertices);
}
Any advice for getting rid of the wierd brown square and actually displaying the texture?
Edit: Here are the texture coordinates
public GL20Renderer(Context context) {
final float[] triangle1VerticesData = {
// X, Y, Z,
// R, G, B, A
-1f, 1f, 0.0f,
-1, -1, 0.0f,
1f, 1f, 0.0f,
-1f, -1f, 0.0f,
1f, -1f, 0.0f,
1f, 1f, 0.0f,
};
// Initialize the buffers.
mTriangle1Vertices = ByteBuffer.allocateDirect(triangle1VerticesData.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mTriangle1Vertices.put(triangle1VerticesData).position(0);
final float[] triangle1TextureCoordinateData =
{
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f
};
mTriangleTextureCoordinates = ByteBuffer.allocateDirect(triangle1TextureCoordinateData.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mTriangleTextureCoordinates.put(triangle1TextureCoordinateData).position(0);
this.context = context;
}
and here is the drawtriangle function
private void drawTriangle(final FloatBuffer aTriangleBuffer)
{
// Pass in the position information
aTriangleBuffer.position(mPositionOffset);
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
mStrideBytes, aTriangleBuffer);
GLES20.glEnableVertexAttribArray(mPositionHandle);
int colorHandle = GLES20.glGetUniformLocation(programHandle, "u_Color");
// Set color for drawing the triangle
GLES20.glUniform4f(colorHandle, 0.0f, 0.8f, 1.0f, 1.0f);
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
}
Your drawTriangle code doesn't set the texture co-ordinates anywhere. Add some code something like this:
triangle1TextureCoordinateData.position(mPositionOffset * 2 / 3);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false,
0, triangle1TextureCoordinateData);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
Note you can set the stride to zero if your data is packed in the buffer.

OpenGL ES 2.0 Not rendering correctly

This is supposed to render a cube. It looks like some parts of the rear faces are rendering in front of the ones closest to the camera. This happens even if I set it farther away. This is from my renderer:
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// Set the camera position
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.setRotateM(mModelMatrix, 0, mAngle, 0f, 1f, 0.0f);
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mModelMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
// Draw object
cube.draw(mMVPMatrix, context);
mAngle++;
}
and my object's draw method
public void draw(float[] mvpMatrix, Context context) {
GLES20.glUseProgram(mProgram);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
GLES20.glVertexAttribPointer(mTexHandle, 2,
GLES20.GL_FLOAT, false,
8, textureBuffer);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glEnableVertexAttribArray(mTexHandle);
GLES20.glActiveTexture ( GLES20.GL_TEXTURE0 );
GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, mTextureID);
GLES20.glUniform1i ( mSampler, 0 );
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTexHandle);
}
and my shaders:
String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"uniform float u_offset; \n" +
"attribute vec4 a_position; \n" +
"attribute vec2 a_texCoord; \n" +
"varying vec2 v_texCoord; \n" +
"void main() \n" +
"{ \n" +
" gl_Position = uMVPMatrix * a_position; \n" +
" gl_Position.x += u_offset;\n" +
" v_texCoord = a_texCoord; \n" +
"} \n";
String fragmentShaderCode =
"precision mediump float; \n" +
"varying vec2 v_texCoord; \n" +
"uniform sampler2D s_texture; \n" +
"void main() \n" +
"{ \n" +
" gl_FragColor = texture2D(s_texture, v_texCoord); \n" +
"} \n";
and the result
Picture:
http://i.imgur.com/eWI2Uom.png
Thanks
Assuming you're using the depth buffer, you don't seem to be clearing it in your onDrawFrame function. Try:
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);
I'm not sure about Android-specific code as I program on iOS, but it's my understanding from reading "OpenGL ES 2.0 Programming Guide" (by Munshi et al.) that very little differs. Here's what my code looks like from a recent small project:
After setting up your framebuffer and color-renderbuffer, as you've already done, set up the depth buffer.
GLuint depthRenderbuffer;
GLint backingWidth, backingHeight;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
It's a good idea to include the part about setting the depthbuffer dimensions based off the color-renderbuffer, using glGetRenderbufferParameteriv(), because it ensures that no matter what, they're going to match.
One side note, on iOS it's recommended to setup the color-renderbuffer storage directly from the underlying iOS drawing layer, however in setting up the depth-renderbuffer it requires the call to glRenderbufferStorage() instead, as I've shown above.
You'll also want to include the following lines of code to your draw routine:
glClearDepthf(1.0);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
If you don't make the call to glEnable(GL_DEPTH_TEST), it seems to glitch at first and then work just fine, at least on my implementation in iOS. The glClearDepthf(1.0) clears it all the way to the far-plane, as opposed to a value of 0.0 which clears it to the front-plane.
It looks like you may have some Android-specific code, but hopefully this gets you off to the right start. Cheers!

Categories

Resources