ArtsAutosBooksBusinessEducationEntertainmentFamilyFashionFoodGamesGenderHealthHolidaysHomeHubPagesPersonal FinancePetsPoliticsReligionSportsTechnologyTravel

Android OpenGL ES Tutorial, Part 1: Rendering a colored triangle to the screen

Updated on July 18, 2012
OpenGL ES (OpenGL for Embedded Systems)
OpenGL ES (OpenGL for Embedded Systems)

What is OpenGL ES?

If you are familiar with OpenGL, then the ES variety is simply a stripped down version of OpenGL 1.3 with a few developer friendly features added. If you have never used OpenGL before, then just think of OpenGL ES as your triangle rendering ally in your quest to develop awesome games and applications.

By reading this tutorial, I am assuming that:

  1. You are familiar with Java (syntax, object-orientated paradigm, etc.). If you have no programming experience and would like to learn, there are plenty of resources freely available on the internet as well as books that you purchase in analog and digital formats.
  2. You are somewhat familiar with Android. If you are not, that is fine too; this tutorial is very thorough.
  3. You have an IDE (preferably Eclipse) installed and configured for Android development. If you do not, read my guide here.
  4. OpenGL ES 1.0 is supported by Android devices 1.6 and above, so I am assuming you have an Android device with a firmware 1.6 or higher. Emulators render with OpenGL very slowly, so I recommend testing OpenGL ES based app and games only on actual devices.
  5. You have an interest in developing graphically demanding applications. Most platforms provide an effective means of drawing and displaying GUI elements, so if that is all you plan on developing, you are better off sticking those native drawing and layout methods (unless you really want to get your feet wet with some graphics programming).

If you are interested in downloading the source code for this project, refer to the next section; otherwise, continue on to "Getting Started".

Click "Finish" and voila!
Click "Finish" and voila!

Source Code

The source code for this tutorial can be downloaded here. You will receive a zip file. Extract the contents of this zip file to your workspace. In Eclipse:

  1. File > Import > General > Existing Projects into Workspace
  2. Select root directory: browse for the "opengl-es-tutorial" folder and click it.
  3. Your screen should look like the one on the right -->

Click thumbnail to view full-size

Getting Started

Okay, let's create an OpenGL ES Android app! Assuming you have Eclipse installed and configured properly for Android development:

  1. File > New > Android Project
  2. Follow the screenshots provided on the right -->
  3. Name your project "openglestutorial"
  4. Set "Android 1.6" as your Build Target
  5. Set the Application Name as "Opengl-es-tutorial"
  6. Set the package name to your website starting with the domain name and followed by the project name. For example, I used: "com.technegames.openglestutorial"
  7. Make sure "Create Activity:" is checked; name it "TriangleActivity"
  8. The Minimum SDK should be set to 4, since OpenGL ES is not supported below that.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="4" />

    <application android:icon="@drawable/ic_launcher"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
        <activity android:name="com.technegames.openglestutorial.TriangleActivity"
            android:label="@string/app_name" >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />


About the AndroidManifest

Most of this will be set up for you by Eclipse by default.

I added one important line:


Adding this line will cause any activities in your application to launch in fullscreen mode.

package com.technegames.openglestutorial;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;

