Extending the Colored 3D Cube --> Pyramid.

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

Extending the Colored 3D Cube --> Pyramid.

Postby plusminus » Thu Nov 15, 2007 6:05 pm

Colored 3D Pyramid

What is this: This tutorial shows how to create colored 3D Objects using the OpenGL® ES cross-platform API.

What you learn: You will learn how easy it is, to create a Colored 3D Pyramid, using OpenGL® ES.

Read before: Colored 3D Cube

:?: Problems/Questions: Write it right below...

Difficulty: 1.5 of 5 :)

What it will look like:
Image

Introduction:
Lets quote wikipedia first:
OpenGL ES (OpenGL for Embedded Systems) is a subset of the OpenGL 3D graphics API designed for embedded devices such as mobile phones, PDAs, and video game consoles. It is defined and promoted by the Khronos Group, a graphics hardware and software industry consortium interested in open APIs for graphics and multimedia.


Description:

What we will do is, create a custom view and using OpenGL ES in it to draw a colored pyramid.
The Main steps are:
    1. Setup the view and create a 3DObject (A rectangle based Pyramid with four sides)
    (1.1. Start/Stop the animation if we are (not) viewing it)
    2. Do some trigonometry (rotation)
    3. Make the Pyramid paint itself

Most interesting:
The main difference compared to the Colored 3D Cube is that we created an abstract ThreeDObject.
Cube and the new Class Pyramid extend this Object. So we can easily replace the Cube with a Pyramid!
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. abstract class ThreeDObject{
  2.         public abstract void draw(GL10 gl);
  3. }
  4.  
  5. ...
  6. private ThreeDObject mThreeDObj;
  7. ...
  8.  
  9. ...
  10. mThreeDObj = new Pyramid();
  11. ...
  12.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


As in the Colored 3D Cube before, we have to set up some vertices of the pyramid.
As we are creating a rectangle based one, we will need 4+1 vertices.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         int one = 0x10000;
  2.         /* Every vertex got 3 values, for
  3.          * x / y / z position in the kartesian space.
  4.          */
  5.         int vertices[] = { -one, -one, -one, // The four floor vertices of the pyramid
  6.                 one, -one, -one,
  7.                 one, one, -one,
  8.                 -one, one, -one,
  9.                 0, 0, one, };  // The top of the pyramid
Parsed in 0.032 seconds, using GeSHi 1.0.8.4


Remember the Cube :?: :arrow: The first four vertices hav not changed! Just Compare...
Image Image

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         /* Every vertex has got its own color, described by 4 values
  2.          * R(ed)
  3.          * G(green)
  4.          * B(blue)
  5.          * A(lpha) <-- Opticacy
  6.          */
  7.         int colors[] = { 0, 0, one, one,
  8.                 one, 0, 0, one,
  9.                 one, one, 0, one,
  10.                 one, 0, one, one, };
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


In this code-block the color of all the 8 vertices are described, as '4' each: R(ed) G(reen) B(lue) A(lpha). (Alpha means Opticacy)
OpenGL SE will create the color-flows automatically!

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         /* The last thing is that we need to describe some Triangles.
  2.                  * A triangle got 3 vertices.
  3.                  * The confusing thing is, that it is important in which order
  4.                  * the vertices of each triangle are described.
  5.                  * So describing a triangle through the vertices: "0, 3, 4"
  6.                  * will not result in the same triangle as: "0, 4, 3"
  7.                  * You probably ask: Why the hell isn't that the same ???
  8.                  * The reason for that is the call of: "gl.glFrontFace(gl.GL_CW);"
  9.                  * which means, that we have to describe the "visible" side of the
  10.                  * triangles by naming its vertices in a ClockWise order!
  11.                  * From the other side, the triangle will be 100% lookthru!
  12.                  * You can create a kind of magic mirror with that <img src="http://www.anddev.org/images/smilies/wink.png" alt=";)" title="Wink" />.
  13.          */
  14.          byte indices[] = { 0, 4, 1, // The four side-triangles
  15.                   1, 4, 2,
  16.                   2, 4, 3,
  17.                   3, 4, 0,
  18.                   1, 2, 0, // The two bottom-triangles
  19.                   0, 2, 3};
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


This is the tricky part. I think that I described it good enough in them comment.
Take a look at this "clockwise"-visualization-example with the cube we did before:
Image

The Code
Based on the following Source:
code.google.com

