Colored 3D Cube

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

Colored 3D Cube

Postby plusminus » Wed Nov 14, 2007 9:03 pm

Colored 3D Cube

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 Cube, using OpenGL® ES.

:?: Problems/Questions: post here

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 cube.
The Main steps are:
    1. Setup the view and create a cube
    (1.1. Start/Stop the animation if we are (not) viewing it)
    2. Do some trigonometry (rotation)
    3. Make the Cube paint itself

Most interesting:
What the heck do those values in the Cube-Constructor mean... :?:
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[] = {
  6.                -one, -one, -one, // Vertex Zero
  7.                 one, -one, -one, // Vertex Two
  8.                 one,  one, -one, // Vertex ...
  9.                -one,  one, -one,
  10.                -one, -one,  one,
  11.                 one, -one,  one,
  12.                 one,  one,  one,
  13.                -one,  one,  one, // Vertex Seven
  14.             };
Parsed in 0.033 seconds, using GeSHi 1.0.8.4


That is pretty easy, each row stands for a single vertex, consisting of three values (x,y,z) which simply result in a point in the cartesian space.
So if you think of each codeline as one vertex you get something like this:
(Note: We only created the vertices, not the edges. I just added them, that the cube-structure becomes better visible.)
(Note2: You will see that the blue coordinate-system is located right in the middle of the cube)
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[] = {
  8.                   0,    0,    0,  one,
  9.                 one,    0,    0,  one,
  10.                 one,  one,    0,  one,
  11.                   0,  one,    0,  one,
  12.                   0,    0,  one,  one,
  13.                 one,    0,  one,  one,
  14.                 one,  one,  one,  one,
  15.                   0,  one,  one,  one,
  16.             };
Parsed in 0.031 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, 4, 5"
  6.                  * will not result in the same triangle as: "0, 5, 4"
  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[] = {
  15.                 0, 4, 5,
  16.                 0, 5, 1,
  17.                 1, 5, 6,
  18.                 1, 6, 2,
  19.                 2, 6, 7,
  20.                 2, 7, 3,
  21.                 3, 7, 4,
  22.                 3, 4, 0,
  23.                 4, 7, 6,
  24.                 4, 6, 5,
  25.                 3, 0, 1,
  26.                 3, 1, 2
  27.         };
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


This is the tricky part. I think that I described it good enough in them comment.
Lets take a look at two example triangles:
Image

The Code
Original Source:
code.google.com

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

Woho this is nice, it grabs one whole cpu-core (got 2), but runs very smoothly.

What was the slowing-factor of emulators ?
Like x0.1 :| even worse I assume.

Not bad for a phone, though.
It even runs QUAKE =D
mrocket
Junior Developer
Junior Developer
 
Posts: 10
Joined: Thu Nov 15, 2007 7:28 pm

Postby sumet » Sat Nov 17, 2007 6:21 pm

great job! it's usefull and easy to understand
sumet
Freshman
Freshman
 
Posts: 5
Joined: Sat Nov 17, 2007 6:02 pm

Postby tum0rc0re » Wed Dec 05, 2007 5:33 pm

mrocket wrote:What was the slowing-factor of emulators ?


I think that yes, it's from emulator.
User avatar
tum0rc0re
Senior Developer
Senior Developer
 
Posts: 158
Joined: Sun Nov 25, 2007 7:15 am
Location: Moscow, Russia

Postby plusminus » Wed Dec 05, 2007 10:24 pm

tum0rc0re wrote:
mrocket wrote:What was the slowing-factor of emulators ?


I think that yes, it's from emulator.


The issue was how much slower is the emulator (on average pc) than an average android device :?:

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 d03boy » Thu Dec 06, 2007 1:26 am

nice little tutorial

..but its "opacity" not "opticacy"
d03boy
Freshman
Freshman
 
Posts: 5
Joined: Tue Nov 20, 2007 8:31 pm
Location: USA

Top

Postby tum0rc0re » Thu Dec 06, 2007 7:33 am

plusminus wrote:The issue was how much slower is the emulator (on average pc) than an average android device :?:


I think that much slower than real Android device, because there's program emulation ARM instructions of assembler in the emulator, as in Windows Mobile Emulator (WME works slower than WM devices too).
User avatar
tum0rc0re
Senior Developer
Senior Developer
 
Posts: 158
Joined: Sun Nov 25, 2007 7:15 am
Location: Moscow, Russia

Postby galahadxu » Mon Dec 24, 2007 3:44 am

I'd like to create a more complex 3D object and I hit the following problem:
When I change the mVertexBuffer from IntBuffer to DoubleBuffer, it does not work properly.
So the following is what I modified on this cube example:

1. Change the vertices to double array:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         double coor = 0x10000;
  2.  
  3.         double vertices[] = {
  4.  
  5.                -coor, -coor, -coor,
  6.  
  7.                coor, -coor, -coor,
  8.  
  9.                coor,  coor, -coor,
  10.  
  11.                -coor,  coor, -coor,
  12.  
  13.                -coor, -coor,  coor,
  14.  
  15.                coor, -coor,  coor,
  16.  
  17.                coor,  coor,  coor,
  18.  
  19.                -coor,  coor,  coor,
  20.  
  21.             };
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


2. Change the declaration of mVertexBuffer:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. //    private IntBuffer   mVertexBuffer;
  2.  
  3.     private DoubleBuffer        mVertexBuffer;
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


3. Change the allocate of mVertexBudder:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. //    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
  2.  
  3. //    vbb.order(ByteOrder.nativeOrder());
  4.  
  5. //    mVertexBuffer = vbb.asIntBuffer();
  6.  
  7.     mVertexBuffer = DoubleBuffer.allocate(vertices.length*8 );  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


The application compiles and runs with very scary looking...

Does anyone has any idea on this? Ideally glVertexPointer should accept any type of Buffer.

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

Postby freenode » Fri Dec 26, 2008 10:38 am

Nice tutorial. But what the heck is that 0x10000 constant? Why not 1.0 or 255 or 0xFFFF? It's ok for vertex but I don't get how it can be applied for color definition? Probably, it will be narrowed to 0xFFFF but it's not a case for tutorials for beginners, so please explain.

Thanks.
freenode
Once Poster
Once Poster
 
Posts: 1
Joined: Fri Dec 26, 2008 10:31 am

Postby Ultrano » Sun Jan 04, 2009 9:28 am

galahadxu: OpenGL implementations were never perfect. Stick with floats and bytes for now. IntBuffer has a bug for streaming, so you might want to avoid it for now, unless you're using it only for constant data.
freenode: GL_FIXED is 16.16 fixed-point, put in integer. So, 1.0f = 1<<16 .

By 0xFFFF, I guess you mean to use it for color:
565 color-data is only allowed for texel-data when uploading your texture with glTexImage2D. All color parameters for API-calls are in normalized 0..1 floats or unsigned-bytes. OpenGL doesn't accept color-parameters in one whole chunk (i.e white being 0xFFFFFFFF) - unless you're doing pointer-tricks in C++ and asm. OpenGL accepts components (in order: R,G,B,A) - you specify their count (1..4) and type (GL_UNSIGNED_BYTE, GL_FIXED or GL_FLOAT) when binding the array.

Btw, the Java bytes are signed -128..127, so white will be:
byte ColorArray[];
....
ColorArray[0] = -1; ColorArray[1] = -1; ColorArray[2] = -1; ColorArray[3] = -1;
or
ColorArray[0] = (byte)255;ColorArray[1] = (byte)255;ColorArray[2] = (byte)255;ColorArray[3] = (byte)255;


I suggest you stick to common data-types: GL_UNSIGNED_BYTE for color, GL_FLOAT and GL_FIXED for coordinates. That is the only sane and usually-tested way.
Ultrano
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sat Dec 20, 2008 12:53 am

Postby SkyNet800 » Tue Feb 24, 2009 3:13 pm

Is there anoy body that could fix this sample to be compiled using SDK 1.1 R1?

This sample has been writted using an older SDK and now it doesn´t compile.
SkyNet800
Junior Developer
Junior Developer
 
Posts: 20
Joined: Tue Feb 24, 2009 11:44 am

Postby MrSnowflake » Tue Feb 24, 2009 4:30 pm

Check the samples dir, there are some OpenGL demos there.
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Postby SkyNet800 » Tue Feb 24, 2009 5:09 pm

I´ve seen some examples, but this is very simple and clear, and is perfect for beginners.

plusminus is very clever. :wink:
SkyNet800
Junior Developer
Junior Developer
 
Posts: 20
Joined: Tue Feb 24, 2009 11:44 am

Re: Colored 3D Cube

Postby Ery86 » Tue May 05, 2009 11:00 am

plusminus wrote:import android.graphics.OpenGLContext;


this import "cannot be resolved"... why?
User avatar
Ery86
Developer
Developer
 
Posts: 27
Joined: Mon Apr 20, 2009 10:09 am
Location: Italy

Postby androiduser123 » Wed May 13, 2009 11:02 am

Unable to resolve openGLContext in new SDK.

Can someone please help?
androiduser123
Junior Developer
Junior Developer
 
Posts: 13
Joined: Tue May 12, 2009 7:20 am

Top
Next

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

Who is online

Users browsing this forum: No registered users and 3 guests