Android-based OpenGL-draw triangles on GLSurfaceView and use projection and camera views

Source: Internet
Author: User

Define triangle

OpenGL allows us to use 3D coordinates to define objects. Before creating a triangle, we need to define the coordinates of each vertex. We generally use arrays to store the coordinates of each vertex.

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

 

Draw triangles

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


Tutorial steps:

1. Add a new Triangle class

The Code is as follows:

[Java] <span style = "font-size: 16px;"> 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 cache of the triangle
ByteBuffer vbb = ByteBuffer. allocateDirect (
// (# Of coordinate values * 4 bytes per float)
TriangleCoords. length * 4 );
Vbb. order (ByteOrder. nativeOrder (); // use the byte sequence of the device hardware.
TriangleVB = vbb. asFloatBuffer (); // create a floating point cache from ByteBuffer
TriangleVB. put (triangleCoords); // Add vertex coordinates to the floating point Cache
TriangleVB. position (0); // read the first coordinate in the cache.
}

Public void draw (GL10 gl)
{
Gl. glColor4f (0.64251875f, 0.76953125f, 0.22265625f, 0.0f); // you can specify the current color.
Gl. glVertexPointer (3, GL10.GL _ FLOAT, 0, triangleVB); // set the vertex
Gl. glDrawArrays (GL10.GL _ TRIANGLES, 0, 3); // draw a triangle
}

Private FloatBuffer triangleVB;
}
</Span>
<Span style = "font-size: 16px;"> 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 cache of the triangle
ByteBuffer vbb = ByteBuffer. allocateDirect (
// (# Of coordinate values * 4 bytes per float)
TriangleCoords. length * 4 );
Vbb. order (ByteOrder. nativeOrder (); // use the byte sequence of the device hardware.
TriangleVB = vbb. asFloatBuffer (); // create a floating point cache from ByteBuffer
TriangleVB. put (triangleCoords); // Add vertex coordinates to the floating point Cache
TriangleVB. position (0); // read the first coordinate in the cache.
}
 
Public void draw (GL10 gl)
{
Gl. glColor4f (0.64251875f, 0.76953125f, 0.22265625f, 0.0f); // you can specify the current color.
Gl. glVertexPointer (3, GL10.GL _ FLOAT, 0, triangleVB); // set the vertex
Gl. glDrawArrays (GL10.GL _ TRIANGLES, 0, 3); // draw a triangle
}
 
Private FloatBuffer triangleVB;
}
</Span>

 


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

The Code is as follows:

 

[Java] <span style = "font-size: 16px;"> public myGLRenderer ()
{
MTriangle = new Triangle ();
}
</Span>
<Span style = "font-size: 16px;"> public myGLRenderer ()
{
MTriangle = new Triangle ();
}
</Span>

 


3. Add the glableclientstate () method to enable the vertex array at the end of the onSurfaceCreated () function of the myGLRenderer class.

The Code is as follows:

 

[Java] <span style = "font-size: 16px;"> @ Override
Public void onSurfaceCreated (GL10 gl, EGLConfig config ){
// TODO Auto-generated method stub
Gl. glClearColor (0.5f, 0.5f, 0.5f, 1.0f );
Gl. glableclientstate (GL10.GL _ VERTEX_ARRAY );
}
</Span>
<Span style = "font-size: 16px;"> @ Override
Public void onSurfaceCreated (GL10 gl, EGLConfig config ){
// TODO Auto-generated method stub
Gl. glClearColor (0.5f, 0.5f, 0.5f, 1.0f );
Gl. glableclientstate (GL10.GL _ VERTEX_ARRAY );
}
</Span>

 


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

The Code is as follows:

 

[Java] <span style = "font-size: 16px;"> @ 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 );
}
</Span>
<Span style = "font-size: 16px;"> @ 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 );
}
</Span>

 


In this way, we have drawn a plane triangle. However, we found that this triangle is not an equilateral triangle as we defined it. This is because OpenGL always assumes that our screen is a square, in this way, the final image will be stretched according to the ratio of the screen length to width. To get the correct display, We need to project the image to the correct position. This function is implemented in the next section.

 

 

The screen of Android devices is usually not square, while OpenGL always projects the square coordinate system to this device by default, which causes the image to fail to be displayed in a real proportion. To solve this problem, we can use OpenGL's projection mode and camera view to convert the coordinates of the image to adapt to different display devices.

 

Tutorial steps:

1. Modify the onSurfaceCreated () function of the myGLRenderer class to enable the GL10.GL _ PROJECTION mode, calculate the aspect ratio of the screen, and use this ratio to convert the coordinates of the object.

The Code is as follows:

[Python] @ 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); // you can specify the current matrix as the PROJECTION matrix.
Gl. glLoadIdentity (); // resets the Matrix to the initial value.
Gl. glFrustumf (-ratio, ratio,-1, 1, 3, 7); // sets the projection matrix based on the aspect ratio.
}
@ 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); // you can specify the current matrix as the PROJECTION matrix.
Gl. glLoadIdentity (); // resets the Matrix to the initial value.
Gl. glFrustumf (-ratio, ratio,-1, 1, 3, 7); // sets the projection matrix based on the aspect ratio.
}

 


2. Modify the onDrawFrame () method of myGLRenderer, enable the MODELVIEW mode, and set the Viewpoint Using GLU. gluLookAt.

The Code is as follows:

[Java] @ 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 the Model View Mode
Gl. glMatrixMode (GL10.GL _ MODELVIEW );
Gl. glLoadIdentity (); // reset the matrix to its default state

// Set the viewpoint
GLU. gluLookAt (gl, 0, 0,-5, 0f, 0f, 0f, 0f, 1.0f, 0.0f );

MTriangle. draw (gl );
}
@ 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 the Model View Mode
Gl. glMatrixMode (GL10.GL _ MODELVIEW );
Gl. glLoadIdentity (); // reset the matrix to its default state

// Set the viewpoint
GLU. gluLookAt (gl, 0, 0,-5, 0f, 0f, 0f, 0f, 1.0f, 0.0f );

MTriangle. draw (gl );
}


In this way, the ratio of the image we draw is always correct, and the image will not be stretched or deformed due to the influence of the device.

 

From Peking University-Google Android lab
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.