Android OpenGL ES 2.0: not getting the results I want with Matrix.traslateM

I am trying to create an application that will display text using OpenGL. I get unexpected behavior when I try to use Matrix.translateM to move the specified object to a specific position. All other transformation matrices work as I would expect from them.

This is what I get when I call Matrix.translateM(model_matrix, 0, -1.0f, 0, 0) : result image

This image is without translation: enter image description here

This is my render code.

 @Override public void onSurfaceCreated(GL10 unused, EGLConfig config) { GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); GLES20.glDisable(GLES20.GL_DEPTH_TEST); GLES20.glEnable(GLES20.GL_BLEND); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); // create programs simple_texture = new SimpleTexture(); // create shapes square = new Square(); // create debug text handlers text_fps = new Text(this.font, this.text_scale); text_fps.setSize(50); text_fps.setText("Test\nLonger line"); // set camera position final float eyeX = 0.0f; final float eyeY = 0.0f; final float eyeZ = -3.0f; final float lookX = 0.0f; final float lookY = 0.0f; final float lookZ = 0.0f; final float upX = 0.0f; final float upY = 1.0f; final float upZ = 0.0f; Matrix.setLookAtM(view_matrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ); } @Override public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); // set projection matrix float ratio = (float) width / height; Matrix.orthoM(projection_matrix, 0, -ratio, ratio, -1, 1, 3, 7); setScreenRatio(ratio); setScreenHeight(height); } @Override public void onDrawFrame(GL10 unused) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // calculate projection and view transformation Matrix.multiplyMM(vp_matrix, 0, projection_matrix, 0, view_matrix, 0); // if we are connected to debugger draw statistics drawStatistics(vp_matrix); } 

And this is my draw code for text.

  // use predefined program GLES20.glUseProgram(program); // get attribute positions attr_matrix = GLES20.glGetUniformLocation(program, "u_Matrix"); attr_position = GLES20.glGetAttribLocation(program, "a_Position"); attr_texture_position = GLES20.glGetAttribLocation(program, "a_TexturePosition"); attr_texture = GLES20.glGetUniformLocation(program, "u_Texture"); // set program parameters GLES20.glEnableVertexAttribArray(attr_position); GLES20.glVertexAttribPointer(attr_position, 2, GLES20.GL_FLOAT, false, 2 * 4, square_buffer); // set texture parameters GLES20.glEnableVertexAttribArray(attr_texture_position); GLES20.glVertexAttribPointer(attr_texture_position, 2, GLES20.GL_FLOAT, false, 2 * 4, texture_buffer); // set matrix float[] result = new float[16]; float ratio = (float) texture_height / texture_width; float screen_scale = (float) texture_height / PageRenderer.getScreenHeight(); Matrix.setIdentityM(model_matrix, 0); Matrix.translateM(model_matrix, 0, -1, 0, 0); Matrix.scaleM(model_matrix, 0, screen_scale, screen_scale * ratio, screen_scale); Matrix.setIdentityM(result, 0); Matrix.multiplyMM(result, 0, matrix, 0, model_matrix, 0); GLES20.glUniformMatrix4fv(attr_matrix, 1, false, result, 0); // assign texture GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, index); GLES20.glUniform1i(attr_texture, 0); // perform drawing GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); // disable vertex array GLES20.glDisableVertexAttribArray(attr_position); GLES20.glDisableVertexAttribArray(attr_texture_position); 

Shaders:

  int vertex_shader = PageRenderer.loadShader( GLES20.GL_VERTEX_SHADER, "uniform mat4 u_Matrix;" + "attribute vec4 a_Position;" + "attribute vec2 a_TexturePosition;" + "varying vec2 v_TexturePosition;" + "void main() {" + " gl_Position = a_Position * u_Matrix;" + " v_TexturePosition = a_TexturePosition;" + "}" ); int fragment_shader = PageRenderer.loadShader( GLES20.GL_FRAGMENT_SHADER, "precision mediump float;" + "varying vec2 v_TexturePosition;" + "uniform sampler2D u_Texture;" + "void main() {" + " gl_FragColor = texture2D(u_Texture, v_TexturePosition);" + "}" ); 

Scaling and rotation of the work, as expected, but I can not understand why the translation is wrong. Please note that until recently, I did not use OpenGL.

I expected for translateM move the text to the left rather than β€œrotate” it.

+6
source share
1 answer

The order of the variables is important when calculating gl_Position ! First, the world matrix is ​​executed, and then the coordinates of the vertices. When I asked a question, I knew about it, but did not pay attention, since the shader code was taken from the Android OpenGL tutorial. Be the guys. The tutorial is wrong!

The correct shader code is:

  int vertex_shader = PageRenderer.loadShader( GLES20.GL_VERTEX_SHADER, "uniform mat4 u_Matrix;" + "attribute vec4 a_Position;" + "attribute vec2 a_TexturePosition;" + "varying vec2 v_TexturePosition;" + "void main() {" + " gl_Position = u_Matrix * a_Position;" + " v_TexturePosition = a_TexturePosition;" + "}" ); int fragment_shader = PageRenderer.loadShader( GLES20.GL_FRAGMENT_SHADER, "precision mediump float;" + "varying vec2 v_TexturePosition;" + "uniform sampler2D u_Texture;" + "void main() {" + " gl_FragColor = texture2D(u_Texture, v_TexturePosition);" + "}" ); 
+11
source

Source: https://habr.com/ru/post/926865/


All Articles