Modified by: Nicolas 'plusminus' Gramlich
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package org.anddev.android.threedcolorobjects;
  2.  
  3. import java.nio.ByteBuffer;
  4. import java.nio.ByteOrder;
  5. import java.nio.IntBuffer;
  6.  
  7. import javax.microedition.khronos.opengles.GL10;
  8.  
  9. import android.app.Activity;
  10. import android.content.Context;
  11. import android.graphics.Canvas;
  12. import android.graphics.OpenGLContext;
  13. import android.os.Bundle;
  14. import android.os.Handler;
  15. import android.os.Message;
  16. import android.os.SystemClock;
  17. import android.view.View;
  18.  
  19. /**
  20.  * Example of how to use OpenGL|ES in a custom view
  21.  *
  22.  */
  23.  
  24. public class ThreeDColorObjects extends Activity {
  25.  
  26.         @Override
  27.         protected void onCreate(Bundle icicle) {
  28.                 super.onCreate(icicle);
  29.                 setContentView(new GLView(getApplication()));
  30.         }
  31.  
  32.         @Override
  33.         protected void onResume() {
  34.                 super.onResume();
  35.                 //android.os.Debug.startMethodTracing("/tmp/trace/GLView1.dmtrace",
  36.                 //  8 * 1024 * 1024);
  37.         }
  38.  
  39.         @Override
  40.         protected void onStop() {
  41.                 super.onStop();
  42.                 //android.os.Debug.stopMethodTracing();
  43.         }
  44. }
  45.  
  46. class GLView extends View {
  47.        
  48.         private OpenGLContext mGLContext;
  49.         private ThreeDObject mThreeDObj;
  50.         private float mAngle;
  51.         private long mNextTime;
  52.         private boolean mAnimate;
  53.  
  54.         /**
  55.          * The View constructor is a good place to allocate our OpenGL context
  56.          */
  57.         public GLView(Context context) {
  58.                 super(context);
  59.  
  60.                 /*
  61.                  * Create an OpenGL|ES context. This must be done only once, an
  62.                  * OpenGL contex is a somewhat heavy object.
  63.                  */
  64.                 mGLContext = new OpenGLContext(0);
  65.                 mThreeDObj = new Pyramid();
  66.                 mAnimate = false;
  67.         }
  68.  
  69.         /*
  70.          * Start the animation only once we're attached to a window
  71.          * @see android.view.View#onAttachedToWindow()
  72.          */
  73.         @Override
  74.         protected void onAttachedToWindow() {
  75.                 mAnimate = true;
  76.                 Message msg = mHandler.obtainMessage(INVALIDATE);
  77.                 mNextTime = SystemClock.uptimeMillis();
  78.                 mHandler.sendMessageAtTime(msg, mNextTime);
  79.                 super.onAttachedToWindow();
  80.         }
  81.  
  82.         /*
  83.          * Make sure to stop the animation when we're no longer on screen,
  84.          * failing to do so will cause most of the view hierarchy to be
  85.          * leaked until the current process dies.
  86.          * @see android.view.View#onDetachedFromWindow()
  87.          */
  88.         @Override
  89.         protected void onDetachedFromWindow() {
  90.                 mAnimate = false;
  91.                 super.onDetachedFromWindow();
  92.         }
  93.  
  94.         /**
  95.          * Draw the view content
  96.          *
  97.          * @see android.view.View#onDraw(android.graphics.Canvas)
  98.          */
  99.         @Override
  100.         protected void onDraw(Canvas canvas) {
  101.                 if (true) {
  102.                         /*
  103.                          * First, we need to get to the appropriate GL interface.
  104.                          * This is simply done by casting the GL context to either
  105.                          * GL10 or GL11.
  106.                          */
  107.                         GL10 gl = (GL10) (mGLContext.getGL());
  108.  
  109.                         /*
  110.                          * Before we can issue GL commands, we need to make sure all
  111.                          * native drawing commands are completed. Simply call
  112.                          * waitNative() to accomplish this. Once this is done, no native
  113.                          * calls should be issued.
  114.                          */
  115.                         mGLContext.waitNative(canvas, this);
  116.  
  117.                         int w = getWidth();
  118.                         int h = getHeight();
  119.  
  120.                         /*
  121.                          * Set the viewport. This doesn't have to be done each time
  122.                          * draw() is called. Typically this is called when the view
  123.                          * is resized.
  124.                          */
  125.  
  126.                         gl.glViewport(0, 0, w, h);
  127.  
  128.                         /*
  129.                          * Set our projection matrix. This doesn't have to be done
  130.                          * each time we draw, but usualy a new projection needs to be set
  131.                          * when the viewport is resized.
  132.                          */
  133.  
  134.                         float ratio = (float) w / h;
  135.                         gl.glMatrixMode(gl.GL_PROJECTION);
  136.                         gl.glLoadIdentity();
  137.                         gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
  138.  
  139.                         /*
  140.                          * dithering is enabled by default in OpenGL, unfortunattely
  141.                          * it has a significant impact on performace in software
  142.                          * implementation. Often, it's better to just turn it off.
  143.                          */
  144.                         gl.glDisable(gl.GL_DITHER);
  145.  
  146.                         /*
  147.                          * Usually, the first thing one might want to do is to clear
  148.                          * the screen. The most efficient way of doing this is to use
  149.                          * glClear(). However we must make sure to set the scissor
  150.                          * correctly first. The scissor is always specified in window
  151.                          * coordinates:
  152.                          */
  153.  
  154.                         gl.glClearColor(1, 1, 1, 1);
  155.                         gl.glEnable(gl.GL_SCISSOR_TEST);
  156.                         gl.glScissor(0, 0, w, h);
  157.                         gl.glClear(gl.GL_COLOR_BUFFER_BIT);
  158.  
  159.                         /*
  160.                          * Now we're ready to draw some 3D object
  161.                          */
  162.  
  163.                         gl.glMatrixMode(gl.GL_MODELVIEW);
  164.                         gl.glLoadIdentity();
  165.                         gl.glTranslatef(0, 0, -3.0f);
  166.                         gl.glScalef(0.5f, 0.5f, 0.5f);
  167.                         gl.glRotatef(mAngle, 0, 1, 0);
  168.                         gl.glRotatef(mAngle * 0.25f, 1, 0, 0);
  169.  
  170.                         gl.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
  171.                         gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
  172.                         gl.glEnableClientState(gl.GL_COLOR_ARRAY);
  173.                         gl.glEnable(gl.GL_CULL_FACE);
  174.  
  175.                         mThreeDObj.draw(gl);
  176.  
  177.                         mAngle += 1.2f;
  178.  
  179.                         /*
  180.                          * Once we're done with GL, we need to flush all GL commands and
  181.                          * make sure they complete before we can issue more native
  182.                          * drawing commands. This is done by calling waitGL().
  183.                          */
  184.                         mGLContext.waitGL();
  185.                 }
  186.         }
  187.  
  188.         // ------------------------------------------------------------------------
  189.  
  190.         private static final int INVALIDATE = 1;
  191.  
  192.         private final Handler mHandler = new Handler() {
  193.  
  194.                 @Override
  195.                 public void handleMessage(Message msg) {
  196.                         if (mAnimate && msg.what == INVALIDATE) {
  197.                                 invalidate();
  198.                                 msg = obtainMessage(INVALIDATE);
  199.                                 long current = SystemClock.uptimeMillis();
  200.                                 if (mNextTime < current) {
  201.                                         mNextTime = current + 20;
  202.                                 }
  203.                                 sendMessageAtTime(msg, mNextTime);
  204.                                 mNextTime += 20;
  205.                         }
  206.                 }
  207.         };
  208. }
  209.  
  210. abstract class ThreeDObject{
  211.         public abstract void draw(GL10 gl);
  212. }
  213.  
  214. class Cube extends ThreeDObject{
  215.        
  216.         private IntBuffer mVertexBuffer;
  217.         private IntBuffer mColorBuffer;
  218.         private ByteBuffer mIndexBuffer;
  219.  
  220.         public Cube() {
  221.                                
  222.                 int one = 0x10000;
  223.                 /* Every vertex got 3 values, for
  224.                 * x / y / z position in the kartesian space.
  225.                 */
  226.                 int vertices[] = { -one, -one, -one,
  227.                         one, -one, -one,
  228.                         one, one, -one,
  229.                         -one, one, -one,
  230.                         -one, -one, one,
  231.                         one, -one, one,
  232.                         one, one, one,
  233.                         -one, one, one, };
  234.  
  235.                 /* Every vertex has got its own color, described by 4 values
  236.                 * R(ed)
  237.                 * G(green)
  238.                 * B(blue)
  239.                 * A(lpha) <-- Opticacy
  240.                 */
  241.                 int colors[] = { 0, 0, 0, one,
  242.                         one, 0, 0, one,
  243.                         one, one, 0, one,
  244.                         0, one, 0, one,
  245.                         0, 0, one, one,
  246.                         one, 0, one, one,
  247.                         one, one, one, one,
  248.                         0, one, one, one, };
  249.  
  250.                  /* The last thing is that we need to describe some Triangles.
  251.                  * A triangle got 3 vertices.
  252.                  * The confusing thing is, that it is important in which order
  253.                  * the vertices of each triangle are described.
  254.                  * So describing a triangle through the vertices: "0, 3, 4"
  255.                  * will not result in the same triangle as: "0, 4, 3"
  256.                  * You probably ask: Why the hell isn't that the same ???
  257.                  * The reason for that is the call of: "gl.glFrontFace(gl.GL_CW);"
  258.                  * which means, that we have to describe the "visible" side of the
  259.                  * triangles by naming its vertices in a ClockWise order!
  260.                  * From the other side, the triangle will be 100% lookthru!
  261.                  * You can create a kind of magic mirror with that <img src="http://www.anddev.org/images/smilies/wink.png" alt=";)" title="Wink" />.
  262.                  */
  263.                 byte indices[] = { 0, 4, 5,
  264.                         0, 5, 1,
  265.                         1, 5, 6,
  266.                         1, 6, 2,
  267.                         2, 6, 7,
  268.                         2, 7, 3,
  269.                         3, 7, 4,
  270.                         3, 4, 0,
  271.                         4, 7, 6,
  272.                         4, 6, 5,
  273.                         3, 0, 1,
  274.                         3, 1, 2 };
  275.  
  276.                 // Buffers to be passed to gl*Pointer() functions
  277.                 // must be direct, i.e., they must be placed on the
  278.                 // native heap where the garbage collector cannot
  279.                 // move them.
  280.                 //
  281.                 // Buffers with multi-byte datatypes (e.g., short, int, float)
  282.                 // must have their byte order set to native order
  283.  
  284.                 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);  // * 4 becuase of int
  285.                 vbb.order(ByteOrder.nativeOrder());
  286.                 mVertexBuffer = vbb.asIntBuffer();
  287.                 mVertexBuffer.put(vertices);
  288.                 mVertexBuffer.position(0);
  289.  
  290.                 ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); // * 4 becuase of int
  291.                 cbb.order(ByteOrder.nativeOrder());
  292.                 mColorBuffer = cbb.asIntBuffer();
  293.                 mColorBuffer.put(colors);
  294.                 mColorBuffer.position(0);
  295.  
  296.                 mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
  297.                 mIndexBuffer.put(indices);
  298.                 mIndexBuffer.position(0);
  299.         }
  300.  
  301.         public void draw(GL10 gl) {
  302.                 gl.glFrontFace(gl.GL_CW);
  303.                 gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
  304.                 gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
  305.                 gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE,     mIndexBuffer);
  306.         }
  307.  
  308. }
  309.  
  310. class Pyramid  extends ThreeDObject{
  311.        
  312.         private IntBuffer mVertexBuffer;
  313.         private IntBuffer mColorBuffer;
  314.         private ByteBuffer mIndexBuffer;
  315.  
  316.         public Pyramid() {
  317.                                
  318.                 int one = 0x10000;
  319.                 /* Every vertex got 3 values, for
  320.                 * x / y / z position in the kartesian space.
  321.                 */
  322.                 int vertices[] = { -one, -one, -one, // The four floor vertices of the pyramid
  323.                         one, -one, -one,
  324.                         one, one, -one,
  325.                         -one, one, -one,
  326.                         0, 0, one, };  // The top of the pyramid
  327.  
  328.                 /* Every vertex has got its own color, described by 4 values
  329.                 * R(ed)
  330.                 * G(green)
  331.                 * B(blue)
  332.                 * A(lpha) <-- Opticacy
  333.                 */
  334.                 int colors[] = { 0, 0, one, one,
  335.                         one, 0, 0, one,
  336.                         one, one, 0, one,
  337.                         0, one, 0, one,
  338.                         one, 0, one, one, };
  339.  
  340.                  /* The last thing is that we need to describe some Triangles.
  341.                  * A triangle got 3 vertices.
  342.                  * The confusing thing is, that it is important in which order
  343.                  * the vertices of each triangle are described.
  344.                  * So describing a triangle through the vertices: "0, 3, 4"
  345.                  * will not result in the same triangle as: "0, 4, 3"
  346.                  * You probably ask: Why the hell isn't that the same ???
  347.                  * The reason for that is the call of: "gl.glFrontFace(gl.GL_CW);"
  348.                  * which means, that we have to describe the "visible" side of the
  349.                  * triangles by naming its vertices in a ClockWise order!
  350.                  * From the other side, the triangle will be 100% lookthru!
  351.                  * You can create a kind of magic mirror with that <img src="http://www.anddev.org/images/smilies/wink.png" alt=";)" title="Wink" />.
  352.                  */
  353.                 byte indices[] = { 0, 4, 1, // The four side-triangles
  354.                         1, 4, 2,
  355.                         2, 4, 3,
  356.                         3, 4, 0,
  357.                         1, 2, 0, // The two bottom-triangles
  358.                         0, 2, 3};
  359.  
  360.                 // Buffers to be passed to gl*Pointer() functions
  361.                 // must be direct, i.e., they must be placed on the
  362.                 // native heap where the garbage collector cannot
  363.                 // move them.
  364.                 //
  365.                 // Buffers with multi-byte datatypes (e.g., short, int, float)
  366.                 // must have their byte order set to native order
  367.  
  368.                 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);  // * 4 becuase of int
  369.                 vbb.order(ByteOrder.nativeOrder());
  370.                 mVertexBuffer = vbb.asIntBuffer();
  371.                 mVertexBuffer.put(vertices);
  372.                 mVertexBuffer.position(0);
  373.  
  374.                 ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); // * 4 becuase of int
  375.                 cbb.order(ByteOrder.nativeOrder());
  376.                 mColorBuffer = cbb.asIntBuffer();
  377.                 mColorBuffer.put(colors);
  378.                 mColorBuffer.position(0);
  379.  
  380.                 mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
  381.                 mIndexBuffer.put(indices);
  382.                 mIndexBuffer.position(0);
  383.         }
  384.  
  385.         public void draw(GL10 gl) {
  386.                 gl.glFrontFace(gl.GL_CW);
  387.                 gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
  388.                 gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
  389.                 gl.glDrawElements(gl.GL_TRIANGLES, 18, gl.GL_UNSIGNED_BYTE,     mIndexBuffer);
  390.         }
  391.  
  392. }
Parsed in 0.067 seconds, using GeSHi 1.0.8.4


I hope you succeeded and understood this tutorial.

Please vote and/or leave a comment :) .

See you soon :wink:
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top

Postby silver » Thu Jan 10, 2008 7:28 pm

The one thing that I do not understand is - why is 'one' set to 0x10000 (65536 decimal)???

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. int one = 0x10000;
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


While the Frustum is set to numbers that make more sense:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


Isn't there some sort of an apparent problem here? =/
silver
Freshman
Freshman
 
Posts: 2
Joined: Thu Jan 10, 2008 7:11 pm

Postby plusminus » Thu Jan 10, 2008 8:15 pm

Hello silver,

Note: I'm no OpenGL-expert at all!
probably because we need to be able to show very small structures, if we would with 0x01 as "normal size" how to display small objects properly.

Regards,
plusminus
Last edited by plusminus on Thu Jan 10, 2008 9:04 pm, edited 1 time in total.
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby silver » Thu Jan 10, 2008 8:23 pm

plusminus, OpenGL works with relative numbers, so your explanation is not correct.

That is exactly what I do not understand: 65536 doesn't quite seem to relate to gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
silver
Freshman
Freshman
 
Posts: 2
Joined: Thu Jan 10, 2008 7:11 pm

