简体   繁体   中英

Center rectangle-object in the screen by using glOrthof in Android with opengles 2, with java

I'm working on the examples of the book OpenGlEs 2 for Android. I did the first example, for drawing a rectangle of base 9, and height 14, by using the below array for defining the coordinates

private float[] tableVerticesWithTriangles = {
        //Triangle
        0f, 0f,
        9f, 14f,
        0f, 14f,
        //Triangle 2
        0f, 0f,
        9f, 0f,
        9f, 14f
};

The rectangle is appearing as in the example, the white rectangle in the top right corner:

如书中所示绘制的矩形

The code I'm working on is in the repository https://github.com/quimperval/opengles-android-rectangle

Now in the book the author centers the rectangle by modifying the coordinates of the rectangle, however as far as I know, openGl can take care of that by using a projection matrix. So, I modified the vertex shader for using a projection Matrix

attribute vec4 a_Position;

attribute mat4 u_Projection;

void main(){
    gl_Position =  u_Projection * a_Position;
}

And in the CRenderer class I added the below variables

private static final String U_PROJECTION = "u_Projection";
int projectionMatrixLocation;

and the

float[] projectionMatrix = new float[16];

And in the onSurfaceChanged method I added the logic for considering the aspectRatio

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

    // Calculate the projection matrix
    float aspectRatio = width > height ?
            (float) width / (float) height :
            (float) height / (float) width;
    if (width > height) {
        // Landscape
        glOrthof(-aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
    } else {
        // Portrait or square
        glOrthof(-1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);
    }

    projectionMatrixLocation = glGetUniformLocation(program, "u_Projection");
    glUniformMatrix4fv(projectionMatrixLocation, 1, false, projectionMatrix, 0);
}

In the onDrawFrame I didn't do changes.

When I compile and install the application in the emulator, It crashes, with the error:

2022-12-31 14:45:23.971 10499-10521/com.perval.myapplication A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 10521 (GLThread 411)

Am I missing some operation?

I expect to center the rectangle (of any dimensions) in the screen of the device.

I believe the answer is that you are:

  • Not declaring the matrix as a uniform
  • Not checking your response from glGetUniformLocation()

As you are accessing a uniform with glGetUniformLocation , you should declare it in your shader like so:

uniform mat4 u_Projection;

I manage to find another way to achive the result I need, by using the below code in the onSurfaceChangedMethod

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

        /*orthoM
         *projectionMarix - float[] m - the destination array
         * mOffset - the offset in to m which the result is written
         * float left - the minimum range of the x-axis
         * float right - the maximum range of the x-axis
         * float bottom - the minimum range of the y-axis
         * float top - the maximum range ot the y-axis
         * float near - the minimum range of the z-axis
         * float far - the maximum range of the z-axis
         *
         */

        float boundingBoxWidth = 300;
        float boundingBoxHeight = 300;

        float aspectRatio;

        if(width>height){
            //Landscape
            aspectRatio = (float) width / (float) height;
            orthoM(projectionMatrix, 0, -aspectRatio*boundingBoxHeight, aspectRatio*boundingBoxHeight, -boundingBoxHeight, boundingBoxHeight, -1f, 1f);
        } else {
            //Portrait or square
            aspectRatio = (float) height / (float) width;
            orthoM(projectionMatrix, 0, -boundingBoxWidth, boundingBoxWidth, -boundingBoxWidth*aspectRatio, boundingBoxWidth*aspectRatio, -1f, 1f);
        }
    }

In that way I got the behaviour I wanted, place an object in the center of the screen, and the object has vertex coordinates outside of the surface extents (-1,-1) to (1,1).

在此处输入图像描述

The key is to know the width and the height of the collision box of the object I want to draw, then it is just a matter of scaling the left, right or bottom/top variables based on the orientation of the screen, with the aspectRatio variable. I placed the code in the repository:

https://github.com/quimperval/opengl-es-android-draw-object

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM