Tag Archives: OpenGL

Cylinder in OpenGL ES 2.0

For my current project, CPU Information I wanted to create a 3D representation for a Battery to indicate the remaining charge of it to the user in a visually appealing way.

Initially I used a 3D battery model but after playing around with it some time, I decided to build the Battery model in code instead. All that was required for it was to find a algo I could easily adjust for my program.

After searching for a few hours ( yes hours ) I came to realize that there was no good example for OpenGL ES 2.0 and I had to write my own.

It seems that there are plenty of examples for OpenGL 1.x or examples in many other different shapes and forms but none that I could find which simply creates a GL_TRAINGLE_STRIP – buffer and passing it to OpenGL ES 2.x.

Algolite

The algorithm will create a cylinder in one buffer by first creating the top circle, then the cylinder and finally the bottom circle. The OpenGL Drawing mode is GL_TRIANGLE_STRIP.

You only have to provide radius, height, and number of segments to create the cylinder. Once the floating point buffer with the vertices is created we have to convert it to OpenGL digestible FloatBuffer and the pass the information to OpenGL for rendering … Done.

Decomplexify

The passing of the data to OpenGL is cookie-cutter OpenGL code which you can find easily. I do not want to complexify this sample here by cookie cutting.


    // Creating a cylinder object to be rendered in OpenGL
    Object3DData createCylinder ( float radius, float height, int segments, float yOffset, float clr[] ) {
        float buffer[]  = createCylinderBuffer ( radius, height, segments );
        FloatBuffer vertices = makeFloatBuffer ( buffer, buffer.length );

        Object3DData     obj = new Object3DData( vertices );
        obj.setDrawMode ( GLES20.GL_TRIANGLE_STRIP );
        obj.setColor    ( clr[0], clr[1], clr[2], clr[3] );
        obj.setPosition ( 0.0f, yOffset, 0.0f );
        return obj;
    }

    // GL_TRIANGLE_STRIP -=> Standing cylinder
    float[] createCylinderBuffer ( float radius, float height, int segments )  {
        int iBuffSize = segments * 3 * 3 + (int)( ((float)segments/3.0f+1.0f )) * 3 * 2 + 6;
        float buffer[] = new float[ iBuffSize ];
        int t, idx = 0;
        float increment = (float)( 360.0f / (float)( segments - 1 ) );

        //create the top
        int iZeroCounter = 2;
        float hh = height / 2.0f;
        for ( t=0; t<segments; t++ )  {
            float angle = (float)( Math.PI/180.0f * t * increment );
            float cos = (float) ( radius * Math.cos ( angle ) );
            float sin = (float) ( radius * Math.sin ( angle ) );

            if ( iZeroCounter++ >= 2 )  {
                buffer[idx++] = 0.0f;
                buffer[idx++] = +hh;
                buffer[idx++] = 0.0f;
                iZeroCounter  = 0;
            }
            buffer[idx++] = cos;
            buffer[idx++] = +hh;
            buffer[idx++] = sin;
        }

        // create the cylinder
        for ( t=0; t<segments+2; t++ )  {
            float angle = (float)( Math.PI/180.0f * t * increment );
            float cos = (float) ( radius * Math.cos ( angle ) );
            float sin = (float)-( radius * Math.sin ( angle ) );

            buffer[idx++] = cos;
            buffer[idx++] = hh;
            buffer[idx++] = sin;
            hh *= -1.0f;
        }

        hh = height / 2.0f;
        for ( t=0; t<segments; t++ )  {
            float angle = (float)( Math.PI/180.0f * t * increment );
            float cos = (float)-( radius * Math.cos ( angle ) );
            float sin = (float) ( radius * Math.sin ( angle ) );

            if ( iZeroCounter++ >= 2 )  {
                buffer[idx++] = 0.0f;
                buffer[idx++] = -hh;
                buffer[idx++] = 0.0f;
                iZeroCounter = 0;
            }
            buffer[idx++] = cos;
            buffer[idx++] = -hh;
            buffer[idx++] = sin;
        }
        return buffer;
    }

    public static FloatBuffer makeFloatBuffer ( float[] arr, int iSize )  {
        if ( iSize == 0 )
             iSize = arr.length;
        ByteBuffer bb = ByteBuffer.allocateDirect ( iSize * 4 ); // Size of Float is 4 bytes
        bb.order ( ByteOrder.nativeOrder( ) );
        FloatBuffer fb = bb.asFloatBuffer ( );
        fb.put ( arr );
        fb.position ( 0 );
        return fb;
    }

Promising results

Here is the result in all its glory after stacking a few cylinders on top of each other, coloring them and give the battery a heart beat. Yeah, I think you can’t enough Special effect this one.

Please feel free to install CPU Information onto your Android device and try it out in action.
Get it on Google Play

Shader Editor app

Android and iOS smart phones support the OpenGL ES 3D library.

The latest version for OpenGL Stand currently at 3.2 which was released in August 2015. Most phones on the market however support OpenGL 3.0 since Android 4.3 or iOS 7.

Those is versions we released in or around 2013 such by now was five years ago.

The OpenGL API had changed a lot between 1.x and 2.0 in that it introduced vertex and fragment shader languages as part of the spec. Prior to this, the OpenGL library stopped a set of will defined API calls to handle most aspects of the OpenGL Städte engine.

OpenGL shaders

As stated above, the shader language became past of the OpenGL Standard with version 2.0 and onwards. What it provides is more flexibility in programming the GPU tender pipelines. Instead of trying on a fixed, hardcore pipeline you can go ahead and code your own shader program.

This flexibility comes at the expense of some additional complexity alas this can greatly be migrated through the usage of or defined coffee snippets or libraries which sit Stop OpenGL.

The shader language is leaning heavily on c-style and is functional in nature. As the code is compiled, linked and will then be loaded into the GPU and run with a limited set of instructions, this language is limited in certain aspects and I would really recommend to find online courses or read a book if you want to truly understand the inner working of OpenGL.

 

OpenGL ES

The ES Stand for embedded systems, and is an indication that it has some limitations to the desktop version. Alright although those limitations are really not as big as one would think.

What is more is that WebGL is basically identical to OpenGL ES and many of the shaders you will find running in the browse will also run in your phone.

For example, the web page Http:www.shadertoy.com has a lot of very interesting looking shader samples which you can adapt easily to run on your phone.

But how ?

Shader editor

The shadertoy app can help you play around with some really cool looking shader examples. When you first download the app you will only see a limited set of available samples. Burger you can easily edit and save new shader samples on your device with this app.

The editor is using a just in time compilation of the code on a semi transparent editor window. This allows you to easily explore you shaders and view the results in real-time.

The way that this tool used the OpenGL libraries is to use a fixed vertex shader code base and have all the code executing in the fragment shader. Which is to say that the whole logic is about coloring the fragments ( parts of a pixel ) to achieve those stunning effects.

If you like to experiment and OpenGL is something you have always wanted to play around with, then Shader Editor is a small app you can not afford to miss.


Get it on Google Play

Get it on Google Play