Postby galahadxu » Fri Jan 11, 2008 4:40 am

Hi Silver,
This is just a guess. Correct me if I am wrong.
It seems that Android is not supporting floating points calculation in OpenGL|ES due to lack of support in some hardware for floating calculation. Thus, the unit 1 is defined relatively large so that they can still achieve certain precision when calculating thing like angles.

I read the class files in android.graphics.glutils where something like a scene-graph kit should be sitting. In Object3D class, you will find that the mVertexBuffer is defined as an IntBuffer instead of an DoubleBuffer or FloatBuffer. When I try to change the sample codes about the 3D cube to use DoubleBuffer, I also cannot get the correct result displayed in the emulator even though there was no compilation error.

Regards,
Xu
galahadxu
Freshman
Freshman
 
Posts: 5
Joined: Mon Dec 24, 2007 3:27 am

Postby venkat » Fri Jan 11, 2008 11:47 am

Hi plus minus, can you give me any good tutorial site for Open GL:)
Regards,
Venkat.
venkat
Senior Developer
Senior Developer
 
Posts: 152
Joined: Tue Nov 27, 2007 5:42 am
Location: India

Top

Postby plusminus » Fri Jan 11, 2008 2:38 pm

Hey venkat,

have a look at :src: this thread.

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby venkat » Fri Jan 11, 2008 5:30 pm

Thank you plusminus :D
Regards,
Venkat.
venkat
Senior Developer
Senior Developer
 
Posts: 152
Joined: Tue Nov 27, 2007 5:42 am
Location: India

Postby galahadxu » Mon Jan 14, 2008 5:04 am

Hi Silver and the rest,

I double checked the OpenGL|ES spec and found out the following:

OpenGL|ES is using fixed-point computation and using the notation 16.16 to indicate a 32-bit two's complement fixed-point number with 16 bits of fraction. This explains why in the sample code "one" is represented as "0x10000".

Thanks and Regards,
Xu
galahadxu
Freshman
Freshman
 
Posts: 5
Joined: Mon Dec 24, 2007 3:27 am

Postby plusminus » Mon Jan 14, 2008 8:00 am

galahadxu wrote:Hi Silver and the rest,

I double checked the OpenGL|ES spec and found out the following:

OpenGL|ES is using fixed-point computation and using the notation 16.16 to indicate a 32-bit two's complement fixed-point number with 16 bits of fraction. This explains why in the sample code "one" is represented as "0x10000".

Thanks and Regards,
Xu


Yeeha, so I was right :D

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby galahadxu » Tue Jan 15, 2008 2:58 am

It's all depend on what data format you are using.

OpenGL|ES has both common and common-lite profile where common profile also allows float-point computation. I have tried in Android to use both fixed-point and float-point computation. When we use fixed-point computation for vertex, it is 16.16 notation and "1" is represented by "0x10000". When we use float-point computation for vertex, "1" is then represented by "1.f".

The attachment is the screen shot of an imported AL in Android. (I don't know how to insert an image, so I just put it as an attachment :( ) I wrote my own parser to read in the file and all vertices are represented in float. It looks ugly as I didn't put in correct normal and color yet. But it gives some idea of how an object model can be loaded in Android.

Again, Android is lacking of the scene-graph implementation and it will be very hard to import a complex scene easily. I am now think of implement a simple scene-graph package which can handle basic things including texture, lighting and node traversal. Is there anyone experienced in this scene-graph implementation?

Thanks and Regards,
Xu
Attachments
gorilla.jpg
gorilla.jpg (22.54 KiB) Viewed 14710 times
galahadxu
Freshman
Freshman
 
Posts: 5
Joined: Mon Dec 24, 2007 3:27 am

Postby Girgante » Mon Apr 07, 2008 2:20 pm

Hi, I am getting an error on the line:

mGLContext.waitNative(canvas, this);

Saying; The methond waitNative() in the type OpenGL Context is not applicable for the arguments (Canvas, GLView).

Can you please tell me how to solve this?

Thanks.
Girgante
Freshman
Freshman
 
Posts: 3
Joined: Mon Apr 07, 2008 2:15 pm

Postby kasas » Mon Jun 16, 2008 6:02 pm

Hi guys,

Ihave migrated to m5 this version. I'm actually a novice, but I have to learn quick how to use this API, so I think this board is the best for learning.

ThreeDColorObjectActivity.java
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package org.anddev.android.threedcolorobjects;
  3.  
  4.  
  5.  
  6. import android.app.Activity;
  7.  
  8. import android.graphics.PixelFormat;
  9.  
  10. import android.os.Bundle;
  11.  
  12.  
  13.  
  14. public class ThreeDColorObjectsActivity extends Activity {
  15.  
  16.  
  17.  
  18.     @Override
  19.  
  20.     protected void onCreate(Bundle icicle) {
  21.  
  22.          super.onCreate(icicle);
  23.  
  24.          getWindow().setFormat(PixelFormat.TRANSLUCENT);
  25.  
  26.          
  27.  
  28.          GLView mView =new GLView(getApplication());
  29.  
  30.          setContentView(mView);
  31.  
  32.     }
  33.  
  34.  
  35.  
  36.     @Override
  37.  
  38.     protected void onResume() {
  39.  
  40.          super.onResume();
  41.  
  42.          //android.os.Debug.startMethodTracing("/tmp/trace/GLView1.dmtrace",
  43.  
  44.          //  8 * 1024 * 1024);
  45.  
  46.     }
  47.  
  48.  
  49.  
  50.     @Override
  51.  
  52.     protected void onStop() {
  53.  
  54.          super.onStop();
  55.  
  56.          //android.os.Debug.stopMethodTracing();
  57.  
  58.     }
  59.  
  60. }
  61.  
  62.  
Parsed in 0.039 seconds, using GeSHi 1.0.8.4


and GLView.java:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package org.anddev.android.threedcolorobjects;
  3.  
  4.  
  5.  
  6. import java.nio.ByteBuffer;
  7.  
  8. import java.nio.ByteOrder;
  9.  
  10. import java.nio.IntBuffer;
  11.  
  12.  
  13.  
  14. import javax.microedition.khronos.opengles.GL10;
  15.  
  16.  
  17.  
  18. import android.app.Activity;
  19.  
  20. import android.content.Context;
  21.  
  22. import android.graphics.Canvas;
  23.  
  24. import android.graphics.OpenGLContext;
  25.  
  26. import android.graphics.PixelFormat;
  27.  
  28. import android.os.Bundle;
  29.  
  30. import android.os.Handler;
  31.  
  32. import android.os.Message;
  33.  
  34. import android.os.SystemClock;
  35.  
  36. import android.util.AttributeSet;
  37.  
  38. import android.view.SurfaceHolder;
  39.  
  40. import android.view.SurfaceView;
  41.  
  42. import android.view.View;
  43.  
  44. import java.util.Map;
  45.  
  46.  
  47.  
  48. /**
  49.  
  50.  * Example of how to use OpenGL|ES in a custom view
  51.  
  52.  *
  53.  
  54.  */
  55.  
  56.  
  57.  
  58. public class GLView extends SurfaceView implements SurfaceHolder.Callback{
  59.  
  60.      
  61.  
  62.          SurfaceHolder mHolder;
  63.  
  64.          private GLThread mGLThread;
  65.  
  66.      private ThreeDObject mThreeDObj;
  67.  
  68.      private float mAngle;
  69.  
  70.      private long mNextTime;
  71.  
  72.      private boolean mAnimate, mHasSurface;
  73.  
  74.  
  75.  
  76.      /**
  77.  
  78.       * The View constructor is a good place to allocate our OpenGL context
  79.  
  80.       */
  81.  
  82.      public GLView(Context context) {
  83.  
  84.           super(context);
  85.  
  86.  
  87.  
  88.           /*
  89.  
  90.            * Create an OpenGL|ES context. This must be done only once, an
  91.  
  92.            * OpenGL contex is a somewhat heavy object.
  93.  
  94.            */
  95.  
  96.           init();
  97.  
  98.      }
  99.  
  100.  
  101.  
  102.      public GLView(Context context, AttributeSet attrs, Map inflateParams) {
  103.  
  104.          super(context, attrs, inflateParams);
  105.  
  106.          init();
  107.  
  108.      }
  109.  
  110.  
  111.  
  112.      private void init() {
  113.  
  114.          // Install a SurfaceHolder.Callback so we get notified when the
  115.  
  116.          // underlying surface is created and destroyed
  117.  
  118.          mHolder = getHolder();
  119.  
  120.          mHolder.addCallback(this);
  121.  
  122.      }
  123.  
  124.  
  125.  
  126.      public void surfaceCreated(SurfaceHolder holder) {
  127.  
  128.          // The Surface has been created, start our drawing thread.
  129.  
  130.          mGLThread = new GLThread();
  131.  
  132.          mGLThread.start();
  133.  
  134.      }
  135.  
  136.  
  137.  
  138.      public void surfaceDestroyed(SurfaceHolder holder) {
  139.  
  140.          // Surface will be destroyed when we return
  141.  
  142.          mGLThread.requestExitAndWait();
  143.  
  144.          mGLThread = null;
  145.  
  146.      }
  147.  
  148.  
  149.  
  150.      public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
  151.  
  152.          // Surface size or format has changed. This should not happen in this
  153.  
  154.          // example.
  155.  
  156.          mGLThread.onWindowResize(w, h);
  157.  
  158.      }
  159.  
  160.      
  161.  
  162.         class GLThread extends Thread {
  163.  
  164.             private boolean mDone;
  165.  
  166.             private int mWidth;
  167.  
  168.             private int mHeight;
  169.  
  170.        
  171.  
  172.             GLThread() {
  173.  
  174.                 super();
  175.  
  176.                 mDone = false;
  177.  
  178.                 mWidth = 0;
  179.  
  180.                 mHeight = 0;
  181.  
  182.                 mThreeDObj = new Pyramid();
  183.  
  184.             }
  185.  
  186.        
  187.  
  188.             @Override
  189.  
  190.             public void run() {
  191.  
  192.                /*
  193.  
  194.                 * First, we need to get to the appropriate GL interface.
  195.  
  196.                 * This is simply done by casting the GL context to either
  197.  
  198.                 * GL10 or GL11.
  199.  
  200.                 */
  201.  
  202.                
  203.  
  204.                 OpenGLContext mGLContext = new OpenGLContext( OpenGLContext.DEPTH_BUFFER);
  205.  
  206.                
  207.  
  208.                 SurfaceHolder holder = mHolder;
  209.  
  210.             mGLContext.makeCurrent(holder);
  211.  
  212.  
  213.  
  214.             GL10 gl = (GL10) (mGLContext.getGL());
  215.  
  216.            
  217.  
  218.             gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
  219.  
  220.            
  221.  
  222.             while (!mDone)
  223.  
  224.             {
  225.  
  226.                int w,h;
  227.  
  228.                synchronized(this){
  229.  
  230.                        w= getWidth();
  231.  
  232.                        h = getHeight();
  233.  
  234.                }
  235.  
  236.                /*
  237.  
  238.                 * Set the viewport. This doesn't have to be done each time
  239.  
  240.                 * draw() is called. Typically this is called when the view
  241.  
  242.                 * is resized.
  243.  
  244.                 */
  245.  
  246.  
  247.  
  248.                gl.glViewport(0, 0, w, h);
  249.  
  250.  
  251.  
  252.                /*
  253.  
  254.                 * Set our projection matrix. This doesn't have to be done
  255.  
  256.                 * each time we draw, but usualy a new projection needs to be set
  257.  
  258.                 * when the viewport is resized.
  259.  
  260.                 */
  261.  
  262.  
  263.  
  264.                float ratio = (float) w / h;
  265.  
  266.                gl.glMatrixMode(gl.GL_PROJECTION);
  267.  
  268.                gl.glLoadIdentity();
  269.  
  270.                gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
  271.  
  272.  
  273.  
  274.                /*
  275.  
  276.                 * dithering is enabled by default in OpenGL, unfortunattely
  277.  
  278.                 * it has a significant impact on performace in software
  279.  
  280.                 * implementation. Often, it's better to just turn it off.
  281.  
  282.                 */
  283.  
  284.                gl.glDisable(gl.GL_DITHER);
  285.  
  286.  
  287.  
  288.                /*
  289.  
  290.                 * Usually, the first thing one might want to do is to clear
  291.  
  292.                 * the screen. The most efficient way of doing this is to use
  293.  
  294.                 * glClear(). However we must make sure to set the scissor
  295.  
  296.                 * correctly first. The scissor is always specified in window
  297.  
  298.                 * coordinates:
  299.  
  300.                 */
  301.  
  302.  
  303.  
  304.                gl.glClearColor(1, 1, 1, 1);
  305.  
  306.                gl.glEnable(gl.GL_SCISSOR_TEST);
  307.  
  308.                gl.glScissor(0, 0, w, h);
  309.  
  310.                gl.glClear(gl.GL_COLOR_BUFFER_BIT);
  311.  
  312.  
  313.  
  314.                /*
  315.  
  316.                 * Now we're ready to draw some 3D object
  317.  
  318.                 */
  319.  
  320.  
  321.  
  322.                gl.glMatrixMode(gl.GL_MODELVIEW);
  323.  
  324.                gl.glLoadIdentity();
  325.  
  326.                gl.glTranslatef(0, 0, -3.0f);
  327.  
  328.                gl.glScalef(0.5f, 0.5f, 0.5f);
  329.  
  330.                gl.glRotatef(mAngle, 0, 1, 0);
  331.  
  332.                gl.glRotatef(mAngle * 0.25f, 1, 0, 0);
  333.  
  334.  
  335.  
  336.                gl.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
  337.  
  338.                gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
  339.  
  340.                gl.glEnableClientState(gl.GL_COLOR_ARRAY);
  341.  
  342.                gl.glEnable(gl.GL_CULL_FACE);
  343.  
  344.  
  345.  
  346.                mThreeDObj.draw(gl);
  347.  
  348.  
  349.  
  350.                mAngle += 1.2f;
  351.  
  352.  
  353.  
  354.                /*
  355.  
  356.                 * Once we're done with GL, we need to flush all GL commands and
  357.  
  358.                 * make sure they complete before we can issue more native
  359.  
  360.                 * drawing commands. This is done by calling waitGL().
  361.  
  362.                 */
  363.  
  364.                //mGLContext.waitGL();
  365.  
  366.                mGLContext.post();
  367.  
  368.                
  369.  
  370.           }
  371.  
  372.      }
  373.  
  374.          public void onWindowResize(int w, int h) {
  375.  
  376.             synchronized(this) {
  377.  
  378.                 mWidth = w;
  379.  
  380.                 mHeight = h;
  381.  
  382.             }
  383.  
  384.      }
  385.  
  386.  
  387.  
  388.      public void requestExitAndWait() {
  389.  
  390.             // don't call this from GLThread thread or it a guaranteed
  391.  
  392.             // deadlock!
  393.  
  394.             mDone = true;
  395.  
  396.             try {
  397.  
  398.                 join();
  399.  
  400.             } catch (InterruptedException ex) { }
  401.  
  402.         }
  403.  
  404.     }
  405.  
  406. }
  407.  
  408.  
  409.  
  410. abstract class ThreeDObject{
  411.  
  412.      public abstract void draw(GL10 gl);
  413.  
  414. }
  415.  
  416.  
  417.  
  418. class Cube extends ThreeDObject{
  419.  
  420.      
  421.  
  422.      private IntBuffer mVertexBuffer;
  423.  
  424.      private IntBuffer mColorBuffer;
  425.  
  426.      private ByteBuffer mIndexBuffer;
  427.  
  428.  
  429.  
  430.      public Cube() {
  431.  
  432.                      
  433.  
  434.           int one = 0x10000;
  435.  
  436.           /* Every vertex got 3 values, for
  437.  
  438.           * x / y / z position in the kartesian space.
  439.  
  440.           */
  441.  
  442.           int vertices[] = {
  443.  
  444.                   -one, -one, -one,
  445.  
  446.                one, -one, -one,
  447.  
  448.                one,  one, -one,
  449.  
  450.               -one,  one, -one,
  451.  
  452.               -one, -one,  one,
  453.  
  454.                one, -one,  one,
  455.  
  456.                one,  one,  one,
  457.  
  458.               -one,  one,  one, };
  459.  
  460.  
  461.  
  462.           /* Every vertex has got its own color, described by 4 values
  463.  
  464.           * R(ed)
  465.  
  466.           * G(green)
  467.  
  468.           * B(blue)
  469.  
  470.           * A(lpha) <-- Opticacy
  471.  
  472.           */
  473.  
  474.           int colors[] = {
  475.  
  476.                           0, 0, 0, one,
  477.  
  478.                           one, 0, 0, one,
  479.  
  480.                           one, one, 0, one,
  481.  
  482.                           0, one, 0, one,
  483.  
  484.                           0, 0, one, one,
  485.  
  486.                           one, 0, one, one,
  487.  
  488.                           one, one, one, one,
  489.  
  490.                           0, one, one, one,
  491.  
  492.                         };
  493.  
  494.  
  495.  
  496.            /* The last thing is that we need to describe some Triangles.
  497.  
  498.            * A triangle got 3 vertices.
  499.  
  500.            * The confusing thing is, that it is important in which order
  501.  
  502.            * the vertices of each triangle are described.
  503.  
  504.            * So describing a triangle through the vertices: "0, 3, 4"
  505.  
  506.            * will not result in the same triangle as: "0, 4, 3"
  507.  
  508.            * You probably ask: Why the hell isn't that the same ???
  509.  
  510.            * The reason for that is the call of: "gl.glFrontFace(gl.GL_CW);"
  511.  
  512.            * which means, that we have to describe the "visible" side of the
  513.  
  514.            * triangles by naming its vertices in a ClockWise order!
  515.  
  516.            * From the other side, the triangle will be 100% lookthru!
  517.  
  518.            * You can create a kind of magic mirror with that .
  519.  
  520.            */
  521.  
  522.           byte indices[] = {
  523.  
  524.                    0, 4, 5,
  525.  
  526.                0, 5, 1,
  527.  
  528.                1, 5, 6,
  529.  
  530.                1, 6, 2,
  531.  
  532.                2, 6, 7,
  533.  
  534.                2, 7, 3,
  535.  
  536.                3, 7, 4,
  537.  
  538.                3, 4, 0,
  539.  
  540.                4, 7, 6,
  541.  
  542.                4, 6, 5,
  543.  
  544.                3, 0, 1,
  545.  
  546.                3, 1, 2 };
  547.  
  548.  
  549.  
  550.           // Buffers to be passed to gl*Pointer() functions
  551.  
  552.           // must be direct, i.e., they must be placed on the
  553.  
  554.           // native heap where the garbage collector cannot
  555.  
  556.           // move them.
  557.  
  558.           //
  559.  
  560.           // Buffers with multi-byte datatypes (e.g., short, int, float)
  561.  
  562.           // must have their byte order set to native order
  563.  
  564.  
  565.  
  566.           ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);  // * 4 becuase of int
  567.  
  568.           vbb.order(ByteOrder.nativeOrder());
  569.  
  570.           mVertexBuffer = vbb.asIntBuffer();
  571.  
  572.           mVertexBuffer.put(vertices);
  573.  
  574.           mVertexBuffer.position(0);
  575.  
  576.  
  577.  
  578.           ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); // * 4 becuase of int
  579.  
  580.           cbb.order(ByteOrder.nativeOrder());
  581.  
  582.           mColorBuffer = cbb.asIntBuffer();
  583.  
  584.           mColorBuffer.put(colors);
  585.  
  586.           mColorBuffer.position(0);
  587.  
  588.  
  589.  
  590.           mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
  591.  
  592.           mIndexBuffer.put(indices);
  593.  
  594.           mIndexBuffer.position(0);
  595.  
  596.      }
  597.  
  598.  
  599.  
  600.      public void draw(GL10 gl) {
  601.  
  602.           gl.glFrontFace(gl.GL_CW);
  603.  
  604.           gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
  605.  
  606.           gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
  607.  
  608.           gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
  609.  
  610.      }
  611.  
  612.  
  613.  
  614. }
  615.  
  616.  
  617.  
  618. class Pyramid  extends ThreeDObject{
  619.  
  620.      
  621.  
  622.      private IntBuffer mVertexBuffer;
  623.  
  624.      private IntBuffer mColorBuffer;
  625.  
  626.      private ByteBuffer mIndexBuffer;
  627.  
  628.  
  629.  
  630.      public Pyramid() {
  631.  
  632.                      
  633.  
  634.           int one = 0x10000;
  635.  
  636.           /* Every vertex got 3 values, for
  637.  
  638.           * x / y / z position in the kartesian space.
  639.  
  640.           */
  641.  
  642.           int vertices[] = { -one, -one, -one, // The four floor vertices of the pyramid
  643.  
  644.                one, -one, -one,
  645.  
  646.                one, one, -one,
  647.  
  648.                -one, one, -one,
  649.  
  650.                0, 0, one, };  // The top of the pyramid
  651.  
  652.  
  653.  
  654.           /* Every vertex has got its own color, described by 4 values
  655.  
  656.           * R(ed)
  657.  
  658.           * G(green)
  659.  
  660.           * B(blue)
  661.  
  662.           * A(lpha) <-- Opticacy
  663.  
  664.           */
  665.  
  666.           int colors[] = { 0, 0, one, one,
  667.  
  668.                one, 0, 0, one,
  669.  
  670.                one, one, 0, one,
  671.  
  672.                0, one, 0, one,
  673.  
  674.                one, 0, one, one, };
  675.  
  676.  
  677.  
  678.            /* The last thing is that we need to describe some Triangles.
  679.  
  680.            * A triangle got 3 vertices.
  681.  
  682.            * The confusing thing is, that it is important in which order
  683.  
  684.            * the vertices of each triangle are described.
  685.  
  686.            * So describing a triangle through the vertices: "0, 3, 4"
  687.  
  688.            * will not result in the same triangle as: "0, 4, 3"
  689.  
  690.            * You probably ask: Why the hell isn't that the same ???
  691.  
  692.            * The reason for that is the call of: "gl.glFrontFace(gl.GL_CW);"
  693.  
  694.            * which means, that we have to describe the "visible" side of the
  695.  
  696.            * triangles by naming its vertices in a ClockWise order!
  697.  
  698.            * From the other side, the triangle will be 100% lookthru!
  699.  
  700.            * You can create a kind of magic mirror with that .
  701.  
  702.            */
  703.  
  704.           byte indices[] = { 0, 4, 1, // The four side-triangles
  705.  
  706.                1, 4, 2,
  707.  
  708.                2, 4, 3,
  709.  
  710.                3, 4, 0,
  711.  
  712.                1, 2, 0, // The two bottom-triangles
  713.  
  714.                0, 2, 3};
  715.  
  716.  
  717.  
  718.           // Buffers to be passed to gl*Pointer() functions
  719.  
  720.           // must be direct, i.e., they must be placed on the
  721.  
  722.           // native heap where the garbage collector cannot
  723.  
  724.           // move them.
  725.  
  726.           //
  727.  
  728.           // Buffers with multi-byte datatypes (e.g., short, int, float)
  729.  
  730.           // must have their byte order set to native order
  731.  
  732.  
  733.  
  734.           ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);  // * 4 becuase of int
  735.  
  736.           vbb.order(ByteOrder.nativeOrder());
  737.  
  738.           mVertexBuffer = vbb.asIntBuffer();
  739.  
  740.           mVertexBuffer.put(vertices);
  741.  
  742.           mVertexBuffer.position(0);
  743.  
  744.  
  745.  
  746.           ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); // * 4 becuase of int
  747.  
  748.           cbb.order(ByteOrder.nativeOrder());
  749.  
  750.           mColorBuffer = cbb.asIntBuffer();
  751.  
  752.           mColorBuffer.put(colors);
  753.  
  754.           mColorBuffer.position(0);
  755.  
  756.  
  757.  
  758.           mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
  759.  
  760.           mIndexBuffer.put(indices);
  761.  
  762.           mIndexBuffer.position(0);
  763.  
  764.      }
  765.  
  766.  
  767.  
  768.      public void draw(GL10 gl) {
  769.  
  770.           gl.glFrontFace(gl.GL_CW);
  771.  
  772.           gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
  773.  
  774.           gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
  775.  
  776.           gl.glDrawElements(gl.GL_TRIANGLES, 18, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
  777.  
  778.      }
  779.  
  780.  
  781.  
  782. }
  783.  
  784.  
Parsed in 0.079 seconds, using GeSHi 1.0.8.4


I hope this help a little bit people who is using the new sdk :)

Cheers!
Attachments
ThreeDColorObjects.tar.gz
code
(32.42 KiB) Downloaded 312 times
kasas
Freshman
Freshman
 
Posts: 5
Joined: Thu May 22, 2008 6:39 pm
Location: Barcelona

Postby lostInTransit » Tue May 12, 2009 1:05 pm

I don't know if there's something wrong with my installation of m5. But whenever I run any of my sample OpenGL code with the new SDK, I get an error that the class android.graphics.OpenGLContext cannot be found!

Can someone please help :(
lostInTransit
Developer
Developer
 
Posts: 26
Joined: Thu Feb 12, 2009 10:37 am
Location: India

Postby 3m3r1c » Wed Jan 20, 2010 9:36 pm

Hello,

This tutorial works very well for me but I want one colors by cube's faces.

how I can do that ?
3m3r1c
Freshman
Freshman
 
Posts: 9
Joined: Fri Sep 18, 2009 1:39 pm

Top
Next

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest