Kaleem Peeroo Kaleem Peeroo - 1 month ago 14
Android Question

android opengl not rendering properly

I am having a problem when rendering a texture to the viewport.
The screen is being rendered but the texture (256*256) does not the same as the original jpg picture I uploaded.

Please find attached images and code for the render. One image is the original jpg and the other is screenshot that is the rendered texture on the android phone.

original

rendered image

This is my MainActivity code:

private void initialize() {
if (hasGLES20()) {
GLSurfaceView mGLView = new GLSurfaceView(this);
mGLView.setEGLContextClientVersion(2);
mGLView.setPreserveEGLContextOnPause(true);
mGLView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
mGLView.setEGLConfigChooser(true);
mGLView.setRenderer(this);
setContentView(mGLView);
}
}

@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
GLES20.glClearColor(0.5f,0.3f,0.8f,1.0f);


String vertexShaderSource = "" +
"uniform mat4 u_projection;" +
"uniform mat4 u_model;" +
"uniform mat4 u_view;" +
"" +
"attribute vec4 a_position;" +
"attribute vec2 a_texCoord;" +
"" +
"varying vec2 v_texCoord;" +

"" +
"void main()" +
"{" +
" gl_Position = u_projection * u_view * u_model * a_position;" +

" v_texCoord = a_texCoord;" +

"}";

String fragmentShaderSource = "" +

"varying vec2 v_texCoord;" +
"uniform sampler2D s_texture;" +
"" +
"void main() {" +
" vec4 texCol = texture2D(s_texture, v_texCoord );" +
" gl_FragColor = texCol;" +

"}";

texture = new Texture(this);


vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vertexShader, vertexShaderSource);
GLES20.glCompileShader(vertexShader);
String vertexShaderCompileLog = GLES20.glGetShaderInfoLog(vertexShader);

fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShader, fragmentShaderSource);
GLES20.glCompileShader(fragmentShader);
String fragmentShaderCompileLog = GLES20.glGetShaderInfoLog(fragmentShader);

programID = GLES20.glCreateProgram();
GLES20.glAttachShader(programID,vertexShader);
GLES20.glAttachShader(programID,fragmentShader);
GLES20.glBindAttribLocation(programID, 0, "a_position");
GLES20.glBindAttribLocation(programID, 1, "a_texCoord");
GLES20.glLinkProgram(programID);

String programLinkLog = GLES20.glGetProgramInfoLog(programID);
GLES20.glUseProgram(programID);

float[] modelMatrix = new float[16], viewMatrix = new float[16], projectionMatrix = new float[16];


ByteBuffer modelMatrixByteBuffer = ByteBuffer.allocateDirect(modelMatrix.length * 4);
modelMatrixByteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer modelMatrixBuffer = modelMatrixByteBuffer.asFloatBuffer();
Matrix.setIdentityM(modelMatrix,0);
Matrix.translateM(modelMatrix, 0, modelMatrix,0,0,0,-2.0f);
modelMatrixBuffer.put(modelMatrix);
modelMatrixBuffer.rewind();

// translate model to 0,0,-2
Matrix.setLookAtM(viewMatrix,0,0,0,0,0,0,-10,0,1,0);
Matrix.perspectiveM(projectionMatrix,0,70,256/256,0.1f,100);

GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(programID,"u_projection"),1,false,projectionMatrix,0);
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(programID,"u_view"),1,false,viewMatrix,0);
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(programID,"u_model"),1,false,modelMatrixBuffer);

}

@Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
GLES20.glViewport(0,0,256,256);
}

@Override
public void onDrawFrame(GL10 gl10){

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
float vertices[] =
{
-1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};

float textureCoord[] =
{
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};


ByteBuffer verticesByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
verticesByteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer verticesBuffer = verticesByteBuffer.asFloatBuffer();
verticesBuffer.put(vertices);
verticesBuffer.rewind();

ByteBuffer textureCoordByteBuffer = ByteBuffer.allocateDirect(textureCoord.length * 4);
textureCoordByteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer textureCoordBuffer = textureCoordByteBuffer.asFloatBuffer();
textureCoordBuffer.put(textureCoord);
textureCoordBuffer.rewind();

GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 3 * 4, verticesBuffer);
GLES20.glVertexAttribPointer(1, 2, GLES20.GL_FLOAT, false, 2 * 4, textureCoordBuffer);
GLES20.glEnableVertexAttribArray(0);
GLES20.glEnableVertexAttribArray(1);



texture.setTexture();
GLES20.glUniform1i(GLES20.glGetUniformLocation(programID,"s_texture"),0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}


This is my load Texture Class

public class Texture
{
private int m_iTextureId;

public Texture(Context ctx)
{
m_iTextureId = loadTexture(ctx, R.drawable.index);
}

public void setTexture()
{
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, m_iTextureId);
}

public int loadTexture(Context ctx, int rsrcId)
{
int[] iTextureId = new int[1];
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glGenTextures(1, iTextureId, 0);

if(iTextureId[0] != 0)
{
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, iTextureId[0]);

BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;

Bitmap bitmap = BitmapFactory.decodeResource(ctx.getResources(), rsrcId,
options);

GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();

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);
}
else
{
throw new RuntimeException("Error loading texture");
}

return iTextureId[0];
}


Any help?

BDL BDL
Answer

Your texture coordinates are wrong. They contain the same coordinate twice:

float textureCoord[] =
{
     0.0f,  1.0f, <--
     0.0f,  0.0f,
     1.0f,  1.0f,
     0.0f,  1.0f  <--
};

To solve this replace the last coordinate with [1, 0] instead of [0, 1].