public class TriangleActivity extends Activity implements android.opengl.GLSurfaceView.Renderer
	private static final String TAG = TriangleActivity.class.getSimpleName();
	private static final int Coordinates_In_A_Vertex = 2;
	private static final int Vertices_In_A_Triangle = 3;
	private static final int Bits_In_A_Byte = 8;
	private static final int Bits_In_A_Float = Float.SIZE;
	private static final int Bytes_In_A_Float = Bits_In_A_Float / Bits_In_A_Byte;
	private GLSurfaceView glSurfaceView;
	private FloatBuffer vertices;
	private int width;
	private int height;
	public void onCreate(Bundle savedInstanceState)
		glSurfaceView = new GLSurfaceView(this);
	public void onResume()
	public void onPause()
	public void onDrawFrame(GL10 gl)
		gl.glColor4f(0.64313725490196f, 0.77647058823529f, 0.22352941176471f, 1);
		gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

	public void onSurfaceChanged(GL10 gl, int width, int height)
		Log.d(TAG, "Surface changed! width = " + String.valueOf(width) + ", height = " + String.valueOf(height));

	public void onSurfaceCreated(GL10 gl, EGLConfig config)
		Log.d(TAG, "Surface Created!");
		width = glSurfaceView.getWidth();
		height = glSurfaceView.getHeight();
		gl.glViewport(0, 0, width, height);
		gl.glOrthof(0, 1, 0, 1, 1, -1);
		gl.glClearColor(1, 1, 1, 1);
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(Coordinates_In_A_Vertex * Vertices_In_A_Triangle * Bytes_In_A_Float);
		vertices = byteBuffer.asFloatBuffer();
		vertices.put(new float[]
					0.0f, 0.0f,
					0.5f, 1.0f,
					1.0f, 0.0f

TriangleActivity members

We have 10 class-level fields in total.

  • TAG is used when writing logs
  • Coordinates_In_A_Vertex stores the number of coordinates for a vertex. On a 2D plane, there are only x and y coordinates, so this number is 2.
  • Vertices_In_A_Triangle should be pretty self explanatory.
  • There are 8 bits in a byte, and there are 32 bits in a Float data type (we know this because Float.SIZE returns 32).
  • OpenGL ES requires that we allocate memory in terms of bytes, so we store 4 in the Bytes_In_A_Float variable (More on this below).
  • glSurfaceView is responsible for displaying all of the OpenGL rendering
  • vertices is a FloatBuffer that stores all of the coordinates of our triangle
  • we use width and height to store the dimensions of our GLSurfaceView

TriangleActivity onCreate, onResume, and onPause

You may have noticed that our TriangleActivity implements android.opengl.GLSurfaceView.Renderer. When creating a GLSurfaceView, we can use the activity class itself to supply the renderer via the setRenderer() function.

In onCreate(), we simply instatiate our glSurfaceView, set its renderer, and finally set the content view to the glSurfaceView.

In onResume and onPause, we call the respective glSurfaceView methods. Note that we only resume our glSurfaceView after we call the super implementation of onResume. The opposite is true for onPause. The reason behind this is because our glSurfaceView cannot be alive and rendering unless the activity is in the foreground.

onSurfaceCreated, onSurfaceChanged, and onDrawFrame

In this section, I will explain each line of OpenGL ES code. If this your first time learning OpenGL ES, read and reread this section until everything makes sense.

  • In onSurfaceChanged, we simply log the dimensions of the glSurfaceView whenever it changes.
  • In onSurfaceCreated, we perform the bulk of the initialization work. After setting width and height, we have to initialize our rendering system:
  • glViewport() sets the portion of the screen that we render to.
  • glMatrixMode(GL_PROJECTION) tells OpenGL ES that we are drawing in a 2-dimensional environment.
  • glLoadIdentity() resets the matrix to its original state.
  • glOrthof() defines our own coordinate system. I set the values so that our triangle would be drawn onto a coordinate system that is 1 unit wide and 1 unit tall.
  • glClearColor(r, g, b, a) specifies what color the screen will be cleared with when
    glClear is called.
  • As for the triangle, we must use a ByteBuffer to supply all of the float coordinates. Each of our coordinate pairs are stored as Floats, since this is what OpenGL ES expects.
  • There are 2 Floats in a vertex, 3 vertices in a triangle, and 4 bytes in a Float. This means we have to allocate 24 bytes to our ByteBuffer.
  • After we allocate our bytes, we transform this ByteBuffer to a FloatBuffer and store it in our vertices variable. After this, we place all of our coordinates in our vertices.
  • Once our coordinates are loaded, we call flip() so that our vertices can be read from the beginning by OpenGL ES.
  • Finally, we enable the client state to GL_VERTEX_ARRAY so that OpenGL ES knows we are going to be drawing vertices.
  • onDrawFrame is where your triangle is actually drawn to the screen! Before drawing our triangle, we clear our screen with the color white via the glClear method. We call the glColor4f method so that our triangle will be drawn with the "Android green" color.
  • The glVertexPointer method is used to describe our vertices to OpenGL ES. Our Vertices have 2 coordinates stored as Floats.
  • In the glDrawArrays method, we tell OpenGL ES that we are drawing a triangle (GL10.GL_TRIANGLES), and we are drawing 3 vertices (1 triangle).

All Done!

Congratulations! If you have done everything correctly, your device screen should look like the one on the right -->

I plan on writing more tutorials, so comment below and let me know how I did and what I should write about in my future articles.


    0 of 8192 characters used
    Post Comment
    • profile image


      6 years ago

      Excellent Tutorial....please help me in Understanding MAP Activities also.

    • profile image


      6 years ago

      It was really awesome to draw a triangle. Could you just tell me how to draw a custom shape over it? It can be any object

    • Alucard_1990 profile imageAUTHOR

      Stephen Gowen 

      6 years ago from Nashville, TN

      @Long Bunly,

      I have been so tied up working on a game for Android/iOS, but I will definitely resume this OpenGL ES tutorial series asap!

    • Long Bunly profile image

      Long Bunly 

      6 years ago

      wow, I must learn OpenGL from you, hope I can make my dream come true. I will try my best to follow you Alucard :)

    • Alucard_1990 profile imageAUTHOR

      Stephen Gowen 

      6 years ago from Nashville, TN


      The java.nio.* package is automatically included with the android.jar. If your project cannot resolve it, try doing a project clean

    • profile image


      6 years ago

      hi, java.nio cannot be resolved? how can I add automatically the library

    • Alucard_1990 profile imageAUTHOR

      Stephen Gowen 

      7 years ago from Nashville, TN


      Will do!


    • profile image


      7 years ago


      I was searching for a good Tutorial for days, and now i have found it.


      Make more! (Rotating, CameraView,...)

    • Alucard_1990 profile imageAUTHOR

      Stephen Gowen 

      7 years ago from Nashville, TN


      Yes, this example starts with only one triangle. However, with just one line of code we can make this triangle rotate on the screen or grow and shrink in size. In future tutorials, I will demonstrate binding a texture to groups of triangles to render sprites and animations.

      Learning OpenGL ES takes time but pays dividends much in the style of an exponential growth curve.

      Keep in mind that hardware accelerated graphics is usually unnecessary for most application development and is almost exclusively used in the gaming development world.

      Thanks for reading!

    • dianetrotter profile image

      G. Diane Nelson Trotter 

      7 years ago from Fontana

      Why would I want to do this? Is it a programming lesson? I'm serious. That's a lot of work to end up with a triangle.


    This website uses cookies

    As a user in the EEA, your approval is needed on a few things. To provide a better website experience, uses cookies (and other similar technologies) and may collect, process, and share personal data. Please choose which areas of our service you consent to our doing so.

    For more information on managing or withdrawing consents and how we handle data, visit our Privacy Policy at:

    Show Details
    HubPages Device IDThis is used to identify particular browsers or devices when the access the service, and is used for security reasons.
    LoginThis is necessary to sign in to the HubPages Service.
    Google RecaptchaThis is used to prevent bots and spam. (Privacy Policy)
    AkismetThis is used to detect comment spam. (Privacy Policy)
    HubPages Google AnalyticsThis is used to provide data on traffic to our website, all personally identifyable data is anonymized. (Privacy Policy)
    HubPages Traffic PixelThis is used to collect data on traffic to articles and other pages on our site. Unless you are signed in to a HubPages account, all personally identifiable information is anonymized.
    Amazon Web ServicesThis is a cloud services platform that we used to host our service. (Privacy Policy)
    CloudflareThis is a cloud CDN service that we use to efficiently deliver files required for our service to operate such as javascript, cascading style sheets, images, and videos. (Privacy Policy)
    Google Hosted LibrariesJavascript software libraries such as jQuery are loaded at endpoints on the or domains, for performance and efficiency reasons. (Privacy Policy)
    Google Custom SearchThis is feature allows you to search the site. (Privacy Policy)
    Google MapsSome articles have Google Maps embedded in them. (Privacy Policy)
    Google ChartsThis is used to display charts and graphs on articles and the author center. (Privacy Policy)
    Google AdSense Host APIThis service allows you to sign up for or associate a Google AdSense account with HubPages, so that you can earn money from ads on your articles. No data is shared unless you engage with this feature. (Privacy Policy)
    Google YouTubeSome articles have YouTube videos embedded in them. (Privacy Policy)
    VimeoSome articles have Vimeo videos embedded in them. (Privacy Policy)
    PaypalThis is used for a registered author who enrolls in the HubPages Earnings program and requests to be paid via PayPal. No data is shared with Paypal unless you engage with this feature. (Privacy Policy)
    Facebook LoginYou can use this to streamline signing up for, or signing in to your Hubpages account. No data is shared with Facebook unless you engage with this feature. (Privacy Policy)
    MavenThis supports the Maven widget and search functionality. (Privacy Policy)
    Google AdSenseThis is an ad network. (Privacy Policy)
    Google DoubleClickGoogle provides ad serving technology and runs an ad network. (Privacy Policy)
    Index ExchangeThis is an ad network. (Privacy Policy)
    SovrnThis is an ad network. (Privacy Policy)
    Facebook AdsThis is an ad network. (Privacy Policy)
    Amazon Unified Ad MarketplaceThis is an ad network. (Privacy Policy)
    AppNexusThis is an ad network. (Privacy Policy)
    OpenxThis is an ad network. (Privacy Policy)
    Rubicon ProjectThis is an ad network. (Privacy Policy)
    TripleLiftThis is an ad network. (Privacy Policy)
    Say MediaWe partner with Say Media to deliver ad campaigns on our sites. (Privacy Policy)
    Remarketing PixelsWe may use remarketing pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to advertise the HubPages Service to people that have visited our sites.
    Conversion Tracking PixelsWe may use conversion tracking pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to identify when an advertisement has successfully resulted in the desired action, such as signing up for the HubPages Service or publishing an article on the HubPages Service.
    Author Google AnalyticsThis is used to provide traffic data and reports to the authors of articles on the HubPages Service. (Privacy Policy)
    ComscoreComScore is a media measurement and analytics company providing marketing data and analytics to enterprises, media and advertising agencies, and publishers. Non-consent will result in ComScore only processing obfuscated personal data. (Privacy Policy)
    Amazon Tracking PixelSome articles display amazon products as part of the Amazon Affiliate program, this pixel provides traffic statistics for those products (Privacy Policy)
    ClickscoThis is a data management platform studying reader behavior (Privacy Policy)