<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>codeNtronix</title>
	
	<link>http://codentronix.com</link>
	<description>Programming and Electronics Tutorials</description>
	<lastBuildDate>Thu, 22 Mar 2012 14:38:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/codentronix" /><feedburner:info uri="codentronix" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>codentronix</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>HTML5 Canvas Crazy Balls</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/HSN3579fRqo/</link>
		<comments>http://codentronix.com/2012/01/24/html5-canvas-crazy-balls/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 20:00:48 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[html5 demo]]></category>
		<category><![CDATA[particles]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=668</guid>
		<description><![CDATA[A few months ago I developed a small javascript application that renders &#8216;crazy balls&#8217; in HTML5 canvas. The balls move in random directions, change size and direction at random times. When they hit the borders of the canvas they bounce &#8230;<p class="read-more"><a href="http://codentronix.com/2012/01/24/html5-canvas-crazy-balls/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>A few months ago I developed a small javascript application that renders &#8216;crazy balls&#8217; in HTML5 canvas. The balls move in random directions, change size and direction at random times. When they hit the borders of the canvas they bounce and eventually change their size.  See below the application in action.</p>
<iframe src="http://codentronix.com/projects/html5/demos/crazy-balls.html" width="550" height="450" frameborder="0"></iframe>
<p><span id="more-668"></span></p>
<p><strong>Source Code</strong></p>
<p>Find below the source code. The code is pretty simple and self-explanatory. If you have any question or suggestion, please drop a comment.</p>
<pre class="brush: jscript; gutter: false; html-script: true; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;HTML5 Canvas Crazy Balls&lt;/title&gt;

  &lt;script&gt;
    function floatEquals(v1,v2,delta) {
      return Math.abs(v1 - v2) &lt;= delta;
    }

    function Ball(ctx,maxRadius) {
      this.calcTargetPoint = function() {
        this.radius = Math.random() * this.maxRadius + 1
        this.maxX = ctx.canvas.width - this.radius
        this.maxY = ctx.canvas.height - this.radius

        this.targetX = Math.random() * this.maxX
        this.targetY = Math.random() * this.maxY

        var speed = Math.random() * 50 + 50
        this.velX = (this.targetX - this.x) / speed
        this.velY = (this.targetY - this.y) / speed

        var r = Math.floor(Math.random() * 155 + 100)
        var g = Math.floor(Math.random() * 155 + 100)
        var b = Math.floor(Math.random() * 155 + 100)
        this.fillColor = &quot;rgb(&quot; + r + &quot;,&quot; + g + &quot;,&quot; + b + &quot;)&quot;
      }

      this.update = function() {
        var needNewTarget = false;

        this.x += this.velX
        this.y += this.velY

        if( this.x &lt;= this.radius ) {
          this.x = this.radius;
          needNewTarget = true;
        }
        if( this.y &lt;= this.radius ) {
          this.y = this.radius;
          needNewTarget = true;
        }
        if( this.x &gt;= this.maxX ) {
          this.x = this.maxX;
          needNewTarget = true;
        }
        if( this.y &gt;= this.maxY ) {
          this.y = this.maxY;
          needNewTarget = true;
        }
        if( floatEquals(this.x,this.targetX,0.9) &amp;&amp; floatEquals(this.y,this.targetY,0.9) ) {
          needNewTarget = true;
        }

        if( needNewTarget ) {
          this.calcTargetPoint();
        }
      }

      this.draw = function() {
        this.ctx.fillStyle = this.fillColor;
        this.ctx.beginPath();
        this.ctx.arc(this.x,this.y,this.radius,0,2*Math.PI,false);
        this.ctx.lineWidth = 3;
        this.ctx.stroke();
        this.ctx.fill();
      }

      this.ctx = ctx
      this.maxRadius = maxRadius
      this.radius = Math.random() * maxRadius + 1

      this.maxX = ctx.canvas.width - this.radius
      this.maxY = ctx.canvas.height - this.radius

      this.x = Math.random() * this.maxX
      this.y = Math.random() * this.maxY

      this.calcTargetPoint()
    }

    window.onload = function() {
      canvas = document.getElementById(&quot;tutorial&quot;)
      if( canvas &amp;&amp; canvas.getContext ) {
        ctx = canvas.getContext(&quot;2d&quot;)
        initDemo()
        setInterval(loop,33)
      }
    }

    function initDemo() {
      gradient = ctx.createLinearGradient(0,0,0,300);
      gradient.addColorStop(0,&quot;#202020&quot;);
      gradient.addColorStop(1,&quot;#304030&quot;);

      balls = new Array(32)
      for( var i = 0; i &lt; balls.length; i++ ) {
        balls[i] = new Ball(ctx,10)
      }
    }

    function loop() {
      ctx.fillStyle = gradient
      ctx.fillRect(0,0,canvas.width,canvas.height)

      for( var i = 0; i &lt; balls.length; i++ ) {
        balls[i].update()
        balls[i].draw()
      }
    }
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;canvas id=&quot;tutorial&quot; width=&quot;500&quot; height=&quot;400&quot;&gt;
    Your browser does not support the HTML5 Canvas element.
    Please, update your browser.
  &lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>If you like this article, please click one of the buttons below to share the article.</p>
<div class="shr-publisher-668"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/" title="3D Starfield in HTML5 Canvas">3D Starfield in HTML5 Canvas</a></li><li><a href="http://codentronix.com/2011/05/10/html5-experiment-a-rotating-solid-cube/" title="HTML5 Experiment: A Rotating Solid Cube">HTML5 Experiment: A Rotating Solid Cube</a></li><li><a href="http://codentronix.com/2011/04/27/first-experiment-with-html5-a-wireframe-cube/" title="First Experiment with HTML5: A Wireframe Cube">First Experiment with HTML5: A Wireframe Cube</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/HSN3579fRqo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2012/01/24/html5-canvas-crazy-balls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codentronix.com/2012/01/24/html5-canvas-crazy-balls/</feedburner:origLink></item>
		<item>
		<title>First Android App: Touch Controlled Cube on Samsung Galaxy S2</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/Ptqp87Pc6yw/</link>
		<comments>http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 15:35:51 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[samsung galaxy s2]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=647</guid>
		<description><![CDATA[A couple of weeks ago I started to tinker with android programming. After reading some articles in android developers guide I developed my first application. It is a simple application that draws a cube in a 2D canvas. The cube can &#8230;<p class="read-more"><a href="http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>A couple of weeks ago I started to tinker with android programming. After reading some articles in <a href="http://developer.android.com/guide/index.html" rel="nofollow">android developers guide</a> I developed my first application. It is a simple application that draws a cube in a 2D canvas. The cube can be controlled with touch input. Below you may see the video of the application in action. I have tested the application on a Samsung Galaxy S2.</p>
<p><object width="400" height="225"><param name="movie" value="http://www.youtube.com/v/0URpA8LPotk?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/0URpA8LPotk?version=3" type="application/x-shockwave-flash" width="400" height="225" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><span id="more-647"></span></p>
<h2>The Idea</h2>
<p>I have created a custom view by extending the <em>View</em> class. In the custom view I overridden the <em>onDraw()</em> method to draw the cube. I also overridden the <em>onTouchEvent() </em>method to capture touch events.</p>
<h2>The Code</h2>
<p><em><strong>CubeView.java</strong>:</em></p>
<p>The <em>CubeView</em> class is the custom view responsible for drawing the cube.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
package com.codentronix.android;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;
import android.graphics.Paint.Style;
import android.graphics.Path;

public class CubeView extends View {
	/* Vertices of the cube. */
	protected Vector3D vertices[];

	/* Define the indices to the vertices of each face of the cube. */
	protected int faces[][];

	/* Colors of each face of the cube. */
	protected int colors[];

	/* Orientation of the cube around X axis. */
	protected float ax;

	/* Orientation of the cube around Y axis. */
	protected float ay;

	/* Orientation of the cube around Z axis. */
	protected float az;

	protected float lastTouchX;
	protected float lastTouchY;

	/* This constructor is used when the view is created from code. */
	public CubeView(Context context) {
		super(context);
	}

	/* This constructor is used when the view is inflated from a XML file. */
	public CubeView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	/**
	 * Initializes the cube geometry.
	 */
	public void initialize() {
		vertices = new Vector3D[] {
	        new Vector3D(-1, 1, -1),
	        new Vector3D(1, 1, -1),
	        new Vector3D(1, -1, -1),
	        new Vector3D(-1, -1, -1),
	        new Vector3D(-1, 1, 1),
	        new Vector3D(1, 1, 1),
	        new Vector3D(1, -1, 1),
	        new Vector3D(-1, -1, 1)
		};

		// Define the 6 faces of the cube. We specify the indices to the 4 vertices of each face.
		faces = new int[][] {{0, 1, 2, 3}, {1, 5, 6, 2}, {5, 4, 7, 6}, {4, 0, 3, 7}, {0, 4, 5, 1}, {3, 2, 6, 7}};

		// Define the color of each face.
		colors = new int[] {Color.BLUE, Color.RED, Color.YELLOW, Color.LTGRAY, Color.CYAN, Color.MAGENTA};
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
		super.onLayout(changed, left, top, right, bottom);

		// Initialize the cube geometry.
		initialize();

		// Allow the view to receive touch input.
		setFocusableInTouchMode(true);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if( event.getAction() == MotionEvent.ACTION_DOWN ) {
			lastTouchX = event.getX();
			lastTouchY = event.getY();
		}else if( event.getAction() == MotionEvent.ACTION_MOVE ) {
			float dx = (event.getX() - lastTouchX) / 30.0f;
			float dy = (event.getY() - lastTouchY) / 30.0f;
			ax += dy;
			ay -= dx;
			postInvalidate();
		}
		return true;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		Vector3D t[]  = new Vector3D[8];
		double avgZ[] = new double[6];
		int order[] = new int[6];

		for( int i = 0; i &lt; 8; i++ ) {
			// Rotate the vertex around X, next around Y, and then around Z.
			t[i] = vertices[i].rotateX(ax).rotateY(ay).rotateZ(az);

			// Finally, map the vertex from 3D to 2D.
			t[i] = t[i].project(getWidth(), getHeight(), 256, 4);
		}

		// Compute the average Z value of each face.
		for( int i = 0; i &lt; 6; i++ ) {
			avgZ[i] = (t[faces[i][0]].z + t[faces[i][1]].z + t[faces[i][2]].z + t[faces[i][3]].z) / 4;
			order[i] = i;
		}

        // Next we sort the faces in descending order based on the Z value.
        // The objective is to draw distant faces first. This is called
        // the PAINTERS ALGORITHM. So, the visible faces will hide the invisible ones.
        // The sorting algorithm used is the SELECTION SORT.
		for( int i = 0; i             int iMax = i;
    		for( int j = i + 1; j  avgZ[iMax] ) {
                    iMax = j;
                }
    		}
            if( iMax != i ) {
	            double dTmp = avgZ[i];
	            avgZ[i] = avgZ[iMax];
	            avgZ[iMax] = dTmp;

	            int iTmp = order[i];
	            order[i] = order[iMax];
	            order[iMax] = iTmp;
            }
		}

		canvas.drawColor(Color.BLACK);

		Paint paint = new Paint();
		paint.setColor(Color.WHITE);
		paint.setStyle(Style.FILL);

		paint.setTextSize(24);
		canvas.drawText(&quot;3D Cube&quot;,10,40,paint);

		paint.setTextSize(12);
		canvas.drawText(&quot;Drag the cube to change its orientation&quot;, 10, 80, paint);
		canvas.drawText(&quot;http://codentronix.com&quot;, 10, getHeight() - 10, paint);

		for( int i = 0; i &lt; 6; i++ ) {
			int index = order[i];

			Path p = new Path();
			p.moveTo((float)t[faces[index][0]].x, (float)t[faces[index][0]].y);
			p.lineTo((float)t[faces[index][1]].x, (float)t[faces[index][1]].y);
			p.lineTo((float)t[faces[index][2]].x, (float)t[faces[index][2]].y);
			p.lineTo((float)t[faces[index][3]].x, (float)t[faces[index][3]].y);
			p.close();

			paint.setColor(colors[index]);
			canvas.drawPath(p, paint);
		}
	}
}
</pre>
<p><em><strong>Vector3D.java</strong></em>:</p>
<p>The <em>Vector3D </em>class is be used to define each vertex of the cube in 3D space.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
package com.codentronix.android;

public class Vector3D {
	protected double x;
	protected double y;
	protected double z;

	public Vector3D() {
		x = y = z = 0;
	}

	public Vector3D(double x, double y, double z) {
		this.x = x;
		this.y = y;
		this.z = z;
	}

	public Vector3D rotateX(double angle) {
        double rad, cosa, sina, yn, zn;

        rad = angle * Math.PI / 180;
        cosa = Math.cos(rad);
        sina = Math.sin(rad);
        yn = this.y * cosa - this.z * sina;
        zn = this.y * sina + this.z * cosa;

        return new Vector3D(this.x, yn, zn);
	}

	public Vector3D rotateY(double angle) {
        double rad, cosa, sina, xn, zn;

        rad = angle * Math.PI / 180;
        cosa = Math.cos(rad);
        sina = Math.sin(rad);
        zn = this.z * cosa - this.x * sina;
        xn = this.z * sina + this.x * cosa;

        return new Vector3D(xn, this.y, zn);
	}

	public Vector3D rotateZ(double angle) {
        double rad, cosa, sina, xn, yn;

        rad = angle * Math.PI / 180;
        cosa = Math.cos(rad);
        sina = Math.sin(rad);
        xn = this.x * cosa - this.y * sina;
        yn = this.x * sina + this.y * cosa;

        return new Vector3D(xn, yn, this.z);
	}

	public Vector3D project(int viewWidth, int viewHeight, float fov, float viewDistance) {
        double factor, xn, yn;

        factor = fov / (viewDistance + this.z);
        xn = this.x * factor + viewWidth / 2;
        yn = this.y * factor + viewHeight / 2;

        return new Vector3D(xn, yn, this.z);
	}
}
</pre>
<p>The methods <em>rotateX()</em>, <em>rotateY()</em>, and <em>rotateZ()</em> rotate the vertex around X, Y, and Z axis respectively. The method <em>project()</em> maps the vertex from 3D space to 2D space.</p>
<p><strong>CubeIn2DCanvasActivity.java:</strong></p>
<p>This file defines the main activity of the application. The activity loads the layout and adds a menu item. The layout is composed by the custom view we defined above.</p>
<pre class="brush: java; gutter: false; title: ; notranslate">
package com.codentronix.android;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;

public class CubeIn2DCanvasActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Remove the title bar.
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.main);
    }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main, menu);
		return true;
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		if( id == R.id.about ) {
			builder.setMessage(&quot;Developed by Leonel Machava &quot;)
				.setPositiveButton(&quot;OK&quot;, null);
		}
		return builder.create();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if( item.getItemId() == R.id.about ) {
			showDialog(R.id.about);
		}
		return true;
	}
}
</pre>
<h2><strong>Resource Files</strong></h2>
<p><strong><em>Layout: main.xml</em></strong></p>
<pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:orientation=&quot;vertical&quot;
    android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;fill_parent&quot;
    &gt;
&lt;com.codentronix.android.CubeView
    android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;fill_parent&quot;
    /&gt;
&lt;/LinearLayout&gt;
</pre>
<p><strong><em>Menu file: menu.xml</em></strong></p>
<pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;menu
  xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
	&lt;item   android:id=&quot;@+id/about&quot;
			android:title=&quot;Sobre&quot; /&gt;
&lt;/menu&gt;
</pre>
<p><em>If you liked this post, please consider leaving a comment, sharing this post using one of the buttons below, or <a href="http://feeds.feedburner.com/codentronix">subscribing to the blog</a>.</em></p>
<div class="shr-publisher-647"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/" title="5 Cool OpenGL Demos in VB.NET">5 Cool OpenGL Demos in VB.NET</a></li><li><a href="http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/" title="3D Starfield in HTML5 Canvas">3D Starfield in HTML5 Canvas</a></li><li><a href="http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/" title="A Simple 3D Room made with DirectX and C++">A Simple 3D Room made with DirectX and C++</a></li><li><a href="http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/" title="How to Draw A Cube Using PHP">How to Draw A Cube Using PHP</a></li><li><a href="http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/" title="3D Starfield made using Python and Pygame">3D Starfield made using Python and Pygame</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/Ptqp87Pc6yw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/</feedburner:origLink></item>
		<item>
		<title>5 Cool OpenGL Demos in VB.NET</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/8xfNMRFhHhA/</link>
		<comments>http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 20:18:15 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[vb.net]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=635</guid>
		<description><![CDATA[A couple of months ago I decided to use OpenGL with .NET. So I needed to choose an OpenGL wrapper for .NET. After a short research I chose the OpenTK library. To try it out I developed some simple demos and I &#8230;<p class="read-more"><a href="http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>A couple of months ago I decided to use OpenGL with .NET. So I needed to choose an OpenGL wrapper for .NET. After a short research I chose the <a title="OpenTK website" href="http://www.opentk.com" rel="nofollow" target="_blank">OpenTK</a> library. To try it out I developed some simple demos and I uploaded some videos of them on my <a title="My youtube page" href="http://www.youtube.com/codentronix" rel="nofollow" target="_blank">youtube page</a>.</p>
<p>In this post I will show some videos of the projects I have developed so far. In later posts I will share the source code of each project.</p>
<p><strong>UPDATE:</strong> <em>I have uploaded the source code of these and other OpenGL demos on my <a href="https://github.com/lefam/opengl_dot_net_experiments">github space</a>.</em></p>
<h2>1. Loading and animating Quake 2 (MD2) models</h2>
<p><iframe width="400" height="300" src="http://www.youtube.com/embed/5nS9Il997qU?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><span id="more-635"></span></p>
<h2>2. Terrain Rendering with heightmaps</h2>
<p><iframe width="400" height="300" src="http://www.youtube.com/embed/3JqWIVFLK2g?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<h2>3. Simple Camera in OpenGL</h2>
<p><iframe width="400" height="300" src="http://www.youtube.com/embed/F0HWSZrPxjE?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<h2>4. Textured Cube</h2>
<p><iframe width="400" height="300" src="http://www.youtube.com/embed/_oHETfkVhq8?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<h2>5. Gouraud Shaded Cube</h2>
<p><iframe width="400" height="300" src="http://www.youtube.com/embed/BXxylZMuqnU?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p><em>If you liked this post, please consider leaving a comment, sharing this post using one of the buttons below, or <a href="http://feeds.feedburner.com/codentronix">subscribing to the blog</a>.</em></p>
<div class="shr-publisher-635"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/05/25/rotating-solid-cube-using-vb-net-and-gdi/" title="Rotating Solid Cube Using VB.NET and GDI+">Rotating Solid Cube Using VB.NET and GDI+</a></li><li><a href="http://codentronix.com/2011/05/24/rotating-wireframe-cube-using-vb-net-and-gdi/" title="Rotating Wireframe Cube using VB.NET and GDI+">Rotating Wireframe Cube using VB.NET and GDI+</a></li><li><a href="http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/" title="First Android App: Touch Controlled Cube on Samsung Galaxy S2">First Android App: Touch Controlled Cube on Samsung Galaxy S2</a></li><li><a href="http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/" title="3D Starfield in HTML5 Canvas">3D Starfield in HTML5 Canvas</a></li><li><a href="http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/" title="A Simple 3D Room made with DirectX and C++">A Simple 3D Room made with DirectX and C++</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/8xfNMRFhHhA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/</feedburner:origLink></item>
		<item>
		<title>3D Starfield in HTML5 Canvas</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/_pM42qt16vs/</link>
		<comments>http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 16:27:13 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[html5 demo]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[starfield]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=597</guid>
		<description><![CDATA[This article will show you how to create a 3D starfield using HTML5 Canvas. Below you can see the 3D starfield in action (well, if your browser supports HTML5 canvas). An interesting aspect of this simulation is that the stars that &#8230;<p class="read-more"><a href="http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>This article will show you how to create a 3D starfield using HTML5 Canvas. Below you can see the 3D starfield in action (well, if your browser supports HTML5 canvas).</p>
<iframe src="http://codeNtronix.com/projects/html5/3d/canvas-3d-starfield.html" width="550" height="420" frameborder="0"></iframe>
<p>An interesting aspect of this simulation is that the stars that are far away look smaller and darker than closer stars.</p>
<p><span id="more-597"></span></p>
<p>In this article I assume that the reader has at least a basic knowledge of HTML and JavaScript. I will begin by presenting the idea and some theory behind the simulation and after that I will present the code. If any question arises, please don&#8217;t hesitate to leave a comment.</p>
<h2>The idea</h2>
<p>The screen is filled with a constant number of stars. In this simulation I filll the screen with 512 stars. For each star we are interested in knowing only its coordinates. Since this is a 3D simulation, the coordinates must be in 3D. So, each star will be represented in the code as an object with properties <strong>X</strong>, <strong>Y</strong>, and <strong>Z</strong>.</p>
<p>After the page is completely loaded, we do the initial positioning of the stars, assigning them random positions, and of course ensuring that they stay within the field of view. Then we enter an infinite loop, where in each iteration (or frame) we decrease the value of the Z coordinate of each star making it move towards the user. When a star goes out of the field of view, ie, when Z is less than or equal to zero, it is repositioned deep inside the screen and is assigned random values ​​for X and Y. The final step is to draw the star, but wait, remember that the stars are in 3D. So before we draw them they should be mapped to 2D. To do the mapping to 2D we will use the following formulas:</p>
<pre>px = 128 * star.x / + star.z + half_canvas_width
py = 128 * star.y / + star.z + half_canvas_height</pre>
<p>In the formula, <em>px</em> and <em>py</em> are the resulting coordinates mapped to 2D. This operation is called a <em>perspective projection.</em></p>
<p>Having the coordinates in 2D we can immediately draw the star. However, I preferred to make the simulation a little bit more interesting by making distant stars look smaller and darker than closer stars. To achieve this, <em>linear interpolation</em> was applied to calculate the size and color of the stars based on the Z coordinate. Here are the formulas:</p>
<pre>size = (1 - star.z / max_depth) * 5
color = (1 - star.z / max_depth) * 255</pre>
<p>The <em>size</em> and <em>color</em> are inversely proportional to the value of Z. Thus, when the star is at the maximum depth, <em>size</em> and <em>color</em> are both zero, approaching 5 and 255, respectively as the value of Z decreases.</p>
<h2>Code</h2>
<p><strong>HTML Structure</strong><br />
Let&#8217;s begin with the structure of the HTML5 page that will run the 3D starfield.</p>
<pre class="brush: jscript; gutter: false; html-script: true; title: ; notranslate">
&lt;!DOCTYPE html5&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;3D Starfield in HTML5 Canvas&lt;/title&gt;
&lt;body&gt;
&lt;canvas id='tutorial' width='500' height='400'&gt;
Your browser does not support the HTML5 Canvas element.
Please update your browser.
&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The statement in the first line tells the browser that the page is based on HTML5. Not including this statement may cause some browsers to ignore the new HTML5 elements. Internet Explorer is an example.<br />
We have defined a canvas element inside the body element. The canvas is 500 pixels wide and 400 pixels tall, and has id <em>tutorial</em>.</p>
<p><strong>JavaScript Code</strong><br />
With the HTML structure defined, the next step is to enter the JavaScript code that performs the simulation. Below is the complete code. Notice that I have introduced the script inside the head element and just below the title element.</p>
<pre class="brush: jscript; gutter: false; html-script: true; title: ; notranslate">
&lt;!DOCTYPE html5&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;3D Starfield in HTML5 Canvas&lt;/title&gt;

  &lt;script type='text/javascript'&gt;
    MAX_DEPTH = 32;

    var canvas, ctx;
    var stars = new Array(512);

    window.onload = function() {
      canvas = document.getElementById(&quot;tutorial&quot;);
      if( canvas &amp;&amp; canvas.getContext ) {
        ctx = canvas.getContext(&quot;2d&quot;);
        initStars();
        setInterval(loop,33);
       }
    }

    /* Returns a random number in the range [minVal,maxVal] */
    function randomRange(minVal,maxVal) {
      return Math.floor(Math.random() * (maxVal - minVal - 1)) + minVal;
    }

    function initStars() {
      for( var i = 0; i &lt; stars.length; i++ ) {
        stars[i] = {
          x: randomRange(-25,25),
          y: randomRange(-25,25),
          z: randomRange(1,MAX_DEPTH)
         }
      }
    }

    function loop() {
      var halfWidth  = canvas.width / 2;
      var halfHeight = canvas.height / 2;

      ctx.fillStyle = &quot;rgb(0,0,0)&quot;;
      ctx.fillRect(0,0,canvas.width,canvas.height);

      for( var i = 0; i &lt; stars.length; i++ ) {
        stars[i].z -= 0.2;

        if( stars[i].z &lt;= 0 ) {
          stars[i].x = randomRange(-25,25);
          stars[i].y = randomRange(-25,25);
          stars[i].z = MAX_DEPTH;
        }

        var k  = 128.0 / stars[i].z;
        var px = stars[i].x * k + halfWidth;
        var py = stars[i].y * k + halfHeight;

        if( px &gt;= 0 &amp;&amp; px &lt;= 500 &amp;&amp; py &gt;= 0 &amp;&amp; py &lt;= 400 ) {
          var size = (1 - stars[i].z / 32.0) * 5;
          var shade = parseInt((1 - stars[i].z / 32.0) * 255);
          ctx.fillStyle = &quot;rgb(&quot; + shade + &quot;,&quot; + shade + &quot;,&quot; + shade + &quot;)&quot;;
          ctx.fillRect(px,py,size,size);
        }
      }
    }
  &lt;/script&gt;

&lt;body&gt;
  &lt;canvas id='tutorial' width='500' height='400'&gt;
    Your browser does not support HTML5 canvas.
    Please upgrade your browser.
  &lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong>Description of code:</strong><br />
The first line defines the <strong>MAX_DEPTH</strong> constant that stores the maximum distance or depth where a star can be. Then, the <strong>canvas</strong> variable is declared which will be used store the reference to the canvas element. The variable <strong>ctx</strong> will store the canvas context and will be used to draw inside the canvas. Obviously the <strong>stars </strong>array will store 512 stars.</p>
<p>Next we define a function that is executed when the page is fully loaded. The function begins by getting the reference of the canvas element. After that, we determine whether the browser supports the new canvas element. If so, we get the reference of the context of the canvas that will be used to draw inside the canvas. Then, we invoke the function <strong>initStars()</strong> that prepares the stars by positioning them randomly in space. Finally, we set the <strong>loop()</strong> function to be invoked every 33 milliseconds.</p>
<p>It is inside the <strong>loop()</strong> function where the simulation takes place. First, we clear the canvas with a black color, and then start a loop that processes the stars. In each iteration, we start by decreasing the Z value of the star. Next, we check if the star is still within the field of view. If not, the star is positioned at the maximum depth and assigned random values ​​for the coordinates X and Y. Then, we do the mapping of coordinates from 3D to 2D. Finally, we draw the star only if it is within the limits of the canvas. See the section <em>The idea</em> to understand the algorithm I use to draw the stars.</p>
<h2>Conclusion</h2>
<p>In this article I have shown how to make an interesting 3D starfield using the new HTML5 Canvas element. More articles on HTML5 Canvas will come. So, please <a title="Subscribe to RSS" href="http://feeds.feedburner.com/codentronix">subscribe to our feed</a> to receive updates.</p>
<p>If you like this article, please click one of the buttons below to share the article. Consider also leaving a comment expressing what you think about this article.</p>
<div class="shr-publisher-597"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/05/10/html5-experiment-a-rotating-solid-cube/" title="HTML5 Experiment: A Rotating Solid Cube">HTML5 Experiment: A Rotating Solid Cube</a></li><li><a href="http://codentronix.com/2011/04/27/first-experiment-with-html5-a-wireframe-cube/" title="First Experiment with HTML5: A Wireframe Cube">First Experiment with HTML5: A Wireframe Cube</a></li><li><a href="http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/" title="3D Starfield made using Python and Pygame">3D Starfield made using Python and Pygame</a></li><li><a href="http://codentronix.com/2012/01/24/html5-canvas-crazy-balls/" title="HTML5 Canvas Crazy Balls">HTML5 Canvas Crazy Balls</a></li><li><a href="http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/" title="First Android App: Touch Controlled Cube on Samsung Galaxy S2">First Android App: Touch Controlled Cube on Samsung Galaxy S2</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/_pM42qt16vs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/</feedburner:origLink></item>
		<item>
		<title>A Simple 3D Room made with DirectX and C++</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/58QE8DRHNQc/</link>
		<comments>http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/#comments</comments>
		<pubDate>Sat, 18 Jun 2011 17:29:01 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Game Programming]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[3d engine]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[directx]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=579</guid>
		<description><![CDATA[Today, while messing around with an old backup disk, I found a DirectX 9 project I made back in 2005. It is an application that renders a 3D room and allows the user to navigate inside it in first person &#8230;<p class="read-more"><a href="http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Today, while messing around with an old backup disk, I found a DirectX 9 project I made back in 2005. It is an application that renders a 3D room and allows the user to navigate inside it in first person camera. I developed this application to test a 3D engine I was developing at the time. The video below shows the 3D application in action.</p>
<iframe width="480" height="390" src="http://www.youtube.com/embed/wqfIzgLc_P4?rel=0" frameborder="0" allowfullscreen></iframe>
<p>&nbsp;</p>
<p><em>I will just share the main file module of the project. To get the rest of the 3D engine files, consider following me on <a title="Go there and follow me" rel="nofollow" href="http://twitter.com/codentronix">twitter</a> or <a title="Go to my Facebook page and click Like" rel="nofollow" href="http://facebook.com/codentronix">facebook</a>, or ask in the <a title="Contact" href="http://codentronix.com/contact/">contact page</a>. Don&#8217;t hesitate to leave a comment if you a have a doubt or suggestion.</em></p>
<p><em><span id="more-579"></span></em></p>
<h2>How it works</h2>
<p>You navigate in the room using the arrow keys. The possible moviments are:</p>
<ul>
<li>Move forward/backward</li>
<li>Move left/right</li>
<li>Strafe left/right</li>
<li>Look down/up</li>
</ul>
<p>I developed the application using C++ and DirectX 9. The application is based on a 3D engine I was developing at the time. The main aim of the engine was to facilitate the creation of windows applications and at the same time make easy the creation of cool 3D games. The engine facilitated setting up DirectX, playing sounds and music, loading 3D models, creating worlds, and making navigations in first person as well as in third person (just to name a few).</p>
<p><span style="font-size: 20px; font-weight: bold;">The Code</span></p>
<p>The main module is divided in two files: <strong>main.cpp</strong> and <strong>main.h</strong>. Below is the code for the <strong>main.h</strong> file.</p>
<pre class="brush: cpp; title: ; notranslate">
#ifndef __MAIN_H__
#define __MAIN_H__

#include &lt;windows.h&gt;
#include &quot;application.h&quot;
#include &quot;graphics.h&quot;
#include &quot;camera.h&quot;

typedef struct {
 float x,y,z;
 float u,v;
}VERTEX;

#define VERTEX_FVF		D3DFVF_XYZ | D3DFVF_TEX1

#define WORLD_X			10
#define WORLD_Y			9

#define NUM_WALL_VERTICES	24
#define NUM_CEIL_VERTICES	6
#define NUM_FLOOR_VERTICES	6

#define NUM_CEIL_TRI		(NUM_CEIL_VERTICES / 3)
#define NUM_WALL_TRI		(NUM_WALL_VERTICES / 3)
#define NUM_FLOOR_TRI		(NUM_FLOOR_VERTICES / 3)

#define WALL_VB_SIZE		NUM_WALL_VERTICES * sizeof(VERTEX)
#define CEIL_VB_SIZE		NUM_CEIL_VERTICES * sizeof(VERTEX)
#define FLOOR_VB_SIZE		NUM_FLOOR_VERTICES * sizeof(VERTEX)

#define KEYDOWN(x)		(GetAsyncKeyState(x) &amp; 0x8000)

class c3DRoom : public cApplication {
 cGraphics *m_pGfx;
 cCAMERA   m_Camera;
 IDirect3DVertexBuffer9 *m_pVBWall;
 IDirect3DVertexBuffer9 *m_pVBCeil;
 IDirect3DVertexBuffer9 *m_pVBFloor;
 IDirect3DTexture9	*m_pTextures[3];
 BOOL m_bFullScreen;

public:
 c3DRoom();
 ~c3DRoom();

 BOOL InitScene();
 BOOL Init();
 void CheckInput();
 void RenderScene();
 BOOL DoFrame();
 BOOL ShutDown();
};
#endif
</pre>
<p>Next is the code for the <strong>main.cpp</strong> file.</p>
<pre class="brush: cpp; title: ; notranslate">
#include &quot;main.h&quot;

VERTEX WallVtx[NUM_WALL_VERTICES] = {
 // 1o Triângulo, face frontal
 -1,1,-1,0,0,
 1,1,-1,1,0,
 -1,-1,-1,0,1,
 // 2o Triângulo, face frontal
 1,1,-1,1,0,
 1,-1,-1,1,1,
 -1,-1,-1,0,1,
 // 1o Triângulo, face lateral direita
 1,1,-1,0,0,
 1,1,1,1,0,
 1,-1,-1,0,1,
 // 2o Triângulo, face lateral direita
 1,1,1,1,0,
 1,-1,1,1,1,
 1,-1,-1,0,1,
 // 1o Triângulo, face lateral esquerda
 -1,1,-1,1,0,
 -1,-1,1,0,1,
 -1,1,1,0,0,
 // 2o Triângulo, face lateral esquerda
 -1,1,-1,1,0,
 -1,-1,-1,1,1,
 -1,-1,1,0,1,
 // 1o Triângulo, face traseira
 1,1,1,0,0,
 -1,1,1,1,0,
 1,-1,1,0,1,
 // 2o Triângulo, face traseira
 1,-1,1,0,1,
 -1,1,1,1,0,
 -1,-1,1,1,1
};

VERTEX CeilVtx[NUM_CEIL_VERTICES] = {
 // 1o Triângulo
 1,1,1,1,1,
 -1,1,1,0,1,
 -1,1,-1,0,0,
 // 2o Triângulo
 -1,1,-1,0,0,
 1,1,-1,1,0,
 1,1,1,1,1
};

VERTEX FloorVtx[NUM_CEIL_VERTICES] = {
 // 1o Triângulo
 -1,0,1,0,0,
 1,0,1,1,0,
 -1,0,-1,0,1,
 // 2o Triângulo
 1,0,1,1,0,
 1,0,-1,1,1,
 -1,0,-1,0,1
};

int iWallMap[WORLD_Y][WORLD_X] = {
 1,1,1,1,1,1,1,1,1,1,
 1,0,0,0,0,0,0,0,0,1,
 1,0,1,0,0,0,0,1,0,1,
 1,0,1,0,0,0,0,1,0,1,
 1,0,0,0,0,0,0,1,0,1,
 1,0,1,0,0,0,0,1,0,1,
 1,0,1,0,1,1,1,1,0,1,
 1,0,0,0,0,0,0,0,0,1,
 1,1,1,1,1,1,1,1,1,1};

c3DRoom::c3DRoom()
{
  m_pTextures[0] = m_pTextures[1] = m_pTextures[2] = NULL;
  m_pVBWall  = NULL;
  m_pVBCeil  = NULL;
  m_pVBFloor = NULL;

  m_dwWidth = 400;
  m_dwHeight = 350;
  m_dwStyle = WS_OVERLAPPEDWINDOW;
  m_dwExStyle = 0;
  m_bFullScreen = FALSE;

  strcpy(m_szClass,&quot;3DRoomClass&quot;);
  strcpy(m_szCaption,&quot;3D Room by Leonel Machava&quot;);
}

BOOL c3DRoom::InitScene()
{
  IDirect3DDevice9 *pDevice;
  D3DXMATRIX matWorld,matView,matProj;
  RECT rcClient;

  pDevice = Graphics()-&gt;GetDevice();

  if( FAILED(D3DXCreateTextureFromFile(pDevice,&quot;Media\\wall2.bmp&quot;,&amp;m_pTextures[0])) ||
    FAILED(D3DXCreateTextureFromFile(pDevice,&quot;Media\\floor.bmp&quot;,&amp;m_pTextures[1])) ||
    FAILED(D3DXCreateTextureFromFile(pDevice,&quot;Media\\ceil1.bmp&quot;,&amp;m_pTextures[2])) )
    return( FALSE );

  if( FAILED(pDevice-&gt;CreateVertexBuffer(WALL_VB_SIZE,D3DUSAGE_WRITEONLY,VERTEX_FVF,
                                         D3DPOOL_MANAGED,&amp;m_pVBWall,NULL)) )
    return( FALSE );

  if( FAILED(pDevice-&gt;CreateVertexBuffer(CEIL_VB_SIZE,D3DUSAGE_WRITEONLY,VERTEX_FVF,
                                         D3DPOOL_MANAGED,&amp;m_pVBCeil,NULL)) )
    return( FALSE );

  if( FAILED(pDevice-&gt;CreateVertexBuffer(FLOOR_VB_SIZE,D3DUSAGE_WRITEONLY,VERTEX_FVF,
                                         D3DPOOL_MANAGED,&amp;m_pVBFloor,NULL)) )
   return( FALSE );

  Graphics()-&gt;FillVertexBuffer(m_pVBWall,WallVtx,0,WALL_VB_SIZE);
  Graphics()-&gt;FillVertexBuffer(m_pVBCeil,CeilVtx,0,CEIL_VB_SIZE);
  Graphics()-&gt;FillVertexBuffer(m_pVBFloor,FloorVtx,0,FLOOR_VB_SIZE);

  pDevice-&gt;SetRenderState(D3DRS_LIGHTING,FALSE);
  pDevice-&gt;SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
  pDevice-&gt;SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
  pDevice-&gt;SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR);

  GetClientRect(GetHWnd(),&amp;rcClient);
  m_Camera.GetMatrix(&amp;matView);

  D3DXMatrixIdentity(&amp;matWorld);
  D3DXMatrixPerspectiveFovLH(&amp;matProj,D3DX_PI / 4.0,(float)rcClient.right / rcClient.bottom,1.0,1000.f);

  pDevice-&gt;SetTransform(D3DTS_WORLD,&amp;matWorld);
  pDevice-&gt;SetTransform(D3DTS_VIEW,&amp;matView);
  pDevice-&gt;SetTransform(D3DTS_PROJECTION,&amp;matProj);

  return( TRUE );
}

BOOL c3DRoom::Init()
{
  m_pGfx = new cGraphics;

  m_Camera.SetPosition(1,0,-7);

  if( !Graphics()-&gt;Init(GetHWnd(),0,0,TRUE,D3DFMT_UNKNOWN,D3DFMT_D16) )
  {
    MessageBox(GetHWnd(),&quot;Não foi possível inicializar os gráficos&quot;,&quot;Erro&quot;,MB_OK);
    return( FALSE );
  }

  if( !InitScene() )
  {
    MessageBox(GetHWnd(),&quot;Não foi possível inicializar a cena&quot;,&quot;Erro&quot;,MB_OK);
    return( FALSE );
  }

  return( TRUE );
}

BOOL c3DRoom::ShutDown()
{
  SAFE_RELEASE(m_pTextures[0]);
  SAFE_RELEASE(m_pTextures[1]);
  SAFE_RELEASE(m_pTextures[2]);
  SAFE_RELEASE(m_pVBWall);
  SAFE_RELEASE(m_pVBCeil);
  SAFE_RELEASE(m_pVBFloor);

  Graphics()-&gt;Close();

  delete m_pGfx;

  return( TRUE );
}

void c3DRoom::CheckInput()
{
  if( KEYDOWN(VK_UP) )	m_Camera.Walk(0.10f);

  if( KEYDOWN(VK_DOWN) )	m_Camera.Walk(-0.10f);

  if( KEYDOWN(VK_LEFT) )	m_Camera.Yaw(-0.02f);

  if( KEYDOWN(VK_RIGHT) ) m_Camera.Yaw(0.02f);

  if( KEYDOWN(VK_PRIOR) )	m_Camera.Pitch(0.02f);

  if( KEYDOWN(VK_NEXT) )	m_Camera.Pitch(-0.02f);

  if( KEYDOWN('A') )		m_Camera.Strafe(-0.1f);

  if( KEYDOWN('D') )		m_Camera.Strafe(0.1f);
}

void c3DRoom::RenderScene()
{
  float xPos,zPos;
  int i,j;

  IDirect3DDevice9 *pDevice;
  D3DXMATRIX matView,matWorld;

  Graphics()-&gt;ClearAll(D3DCOLOR_XRGB(0,0xF0,0),1.0);
  Graphics()-&gt;BeginScene();

  pDevice = Graphics()-&gt;GetDevice();
  pDevice-&gt;SetFVF(VERTEX_FVF);

  m_Camera.GetMatrix(&amp;matView);
  pDevice-&gt;SetTransform(D3DTS_VIEW,&amp;matView);

  pDevice-&gt;SetStreamSource(0,m_pVBFloor,0,sizeof(VERTEX));
  pDevice-&gt;SetTexture(0,m_pTextures[1]);

  for( i = 0,zPos = 5; i &lt; WORLD_Y; i++ )
  {
    xPos = -5;
    for( j = 0; j &lt; WORLD_X; j++ )
    {
      D3DXMatrixTranslation(&amp;matWorld,xPos,-1,zPos);
//    if( 0 == iWallMap[i][j] )
      {
        pDevice-&gt;SetTransform(D3DTS_WORLD,&amp;matWorld);
        pDevice-&gt;DrawPrimitive(D3DPT_TRIANGLELIST,0,NUM_FLOOR_TRI);
      }
      xPos += 2;
    }
    zPos -= 2;
  }

  pDevice-&gt;SetStreamSource(0,m_pVBCeil,0,sizeof(VERTEX));
  pDevice-&gt;SetTexture(0,m_pTextures[2]);

  for( i = 0,zPos = 5; i &lt; WORLD_Y; i++ )
  {
    xPos = -5;
    for( j = 0; j &lt; WORLD_X; j++ )
    {
      D3DXMatrixTranslation(&amp;matWorld,xPos,0,zPos);
//    if( 0 == iWallMap[i][j] )
      {
        pDevice-&gt;SetTransform(D3DTS_WORLD,&amp;matWorld);
        pDevice-&gt;DrawPrimitive(D3DPT_TRIANGLELIST,0,NUM_CEIL_TRI);
      }
    xPos += 2;
    }
    zPos -= 2;
  }

  pDevice-&gt;SetStreamSource(0,m_pVBWall,0,sizeof(VERTEX));
  pDevice-&gt;SetTexture(0,m_pTextures[0]);

  for( i = 0,zPos = 5; i &lt; WORLD_Y; i++ )
  {
    xPos = -5;
    for( j = 0; j &lt; WORLD_X; j++ )
    {
      D3DXMatrixTranslation(&amp;matWorld,xPos,0,zPos);
      if( iWallMap[i][j] != 0 )
      {
        pDevice-&gt;SetTransform(D3DTS_WORLD,&amp;matWorld);
        pDevice-&gt;DrawPrimitive(D3DPT_TRIANGLELIST,0,NUM_WALL_TRI);
      }
      xPos += 2;
    }
    zPos -= 2;
  }

  pDevice-&gt;SetTexture(0,NULL);
  Graphics()-&gt;EndScene();
  Graphics()-&gt;Flip();
}

BOOL c3DRoom::DoFrame()
{
  CheckInput();
  RenderScene();
  return( TRUE );
}

c3DRoom::~c3DRoom()
{
  //NOP
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
 LPSTR lpCmdLine,int nShowCmd)
{
  c3DRoom cApp;

  return( cApp.Run() );
}
</pre>
<p>In the next days I will share other projects of mine that I made a while ago. If you want to stay updated, you can <a title="Subscribe by email" rel="nofollow" href="http://feedburner.google.com/fb/a/mailverify?uri=codentronix&amp;loc=en_US">subscribe by email</a>.</p>
<p><em>If you like this article please share it by clicking one of the buttons below, follow me on <a title="My twitter" href="http://twitter.com/codentronix" target="_blank">twitter</a>, or <a href="http://feeds.feedburner.com/codentronix" target="_blank">register on my RSS</a> to receive article updates. Thanks!</em></p>
<div class="shr-publisher-579"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/" title="First Android App: Touch Controlled Cube on Samsung Galaxy S2">First Android App: Touch Controlled Cube on Samsung Galaxy S2</a></li><li><a href="http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/" title="5 Cool OpenGL Demos in VB.NET">5 Cool OpenGL Demos in VB.NET</a></li><li><a href="http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/" title="3D Starfield in HTML5 Canvas">3D Starfield in HTML5 Canvas</a></li><li><a href="http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/" title="How to Draw A Cube Using PHP">How to Draw A Cube Using PHP</a></li><li><a href="http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/" title="3D Starfield made using Python and Pygame">3D Starfield made using Python and Pygame</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/58QE8DRHNQc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/</feedburner:origLink></item>
		<item>
		<title>How to Draw A Cube Using PHP</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/9t3FD9tBgms/</link>
		<comments>http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 21:22:37 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[GD]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php tips]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=558</guid>
		<description><![CDATA[PHP is one of the most used languages for web development, and it is often used to generate HTML pages. Today, I will show you how to use it to make something different. We will make a script to draw &#8230;<p class="read-more"><a href="http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>PHP is one of the most used languages for web development, and it is often used to generate HTML pages. Today, I will show you how to use it to make something different. We will make a script to draw a 3D cube.</p>
<p><strong>The image below shows an output from the PHP script. Click the image to draw another cube.</strong></p>
<iframe src="http://codentronix.com/projects/php/tricks/php_cube.html" width="450" height="350" frameborder="0"> </iframe>
<p><span id="more-558"></span></p>
<p><strong>NOTE:</strong> PHP is often used to output text content, however it can also output images (really, it can output pretty much anything). To draw images I relied on the GD library. If you have never used the GD library, consider reading the tutorial <a title="Generating Images with PHP" href="http://codentronix.com/2011/04/17/generating-images-with-php/">Generating Images with PHP</a>.</p>
<h2>Code</h2>
<p>Before checking the code let me remember you that a cube is made of 8 vertices and 6 faces. I guess the code is pretty much self-explanatory, so I will not give too much detail.</p>
<p>When drawing the cube, we must draw only the faces that are visible. In 3D computer graphics theory, this is called the &#8220;visibility problem&#8221;, and there are some algorithms, called hidden surface algorithms, which solve this problem. The Painter&#8217;s Algorithm is one of them, and solves the problem drawing the faces from back to front. To do this, we calculate the average Z value of each face, then we sort them, and finally we draw them in descending order of the Z value.</p>
<pre class="brush: php; gutter: false; title: ; notranslate">
&lt;?php
/**
 * This script draws and outputs a Cube.
 *
 * The GD library is used to draw the cube and output it as a
 * PNG image.
 *
 * Developed by Leonel Machava &lt;leonelmachava@gmail.com&gt;
 * http://codentronix.com
 *
 * This code is released under the &quot;MIT License&quot; available at
 * http://www.opensource.org/licenses/mit-license.php
 */

/* Represents points in 3D space. */
class Point3D {
  public $x;
  public $y;
  public $z;

  public function __construct($x,$y,$z) {
    $this-&gt;x = $x;
    $this-&gt;y = $y;
    $this-&gt;z = $z;
  }

  public function rotateX($angle) {
    $rad = $angle * M_PI / 180;
    $cosa = cos($rad);
    $sina = sin($rad);
    $y = $this-&gt;y * $cosa - $this-&gt;z * $sina;
    $z = $this-&gt;y * $sina + $this-&gt;z * $cosa;
    return new Point3D($this-&gt;x, $y, $z);
  }

  public function rotateY($angle) {
    $rad = $angle * M_PI / 180;
    $cosa = cos($rad);
    $sina = sin($rad);
    $z = $this-&gt;z * $cosa - $this-&gt;x * $sina;
    $x = $this-&gt;z * $sina + $this-&gt;x * $cosa;
    return new Point3D($x, $this-&gt;y, $z);
  }

  public function rotateZ($angle) {
    $rad = $angle * M_PI / 180;
    $cosa = cos($rad);
    $sina = sin($rad);
    $x = $this-&gt;x * $cosa - $this-&gt;y * $sina;
    $y = $this-&gt;x * $sina + $this-&gt;y * $cosa;
    return new Point3D($x, $y, $this-&gt;z);
  }

  public function project($width,$height,$fov,$viewerDistance) {
    $factor = (float)($fov) / ($viewerDistance + $this-&gt;z);
    $x = $this-&gt;x * $factor + $width / 2;
    $y = -$this-&gt;y * $factor + $height / 2;
    return new Point3D($x,$y,$this-&gt;z);
  }
}

/* Define the 8 vertices of the cube. */
$vertices = array(
  new Point3D(-1,1,-1),
  new Point3D(1,1,-1),
  new Point3D(1,-1,-1),
  new Point3D(-1,-1,-1),
  new Point3D(-1,1,1),
  new Point3D(1,1,1),
  new Point3D(1,-1,1),
  new Point3D(-1,-1,1)
);

/* Define the vertices that compose each of the 6 faces. These numbers are
   indices to the vertex list defined above. */
$faces = array(array(0,1,2,3),array(1,5,6,2),array(5,4,7,6),array(4,0,3,7),array(0,4,5,1),array(3,2,6,7));

/* Define colors for each face. */
$colors = array(array(255,0,255),array(255,0,0),array(0,255,0),array(0,0,255),array(0,255,255),array(255,255,0));

/* Create the image. */
$im = imagecreatetruecolor(400,300);

$im_colors = array();

foreach( $colors as $color ) {
  $im_colors[] = imagecolorallocate($im,$color[0],$color[1],$color[2]);
}

/* Assign random values for the angles that describe the cube orientation. */
$angleX = rand() * 15;
$angleZ = rand() * -30;
$angleY = rand() * -30;

/* It will store transformed vertices. */
$t = array();

/* Transform all the vertices. */
foreach( $vertices as $v ) {
  $t[] = $v-&gt;rotateX($angleX)-&gt;rotateY($angleY)-&gt;rotateZ($angleZ)-&gt;project(400,300,256,4);
}

/* When drawing the cube we must be careful to draw only the faces that are visible.
   We do that by using the Painter's Algorithm, which consists in drawing the faces
   from back to front.
   Note that other algorithms do exist, and are classified as HIDDEN SURFACE REMOVAL
   ALGORITHMS. */

/* It will store the average Z value of each face. */
$avgZ = array();

/* Calculate the average Z value of each face. */
foreach( $faces as $index=&gt;$f ) {
  $avgZ[&quot;$index&quot;] = ($t[$f[0]]-&gt;z + $t[$f[1]]-&gt;z + $t[$f[2]]-&gt;z + $t[$f[3]]-&gt;z) / 4.0;
}

/* Sort the array in descending order. */
arsort($avgZ);

/* Draw the faces from back to front. */
foreach( $avgZ as $index=&gt;$z ) {
  $f = $faces[$index];
  $points = array(
    $t[$f[0]]-&gt;x,$t[$f[0]]-&gt;y,
    $t[$f[1]]-&gt;x,$t[$f[1]]-&gt;y,
    $t[$f[2]]-&gt;x,$t[$f[2]]-&gt;y,
    $t[$f[3]]-&gt;x,$t[$f[3]]-&gt;y
  );
  imagefilledpolygon($im,$points,4,$im_colors[$index]);
}

/* Tell the browser/client we are outputing a PNG image. */
header(&quot;Content-Type: image/png&quot;);

/* Output the image. */
imagepng($im);
</pre>
<p><em>If you like this article please share it by clicking one of the buttons below, follow me on <a title="My twitter" href="http://twitter.com/codentronix" target="_blank">twitter</a>, or <a href="http://feeds.feedburner.com/codentronix" target="_blank">register on my RSS</a> to receive article updates. Thanks!</em></p>
<div class="shr-publisher-558"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/04/17/generating-images-with-php/" title="Generating Images with PHP">Generating Images with PHP</a></li><li><a href="http://codentronix.com/2011/10/08/first-android-app-touch-controlled-cube-on-samsung-galaxy-s2/" title="First Android App: Touch Controlled Cube on Samsung Galaxy S2">First Android App: Touch Controlled Cube on Samsung Galaxy S2</a></li><li><a href="http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/" title="5 Cool OpenGL Demos in VB.NET">5 Cool OpenGL Demos in VB.NET</a></li><li><a href="http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/" title="3D Starfield in HTML5 Canvas">3D Starfield in HTML5 Canvas</a></li><li><a href="http://codentronix.com/2011/06/18/a-simple-3d-room-made-with-directx-and-c/" title="A Simple 3D Room made with DirectX and C++">A Simple 3D Room made with DirectX and C++</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/9t3FD9tBgms" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/</feedburner:origLink></item>
		<item>
		<title>Arduino LED Bar Graph with a 4017 Counter and Potentiometer</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/a3w7y0Gr6Jg/</link>
		<comments>http://codentronix.com/2011/06/05/arduino-led-bar-graph-with-a-4017-counter-and-potentiometer/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 18:34:03 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[4017]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[LED]]></category>
		<category><![CDATA[potentiometer]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=505</guid>
		<description><![CDATA[In this tutorial I will show you how to drive a LED bar graph using an arduino and a potentiometer. This is fairly easy to do and a nice tutorial about it already exists on the arduino website. This tutorial &#8230;<p class="read-more"><a href="http://codentronix.com/2011/06/05/arduino-led-bar-graph-with-a-4017-counter-and-potentiometer/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>In this tutorial I will show you how to drive a LED bar graph using an arduino and a potentiometer. This is fairly easy to do and a <a href="http://www.arduino.cc/en/Tutorial/BarGraph" rel="nofollow" target="_blank">nice tutorial</a> about it already exists on the arduino website. This tutorial will be different in that we will use a 4017 counter to save pins from the microcontroller. Additionally, I will demonstrate the concept of &#8220;persistence of vision&#8221;.</p>
<p>See below a video of the circuit in action.</p>
<iframe width="560" height="349" src="http://www.youtube.com/embed/F-hTrOj0SPo?rel=0" frameborder="0" allowfullscreen></iframe>
<p><span id="more-505"></span></p>
<p><em>If you are able to reproduce this project, have any question, correction, or suggestion, please, let me know by leaving a comment.</em></p>
<h2>Hardware Required</h2>
<ul>
<li>Arduino board</li>
<li>(1) Rotary Potentiometer</li>
<li>(1) 4017 Decade Counter</li>
<li>Breadboard</li>
<li>Some wires</li>
</ul>
<h2>Schematic</h2>
<div class="wp-caption alignnone" style="width: 484px"><a href="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_pot_schem.png"><img class=" " title="Arduino LED Bar Graph Driven with a 4017 Counter and a Potentiometer" src="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_pot_schem.png" alt="Arduino LED Bar Graph Driven with a 4017 Counter and a Potentiometer" width="474" height="350" /></a><p class="wp-caption-text">(Click the image to enlarge)</p></div>
<p><strong>This is how it works:</strong></p>
<p>The 10 LEDs are wired to the outputs of the 4017 counter. There is no need to protect them with current limiting resistors because the maximum current per pin is 10 mA. The arduino controls the 4017 counter using just 2 digital pins: digital pin 2 is connected to the counter&#8217;s clock pin, and the digital pin 3 is connected to the counter&#8217;s reset pin. The arduino runs a program that reads the analog input from the potentiometer (returning a value between 0 and 1023). The value read is mapped to the range 0-9 and is used to decide the number of LEDs to turn on.</p>
<p>Using the counter we face the limitation of not being able to turn on more than one LED at the same time. To solve this, we quickly turn on/off the LEDs in succession, and thanks to the &#8221;<a title="Persistence of Vision on Wikipedia" href="http://en.wikipedia.org/wiki/Persistence_of_vision" rel="nofollow" target="_blank">persistence of vision</a>&#8221; effect, all the LEDs appear to be on at the same time.</p>
<p>Below is the picture of the circuit in real life.</p>
<div class="wp-caption alignnone" style="width: 490px"><a href="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_pot_real.JPG"><img class=" " title="Arduino LED Bar Graph with a 4017 Counter and Potentiometer" src="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_pot_real.JPG" alt="Arduino LED Bar Graph with a 4017 Counter and Potentiometer" width="480" height="360" /></a><p class="wp-caption-text">(Click the image to enlarge)</p></div>
<h2>CODE</h2>
<pre class="brush: cpp; gutter: false; title: ; notranslate">
/*
 * LED Bar Graph controlled with an external potentiometer.
 *
 * A 4017 counter is used to save pins on the arduino.
 * The technique of &quot;Persistence of vision&quot; is used to turn on
 * many LEDs at the same time.
 *
 * Developed by Leonel Machava
 * http://codentronix.com
 *
 * This code is release under the &quot;MIT License&quot; available at
 * http://www.opensource.org/licenses/mit-license.php
 */

/* Digital pin connected to the counter's clock pin */
int clockPin = 2;

/* Digital pin connected to the counter's reset pin */
int resetPin = 3;

/* Analog pin connected to the potentiometer wiper */
int potPin = 0;

void setup() {
  pinMode(clockPin,OUTPUT);
  pinMode(resetPin,OUTPUT);
  reset();
}

void loop() {
  /* Read the analog value from the potentiometer. */
  int potValue = analogRead(potPin);

  /* Map the value to the range 0-9. */
  int n = potValue * 10 / 1024;

  /* Turn ON/OFF quickly the first n LEDs. The n LEDs
     will appear to be ON at the same time due to the
     &quot;persistence of vision&quot; effect. */
  for( int i = 0; i &lt; n; i++ ) {
    clock();
  }

  reset();
}

/*
 * Sends a clock pulse to the counter making it advance.
 */
void clock() {
  digitalWrite(clockPin,HIGH);
  delay(1);
  digitalWrite(clockPin,LOW);
}

/*
 * Resets the counter making it start counting from zero.
 */
void reset() {
  digitalWrite(resetPin,HIGH);
  delay(1);
  digitalWrite(resetPin,LOW);
}
</pre>
<p><a title="Link to the Source Code" href="http://goo.gl/Uef1l">Click here</a> to download the source code (<em>arduino_led_bar_graph_4017_pot.pde / 1.38 Kb</em>)</p>
<p><em>If you like this article please share it by clicking one of the buttons below, follow me on <a title="My twitter" href="http://twitter.com/codentronix" target="_blank">twitter</a>, or <a href="http://feeds.feedburner.com/codentronix" target="_blank">register on my RSS</a> to receive article updates. Thanks!</em></p>
<div class="shr-publisher-505"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/06/05/arduino-led-bar-graph-driven-by-a-4017-counter/" title="Arduino LED Bar Graph Driven by a 4017 Counter">Arduino LED Bar Graph Driven by a 4017 Counter</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/a3w7y0Gr6Jg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/06/05/arduino-led-bar-graph-with-a-4017-counter-and-potentiometer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/06/05/arduino-led-bar-graph-with-a-4017-counter-and-potentiometer/</feedburner:origLink></item>
		<item>
		<title>Arduino LED Bar Graph Driven by a 4017 Counter</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/Duh5ZLknP6M/</link>
		<comments>http://codentronix.com/2011/06/05/arduino-led-bar-graph-driven-by-a-4017-counter/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 02:21:33 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[4017]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[LED]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=507</guid>
		<description><![CDATA[In this tutorial, my primary objective is to show you how to make a simple LED animation using a LED bar graph and an Arduino. My secondary objective is to share with you a trick to save pins of the &#8230;<p class="read-more"><a href="http://codentronix.com/2011/06/05/arduino-led-bar-graph-driven-by-a-4017-counter/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>In this tutorial, my primary objective is to show you how to make a simple LED animation using a LED bar graph and an <a title="Arduino Website" rel="nofollow" href="http://arduino.cc" target="_blank">Arduino</a>. My secondary objective is to share with you a trick to save pins of the Arduino using a 4017 decade counter circuit. The video below shows what we will be making.</p>
<iframe width="560" height="349" src="http://www.youtube.com/embed/P9s0vfk-uII?rel=0" frameborder="0" allowfullscreen></iframe>
<p>&nbsp;</p>
<p><span id="more-507"></span></p>
<p><em>If you are able to reproduce this project, have any doubt, correction, or suggestion, please, let me know by leaving a comment.</em></p>
<h2>Hardware Required</h2>
<ul>
<li>Arduino board.</li>
<li>(1) LED bar graph (or alternatively 10 LEDs)</li>
<li>(1) 4017 Decade Counter IC</li>
<li>Some wires</li>
<li>Breadboard</li>
</ul>
<h2>Schematic</h2>
<div class="wp-caption alignnone" style="width: 414px"><a href="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_schem.png"><img title="Arduino LED Bar Graph with a 4017 Counter" src="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_schem.png" alt="Arduino LED Bar Graph with a 4017 Counter" width="404" height="350" /></a><p class="wp-caption-text">(Click the image to enlarge)</p></div>
<p>As you can see, using the 4017 counter we just need one digital pin from the arduino. Otherwise, we would need 10 pins from the arduino.</p>
<p>This is how it works: the LEDs of the bar graph are wired to the 10 outputs of the 4017 counter. The clock pin from the counter is wired to the arduino. When the arduino is running, it sends clock pulses to the counter making it advance. When the counter advances, the current LED is turned OFF, and the next one is turned ON. See below the picture of the circuit in real life.</p>
<div class="wp-caption alignnone" style="width: 490px"><a href="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_real.JPG"><img class=" " title="The real life circuit" src="http://codentronix.com/projects/electronics/arduino/led_bar_graph/arduino_led_bar_graph_4017_real.JPG" alt="Arduino LED Bar graph driven by a 4017 counter" width="480" height="360" /></a><p class="wp-caption-text">(Click the image to enlarge)</p></div>
<p><span style="font-size: 20px; font-weight: bold;">Code</span></p>
<pre class="brush: cpp; gutter: false; title: ; notranslate">
/*
 * Simple LED Bar graph animation using a 4017 counter.
 * The 4017 is used to save pins on the arduino.
 *
 * Developed by Leonel Machava
 * http://codentronix.com
 *
 * This code is release under the &quot;MIT License&quot; available at
 * http://www.opensource.org/licenses/mit-license.php
 */

/* PIN used to send clock pulses to the counter. */
int clockPin = 2;

void setup() {
  pinMode(clockPin,OUTPUT);
}

/*
 * Sends a clock pulse to the counter making it advance.
 */
void clock() {
  digitalWrite(clockPin,HIGH);
  delay(1);
  digitalWrite(clockPin,LOW);
}

void loop() {
  /* Send a clock pulse to the counter. It makes the counter advance
     causing the current LED to be turned off, and the next one to be
     turned ON */
  clock();
  /* Wait for 300 ms. */
  delay(300);
}
</pre>
<p><a title="Link to the source code" href="http://goo.gl/BQ4Zk">Click here</a> to download the source (<em>arduino_led_bar_graph_4017.pde / 1KB</em>)</p>
<p><strong>NOTE:</strong> This animation can also be made using just a LED bar graph, a 555 timer, and a counter. My main aim in this tutorial was to share with the arduino fans how to make it using an arduino. Additionally, as said in the beginning, my secondary objective was to show a method of saving pins on the arduino, and I did it using a 4017 counter. An alternative way of saving pins would be through the use of 595 shift registers, but for this case it would not be better than using a 4017 counter because we would need 3 pins from the arduino and 2 shift registers.</p>
<p><em>If you like this article please share it by clicking one of the buttons below, follow me on <a title="My twitter" href="http://twitter.com/codentronix" target="_blank">twitter</a>, or <a href="http://feeds.feedburner.com/codentronix" target="_blank">register on my RSS</a> to receive article updates. Thanks!</em></p>
<div class="shr-publisher-507"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/06/05/arduino-led-bar-graph-with-a-4017-counter-and-potentiometer/" title="Arduino LED Bar Graph with a 4017 Counter and Potentiometer">Arduino LED Bar Graph with a 4017 Counter and Potentiometer</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/Duh5ZLknP6M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/06/05/arduino-led-bar-graph-driven-by-a-4017-counter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/06/05/arduino-led-bar-graph-driven-by-a-4017-counter/</feedburner:origLink></item>
		<item>
		<title>3D Starfield made using Python and Pygame</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/U3isNSY2vDM/</link>
		<comments>http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/#comments</comments>
		<pubDate>Sat, 28 May 2011 17:53:58 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[Computer Graphics]]></category>
		<category><![CDATA[Pygame]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[starfield]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=462</guid>
		<description><![CDATA[In this tutorial I will show you how to create a pretty cool 3D Starfield simulation using Python and Pygame.<p class="read-more"><a href="http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>In this tutorial I will show you how to create a pretty cool 3D Starfield simulation using Python and Pygame. See in the video below a demonstration of the simulation.</p>
<iframe width="480" height="390" src="http://www.youtube.com/embed/Q_tKrwUMR78?rel=0" frameborder="0"></iframe><p>&nbsp;</p>
<p><a title="Link to the full source code." href="http://goo.gl/7jzR1">Click here</a> to download the full source code.</p>
<p>NOTE: In previous tutorials, I have demonstrated how to create a <a title="Simple Starfield with Python and Pygame" href="http://codentronix.com/2011/04/24/simple-starfield-with-python-and-pygame/">Simple Starfield</a> as well as how to create a <a title="A Cool Parallax Starfield Simulation using Python" href="http://codentronix.com/2011/04/27/a-cool-parallax-starfield-simulation-using-python/">Parallax Starfield</a>.</p>
<h2>The Code</h2>
<p>To simulate the effect of a 3D starfield, we initially create a list of stars that are randomly positioned in the world. Each star is represented as a 3D coordinate, I mean, for each star we just store its X,Y and Z coordinates. Then we start the animation loop where we decrease the star&#8217;s Z coordinates on each frame. Decreasing the Z coordinate of a star makes it appear to be approaching the screen. When a star disappears from the screen, we reposition it again in the screen giving it random X and Y coordinates, and setting Z = maximum depth.</p>
<p>To make it even more interesting, we make closer stars bigger than distant stars. Similarly, we make closer stars brighter than the distant ones.</p>
<p>Since the stars are represented as 3D coordinates, they must be converted to 2D before being drawn into the screen. The code does that  using perspective projection formulas.</p>
<p>The code is presented below. As you can see, the simulation is made with very few lines of code. If you have any doubt or suggestion, please don&#8217;t hesitate to leave a comment.</p>
<pre class="brush: python; gutter: false; title: ; notranslate">
&quot;&quot;&quot;
 3D Starfield Simulation
 Developed by Leonel Machava &lt;leonelmachava@gmail.com&gt;

http://codeNtronix.com

http://twitter.com/codentronix

&quot;&quot;&quot;
import pygame, math
from random import randrange

class Simulation:
    def __init__(self, num_stars, max_depth):
        pygame.init()

        self.screen = pygame.display.set_mode((640, 480))
        pygame.display.set_caption(&quot;3D Starfield Simulation (visit codeNtronix.com)&quot;)

        self.clock = pygame.time.Clock()
        self.num_stars = num_stars
        self.max_depth = max_depth

        self.init_stars()

    def init_stars(self):
        &quot;&quot;&quot; Create the starfield &quot;&quot;&quot;
        self.stars = []
        for i in range(self.num_stars):
            # A star is represented as a list with this format: [X,Y,Z]
            star = [randrange(-25,25), randrange(-25,25), randrange(1, self.max_depth)]
            self.stars.append(star)

    def move_and_draw_stars(self):
        &quot;&quot;&quot; Move and draw the stars &quot;&quot;&quot;
        origin_x = self.screen.get_width() / 2
        origin_y = self.screen.get_height() / 2

        for star in self.stars:
            # The Z component is decreased on each frame.
            star[2] -= 0.19

            # If the star has past the screen (I mean Z&lt;=0) then we
            # reposition it far away from the screen (Z=max_depth)
            # with random X and Y coordinates.
            if star[2] &lt;= 0:
                star[0] = randrange(-25,25)
                star[1] = randrange(-25,25)
                star[2] = self.max_depth

            # Convert the 3D coordinates to 2D using perspective projection.
            k = 128.0 / star[2]
            x = int(star[0] * k + origin_x)
            y = int(star[1] * k + origin_y)

            # Draw the star (if it is visible in the screen).
            # We calculate the size such that distant stars are smaller than
            # closer stars. Similarly, we make sure that distant stars are
            # darker than closer stars. This is done using Linear Interpolation.
            if 0 &lt;= x &lt; self.screen.get_width() and 0 &lt;= y &lt; self.screen.get_height():
                size = (1 - float(star[2]) / self.max_depth) * 5
                shade = (1 - float(star[2]) / self.max_depth) * 255
                self.screen.fill((shade,shade,shade),(x,y,size,size))

    def run(self):
        &quot;&quot;&quot; Main Loop &quot;&quot;&quot;
        while 1:
            # Lock the framerate at 50 FPS.
            self.clock.tick(50)

            # Handle events.
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    return

            self.screen.fill((0,0,0))
            self.move_and_draw_stars()
            pygame.display.flip()

if __name__ == &quot;__main__&quot;:
    Simulation(512, 32).run()
</pre>
<p><a title="Link to the full source code." href="http://goo.gl/7jzR1">Click here</a> to download the full source code.</p>
<p><em>If you liked this article, please consider leaving a comment, or sharing this post using one of the buttons below, or even <a href="http://feeds.feedburner.com/codentronix">subscribing to the blog</a>.</em></p>
<div class="shr-publisher-462"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/05/12/rotating-3d-cube-using-python-and-pygame/" title="Rotating 3D Cube using Python and Pygame">Rotating 3D Cube using Python and Pygame</a></li><li><a href="http://codentronix.com/2011/04/27/a-cool-parallax-starfield-simulation-using-python/" title="A Cool Parallax Starfield Simulation using Python">A Cool Parallax Starfield Simulation using Python</a></li><li><a href="http://codentronix.com/2011/04/24/simple-starfield-with-python-and-pygame/" title="Simple Starfield with Python and Pygame">Simple Starfield with Python and Pygame</a></li><li><a href="http://codentronix.com/2011/04/21/rotating-3d-wireframe-cube-with-python/" title="Rotating 3D Wireframe Cube with Python">Rotating 3D Wireframe Cube with Python</a></li><li><a href="http://codentronix.com/2011/04/20/simulation-of-3d-point-rotation-with-python-and-pygame/" title="Simulation of 3D Point Rotation with Python and Pygame">Simulation of 3D Point Rotation with Python and Pygame</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/U3isNSY2vDM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/</feedburner:origLink></item>
		<item>
		<title>Rotating Solid Cube Using VB.NET and GDI+</title>
		<link>http://feedproxy.google.com/~r/codentronix/~3/geyLnfq3wDU/</link>
		<comments>http://codentronix.com/2011/05/25/rotating-solid-cube-using-vb-net-and-gdi/#comments</comments>
		<pubDate>Wed, 25 May 2011 11:30:36 +0000</pubDate>
		<dc:creator>lefam</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Computer Graphics]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[GDI+]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[visual basic]]></category>

		<guid isPermaLink="false">http://codentronix.com/?p=447</guid>
		<description><![CDATA[In my last tutorial I have shown how to make a wireframe cube using VB.NET and GDI+. Today, we will work on the code from that tutorial in order to make a rotating solid cube.<p class="read-more"><a href="http://codentronix.com/2011/05/25/rotating-solid-cube-using-vb-net-and-gdi/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>In my last tutorial I have shown how to make a <a title="Rotating Wireframe Cube using VB.NET and GDI+" href="http://codentronix.com/2011/05/24/rotating-wireframe-cube-using-vb-net-and-gdi/">wireframe cube using VB.NET and GDI+</a>. Today, we will build from the code from the last tutorial in order to make a rotating solid cube. The video below shows what we will achieve after finishing the tutorial.</p>
<p><object width="400" height="300"><param name="movie" value="http://www.youtube.com/v/P_vyg7rDE5A?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/P_vyg7rDE5A?version=3" type="application/x-shockwave-flash" width="400" height="300" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>THE FULL SOURCE CODE IS <a title="Link to the Full Source Code" href="http://goo.gl/cyplT">HERE</a>.</p>
<h2>The Code</h2>
<p>The original code was divided in 2 files [<strong>Point3D.vb</strong> and <strong>Main.vb</strong>]. The Point3D.vb file  defined the Point3D class which represents points in 3D space. The file Main.vb defined the Window form where the simulation runs.</p>
<p>The class Point3D remains unchanged and is presented below.</p>
<pre class="brush: vb; title: ; notranslate">
'
' Defines the Point3D class that represents points in 3D space.
' Developed by leonelmachava &lt;leonelmachava@gmail.com&gt;
' http://codentronix.com
'
' Copyright (c) 2011 Leonel Machava
'
Option Explicit On

Public Class Point3D
    Protected m_x As Double, m_y As Double, m_z As Double

    Public Sub New(ByVal x As Double, ByVal y As Double, ByVal z As Double)
        Me.X = x
        Me.Y = y
        Me.Z = z
    End Sub

    Public Property X() As Double
        Get
            Return m_x
        End Get
        Set(ByVal value As Double)
            m_x = value
        End Set
    End Property

    Public Property Y() As Double
        Get
            Return m_y
        End Get
        Set(ByVal value As Double)
            m_y = value
        End Set
    End Property

    Public Property Z() As Double
        Get
            Return m_z
        End Get
        Set(ByVal value As Double)
            m_z = value
        End Set
    End Property

    Public Function RotateX(ByVal angle As Integer) As Point3D
        Dim rad As Double, cosa As Double, sina As Double, yn As Double, zn As Double

        rad = angle * Math.PI / 180
        cosa = Math.Cos(rad)
        sina = Math.Sin(rad)
        yn = Me.Y * cosa - Me.Z * sina
        zn = Me.Y * sina + Me.Z * cosa
        Return New Point3D(Me.X, yn, zn)
    End Function

    Public Function RotateY(ByVal angle As Integer) As Point3D
        Dim rad As Double, cosa As Double, sina As Double, Xn As Double, Zn As Double

        rad = angle * Math.PI / 180
        cosa = Math.Cos(rad)
        sina = Math.Sin(rad)
        Zn = Me.Z * cosa - Me.X * sina
        Xn = Me.Z * sina + Me.X * cosa

        Return New Point3D(Xn, Me.Y, Zn)
    End Function

    Public Function RotateZ(ByVal angle As Integer) As Point3D
        Dim rad As Double, cosa As Double, sina As Double, Xn As Double, Yn As Double

        rad = angle * Math.PI / 180
        cosa = Math.Cos(rad)
        sina = Math.Sin(rad)
        Xn = Me.X * cosa - Me.Y * sina
        Yn = Me.X * sina + Me.Y * cosa
        Return New Point3D(Xn, Yn, Me.Z)
    End Function

    Public Function Project(ByVal viewWidth, ByVal viewHeight, ByVal fov, ByVal viewDistance)
        Dim factor As Double, Xn As Double, Yn As Double
        factor = fov / (viewDistance + Me.Z)
        Xn = Me.X * factor + viewWidth / 2
        Yn = Me.Y * factor + viewHeight / 2
        Return New Point3D(Xn, Yn, Me.Z)
    End Function
End Class
</pre>
<p>The file Main.vb has suffered some changes. See below its code.</p>
<pre class="brush: vb; title: ; notranslate">
'
' Simulation of a Rotating Cube using GDI+
' Developed by leonelmachava &lt;leonelmachava@gmail.com&gt;
' http://codentronix.com
'
' Copyright (c) 2011 Leonel Machava
'
Imports System.Drawing.Graphics
Imports System.Drawing.Pen
Imports System.Drawing.Color
Imports System.Drawing.Brush
Imports System.Drawing.Point
Imports System.Drawing.Bitmap

Public Class Main
    Protected m_timer As Timer
    Protected m_vertices(8) As Point3D
    Protected m_faces(6, 4) As Integer
    Protected m_colors(6) As Color
    Protected m_brushes(6) As Brush
    Protected m_angle As Integer

    Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Enable double-buffering to eliminate flickering.
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)

        InitCube()

        ' Create the timer.
        m_timer = New Timer()

        ' Set the timer interval to 25 milliseconds. This will give us 1000/25 ~ 40 frames per second.
        m_timer.Interval = 25

        ' Set the callback for the timer.
        AddHandler m_timer.Tick, AddressOf AnimationLoop

        ' Start the timer.
        m_timer.Start()
    End Sub

    Private Sub InitCube()
        ' Create the cube vertices.
        m_vertices = New Point3D() {
                     New Point3D(-1, 1, -1),
                     New Point3D(1, 1, -1),
                     New Point3D(1, -1, -1),
                     New Point3D(-1, -1, -1),
                     New Point3D(-1, 1, 1),
                     New Point3D(1, 1, 1),
                     New Point3D(1, -1, 1),
                     New Point3D(-1, -1, 1)}

        ' Create an array representing the 6 faces of a cube. Each face is composed by indices to the vertex array
        ' above.
        m_faces = New Integer(,) {{0, 1, 2, 3}, {1, 5, 6, 2}, {5, 4, 7, 6}, {4, 0, 3, 7}, {0, 4, 5, 1}, {3, 2, 6, 7}}

        ' Define the colors of each face.
        m_colors = New Color() {Color.BlueViolet, Color.Cyan, Color.Green, Color.Yellow, Color.Violet, Color.LightSkyBlue}

        ' Create the brushes to draw each face. Brushes are used to draw filled polygons.
        For i = 0 To 5
            m_brushes(i) = New SolidBrush(m_colors(i))
        Next
    End Sub

    Private Sub AnimationLoop()
        ' Forces the Paint event to be called.
        Me.Invalidate()

        ' Update the variable after each frame.
        m_angle += 1
    End Sub

    Private Sub Main_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        Dim t(8) As Point3D
        Dim f(4) As Integer
        Dim v As Point3D
        Dim avgZ(6) As Double
        Dim order(6) As Integer
        Dim tmp As Double
        Dim iMax As Integer

        ' Clear the window
        e.Graphics.Clear(Color.LightBlue)

        ' Transform all the points and store them on the &quot;t&quot; array.
        For i = 0 To 7
            Dim b As Brush = New SolidBrush(Color.White)
            v = m_vertices(i)
            t(i) = v.RotateX(m_angle).RotateY(m_angle).RotateZ(Me.m_angle)
            t(i) = t(i).Project(Me.ClientSize.Width, Me.ClientSize.Height, 256, 4)
        Next

        ' Compute the average Z value of each face.
        For i = 0 To 5
            avgZ(i) = (t(m_faces(i, 0)).Z + t(m_faces(i, 1)).Z + t(m_faces(i, 2)).Z + t(m_faces(i, 3)).Z) / 4.0
            order(i) = i
        Next

        ' Next we sort the faces in descending order based on the Z value.
        ' The objective is to draw distant faces first. This is called
        ' the PAINTERS ALGORITHM. So, the visible faces will hide the invisible ones.
        ' The sorting algorithm used is the SELECTION SORT.
        For i = 0 To 4
            iMax = i
            For j = i + 1 To 5
                If avgZ(j) &gt; avgZ(iMax) Then
                    iMax = j
                End If
            Next
            If iMax &lt;&gt; i Then
                tmp = avgZ(i)
                avgZ(i) = avgZ(iMax)
                avgZ(iMax) = tmp

                tmp = order(i)
                order(i) = order(iMax)
                order(iMax) = tmp
            End If
        Next

        ' Draw the faces using the PAINTERS ALGORITHM (distant faces first, closer faces last).
        For i = 0 To 5
            Dim points() As Point
            Dim index As Integer = order(i)
            points = New Point() {
                New Point(CInt(t(m_faces(index, 0)).X), CInt(t(m_faces(index, 0)).Y)),
                New Point(CInt(t(m_faces(index, 1)).X), CInt(t(m_faces(index, 1)).Y)),
                New Point(CInt(t(m_faces(index, 2)).X), CInt(t(m_faces(index, 2)).Y)),
                New Point(CInt(t(m_faces(index, 3)).X), CInt(t(m_faces(index, 3)).Y))
            }
            e.Graphics.FillPolygon(m_brushes(index), points)
        Next
    End Sub
End Class
</pre>
<p>The code is pretty much self-explanatory. Below I will just list the key changes.</p>
<p>In the Load event I enable double buffering. This is fundamental to eliminate flickering in the animation. Try to remove the first 2 lines of code, and run the application. You will certainly see the flickering that results.</p>
<p>Basically I have changed the code to draw filled faces instead of lines. However, now we must make sure to draw distant faces first, and closer ones last (<em>Painters Algorithm).</em></p>
<p>THE FULL SOURCE CODE IS <a title="Link to the Full Source Code" href="http://goo.gl/cyplT">HERE</a>.</p>
<h2>Conclusion</h2>
<p>As I have promised in the last tutorial, today I have shown how to make a rotating solid cube. In my next VB.NET tutorial, I will show you how to make a cool game in pretty simple steps.<br />
<em>If you liked this article, please consider leaving a comment, or sharing this post using one of the buttons below, or even <a href="http://feeds.feedburner.com/codentronix">subscribing to the blog</a>.</em></p>
<div class="shr-publisher-447"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic --><h3  class="related_post_title">See Also:</h3><ul class="related_post"><li><a href="http://codentronix.com/2011/05/24/rotating-wireframe-cube-using-vb-net-and-gdi/" title="Rotating Wireframe Cube using VB.NET and GDI+">Rotating Wireframe Cube using VB.NET and GDI+</a></li><li><a href="http://codentronix.com/2011/10/07/5-cool-opengl-demos-in-vb-net/" title="5 Cool OpenGL Demos in VB.NET">5 Cool OpenGL Demos in VB.NET</a></li><li><a href="http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame/" title="3D Starfield made using Python and Pygame">3D Starfield made using Python and Pygame</a></li><li><a href="http://codentronix.com/2011/05/12/rotating-3d-cube-using-python-and-pygame/" title="Rotating 3D Cube using Python and Pygame">Rotating 3D Cube using Python and Pygame</a></li><li><a href="http://codentronix.com/2011/04/27/first-experiment-with-html5-a-wireframe-cube/" title="First Experiment with HTML5: A Wireframe Cube">First Experiment with HTML5: A Wireframe Cube</a></li></ul><img src="http://feeds.feedburner.com/~r/codentronix/~4/geyLnfq3wDU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codentronix.com/2011/05/25/rotating-solid-cube-using-vb-net-and-gdi/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://codentronix.com/2011/05/25/rotating-solid-cube-using-vb-net-and-gdi/</feedburner:origLink></item>
	</channel>
</rss>

