English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Example of Drawing Triangles and Using Projection and Camera View Methods on GLSurfaceView Based on OpenGL in Android

This article instance describes how to draw triangles on GLSurfaceView based on Android OpenGL and how to use projection and camera view methods. Shared for everyone's reference, as follows:

Define triangle

OpenGL allows us to define objects using three-dimensional coordinates. Before drawing triangles, we need to define the coordinates of each point. We usually use arrays to store the coordinates of each vertex.

OpenGL ES defaults [0,0,0] (X,Y,Z) to the center of GLSurfaceView, [1,1,0]at the upper right corner, [-1,-1,0]at the lower left corner.

Draw a triangle

Before drawing the triangle, we must tell OpenGL that we are using vertex arrays. Then we use the drawing function to draw the triangle.

Experimental steps:

1Add a new class Triangle

The code is as follows:

public class Triangle {
  public Triangle()
  {
     float triangleCoords[] = {
          // X, Y, Z This is an equilateral triangle
          -0.5f, -0.25f, 0,
           0.5f, -0.25f, 0,
           0.0f, 0.559016994f, 0
        };
        // Initialize the vertex buffer for the triangle
        ByteBuffer vbb = ByteBuffer.allocateDirect(
            // (# of coordinate values * 4 bytes per float)
            triangleCoords.length * 4);
        vbb.order(ByteOrder.nativeOrder());// Use the byte order of the device hardware itself
        triangleVB = vbb.asFloatBuffer(); // Create a floating-point buffer from ByteBuffer
        triangleVB.put(triangleCoords); // Add vertex coordinates to the floating-point cache
        triangleVB.position(0); // Make the cache read the first coordinate
  }
  public void draw(GL10 gl)
  {
    gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f); //Set current color
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);//Set vertex
    gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);//Draw a triangle
  }
  private FloatBuffer triangleVB;
}

2Add member privateTriangle mTriangle in the myGLRenderer class and initialize it in the constructor.

The code is as follows:

public myGLRenderer()
{
    mTriangle = new Triangle();
}

3Add the glEnableClientState() method to enable vertex arrays at the end of the onSurfaceCreated() function in the myGLRenderer class.

The code is as follows:

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // TODO Auto-generated method stub
    gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
}

4Add the triangle drawing method at the end of the onDrawFrame() function in the myGLRenderer class.

The code is as follows:

@Override
public void onDrawFrame(GL10 gl) {
    // TODO Auto-generated method stub
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    mTriangle.draw(gl);
}

Thus, we have completed the drawing of a flat triangle. However, we find that the triangle is not an equilateral triangle as defined, which is due to OpenGL always assuming that our screen is square, so the final graphics will be stretched according to the screen aspect ratio. To achieve the correct display, we need to project the graphics to the correct position. This feature will be implemented in the next section.

The screen of an Android device is usually not square, while OpenGL always defaults to projecting a square coordinate system onto this device, which causes the graphics to be displayed in a non-realistic ratio. To solve this problem, we can use OpenGL's projection mode and camera view to transform the coordinates of the graphics to adapt to different device displays.

Experimental steps:

1Modify the onSurfaceCreated() function of the myGLRenderer class to enable GL10Set the screen aspect ratio by converting the coordinates of objects using the GL_PROJECTION mode.

The code is as follows:

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub
    gl.glViewport(0, 0, width, height);
    float ratio = (float) width / height;
    gl.glMatrixMode(GL10.GL_PROJECTION); // Set the current matrix to the projection matrix
    gl.glLoadIdentity(); // Reset the matrix to its initial value
    gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // Set the projection matrix based on the aspect ratio
}

2Modify the onDrawFrame() method of myGLRenderer to enable MODELVIEW mode and use GLU.gluLookAt() to set the view point.

The code is as follows:

@Override
public void onDrawFrame(GL10 gl) {
  // TODO Auto-generated method stub
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    // Set the current matrix to model view mode
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();  // reset the matrix to its default state
    // Set Viewpoint
    GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    mTriangle.draw(gl);
}

In this way, the proportions of the graphics we draw are always correct, no longer stretched and deformed due to the influence of the device.

Readers who are interested in more content related to Android can check the special topics on this site: 'Summary of Android Graphics and Image Processing Techniques', 'Android Development Tutorial for Beginners and Advanced', 'Summary of Android Debugging Techniques and Common Problem Solutions', 'Summary of Android Multimedia Operation Techniques (audio, video, recording, etc.)', 'Summary of Android Basic Component Usage', 'Summary of Android View View Techniques', 'Summary of Android Layout Layout Techniques', and 'Summary of Android Widget Usage'.

I hope the description in this article will be helpful to everyone in Android program design.

Declaration: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, does not edit the content manually, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#w3Please replace # with @ when sending an email for reporting. Provide relevant evidence, and once verified, this site will immediately delete the infringing content.

You May Also Like