Saturday, May 26, 2012

Three.JS Setup Tutorial

0 comments

Ok guys, so I have been looking at getting back into web development by starting this blog, but mostly I am interested in creating HTML5 web applications. I have been looking at the open source Three.JS library which can use the HTML5 canvas element for rendering or WebGL. I am amazed at how quickly you can get up and running with full access to the GPU with such a short amount of code. I heavily commented it for anyone wishing to learn from it. It is basically the sample found at the Three.JS Github Page but separated and much more thoroughly commented. ;)

Here is the HTML page that we will use to run our javascript to view our 3D Scene:

<doctype html>
<html lang="en">
 <head>
  <title>Three.js WebGL Test</title>
  <meta charset="utf-8">
  <style>
   body 
   {
    margin: 0px;
    background-color: #000000;
    overflow: hidden;
   }
  </style>
 </head>
 <body>
  <noscript>
   <p style="color: #ff0000">
Sorry, you need Javascript in order to view this web app. 
    Please enable it in your browser settings.
   </p>
</noscript>
  <script src="Three.js"></script>
  <script src="WebGLTest.js"></script>
 </body>
</html>

Notice all that is really needed is to include source to the minified Three.js library and after that we're ready to get our own scripting on the go:

/** 
 * WebGLTest.js
 * 
 *  Author: Cory Gross, May 26, 2012
 *  Description: Used to illustrate setting up a WebGL renderer and camera
 *      using Three.js to be displayed using HTML5 technologies. Thoroughly
 *      commented to illustrate the core components of a typical 3D set up.
 **/
var camera, scene, renderer;  //Core Three.JS components
var geometry, material, mesh; //Other globals

/** Simply call the functions created below */
init();
animate();

/** This function is responsible for creating all of our Three.js objects that
 *  that will be part of our scene. The core components and all other global 
 *  variables should be initialized here. */
function init()
{
    scene = new THREE.Scene(); //Scene object holds set of all 3D objects
    
/** We need to define a view frustrum for our camera, this is a 3D region
     *  of space which contains all the points visible to the camera. The field
     *  of view is the angle measured from the y-axis. Objects closer than the
     *  near plane or behind the far plane distance will not be rendered. */

    var FOV = 75;
    var aspectRatio = window.innerWidth / window.innerHeight;
    var near = 1;
    var far = 1000;
    

    /** Initialize our camera with frustrum view data and set position */
    camera = new THREE.PerspectiveCamera(FOV, aspectRatio, near, far);
    camera.position.z = 400; // Positive z axis comes out of screen

    /** Three.JS provides global namespace functions for creating geometry
     *  and core objects such as meshes and materials. */
    geometry = new THREE.CubeGeometry(200, 200, 200);
    material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true});

    /** Apply the material to the geometry to create a 3D mesh object
     *  finally add that to our scene at default position at origin */
    mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);

    /** Three.JS provides several renderers, WebGL is used here so Chrome is
     *  recommended but HTML5 Canvas is also supported along with others. */
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild( renderer.domElement );
}

/** This function does all animation before calling redrawing the scene */
function animate()
{
    /** Three.JS includes requestAnimationFrame shim. This is implemented
        by modern browsers to optimize animations */
    requestAnimationFrame(animate);
    /** Rotate our mesh, slower around x axis, faster around y */
    mesh.rotation.x += 0.005;
    mesh.rotation.y += 0.01;
    /** Redraw the scene based on our camera's projection */
    renderer.render(scene, camera);
}

After this all that is left to do is do is put these two files, along with the minified Three.js file, into a directory of your choice. Or upload it to a webserver and view in your favorite WebGL supported web browser. I will be posting more soon.

Here is my project uploaded to a free web host: check it out

Friday, May 18, 2012

Welcome to the machine...

1 comments
So this is my first post on my new blog. I have had a couple of these where I have posted what I have been working on in the past, always having them hosted privately with funding. This time I have decided to go with Google's Blogger service. I spent just a little time customizing a template to my liking. Everything has to be dark as sunglasses at night.

Anyway, I have been working intensely since summer began a week or so ago on building up my knowledge of network programming (before I started I practically had none). I have learned all about the network stack that most servers have and read up on networking basics and communication protocols. I found some fantastic websites and guides. For anyone interested in this type of thing I highly recommend checking out these when you get time:

Beej's Guide to Network Programming (Sockets)
HTTP Made Really Easy

Both of these are great written guides and you are sure to learn a ton if you haven't had the joy of reading them yet. Anyways.. I read both of those back to front, err... front to.. kind of both ways actually. Earlier this past semester I got to wondering about how much work goes into a modern browser and I read another article which is very informative as well.

How Modern Browsers Work

After I learned a good bit about sockets and got in good with the Winsock2 API. I created a nice program that would take a hostname, use the API to tap into DNS to resolve the hostname to an IP address. At that point the program connect to server on port 80 (default for HTTP protocol) and sends a request to the server.

HTTP requests come in a few forms. You can send a HEAD request which returns a response that basically tells you what kind of content you will receive if you go to that address. My program used a GET request in order to pull the HTML (or other data) from the default page at the given hostname's address. I'm not sure if you can see where this is going, but basically this program is already part of what a browser does. All that is left really is to be able to render HTML.

I am now working with a cross-platform GUI library that is actually capable of rendering a DOM tree (this is what HTML is parsed into). I am now working on a basic text based browser. I plan on making a tutorial or guide when I am finished. The library is called wxWidgets and I mostly chose it for being open-source (my favorite), cross-platform, native C++, and mostly for the ability to render the HTML DOM tree.

Here is a screenshot of the GUI I threw together with a add-on tool called wxFormBuilder:


And here is a screenshot of the console program using sockets and http to pull the html data from a simple test site I set up: