<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Rodrigo Silveira</title>
	<atom:link href="http://www.rodrigo-silveira.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rodrigo-silveira.com</link>
	<description>Hybrid Web Developer &#38; Web Designer</description>
	<lastBuildDate>Wed, 02 May 2012 20:11:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WebGL Inspector: Debug OpenGL on the Browser</title>
		<link>http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/</link>
		<comments>http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 13:29:18 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Fun Projects]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Chromium WebGL]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Free Download]]></category>
		<category><![CDATA[Plug-in]]></category>
		<category><![CDATA[quick tip]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=413</guid>
		<description><![CDATA[Now you can debug your OpenGL or WebGL applications in real-time using this Firebug-like extension for the three major browsers [that work] called WebGL Inspector.]]></description>
			<content:encoded><![CDATA[<p>For those of you who have done any web development at all, you are well aware of tools such as <a href="https://addons.mozilla.org/en-US/firefox/addon/firebug/">Firebug</a>, Google Chrome&#8217;s Developer Tools, and other browser plug-ins that allow you to inspect a web page&#8217;s DOM structure in real time. Normally these tools also allow you to execute Javascript code, check for HTTP requests and statuses, etc., all in real-time.</p>
<p>Now, in case you have also been doing some 3D game programming, or just some WebGL development in general, you are probably hoping and waiting for the day when someone will come around and put out a tool similar to those described above, but one that is aimed at WebGL. I&#8217;m here today to bring you the good news: Now you can debug your OpenGL or WebGL applications in real-time using this Firebug-like extension for the three major browsers [that work] called <a href="http://benvanik.github.com/WebGL-Inspector/">WebGL Inspector</a>.</p>
<p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/webgl-inspector-screenshot/" rel="attachment wp-att-414"><img class="alignleft size-full wp-image-414" title="webgl-inspector-screenshot" src="http://rodrigo-silveira.com/wp-content/uploads/2012/04/webgl-inspector-screenshot.jpg" alt="" width="540" height="308" /></a></p>
<p><span id="more-413"></span>This extension will seem familiar to most who have done any web design work before using available debugging browser tools. To install the plugin, run the following Git command:</p>
<div class="i_code">
<pre>$ git clone git://github.com/benvanik/WebGL-Inspector</pre>
</div>
<p>You can also download the project as a Zip or Tar collection directly from the link above.</p>
<p>With WebGL Inspector, you can see all the buffers used in a given frame, view and even download any and all texture files used, view all the 3D models, and even look at the original fragment and vertex shader programs. While the inspector is meant to be used within a browser context, it can be super helpful to traditional OpenGL developers, since it gives you access to an application&#8217;s inner workings.</p>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/webgl-quake/" rel="bookmark" class="crp_title">Webgl Quake</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-3d-demos/" rel="bookmark" class="crp_title">My First WebGL 3D Demos: Hello, World (of OpenGL)</a></p><p><a href="http://www.rodrigo-silveira.com/gwt-unable-connect/" rel="bookmark" class="crp_title">Google Web Toolkit: Failed to Connect</a></p><p><a href="http://www.rodrigo-silveira.com/html5-stock-market-simulation-php/" rel="bookmark" class="crp_title">HTML5 Stock Market Simulation in PHP</a></p><p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/" rel="bookmark" class="crp_title">3D Programming: Transformation Matrix Tutorial</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Webgl Quake</title>
		<link>http://www.rodrigo-silveira.com/webgl-quake/</link>
		<comments>http://www.rodrigo-silveira.com/webgl-quake/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 03:59:43 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Chromium WebGL]]></category>
		<category><![CDATA[Google Web Toolkit]]></category>
		<category><![CDATA[HTML5 Demo]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=397</guid>
		<description><![CDATA[As a demonstration of the new HTML5 technologies and capabilities, a few cool people from Google used Google Web Toolkit to write a WebGL Quake port. ]]></description>
			<content:encoded><![CDATA[<p>In case you have been offline for the past two years or so, there has been a few improvements and advances on what can be done on a browser, namely doing awesome stuff without a plugin. By that I mean that Flash has been replaced by HTML5. As a demonstration of the new HTML5 technologies and capabilities, a few cool people from Google used Google Web Toolkit to write a WebGL Quake port. Here is a summary of how this has come about:</p>
<h2>GWT Port of Quake: Official Preview</h2>
<p><iframe src="http://www.youtube.com/embed/XhMN0wlITLk" frameborder="0" width="540" height="285"></iframe></p>
<p>&nbsp;</p>
<h2>Official GWT Blog Post</h2>
<p><img class="alignleft size-full wp-image-399" title="webgl-quake-3-official-preview" src="http://rodrigo-silveira.com/wp-content/uploads/2012/04/webgl-quake-3-official-preview.jpg" alt="" width="542" height="329" /></p>
<p><span id="more-397"></span>You can <a href="http://googlewebtoolkit.blogspot.com/2010/04/look-ma-no-plugin.html">read the official post</a> describing this awesome feat. The way they describe what they did was as follows: &#8220;We started with the existing Jake2 Java port of the Quake II engine, then used the Google Web Toolkit(along with WebGL, WebSockets, and a lot of refactoring) to cross-compile it into Javascript.&#8221; You can also checkout a copy of the <a href="http://code.google.com/p/quake2-gwt-port/">GWT project from Google Code</a> and play the game on your own machine, or you can <a href="http://playwebgl.com/games/quake-2-webgl/">play WebGL Quake online</a>.</p>
<h2>WebGL Quake 3 Demo</h2>
<p><a href="http://www.rodrigo-silveira.com/webgl-quake/webgl-quake-3-demo/" rel="attachment wp-att-398"><img class="alignleft size-full wp-image-398" title="webgl-quake-3-demo" src="http://rodrigo-silveira.com/wp-content/uploads/2012/04/webgl-quake-3-demo.jpg" alt="" width="542" height="349" /></a></p>
<p><!--more-->If all else fails, and you have a hard time both playing the game online or getting the repository source code to run on your own computer, I guess you could at least play around with this <a href="http://media.tojicode.com/q3bsp/?tesselate=2">Quake 3 demo</a> written in Javascript and some of the other HTML5 APIs, such as HTML5 audio, web workers, etc. This demo is actually just a map from the game, with clunky controls, and a few options, such as full-screen, background music, etc.</p>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/" rel="bookmark" class="crp_title">WebGL Inspector: Debug OpenGL on the Browser</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-3d-demos/" rel="bookmark" class="crp_title">My First WebGL 3D Demos: Hello, World (of OpenGL)</a></p><p><a href="http://www.rodrigo-silveira.com/sudoku-solver-algorithm-javascript/" rel="bookmark" class="crp_title">Sudoku Solver Algorithm in JavaScript</a></p><p><a href="http://www.rodrigo-silveira.com/gwt-unable-connect/" rel="bookmark" class="crp_title">Google Web Toolkit: Failed to Connect</a></p><p><a href="http://www.rodrigo-silveira.com/html5-stock-market-simulation-php/" rel="bookmark" class="crp_title">HTML5 Stock Market Simulation in PHP</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/webgl-quake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Paper on Extreme Programming</title>
		<link>http://www.rodrigo-silveira.com/research-paper-extreme-programming/</link>
		<comments>http://www.rodrigo-silveira.com/research-paper-extreme-programming/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 03:11:44 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[BYU-I]]></category>
		<category><![CDATA[writting]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=389</guid>
		<description><![CDATA[Extreme Programming is a software development method created by Kent Beck in 1996. It is considered an incremental development method, meaning that a project is completed in small, incremental cycles, where more functionality is added to the software as the project progresses.]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;" align="center">The following is a paper I wrote originally as part of a school assignment during my work at Brigham Young University – Idaho. I attended BYU-I between 2010 and 2012, and ultimately earned by Bachelor’s degree in Computer Science</p>
<h2 style="text-align: left;" align="center">Extreme Programming, by Rodrigo Silveira<em></em></h2>
<h3>Summary, history, and what it is</h3>
<p>Extreme Programming is a software development method created by Kent Beck in 1996 [4, 6]. It is considered an incremental development method, meaning that a project is completed in small, incremental cycles, where more functionality is added to the software as the project progresses [2]. A typical cycle lasts between one and four weeks [3]. The method contrasts with the popular Waterfall life-cycle model for software development in that it focuses on producing code primarily, as opposed to producing documentation upon which to base the coding efforts [4]. Contrary to popular belief, however, Extreme Programming does focus in the production of complete and accurate documentation. The difference between documentation produced in a Waterfall approach and the documentation produced by Extreme Programming is that, while Waterfall provides careful documentation to guide coding efforts, Extreme Programming (XP) uses documentation as a means to explain and justify design decisions [7]. In other words, in XP, design documents “serve a different purpose. [They are] not [templates] or [blueprints] for future construction. Instead, [they] can be a guide for understanding why certain decisions were made. In this regard, [design documents are] a biography of the development, not a plan of action [7].”</p>
<p>Another focus of XP is involving the customer throughout the development process. Ideally, the customer is involved from the beginning of the development effort, and stays with the development team until the project is complete. That is, a “person or group who represents the users, [is/are] responsible for identifying the features (known as stories) that the programmers must implement, providing detailed acceptance tests for those stories and assigning priority to them [4].” Thus, the programmers become responsible for analyzing these stories, providing the customer with estimates regarding time and schedule related to the completion of each story [4]. Once an initial set of requirements have been identified and selected, the programmers implement these requirements within the specified time frame.</p>
<p>Other major characteristics of XP include its specific focus in the following activities: test-driven development, paired programming, accurate configuration management, customer involvement and collaboration, and refactoring of code [2, 8]. A description of each of these activities will follow.</p>
<p>Test-driven development is a method used to ensure that any code written to implement the user requirements is correctly written. That is, “engineers first write automated tests before building the production code [8].” As the code is written, and later modified or refactored, these automated tests ensure that customer requirements are still satisfied by the final code.</p>
<p>Paired programming, simply put, means that two programmers work on the same code, together, and at the same time. In other words, two programmers share one keyboard. “This concept encourages developers to code review (each other) all the time and removes some of a programmer bias towards his or her own code [2].”</p>
<p>Configuration management deals with monitoring and controlling changes in the software. Configuration management “allows for parallel development and reduces the risk of overwriting code [2].” With one of the main goals of Extreme Programming being the fast development of functional software, being able to modularize the various parts that make up the final product is fundamental to the successful achievement of this goal.</p>
<p>The purpose of involving the customer throughout the development process is to ensure that, not only is the software developed right, but also that the right software is developed. Better communication between developers and the customer means that both sides gain a better understanding of what is needed, what the process will be to produce the software to satisfy those needs, and constant and timely feedback enables the product to remain close to the needs of the customer [1].</p>
<p>Finally, code refactoring refers to the process of “improving the quality of the design or implementation of the system without changing its functionality [8].” That is, as the development process progresses, and new and subsequent stories are implemented, “older pieces of code are redesigned to fit to the new pieces that are under development. The idea is that less time is spent designing the system and more time is spent actually building the system [2].” It is important to note that “the process of refactoring should not become the dominant portion of the work being done on the project [2].”</p>
<h3>Advantages of Extreme Programming</h3>
<p>The main advantages of Extreme Programming include, when properly and rigorously employed, paired programming, test-driven development, and refactoring. A brief description of each of these advantages will follow.</p>
<p>Ideally, when developing in pairs of programmers, “highly experienced and valuable team members can be paired with new, or inexperienced members. This allows the transfer of knowledge and experience throughout the project team, between pairs. This socialization process minimizes the need for extensive documentation [2].” Doing so also “leads to the efficient exchange of knowledge and experience between the team members. In this way, the risk of turnover is also reduced, since the knowledge about the system is distributed among the members of the team [5].”</p>
<p>The quality control aspect of XP is very advantageous in that it “promotes constant improvement of test coverage quality [1].” As mentioned earlier, instead of writing unit tests to verify and validate the code after some or all of the code has been written, “before adding code to the system, the programmers must write a failing unit test that the new code must make successful. This ensures that as the program grows, a copious suite of tests grows with it. These tests keep the quality of the software high and give the programmers the courage they need to continually rework the code into its simplest form [4].”</p>
<p>Thus, refactoring becomes a great advantage of XP. The idea of writing code that is expected to be reworked in the near future may be of concern to some, as redesigning and rewriting code can quickly lead to confusing, patch-based code. However, “XP is acutely sensitive to poor code quality and addresses it in several ways. First, XP demands simplicity from the programmers—they must leave the code in the simplest possible state that passes all the acceptance tests. Thus, when code is reworked from iteration to iteration, it is also continually reduced to the simplest state the programmers can find [4].” A study comparing Extreme Programming and Waterfall projects revealed that programmers using XP ended up writing a higher “percentage of comments in the source code [7].”</p>
<h3>Disadvantages of Extreme Programming</h3>
<p>With one of the main features of XP being the close communication between the customer and the development team, as well as internal communication between team members, one disadvantage of XP is difficulty outsourcing parts of a project to groups of developers physically separated from each other [9]. “The success of an Extreme Programming team relies on a shared common set of values and principles, such as coding standards, test-driven development, and refactoring. However, the specifics of these principles and values can be interpreted differently by each individual. This makes it difficult to outsource portions of a project because physically separating team members makes communication more difficult [9].”</p>
<p>Another disadvantage of XP is the way the method is designed to address change. While anticipating and managing changes are keys point in successful in software development, Extreme Programming takes this too far by placing the responsibility of choosing what features to implement, modify, or remove from a system completely on the hands of the customer [4]. Thus, the development team must follow the dictates of the customer in implementing stories, and working and reworking the code base. Doing so can ultimately lead to “stagnation, [modifying] the finished work, and even [abandoning] the finished work in some cases, and [increasing] the workload, [undermining] the project plan, and [extending] the project cycle [6].”</p>
<p>Finally, since planning for implementation of a particular cycle doesn’t extend beyond that particular development cycle, some programmers may find themselves “spending a lot of time changing the architecture so that [they] can implement the next phase [2].” This can be especially expensive if work done in a particular cycle is found to be an inappropriate foundation for the features expected for a cycle several iterations in the future. This means that a lot more than just a trivial amount of infrastructure and functionality must be changed. Thus, the longer an earlier poor implementation remains undiscovered, the more expensive it becomes to fix it.</p>
<p><strong>Works Cited</strong></p>
<p>1. Choudhari, J.; Suman, U.; , &#8220;Iterative Maintenance Life Cycle Using eXtreme Programming,&#8221; Advances in Recent Technologies in Communication and Computing (ARTCom), 2010 International Conference on , vol., no., pp.401-403, 16-17 Oct. 2010<br />
doi: 10.1109/ARTCom.2010.52<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=5655582&amp;isnumber=5655294">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=5655582&amp;isnumber=5655294</a></p>
<p>2. Kivi, J.; Haydon, D.; Hayes, J.; Schneider, R.; Succi, G.; , &#8220;Extreme programming: a university team design experience,&#8221; Electrical and Computer Engineering, 2000 Canadian Conference on , vol.2, no., pp.816-820 vol.2, 2000<br />
doi: 10.1109/CCECE.2000.849579<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=849579&amp;isnumber=18402">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=849579&amp;isnumber=18402</a></p>
<p>3. Macias, F.; Holcombe, M.; Gheorghe, M.; , &#8220;A formal experiment comparing extreme programming with traditional software construction,&#8221; Computer Science, 2003. ENC 2003. Proceedings of the Fourth Mexican International Conference on , vol., no., pp. 73- 80, 8-12 Sept. 2003<br />
doi: 10.1109/ENC.2003.1232877<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1232877&amp;isnumber=27628">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1232877&amp;isnumber=27628</a></p>
<p>4. Martin, R.C.; , &#8220;eXtreme Programming development through dialog,&#8221; Software, IEEE , vol.17, no.4, pp.12-13, Jul/Aug 2000<br />
doi: 10.1109/52.854062<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=854062&amp;isnumber=18557">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=854062&amp;isnumber=18557</a></p>
<p>5. Succi, G.; Stefanovic, M.; Pedrycz, W.; , &#8220;Quantitative assessment of extreme programming practices,&#8221; Electrical and Computer Engineering, 2001. Canadian Conference on , vol.1, no., pp.81-86 vol.1, 2001<br />
doi: 10.1109/CCECE.2001.933661<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=933661&amp;isnumber=20196">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=933661&amp;isnumber=20196</a></p>
<p>6. Li-li, Zhai; Lian-feng, Hong; Qin-ying, Sun; , &#8220;Research on Requirement for High-quality Model of Extreme Programming,&#8221; Information Management, Innovation Management and Industrial Engineering (ICIII), 2011 International Conference on , vol.1, no., pp.518-522, 26-27 Nov. 2011<br />
doi: 10.1109/ICIII.2011.132<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=6115089&amp;isnumber=6114614">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=6115089&amp;isnumber=6114614</a></p>
<p>7. Sedano, T.; Feng Ji; , &#8220;Comparing extreme programming and Waterfall project results,&#8221; Software Engineering Education and Training (CSEE&amp;T), 2011 24th IEEE-CS Conference on , vol., no., pp.482-486, 22-24 May 2011<br />
doi: 10.1109/CSEET.2011.5876129<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=5876129&amp;isnumber=5876072">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=5876129&amp;isnumber=5876072</a></p>
<p>8. Wellington, C.A.; , &#8220;Managing a project course using Extreme Programming,&#8221; Frontiers in Education, 2005. FIE &#8217;05. Proceedings 35th Annual Conference , vol., no., pp.T3G-1, 19-22 Oct. 2005<br />
doi: 10.1109/FIE.2005.1611948<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1611948&amp;isnumber=33854">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1611948&amp;isnumber=33854</a></p>
<p>9. Yap, M.; , &#8220;Follow the sun: distributed extreme programming development,&#8221; Agile Conference, 2005. Proceedings , vol., no., pp. 218- 224, 24-29 July 2005<br />
doi: 10.1109/ADC.2005.26<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1609825&amp;isnumber=33795">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1609825&amp;isnumber=33795</a></p>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/cleanroom-software-engineering/" rel="bookmark" class="crp_title">A Paper on Cleanroom Software Engineering</a></p><p><a href="http://www.rodrigo-silveira.com/abstraction-software-development/" rel="bookmark" class="crp_title">Abstraction in Software Development</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/" rel="bookmark" class="crp_title">WebGL Inspector: Debug OpenGL on the Browser</a></p><p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/" rel="bookmark" class="crp_title">3D Programming: Transformation Matrix Tutorial</a></p><p><a href="http://www.rodrigo-silveira.com/gwt-unable-connect/" rel="bookmark" class="crp_title">Google Web Toolkit: Failed to Connect</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/research-paper-extreme-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Paper on Cleanroom Software Engineering</title>
		<link>http://www.rodrigo-silveira.com/cleanroom-software-engineering/</link>
		<comments>http://www.rodrigo-silveira.com/cleanroom-software-engineering/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 00:57:21 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[BYU-I]]></category>
		<category><![CDATA[Writing]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=376</guid>
		<description><![CDATA[Two fundamental differences between computers and humans are that computers don’t forget, and computers don’t vary in the least when repeating an instruction. Thus, when a computer program is executed for the millionth time, the computer still remembers what to do, and does so exactly the same way as it did the first time.]]></description>
			<content:encoded><![CDATA[<p>The following is a paper I wrote originally as part of a school assignment during my work at Brigham Young University – Idaho. I attended BYU-I between 2010 and 2012, and ultimately earned by Bachelor’s degree in Computer Science</p>
<h2>Cleanroom Software Engineering, by Rodrigo Silveira</h2>
<p><img class="alignleft  wp-image-379" title="ibm-cleanroom" src="http://rodrigo-silveira.com/wp-content/uploads/2012/04/ibm-cleanroom.jpg" alt="" width="499" height="384" /></p>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3></h3>
<h3>Summary, history, and what it is</h3>
<p>Two fundamental differences between computers and humans are that computers don’t forget, and computers don’t vary in the least when repeating an instruction. Thus, when a computer program is executed for the millionth time, the computer still remembers what to do, and does so exactly the same way as it did the first time. In this context, the only way a computer program may come to break, much like a physical machine will eventually break down after repeated use, is by having been built in a way that causes it to break. In other words, the reason a computer program fails is because it was constructed poorly, or better stated, lacking in precision.</p>
<p>In an attempt to prevent programs from being built poorly, or in other words, in an effort to build zero-defect software, Harlan Mills from IBM proposed the incremental Cleanroom software process in the early 1980s [2]. The name for this engineering method was inspired by the way silicon chips are built in the semiconductor industry. In order to prevent the introduction of low level pollutants into the chips, special contaminant-free environments called cleanrooms are used [7].</p>
<p>The goal of Cleanroom is to product is to produce software with no defects during development [7]. The philosophy is to get it right the first time [6]. The process promises to “dramatically improve the quality of software products by allowing their correctness to be formally verified. In order to use this technology, the design must be expressed in a formal representation and verification techniques must be used to verify the design is correct [3].”</p>
<p>The three major components of Cleanroom are software specification, design and code verification, and software quality verification [3]. The specification is intended to describe precisely what the program is to do, and how it is to behave [7]. For specification, the box structures approached is commonly used, where every system is represented by three different views, namely black box, state box, and clear box [4]. The black box view, as the name implies, only exposes its surface to the outside world. Everything inside it, including specific details of how things work under the hood, is kept abstracted out from the user. In other words, a black box behavior specification “precisely defines the inputs, outputs, and behavior of an object [7].” The state box view describes the data, while still maintaining the processing of the data as abstract as possible. Finally, the clear box view describes any algorithmic implementation and processes used [2].</p>
<p>Cleanroom relies on very rigorous activities such as formal correctness verification. The idea is that the problem to be solved is well understood, and the program is so thoroughly and precisely designed, that coding and testing activities have somewhat of a different meaning than they do in traditional software development. In other methodologies, coding is viewed as a way to satisfy the requirements by implementing the specified design. In cleanroom, coding is linked more closely to a translation of the detailed design into a language that can be executed by the machine [3]. Also, whereas testing is normally associated with an activity aimed at finding bugs and defects in software (as testing can never confirm the absence of bugs, but merely expose the presence of such), in Cleanroom testing is merely a means to “measure the quality of the developed software product, and not to test quality in [2].” Testing is the means to certify reliability in the software through statistical testing [3].</p>
<p>Recent examinations of Cleanroom attempt to justify the extreme level of software engineering prescribed by Cleanroom. Since the idea of Cleanroom is to use formal design methods to guarantee highly efficient code, programmers are not allowed to compile and test their own code. Instead, the testing process is completely separated from the development process [5]. It has been pointed out that when Mills proposed Cleanroom, “programming was ego intensive and idiosyncratic. Almost everything was sacrificed to supposed efficiency and memory conservation. There was no distinction between testing and debugging. Notions of what constituted effective testing were primitive compared to what we know today: the “best” testing was generally considered to be exhaustive testing of all possible inputs, which was obviously impractical and often theoretically impossible [1].” In other words, the testing discipline of the day was quite different than the maturing one we know today. Thus, it can be argued that Cleanroom takes things a bit to the extreme, which might be a valid explanation as to why the methodology hasn’t become the standard today.</p>
<h3>Advantages of Clearnroom in Software Engineering</h3>
<p>There have been numerous projects and studies done on Cleanroom software engineering. As extreme as the method may seem, there are quite a few advantages to using Cleanroom, as opposed to any of the many alternatives to software development.</p>
<p>Some of the reported benefits experienced through the use of Cleanroom include such things as code verification being much faster, and a deeper understanding of the requirements, design, and code by all verifiers involved [3]. This can be explained by the extra effort on requirements and design, which is a distinguishing characteristic of Cleanroom. It can be easily seem that the more time one puts on coming up with a sound design, the less time one will spend translating such design into code. With code built upon such carefully crafted requirements and design, it follows that verifying said code should be more natural than if the design was vague and incorrect.</p>
<p>Another advantage of Cleanroom is that programs built with it are of higher quality than those built without it. The total amount of defects in a program produced in Cleanroom is significantly smaller. “Although it is theoretically impossible to ever know for certain that a software product has zero defects, it is possible to know that it has zero defects with high probability [4].” This high certainty about the low rate of defects in a program is attributed to the way that Cleanroom uses statistical usage testing. “Statistical reliability testing is based on the idea that, by testing software the way it is expected to be used, an accurate prediction of reliability can be made [2].”</p>
<p>Finally, a significant advantage of Cleanroom is that it can be implemented gradually [8]. While the activities involved in cleanroom are strict, and may seem overly severe, the methodology is incremental, and can be implemented in steps. This is a major plus because any overwhelming goal becomes instantly more manageable when it can be broken down into smaller, more realistic pieces.</p>
<h3>Disadvantages of Cleanroom Software Engineering</h3>
<p>In contrast with some of the advantages of the Cleanroom methodology outlined above, there have been reports that Cleanroom is simply too hard. While great in theory, design verification is not always easy enough to justify the extra effort [8]. Similarly, the time it takes to train a team to the point where they are effective and efficient at verifying designs might be too long and expensive.</p>
<p>Other common disadvantages refer to Cleanroom being so out of the norm, and so extreme, that the required drastic change of culture might be too much for companies to handle [8]. Although most changes might seem too risky, and the benefits from changing too far out of reach, once the change is complete and the new is then the norm, the advantages might prove themselves worth the extra efforts. Still, some companies have shown hesitance to make the switch and commitment to Cleanroom. A common fear is that the change will be too drastic, and the resources required to adequately train their staff will be beyond the acceptable level [8]. Although the promised benefits might seem desirable, the perceived risk and challenge involved in attempting the methodology is a major factor that keeps companies from giving Cleanroom a try.</p>
<h3>Works Cited</h3>
<p>1. Beizer, B.; , &#8220;Cleanroom process model: a critical examination,&#8221; Software, IEEE , vol.14, no.2, pp.14-16, Mar/Apr 1997<br />
doi: 10.1109/52.582968<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=582968&amp;isnumber=12658">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=582968&amp;isnumber=12658</a></p>
<p>2. Deck, M.; Hines, B.E.; , &#8220;Cleanroom software engineering for flight systems: A preliminary report,&#8221; Aerospace Conference, 1997. Proceedings., IEEE , vol.4, no., pp.329-347 vol.4, 1-8 Feb 1997<br />
doi: 10.1109/AERO.1997.577519<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=577519&amp;isnumber=12521">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=577519&amp;isnumber=12521</a></p>
<p>3. Highland, F.; Kornman, B.; , &#8220;The use of cleanroom methodology for knowledge based application development,&#8221; Artificial Intelligence for Applications, 1993. Proceedings., Ninth Conference on , vol., no., pp.361-367, 1-5 Mar 1993<br />
doi: 10.1109/CAIA.1993.366588<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=366588&amp;isnumber=8403">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=366588&amp;isnumber=8403</a></p>
<p>4. Linger, R.C.; , &#8220;Cleanroom software engineering for zero-defect software,&#8221; Software Engineering, 1993. Proceedings., 15th International Conference on , vol., no., pp.2-13, 17-21 May 1993<br />
doi: 10.1109/ICSE.1993.346060<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=346060&amp;isnumber=8036">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=346060&amp;isnumber=8036</a></p>
<p>5. Selby, R.W.; Basili, V.R.; Baker, F.T.; , &#8220;Cleanroom Software Development: An Empirical Evaluation,&#8221; Software Engineering, IEEE Transactions on , vol.SE-13, no.9, pp. 1027- 1037, Sept. 1987<br />
doi: 10.1109/TSE.1987.233525<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1702325&amp;isnumber=35891">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=1702325&amp;isnumber=35891</a></p>
<p>6. Sherer, S.W.; Kouchakdjian, A.; Arnold, P.G.; , &#8220;Experience using cleanroom software engineering,&#8221; Software, IEEE , vol.13, no.3, pp.69-76, May 1996<br />
doi: 10.1109/52.493022<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=493022&amp;isnumber=10620">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=493022&amp;isnumber=10620</a></p>
<p>7. Spangler, A.; , &#8220;Cleanroom software engineering-plan your work and work your plan in small increments,&#8221; Potentials, IEEE , vol.15, no.4, pp.29-32, Oct/Nov 1996<br />
doi: 10.1109/45.539962<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=539962&amp;isnumber=11598">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=539962&amp;isnumber=11598</a></p>
<p>8. Trammell, C.J.; Hausler, P.A.; Galbraith, C.E.; , &#8220;Incremental implementation of cleanroom practices,&#8221; System Sciences, 1992. Proceedings of the Twenty-Fifth Hawaii International Conference on , vol.ii, no., pp.437-448 vol.2, 7-10 Jan 1992<br />
doi: 10.1109/HICSS.1992.183257<br />
URL: <a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=183257&amp;isnumber=4717">http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&amp;arnumber=183257&amp;isnumber=4717</a></p>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/research-paper-extreme-programming/" rel="bookmark" class="crp_title">A Paper on Extreme Programming</a></p><p><a href="http://www.rodrigo-silveira.com/abstraction-software-development/" rel="bookmark" class="crp_title">Abstraction in Software Development</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/" rel="bookmark" class="crp_title">WebGL Inspector: Debug OpenGL on the Browser</a></p><p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/" rel="bookmark" class="crp_title">3D Programming: Transformation Matrix Tutorial</a></p><p><a href="http://www.rodrigo-silveira.com/gwt-unable-connect/" rel="bookmark" class="crp_title">Google Web Toolkit: Failed to Connect</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/cleanroom-software-engineering/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abstraction in Software Development</title>
		<link>http://www.rodrigo-silveira.com/abstraction-software-development/</link>
		<comments>http://www.rodrigo-silveira.com/abstraction-software-development/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 00:51:50 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[BYU-I]]></category>
		<category><![CDATA[Papers]]></category>
		<category><![CDATA[Writing]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=368</guid>
		<description><![CDATA[By creating a clear distinction within program logic, its behavior, and its data, expertly applied abstraction can transform software into a solution which is both easily maintainable and easily understood.]]></description>
			<content:encoded><![CDATA[<p>The following is a paper I wrote originally as part of a school assignment during my work at Brigham Young University – Idaho. I attended BYU-I between 2010 and 2012, and ultimately earned by Bachelor’s degree in Computer Science.</p>
<h2>Abstraction in Software Development</h2>
<h3>Introduction</h3>
<p>Modern software has evolved to become so complicated that it has become impossible to engineer an enterprise system on a scale simple enough to be completely internalized in human memory.  To better illustrate these systems and their functionality, software engineers have turned to abstraction to bring order to what was once one single implementation.  By creating a clear distinction within program logic, its behavior, and its data, expertly applied abstraction can transform software into a solution which is both easily maintainable and easily understood.</p>
<p>These distinctions made through the use of abstraction can support the development of a product, making its structure more easily visualized than if it were to be tightly coupled with itself with no distinct classes of behavior.</p>
<p>The application of abstraction is an essential part of modern programming, and is relevant even to the smallest software.  As software becomes more complicated through the evolution of computer science, the application of abstraction in design is paramount for developing robust software.</p>
<h3>What is Abstraction?</h3>
<p>In practice, abstraction is the means by which a particular thought or concept is implemented into a more granular interpretation.  This is the basis by which humans interpret the world around them, and is the means that allow us to manage and manipulate vast quantities of information effortlessly.  We don’t need to know how something works to use it.  We just need to know what it does and what we need to do in order to make it work.</p>
<p>Abstraction in computing is an identical application, where the implementation of a particular interface is separated from its design.  The interface can be a data structure or a framework.  An API, for example, is literally an <em>application programming interface</em>, providing a “deeper discussion of the relations among types, data abstraction, and polymorphism [2].”<em> </em></p>
<p>Abstraction is imperative for modeling both large and complex systems, such as enterprise solutions, where development relies upon more than a single developer [8].  With careful preparation, design and development can be scheduled according to interfaces that can be developed independent of one another [1].  The byproduct should result in software that is simpler to understand, easier to budget, and affordable to maintain.</p>
<h3>Why Abstraction is Important</h3>
<p>Abstraction in computer programming is an evolution that resulted out of the necessity of reducing complexity for users as well as engineers [1] and to quantify and to simplify new applications of existing paradigms.  The iteration to this new style provides a technique for programming and a way to write “good” programs to solve a given problem in an organized, portable, and reusable way.</p>
<p>Object-oriented programming, for example, is an abstraction which provides an interface to user defined types.  According to Bjarne Stroustrup, the creator of C++, “if the term ‘object-oriented programming language’ means anything, it must mean a programming language that provides mechanisms that support the object-oriented style of programming well [10].” Writing good code is extremely difficult because it must account for how well people other than the original author of the code can read and understand what was written.The proper description of the interfaces available is extremely important, and allows a programmer to identify how to create a solution without delving into the actual code.</p>
<h3>Applications and Examples of Abstraction in Computing<strong> </strong></h3>
<p>However, the concept of abstraction by itself isn’t enough to product outstanding software.  Utilizing the right amount of abstraction when designing software is just as important as actually applying abstraction.  It should be used with caution and prudence.  Abstraction doesn’t evolve out of nothing and doesn’t always come naturally, as explained by Jeff Kramer of Imperial College in London.  Applying the right degree of abstraction, says he, “requires some degree of awareness and experience [5].”</p>
<p>Code that utilizes abstraction to separate its interfaces from implementation has a high degree of reusability [6], is easier to scale [7], and allows the possibility to provide a drop-in replacement which can be used to alter performance depending on the task at hand.  These facts define abstraction as an important fundamental concept in modern software.</p>
<p>Figure 1.0 illustrates this concept by abstracting a class used to describe a vehicle.  Note that implementation is not a concern at this point.  The crucial technical details (code) that make an air freighter work is not as important in abstracting this plane class as the fact, in this example, that the air freighter belongs to the plane class.  The plane class, in turn, is part of the class air vehicle, and therefore inherits the characteristics and features of that class.  Finally, an air vehicle class is a subset of a vehicle.</p>
<p align="center"> <a href="http://www.rodrigo-silveira.com/abstraction-software-development/abstraction-of-car-structure/" rel="attachment wp-att-369"><img class="aligncenter size-full wp-image-369" title="abstraction-of-car-structure" src="http://rodrigo-silveira.com/wp-content/uploads/2012/04/abstraction-of-car-structure.png" alt="" width="493" height="248" /></a></p>
<p align="center"><strong>Figure 1.0.  The abstraction structure of vehicles [9].</strong></p>
<p>Once the vehicle class has been properly implemented, reusing it for, say, a land vehicle becomes very natural and intuitive.  Likewise, implementing a custom-made passenger aircraft would be a more manageable task once the plane class has been abstracted accurately.</p>
<p>Although the instructions contained in software source code are followed effortlessly by a machine, the development, maintenance, and cost of upgrades is retained by people.  Therefore, code needs to be readable and understandable by the programmers who deal with it.  By applying proper abstraction to the design and implementation phases of software development, the byproduct of such work is simpler to understand and maintain.  Not only is abstraction a key component of software development, but “abstraction is fundamental to mathematics and engineering in general” as well as “playing a critical part in the production of models for analysis and in the production of sound engineering solutions [4].”</p>
<p>Once a good technique is acquired, the tendency is for such technique to be used abundantly.  With abstraction, however, there are times when applying less abstraction yields the optimal solution.  Orit Hazzan hypothesized that by increasing the exposure a person has with an object, the more concrete that object is to the person [3].  By reducing abstraction, a person is able to focus more on the details related to solving the problem.  By this we can see that the abstraction requires experience to apply properly.   Dr.  Hazzan confirms: “The knowledge of [applying] different levels of abstraction does not, however, always come naturally, and requires some degree of awareness and experience [5].”</p>
<p>Simply being able to abstract the significant information is of great benefit; being able to separate the design from the different ways it may be implemented is an asset.  A logical outcome is that it simplifies debugging.  When a problem is clearly defined, even when only partially understood, the process of resolving such predicament is more directed and focused.  Debugging software that has been designed with a <em>sufficient</em> level of abstraction can be significantly simplified.  Matthias Zenger, from Google’s Research and Development team, explains how one might scale a system through abstract type members by hiding imperative information about the internal workings of the system, allowing a programmer to express the required components of a service through the use of an abstract pointer such as <em>this</em>.  He goes on to say that “both abstraction are scalable, in the sense that they can describe very small as well as very large components.  Scalability is ensured by the principle that the result of a composition should have the same fundamental properties as its constituents [7].</p>
<h3>Conclusion and Final Thoughts</h3>
<p>Without proper abstraction and separation of data and the operations associated with them, starting a project with raw code is clearly counterproductive.  The use of abstraction in software development is important in designing, implementing, debugging, and understanding the logic upon which the program or system is built.</p>
<p>The evolution of software in computer science is accomplished by building upon existing research to produce new and innovative solutions.  The concepts established by this change are realized through the use of abstraction by creating a self-contained model for further application.  Without abstraction, software would continue to become exceedingly complex until it can no longer be maintained.  The future of this evolution will be achieved through further generalization of existing interfaces, the aggregation of data and modularization, all of which is made possible through abstraction.</p>
<p>Abstraction is what allows modern software to be written at a staggering scale.  This is what makes software modular, portable, replaceable, and readily tested independent of the original logic.  This evolution in computing sets it apart as a new paradigm and makes programming through the use of high level abstractions the new precursor for future innovative software design.</p>
<h3>Sources</h3>
<ol>
<li>Berzins, V., Gray, M., and Naumann, D. 1986. Abstraction-based software development. Commun. ACM 29, 5 (May. 1986), 402-415. DOI= <a href="http://doi.acm.org/10.1145/5689.5691">http://doi.acm.org/10.1145/5689.5691</a></li>
<li>Cardelli, L. and Wegner, P. 1985. On understanding types, data abstraction, and polymorphism. ACM Comput. Surv. 17, 4 (Dec. 1985), 471-523. DOI= <a href="http://doi.acm.org/10.1145/6041.6042">http://doi.acm.org/10.1145/6041.6042</a></li>
<li>Hazzan, O. 2002. Reducing abstraction level when learning computability theory concepts. SIGCSE Bull. 34, 3 (Sep. 2002), 156-160. DOI= <a href="http://doi.acm.org/10.1145/637610.544461">http://doi.acm.org/10.1145/637610.544461</a></li>
<li>Kramer, J. 2007. Is abstraction the key to computing?. Commun. ACM 50, 4 (Apr. 2007), 36-42. DOI= <a href="http://doi.acm.org/10.1145/1232743.1232745">http://doi.acm.org/10.1145/1232743.1232745</a></li>
<li>Kramer, J. and Hazzan, O. 2006. The role of abstraction in software engineering. In Proceedings of the 2006 international Workshop on Role of Abstraction in Software Engineering (Shanghai, China, May 21 &#8211; 21, 2006). ROA &#8217;06. ACM, New York, NY, 1-2. DOI= <a href="http://doi.acm.org/10.1145/1137620.1137621">http://doi.acm.org/10.1145/1137620.1137621</a></li>
<li>Krueger, C. W. 1992. Software reuse. ACM Comput. Surv. 24, 2 (Jun. 1992), 131-183. DOI= <a href="http://doi.acm.org/10.1145/130844.130856">http://doi.acm.org/10.1145/130844.130856</a></li>
<li>Odersky, M. and Zenger, M. 2005. Scalable component abstractions. SIGPLAN Not. 40, 10 (Oct. 2005), 41-57. DOI= <a href="http://doi.acm.org/10.1145/1103845.1094815">http://doi.acm.org/10.1145/1103845.1094815</a></li>
<li>Perry, D. E. 2008. &#8220;Large&#8221; abstractions for software engineering. In Proceedings of the 2nd international Workshop on the Role of Abstraction in Software Engineering (Leipzig, Germany, May 11 &#8211; 11, 2008). ROA &#8217;08. ACM, New York, NY, 31-33. DOI= <a href="http://doi.acm.org/10.1145/1370164.1370172">http://doi.acm.org/10.1145/1370164.1370172</a></li>
<li>Smith, J. M. and Smith, D. C. 1977. Database abstractions: aggregation and generalization. <em>ACM Trans. Database Syst.</em> 2, 2 (Jun. 1977), 105-133. DOI= http://doi.acm.org/10.1145/320544.320546</li>
<li>CITATION NEEDED (The C++ Programming Language &#8211; Third Edition)</li>
</ol>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/cleanroom-software-engineering/" rel="bookmark" class="crp_title">A Paper on Cleanroom Software Engineering</a></p><p><a href="http://www.rodrigo-silveira.com/research-paper-extreme-programming/" rel="bookmark" class="crp_title">A Paper on Extreme Programming</a></p><p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/" rel="bookmark" class="crp_title">3D Programming: Transformation Matrix Tutorial</a></p><p><a href="http://www.rodrigo-silveira.com/gwt-unable-connect/" rel="bookmark" class="crp_title">Google Web Toolkit: Failed to Connect</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/" rel="bookmark" class="crp_title">WebGL Inspector: Debug OpenGL on the Browser</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/abstraction-software-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3D Programming OpenGL: Load OBJ Model from Blender in C++</title>
		<link>http://www.rodrigo-silveira.com/3d-programming-opengl-obj-parser/</link>
		<comments>http://www.rodrigo-silveira.com/3d-programming-opengl-obj-parser/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 03:12:56 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[OBJ File]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Parser]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=335</guid>
		<description><![CDATA[A quick screencast demonstrating some C++ code I wrote for OpenGL that parses an OBJ file exported from Blender. I also included some mouse event handlers that moves the model around on the mouse's scroll event, as well as drag-and-drop]]></description>
			<content:encoded><![CDATA[<p><object type="application/x-shockwave-flash" id="player38898017_131060932" name="player38898017_131060932" class="" data="https://secure-a.vimeocdn.com/p/flash/moogaloop/5.2.18/moogaloop.swf?v=1.0.0" width="550" height="450" style="visibility: visible; "><param name="allowscriptaccess" value="always"><param name="allowfullscreen" value="true"><param name="scalemode" value="noscale"><param name="quality" value="high"><param name="wmode" value="opaque"><param name="bgcolor" value="#000000"><param name="flashvars" value="server=vimeo.com&amp;player_server=player.vimeo.com&amp;cdn_server=a.vimeocdn.com&amp;embed_location=https%3A%2F%2Fvimeo.com%2F38898017%2Fsettings&amp;force_embed=0&amp;force_info=0&amp;moogaloop_type=moogaloop_local&amp;js_api=1&amp;js_getConfig=player38898017_131060932.getConfig&amp;js_setConfig=player38898017_131060932.setConfig&amp;clip_id=38898017&amp;fullscreen=1&amp;js_onLoad=player38898017_131060932.player.moogaloopLoaded&amp;js_onThumbLoaded=player38898017_131060932.player.moogaloopThumbLoaded"></object></p>
<p>A quick screencast demonstrating some C++ code I wrote for OpenGL that parses an OBJ file exported from Blender. I also included some mouse event handlers that moves the model around on the mouse&#8217;s scroll event, as well as drag-and-drop.</p>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/html5-stock-market-simulation-php/" rel="bookmark" class="crp_title">HTML5 Stock Market Simulation in PHP</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-3d-demos/" rel="bookmark" class="crp_title">My First WebGL 3D Demos: Hello, World (of OpenGL)</a></p><p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/" rel="bookmark" class="crp_title">3D Programming: Transformation Matrix Tutorial</a></p><p><a href="http://www.rodrigo-silveira.com/opengl-tutorial-parsing-obj-file-blender/" rel="bookmark" class="crp_title">OpenGL Tutorial Part 1: Parsing OBJ File From Blender</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/" rel="bookmark" class="crp_title">WebGL Inspector: Debug OpenGL on the Browser</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/3d-programming-opengl-obj-parser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My First WebGL 3D Demos: Hello, World (of OpenGL)</title>
		<link>http://www.rodrigo-silveira.com/webgl-3d-demos/</link>
		<comments>http://www.rodrigo-silveira.com/webgl-3d-demos/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 02:22:48 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[demos]]></category>
		<category><![CDATA[wegbl]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=320</guid>
		<description><![CDATA[The following is a list of simple HTML5 WebGL demos I have done for a graphics class I'm taking at school. The class focuses on OpenGL and C++. I have ported some of the C++ code I have written for that class into Javascript and HTML5.]]></description>
			<content:encoded><![CDATA[<p>The following is a list of simple HTML5 WebGL demos I have done for a graphics class I&#8217;m taking at school. The class focuses on OpenGL and C++. I have ported some of the C++ code I have written for that class into Javascript and HTML5. I am surprised at how close OpenGL and WebGL (OpenGL ES) are. So far I have not yet found any differences between the libraries whatsoever. Actually, the one difference I have ran into is that, as with older versions of OpenGL (pre 2.0-ish), texture files had to have a width and height of powers of 2 (in pixels &#8211; 2, 4, 8, 16, 32, 64, 128 512, etc.). OpenGL 2.0+ doesn&#8217;t enforce this restriction, although I&#8217;m sure this can be advantageous to do (sizing your texture images as such).</p>
<h1><strong>List of demos:</strong></h1>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/simple-triangles.php">Simple Gradiated Triangles</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/simple-triangles.php"><img class="alignnone size-full wp-image-327" title="webgl-demo-simple-triangles" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-simple-triangles.jpg" alt="" width="550" height="200" /></a></p>
<p>Nothing too special here. I think the simple triangle is the <em>Hello, World</em> of 3D graphics.</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/triangle-storm.php">A Storm of Triangles</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/triangle-storm.php"><img class="alignnone size-full wp-image-331" style="border-style: initial; border-color: initial;" title="webgl-demo-triangle-storm" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-triangle-storm.jpg" alt="" width="550" height="200" /></a></p>
<p>This demo was designed to be a quick and dirty way to see how much my browser could handle. The demo just renders a bunch of triangles every frame at random locations. You can rotate the triangles, zoom in and out, add or remove more triangles from the scene. Very little optimizations here, if any at all. Each triangle is drawn from its own call to gl_Draw()</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/snow-fall-with-fog.php">Snow Fall with Fog</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/snow-fall-with-fog.php"><img class="alignnone size-full wp-image-325" title="webgl-demo-fog-effect" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-fog-effect.jpg" alt="" width="550" height="200" /></a></p>
<p>This demo is built on the previous demo. The main difference between the two is the vertex shader, which calculates each vertex&#8217;s z position relative to the camera, and render it with more of the color representing the fog. Simple stuff.</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/simple-square.php">Simple Square</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/simple-square.php"><img class="alignnone size-full wp-image-326" style="border-style: initial; border-color: initial;" title="webgl-demo-simple-squares" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-simple-squares.jpg" alt="" width="550" height="200" /></a></p>
<p>Similar to the triangle demo, but with more vertices. One other difference is that this example uses a index buffer (GL_ELEMENT_ARRAY_BUFFER).</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/spinning-cube.php">Spinning Cube</a></h2>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/spinning-cube.php"><img class="alignnone size-full wp-image-328" style="border-style: initial; border-color: initial;" title="webgl-demo-spinning-cube" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-spinning-cube.jpg" alt="" width="550" height="200" /></a></h2>
<p>This is the other <em>Hello, World</em> of 3D graphics. Built on the previous demo also (it even uses the same shaders), the only difference between the two examples is the amount of vertices and how the vertices are animated each frame.</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/textured-cube.php">Textured Cube</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/textured-cube.php"><img class="alignnone size-full wp-image-329" title="webgl-demo-super-mario-cube" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-super-mario-cube.jpg" alt="" width="550" height="200" /></a></p>
<p>Now the examples are getting better. This code is the exact same as the previous demo (with the animation being very slightly different), but a new shader is used, which loads the Super Mario Brothers texture. One thing that took me a while to figure out is this: <strong>in WebGL, texture images must be sized as a power of 2!</strong> This is very important to remember. If the image is a single pixel too wide or high, everything will load up fine, but the fragment shader will output black for every fragment. So keep that in mind when loading up your textures!</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/cloud-of-cubes.php">Super Mario Galaxy</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/cloud-of-cubes.php"><img class="alignnone size-full wp-image-330" style="border-style: initial; border-color: initial;" title="webgl-demo-super-mario-galaxy" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-super-mario-galaxy.jpg" alt="" width="550" height="200" /></a></p>
<p>This demo uses the same code as the previous example, but it prints more than one cube. The main difference is the introduction of a camera matrix, which allows you to navigate the scene without having to move any of the objects in it. In one of the previous demos, a similar effect is achieved by changing the actual vertices of every object&#8217;s model-view matrix. Not the best way to do things. Who needs that 99 lives trick in Super Mario 64 when you can get ten thousand mystery blocks in outer space!</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/mesh-from-json.php">Loading Mesh File with AJAX &amp; JSON</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/mesh-from-json.php"><img class="alignnone size-full wp-image-330" style="border-style: initial; border-color: initial;" title="webgl-demo-mesh-downloaded-from-ajax-json" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-mesh-downloaded-from-ajax-json.jpg" alt="" width="550" height="200" /></a></p>
<p>This demo uses the same code as the previous example, with the only difference being that the mesh it uses in the scene is completely loaded from the server asynchronously. The mesh file is stored in the server as a JSON file (JavaScript Object Notation), and was made by a simple program I wrote in C++ that converts an OBJ file exported from Blender 3D 2.6. This allows future demos and apps to be more realistic, as I won&#8217;t be dealing with blocks and triangles anymore.</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/lowres-skybox.php">Low Resolution Skybox Effect</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/lowres-skybox.php"><img title="webgl-demo-low-resolution-skybox" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-lowres-skybox.jpg" alt="" width="550" height="200" /></a></p>
<p>This demo is my first attempt at the awesome looking skybox effect. Since I was more concerned with getting the effect to work (as opposed to looking beautiful and realistic right away), the texture being used isn&#8217;t the best. The size of each face is not quite optimized, plus the edges don&#8217;t come together very nicely. Overall, I think the effect looks decent, although it clearly needs work.</p>
<p>&nbsp;</p>
<h2><a href="http://rodrigo-silveira.com/webgl/demos/skeletal-animation.php">Simulated Skeletal Animation (soft body deformation)</a></h2>
<p><a href="http://rodrigo-silveira.com/webgl/demos/skeletal-animation.php"><img title="webgl-demo-low-resolution-skybox" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/webgl-demo-skeletal-animation.jpg" alt="" width="550" height="200" /></a></p>
<p>While this demo doesn&#8217;t actually use a bone system, the concept of transforming some vertices more than others is the goal. I actually have this model nicely animated with a real and complete skeletal structure set up in Blender 2.6. The main issue I&#8217;m having with this is being able to understand the way that the exported Collada file (.dae) represents the animation. As I get some more research in on this particular topic, I&#8217;ll be updating this demo.</p>
<p>&nbsp;</p>
<p><strong>Coming soon:</strong></p>
<p>The following are topics I&#8217;ll be learning and posting a demo for soon:</p>
<ul>
<li>Multiple VBOs (Vertex Buffer Objects)</li>
<li>Skeletal Animation (bones, joints, skinning)</li>
<li>Lighting (diffused and specular)</li>
<li>3D Soft Deformation</li>
<li>Cell Shading (Toon Shading)</li>
<li>Collision Detection</li>
<li>Physics</li>
<li>HTML5 Audio</li>
</ul>
<p>I will be posting a detailed tutorial for each of the examples above as soon as I get the time. Also, if there is a certain example you&#8217;d like to see, feel free to post your request in the comments area.</p>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/webgl-quake/" rel="bookmark" class="crp_title">Webgl Quake</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/" rel="bookmark" class="crp_title">WebGL Inspector: Debug OpenGL on the Browser</a></p><p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/" rel="bookmark" class="crp_title">3D Programming: Transformation Matrix Tutorial</a></p><p><a href="http://www.rodrigo-silveira.com/opengl-tutorial-parsing-obj-file-blender/" rel="bookmark" class="crp_title">OpenGL Tutorial Part 1: Parsing OBJ File From Blender</a></p><p><a href="http://www.rodrigo-silveira.com/jquery-plugin-rokkocode-syntax-highlighter/" rel="bookmark" class="crp_title">Code Formatter &#038; Syntax Highlighter jQuery Plugin</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/webgl-3d-demos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3D Programming: Transformation Matrix Tutorial</title>
		<link>http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/</link>
		<comments>http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 22:50:59 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Math & Programming]]></category>
		<category><![CDATA[The Matrix]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=289</guid>
		<description><![CDATA[This tutorial is an introduction to 3D programming. While code examples will be in C++ and using OpenGL, the concepts can be used in any language. In fact, the focus of this tutorial is the concepts rather than the implementation.]]></description>
			<content:encoded><![CDATA[<p>This tutorial is an introduction to 3D programming. While code examples will be in C++ and using <a href="http://www.opengl.org/" target="_blank">OpenGL</a>, the concepts can be used in any language. In fact, the focus of this tutorial is the concepts rather than the implementation.</p>
<p>For starters, let’s briefly go over the idea of displaying a 3D world in a computer screen. As you know, computers ultimately display images as a series of pixels. A pixel can be thought of as a single dot (normally shaped like a rectangle) with a single color. You can think of an image displayed by a computer screen as array of objects type Pixel:<br />
Pixel image[600 * 800] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0, …};</p>
<p>In order to keep things simple, you can interpret the numbers inside the image array as a series of values representing a color made up of 3 different values, namely red, green, and blue (RGB). So the first 3 values in the array are red = 1, green = 0, blue = 0, which gives you a very bright red pixel. The size of that array (600 * 800) means that this array has a width of 600 and a height of 800 pixels. Below is an example of a small pixel grid, where you can imagine an image can be drawn:</p>
<p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/pixel-grid/" rel="attachment wp-att-292"><img class="size-full wp-image-292 aligncenter" title="pixel-grid" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/pixel-grid.gif" alt="" width="326" height="181" /></a></p>
<p>So the first 3 values in that pixel array correspond to the color that the very first pixel in the array will be displayed in. In this space – pixel space (more on that later), the first pixel in the pixel array corresponds to the top left corner of this screen. Below is an example of this grid of points with a few points colored in red:</p>
<p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/pixel-grid-filled/" rel="attachment wp-att-293"><img class="size-full wp-image-293 aligncenter" title="pixel-grid-filled" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/pixel-grid-filled.gif" alt="" width="326" height="181" /></a></p>
<p>The moral of this example is that you can access any point within this grid by specifying its x and y coordinates. The image below shows a blue pixel with a coordinate of (4, 2).</p>
<p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/pixel-grid-indexed/" rel="attachment wp-att-294"><img class="size-full wp-image-294 aligncenter" title="pixel-grid-indexed" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/pixel-grid-indexed.gif" alt="" width="351" height="195" /></a></p>
<p>At this point you may be asking yourself where the z coordinate goes… Since we’ll be drawing 3D objects, we’ll need more than just x and y axis, right?! Well, unfortunately computer screens don’t know anything about that third axis, and all it can draw is x and y points.</p>
<h1>Coordinate System Transformation</h1>
<p>The point of the above discussion is to introduce the idea of a coordinate system. At the lowest level, the computer monitor can only deal with the x and y coordinates system (also known as pixel space). With 3D objects, we’ll be working with 3 additional spaces, namely the model space (also known as object space), world space, and view space (also known as camera space and eye space).</p>
<p>As the title of this tutorial implies, the way you get from one pixel space to the next is through transformation matrices. In case you only know the work “matrix” because you’ve watched the movie, I recommend you look up a few tutorials on matrix math, or better yet, pay more attention in school…</p>
<p>The next few sections of this tutorial will introduce each of these spaces (coordinate systems), and how you move your 3D objects from one space to the next, until you can finally display the 3D image (project it) on your 2D computer screen.</p>
<h1>MVP Model View Projection Matrix</h1>
<h2>Model Space</h2>
<p>When you first model an object in 3D (normally you’d use a 3D modeling program like <a href="http://www.blender.org/" target="_blank">Blender </a>or <a href="http://sketchup.google.com/" target="_blank">Google Sketchup</a>, both of which are free, by the way), you create your model in a coordinate system called the model space. That is, the center of the object is the point (0, 0, 0), meaning that you now have an axis for each dimension (x, y, and z). The following image should help to illustrate this idea:</p>
<p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/3d-cube-in-model-space/" rel="attachment wp-att-291"><img class="size-full wp-image-291 aligncenter" title="3d-cube-in-model-space" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/3d-cube-in-model-space.png" alt="" width="486" height="503" /></a></p>
<p>For the purposes of this tutorial, we’ll define this cube as an array of points representing each vertex (corner) of this cube:</p>
<pre class="i_code">float cube[] = {
    -1.0, -1.0, -1.0, // front face, top left corner
    -1.0, 1.0, -1.0, // front face, bottom left corner
     1.0, 1.0, -1.0,
     1.0, -1.0, -1.0,
    -1.0, -1.0, 1.0, // back face, top left corner
    -1.0, 1.0, 1.0, // back face, bottom left corner
     1.0, 1.0, 1.0,
     1.0, -1.0, 1.0
};</pre>
<p>This cube defines the points along the negative z axis to be closer to the viewer, points to the left of the center of the model to be going along the negative x axis, and going up as moving to the negative y direction.</p>
<p>So in summary, those points defining the cube represent a model in model space. This says nothing about where the cube is to be displayed within a virtual world.</p>
<h2>World Space</h2>
<p>Now image your virtual 3D world. Let’s say that in it you have only one object – the cube we just talked about. Similar to the coordinate system in model space, the point (0, 0, 0) represents the center of the world. Let’s say we want to display our cube centered on point (10, 10, 10). That is, 10 units to the right, 10 units down, and 10 units away from the camera.</p>
<p>To do this, we’ll need to create a matrix and multiply all the points that make up the cube by it. Basically, we’ll be performing the multiplication by a vector (the vector has 3 points, which represents a particular vertex).</p>
<p>Once you multiply a vertex by your model matrix, you will have moved that vertex from model space to world space. This is as simple as that. The model matrix can be really simple or not so simple. Basically what it does it perform 3 transformations to your vertices:</p>
<ul>
<li>Rotate</li>
<li>Scale</li>
<li>Translate</li>
</ul>
<p>In other words, this matrix specifies how much you want to rotate your object (it may simply specify that there will be no rotation at all), how big you want it to display within the world (with relation to the original model, which in our example is a 1x1x1 cube), and where within the entire world you want it (in this example we want to translate it from the origin to the point (10, 10, 10)).</p>
<p>The easiest way to accomplish this is to create each of the five matrices, then multiply them all together to create a composite model matrix:</p>
<p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/rotation-matrices/" rel="attachment wp-att-295"><img class="alignnone size-full wp-image-295" title="rotation-matrices" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/rotation-matrices.png" alt="" width="262" height="299" /></a></p>
<p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/scale-matrices-2/" rel="attachment wp-att-299"><img class="alignnone size-full wp-image-299" title="scale-matrices" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/scale-matrices1.png" alt="" width="196" height="98" /></a></p>
<p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/translation-matrices/" rel="attachment wp-att-300"><img class="alignnone size-full wp-image-300" title="translation-matrices" src="http://rodrigo-silveira.com/wp-content/uploads/2012/03/translation-matrices.png" alt="" width="196" height="122" /></a></p>
<p>Once you have specified the values for your model transformation, generated the appropriate matrices, and multiplied them together, you’ll have your model matrix. Run each vertex of your model through it, and you’ll have your vertices in world space.</p>
<h2>View Space</h2>
<p>View space is the coordinate system that you’ll have your vertices in after you transform your vertices from world space by using a view matrix (also known as the camera matrix). All this means is that your camera will be in point (0, 0, 0) of your world, and all the points that were in world space are transformed accordingly. Actually, your camera matrix looks exactly like your model matrix. The truth is that the camera is just another object, but one that’s invisible. This means that you create your camera matrix the same way as your model matrix (you rotate it, scale it, and translate it). The difference is this: Say you have an object in your world space located at point (10, 10, 10). Now, let’s say you want the camera to sit 5 unites away from this cube. Well, so we can imagine that the camera will be located (in world space) at point (10, 10, 5). However, view space is a completely different space. Like I mentioned, in camera space (same as view space) the camera is always at the origin. So that means that your cube that was at (10, 10, 10) in world space will now be located at (0, 0, 5), which is the same thing as before, but now it’s positioned relative to the camera. If you choose to scale and rotate your camera, then your objects (vertices) in world space will be scaled and rotated relative to your camera as well.</p>
<p>So to transform a vertex from your model space down to camera space, you’ll have to multiply the camera matrix by the model matrix, and all your vertices by this new composite matrix.</p>
<h1>Projection Space</h1>
<p>Now that we’ve moved vertices from model space down to view space, we only have one transformation left before we can have our points in pixel space. Like we mentioned earlier, your monitor only knows about x and y points. It has no sense of depth (z axis). The way we simulate that is by projecting the 3D shapes onto a 2D plane. To accomplish this effect, we run our points through the projection matrix, which could be a perspective projection or an orthographic projection.</p>
<p>The projection matrix shown below does two things: it creates the illusion of depth by projecting points in our 3D space (from the near plane to the far plane, meaning that points along the z-axis beyond those points won’t be drawn) onto a 2D plane, and it also adjusts the image to take the aspect ratio of your display into account. This last part is important. In projection space, the coordinate system is centered on its origin (point (0, 0, 0)), and the dimensions range from -1 to 1. In other words, the upper-left point on the display is (-1, -1), and the lower-right corner is (1, 1). That means the display is a square, right?! But what if your display is actually not a square? Then your cube would look weird. So the projection matrix adjusts for that, so you’d still have a cube with all sides looking the same length (or a circle that doesn’t look lopsided).</p>
<pre class="i_code">void MatrixPerspective(float fov_deg, /* width / height */
                       float aspectRatio,
                       float near,
                       float far)
{
    float Sx = (aspectRatio&gt;1.0f) ? 1.0f/aspectRatio : 1.0f;
    float Sy = (aspectRatio&gt;1.0f) ? 1.0f : aspectRatio;
    float cotA2 = 1.0f / tan(DEG_2_RAD(angle_deg / 2.0f));
    float scaleX = cotA2 * Sx;
    float scaleY = cotA2 * Sy;
    float depth = far - near;

   this-&gt;setElements( scaleX, 0, 0, 0,
                         0, scaleY, 0, 0,
                         0, 0, far / depth, -(far + near) / depth,
                         0, 0, 1.0f, 0);
}</pre>
<p>Where the function setElements would construct or update an array of 16 floats representing your matrix structure.<br />
In summary, after you create your MVP matrix stack (by multiplying together your projection, view, and model matrices), you simply multiply every point in your 3D mesh, and the resulting points will be in pixel space, meaning that a call to a function like the example below would render that 3D object on a 2D computer screen:</p>
<pre class="i_code">void drawPixel(float x, float y, float* color_rgb)
{
    // Draw points to some type of buffer that gets drawn by your application
}</pre>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/webgl-3d-demos/" rel="bookmark" class="crp_title">My First WebGL 3D Demos: Hello, World (of OpenGL)</a></p><p><a href="http://www.rodrigo-silveira.com/opengl-tutorial-parsing-obj-file-blender/" rel="bookmark" class="crp_title">OpenGL Tutorial Part 1: Parsing OBJ File From Blender</a></p><p><a href="http://www.rodrigo-silveira.com/binary-matrix-multiplication/" rel="bookmark" class="crp_title">Binary Matrix Multiplication</a></p><p><a href="http://www.rodrigo-silveira.com/abstraction-software-development/" rel="bookmark" class="crp_title">Abstraction in Software Development</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-quake/" rel="bookmark" class="crp_title">Webgl Quake</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenGL Tutorial Part 1: Parsing OBJ File From Blender</title>
		<link>http://www.rodrigo-silveira.com/opengl-tutorial-parsing-obj-file-blender/</link>
		<comments>http://www.rodrigo-silveira.com/opengl-tutorial-parsing-obj-file-blender/#comments</comments>
		<pubDate>Thu, 15 Mar 2012 03:45:41 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Screencast]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=281</guid>
		<description><![CDATA[Here's a quick demo of how I parse an OBJ file from a 3D model made using Blender. I'm learning OpenGL using C++, but my ultimate goal is to become a WebGL ninja and put up some awesome games in the browser.]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been trying to learn OpenGL, shaders, and that soft of stuff. The more I learn about it, the more I get excited about it. My ultimate goal is to get familiar enough with OpenGL and make the slight move into WebGL. I want to learn how to bust out some awesome 3D graphics, games, etc., without the need to use those WebGL frameworks like <a href="http://www.aerotwist.com/tutorials/getting-started-with-three-js/" target="_blank">Three.js</a>. So To get things started, I wrote this simple program that parses out an OBJ file exported from <a href="http://www.blender.org" target="_blank">Blender</a>. There are no colors or textures so far, so the model might look a bit incomplete. My goal for the next few weeks is to master lighting and add that to my model, as well as some textures and such.</p>
<p><iframe src="http://www.youtube.com/embed/UWxp3FC2eNc" frameborder="0" width="560" height="315"></iframe></p>
<p>To help me stay motivated about this, I decided to record a quick screencast to show what I have so far, but also so hopefully there will be some people asking enough questions and requesting enough help, that I&#8217;ll have the extra reason to continue learning.</p>
<h1>How to read the OBJ file</h1>
<p>To extract the data form the OBJ file, you need to do the following:</p>
<p>Loop through each line inside your C++ script and look for lines that start with -v -vt -vn and -f</p>
<p>-v = Coordinates for the vertex. This could be two numbers or three numbers. Numbers are separated by a white space</p>
<p>-vt = UV coordinate. There will always be two values here.</p>
<p>-vn = Normal coordinates. Again, there will always be three numbers here</p>
<p>-f = Faces. This is a bit tricky. The faces are in a format like this: 1/2/3 (three integers, separated by a slash), where the first number is the index in the vertices array, the second if the index of the texture coordinate,and the last number is the index within the normals array. The trick is that a face can be in one of the following formats:</p>
<p>1// (only points to a vertex)<br />
1//1 (links a vertex to a normal)<br />
1/1/1 (has all three)</p>
<p>So when you parse that out, keep that in mind.</p>
<p>So in your C++ code, you will need to keep an array for each of those elements (vertices, normals, and UV coordinates). I find it easier to store those in a STL vector, but you can implement it in many ways.</p>
<h1>My C++ OBJ Parser</h1>
<p>There are three files that make up my parser. I&#8217;ll add detail to explain it as needed, so be sure to post your questions and comments. The files are main.cpp, RokkoParser.h, and its implementation in RokkoParser.cpp.</p>
<h3>main.cpp</h3>
<div class="i_code">
<pre>#include <iostream>
#include <string>
#include "RokkoParser.h"

using namespace std;

int main(int argc, char** argv)
{
   if(argc < 3)
      cout << "Usage: " << argv[0]
           << " [output filename] [input filename] [0|1 = verbose]"
           << endl;

   string obj_filename;
   string out_filename;

   if(argc > 2)
   {
      out_filename = argv[2];
   }
   else
   {
      cout << "Enter name of output file: ";
      getline(cin, out_filename);
   }

   if(argc > 1)
   {
      out_filename = argv[1];
   }
   else
   {
      cout << "Enter name of input file: ";
      getline(cin, obj_filename);
   }

   bool verbose = false;
   if(argc > 3)
      if(argv[3][0] != '0')
         verbose = true;

   RokkoParser::objToTxt(obj_filename, out_filename, verbose);

   return 0;
}</pre>
</div>
<h3>RokkoParser.h</h3>
<div class="i_code">
<pre>#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include
<map>

using namespace std;

class RokkoParser
{

public:
   static void objToTxt(const string aInFilename,
                        const string aOutFilename,
                        bool aVerbose = false);
   static vector<string> explode(string aStr, char aDelim);
};
</pre>
</div>
<h3>RokkoParser.cpp</h3>
<div class="i_code">
<pre>#include "RokkoParser.h"

vector<string> RokkoParser::explode(string aStr, char aDelim)
{
  vector<string> res;
  string str = aStr.substr(0, aStr.find(aDelim));

  while(str.size() < aStr.size())
  {
    res.push_back(str);
    aStr = aStr.substr(aStr.find(aDelim) + 1);
    str = aStr.substr(0, aStr.find(aDelim));
  }

  res.push_back(str);

  return res;
}

void RokkoParser::objToTxt(const string aInFilename,
                  const string aOutFilename,
                  bool aVerbose)
{
  if(aVerbose) cout << "Loading OBJ file <"
              << aInFilename << ">" << endl;

  // Open file
  ifstream objFile(aInFilename.c_str());

  if(objFile.fail())
  {
    cout << "Error: could not open file <"
        << aInFilename << ">" << endl;
    exit(1);
  }

  // Extract verts, normals, textures, and faces
  vector<float> verts, norms, textures;
  vector<int> faces;
  map<string, int> faceHash;

  vector<float> finalVerts, finalNorms, finalTextures;
  vector<int> finalFaces;

  string line;
  int hashIndex = 0;

  if(aVerbose) cout << "Extracting values from file" << endl;

  // Visit each line of the obj file
  while(getline(objFile, line))
  {
    // Extract vertex
    // Line starts with v[space]...
    if(line[0] == 'v' &#038;&#038; line[1] == ' ')
    {
      string lineVals = line.substr(2);
      float val;

      string val0 = lineVals.substr(0, lineVals.find(' '));
      val = (float)atof(val0.c_str());
      verts.push_back(val);

      string val1 = lineVals.substr(val0.length() + 1,
                          lineVals.find(' '));
      val = (float)atof(val1.c_str());
      verts.push_back(val);

      string val2 = lineVals.substr(lineVals.find_last_of(' ') + 1);
      val = (float)atof(val2.c_str());
      verts.push_back(val);
    }

    // Extract textures
    // Line starts with vt[space]...
    else if(line[0] == 'v' &#038;&#038; line[1] == 't' &#038;&#038; line[2] == ' ')
    {
      string lineVals = line.substr(3);
      float val;

      string val0 = lineVals.substr(0, lineVals.find(' '));
      val = (float)atof(val0.c_str());
      textures.push_back(val);

      string val1 = lineVals.substr(val0.length() + 1,
                          lineVals.find(' '));
      val = (float)atof(val1.c_str());
      textures.push_back(val);
    }

    // Extract normals
    // Line starts with vn[space]...
    else if(line[0] == 'v' &#038;&#038; line[1] == 'n' &#038;&#038; line[2] == ' ')
    {
      string lineVals = line.substr(3);
      float val;

      string val0 = lineVals.substr(0, lineVals.find(' '));
      val = (float)atof(val0.c_str());
      norms.push_back(val);

      string val1 = lineVals.substr(val0.length() + 1,
                          lineVals.find(' '));
      val = (float)atof(val1.c_str());
      norms.push_back(val);

      string val2 = lineVals.substr(lineVals.find_last_of(' ') + 1);
      val = (float)atof(val2.c_str());
      norms.push_back(val);
    }

  //
  // 2. Hash faces
  //
    // Extract faces
    // Line starts with f[space]...
    else if(line[0] == 'f' &#038;&#038; line[1] == ' ')
    {
      string lineVals = line.substr(2);

      string val0 = lineVals.substr(0, lineVals.find_first_of(' '));

      // If the value for this face includes texture and/or
      // normal, parse them out
      if(val0.find('/') >= 0)
      {
        // Get first group of values
        string g1 = val0.substr(0, val0.find(' '));

        // Get second group of values
        string g2 = line.substr(line.find(' ') + 2);
        g2 = g2.substr(g2.find(' ') + 1);
        g2 = g2.substr(0, g2.find(' '));

        string g3 = line.substr(line.find_last_of(' ') + 1);

        if(aVerbose)
          cout << "Face: (" << g1 << ") (" << g2 << ") (" << g3 << ")" << endl;

        // Just stick all the unique values in this hash and give each key a
        // unique, increasing value
        map<string, int>::iterator itr;

        //
        // Add key's position to the faces list
        //

        itr = faceHash.find(g1);
        // If key not in map
        if(itr == faceHash.end())
        {
          faceHash[g1] = hashIndex++;
        }
        itr = faceHash.find(g1);
        faces.push_back(itr->second);

        itr = faceHash.find(g2);
        // If key not in map
        if(itr == faceHash.end())
        {
          faceHash[g2] = hashIndex++;
        }
        itr = faceHash.find(g2);
        faces.push_back(itr->second);

        itr = faceHash.find(g3);
        // If key not in map
        if(itr == faceHash.end())
        {
          faceHash[g3] = hashIndex++;
        }
        itr = faceHash.find(g3);
        faces.push_back(itr->second);
      }

      // Only verts in file
      else
      {
        // Push faces straight up -- converting to
        // base zero in the process
      }
    }
  } /* end getline(file, line) */

  if(aVerbose) cout  << "Finished extracting values from file" << endl
            << "Quick count check:" << endl
            << "\tVerts = " << verts.size() << endl
            << "\tNorms = " << norms.size() << endl
            << "\tTexts = " << textures.size() << endl
            << "\tFaces = " << faces.size() << endl;

  objFile.close();

  if(aVerbose) cout << "Preparing to build faces" << endl;

  //
  // 3. Fill verts, texts, and norms lists so it can be indexed directly.
  //   Length = hash.size
  //
  for(int i = 0; i < faceHash.size() * 2; i++)
    finalTextures.push_back(0.0f);

  for(int i = 0; i < faceHash.size() * 3; i++)
  {
    finalVerts.push_back(0.0f);
    finalNorms.push_back(0.0f);
  }

  // 5. Walk through hash, extract each value in current key
  // * Remember to make faces array zero based
  //
  // Cases for keys:
  //    1. ## ## ## (verts only)
  //    2. ##/## ##/## ##/## (verts and textures)
  //    3. ##//## ##//## ##//## (verts and normals)
  //    4. ##// ##// ##// (verts only)
  //

  if(aVerbose) cout << "Hashing list of unique vertices" << endl;

  if(aVerbose) cout << faceHash.size() << " unique vertices found" << endl;

  map<string, int>::iterator hashItr = faceHash.begin();
  int faceCounter = 0;
  while(hashItr != faceHash.end())
  {
    string faceHashKey = hashItr->first;
    int faceHashVal = hashItr->second;

    if(aVerbose) cout << "Unique face #" << faceHashVal
                << " = " << faceHashKey << endl;

    // Default values
    float v0 = (float)0.0f;
    float v1 = (float)0.0f;
    float v2 = (float)0.0f;

    float t0 = (float)0.0f;
    float t1 = (float)0.0f;

    float n0 = (float)0.0f;
    float n1 = (float)0.0f;
    float n2 = (float)0.0f;

    vector<string> vals = RokkoParser::explode(faceHashKey, '/');

    v0 = (float)verts[(atoi(vals[0].c_str()) - 1) * 3];
    v1 = (float)verts[(atoi(vals[0].c_str()) - 1) * 3 + 1];
    v2 = (float)verts[(atoi(vals[0].c_str()) - 1) * 3 + 2];

    if(vals.size() > 1 &#038;&#038; vals[1].size() > 0)
    {
      t0 = (float)textures[(atoi(vals[1].c_str()) - 1) * 2];
      t1 = (float)textures[(atoi(vals[1].c_str()) - 1) * 2 + 1];
    }

    if(vals.size() > 2 &#038;&#038; vals[2].size() > 0)
    {
      n0 = (float)norms[(atoi(vals[2].c_str()) - 1) * 3];
      n1 = (float)norms[(atoi(vals[2].c_str()) - 1) * 3 + 1];
      n2 = (float)norms[(atoi(vals[2].c_str()) - 1) * 3 + 2];
    }

    finalVerts.at(faceHashVal * 3) = v0;
    finalVerts.at(faceHashVal * 3 + 1) = v1;
    finalVerts.at(faceHashVal * 3 + 2) = v2;

    finalTextures.at(faceHashVal * 2) = t0;
    finalTextures.at(faceHashVal * 2 + 1) = t1;

    finalNorms.at(faceHashVal * 3) = n0;
    finalNorms.at(faceHashVal * 3 + 1) = n1;
    finalNorms.at(faceHashVal * 3 + 2) = n2;

    if(aVerbose) cout  << "  Vert: " << finalVerts.at(faceHashVal * 3)
                  << " " << finalVerts.at(faceHashVal * 3 + 1)
                  << " "
                  << finalVerts.at(faceHashVal * 3 + 2)
                  << "  Text: " << finalTextures.at(faceHashVal * 2)
                  << " "
                  << finalTextures.at(faceHashVal * 2 + 1)
                  << "  Norm: " << finalNorms.at(faceHashVal * 3)
                  << " "
                  << finalNorms.at(faceHashVal * 3 + 1)
                  << " "
                  << finalNorms.at(faceHashVal * 3 + 2)
              << endl;

    hashItr++;
  }

  ofstream out(aOutFilename.c_str());

  if(out.fail())
  {
    cout << "Error: could not create output file " << aOutFilename << endl;
    exit(1);
  }

  if(aVerbose) cout << "Saving data to " << aOutFilename << endl;

  int len;

  // Verts
  out << "{"
    << "\"Verts\": [";

  len = finalVerts.size();
  for(int i = 0; i < len; i++)
  {
    out << finalVerts[i];

    if(i < len - 1)
      out << ",";
  }

  out << "]";

  // Normals
  out << ",\"Normals\": [";

  len = finalNorms.size();
  for(int i = 0; i < len; i++)
  {
    out << finalNorms[i];

    if(i < len - 1)
      out << ",";
  }

  out << "]";

  // Textures
  out << ",\"Textures\": [";

  len = finalTextures.size();
  for(int i = 0; i < len; i++)
  {
    out << finalTextures[i];

    if(i < len - 1)
      out << ",";
  }

  out << "]";

  // Textures
  out << ",\"Textures\": [";

  len = finalTextures.size();
  for(int i = 0; i < len; i++)
  {
    out << finalTextures[i];

    if(i < len - 1)
      out << ",";
  }

  out << "]";

  // Faces
  out << ",\"Faces\": [";

  len = faces.size();
  for(int i = 0; i < len; i++)
  {
    out << faces[i];

    if(i < len - 1)
      out << ",";
  }

  out << "]";

  out << "}";

  if(aVerbose) cout << "All done!" << endl;
  out.close();
}
</pre>
</div>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/cs-238-exploration-2-slight-progress/" rel="bookmark" class="crp_title">CS 238 Exploration 2 &#8211; Slight Progress</a></p><p><a href="http://www.rodrigo-silveira.com/cs-238-exploration-2/" rel="bookmark" class="crp_title">CS 238 Exploration 2</a></p><p><a href="http://www.rodrigo-silveira.com/zero-one-matrix-relations/" rel="bookmark" class="crp_title">Zero-one Matrix Relations &raquo; CS238 Exploration 3</a></p><p><a href="http://www.rodrigo-silveira.com/3d-programming-transformation-matrix-tutorial/" rel="bookmark" class="crp_title">3D Programming: Transformation Matrix Tutorial</a></p><p><a href="http://www.rodrigo-silveira.com/binary-matrix-multiplication/" rel="bookmark" class="crp_title">Binary Matrix Multiplication</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/opengl-tutorial-parsing-obj-file-blender/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Web Toolkit: Failed to Connect</title>
		<link>http://www.rodrigo-silveira.com/gwt-unable-connect/</link>
		<comments>http://www.rodrigo-silveira.com/gwt-unable-connect/#comments</comments>
		<pubDate>Sat, 10 Mar 2012 07:22:49 +0000</pubDate>
		<dc:creator>Rodrigo Silveira</dc:creator>
				<category><![CDATA[GWT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://www.rodrigo-silveira.com/?p=273</guid>
		<description><![CDATA[This post presents a solution to debugging the problem in Eclipse when you try to launch a GWT project and the project won't load in the browser. If you've searched around for this problem, you'll probably see this problem referred to as: 
 
<strong>GWT 2.0.2 : Failed to Connect 127.0.0.1:8888 development mode</strong>]]></description>
			<content:encoded><![CDATA[<p>This post presents a solution to debugging the problem in Eclipse when you try to launch a GWT project and the project won&#8217;t load in the browser. If you&#8217;ve searched around for this problem, you&#8217;ll probably see this problem referred to as:</p>
<p><strong>GWT 2.0.2 : Failed to Connect 127.0.0.1:8888 development mode</strong></p>
<p>Today I got my new laptop in the mail. The very first thing I did was download all my usual development tools. Eclipse was one of the first things I downloaded, followed immediately by the installation of Google Web Toolkit (GWT). As I tried to launch the quick sample application just to make sure everything was working fine, I was frustrated to be greeted by a Oops! Google Chrome failed to connect.</p>
<p>In Mozilla Firefox, the error message was something like:</p>
<p><strong>Page load errorFailed to ConnectFirefox can&#8217;t establish a connection to the server at 127.0.0.1:8888.</strong></p>
<p>After searching around, I found various blog entries and forums messages that suggested that you change the 127.0.0.1 to localhost. To me, as it appears to have happened to a lot of other people in those forums, this did not help. So I played around with Eclipse and found a solution to this problem. So if you&#8217;re trying to compile and develop your GWT applications, but your browser says that you were not able to connect to the app, try the following:</p>
<h1>The Solution</h1>
<p>In your Eclipse IDE, go to the main navigation bar and choose the option <strong>Run</strong>, then <strong>Run Configurations</strong>.</p>
<p>Now find the tab with the blue Google icon labeled <strong>Server</strong>. Check the box that says <strong>Run built-in server</strong>, which will allow you to also check the check box for <strong>Automatically select an unused port </strong>(so be sure to check this box also).</p>
<p>Then find the next tab over, which is labeled <strong>GWT</strong>. Repeat the same step, meaning, check the check box labeled <strong>Automatically select an unused port</strong>. Hit apply, then run. Now you Google Web Toolkit applications will work fine.</p>
<p>As a final step, but one that Chrome will guide you through, you will need to enable the browser extension that allows you to run GWT projects from the IDE into the browser. But I&#8217;m sure you can figure this part out if you get this far. Besides, the browser will tell you to enable the extension (plug-in), and give you a button to click and install it. Should be pretty easy.</p>
<p>Enjoy!</p>
<div id="crp_related"><h1> Related Posts</h1><p><a href="http://www.rodrigo-silveira.com/webgl-inspector-debug-tool/" rel="bookmark" class="crp_title">WebGL Inspector: Debug OpenGL on the Browser</a></p><p><a href="http://www.rodrigo-silveira.com/zero-one-matrix-relations/" rel="bookmark" class="crp_title">Zero-one Matrix Relations &raquo; CS238 Exploration 3</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-3d-demos/" rel="bookmark" class="crp_title">My First WebGL 3D Demos: Hello, World (of OpenGL)</a></p><p><a href="http://www.rodrigo-silveira.com/webgl-quake/" rel="bookmark" class="crp_title">Webgl Quake</a></p><p><a href="http://www.rodrigo-silveira.com/html5-stock-market-simulation-php/" rel="bookmark" class="crp_title">HTML5 Stock Market Simulation in PHP</a></p></div>]]></content:encoded>
			<wfw:commentRss>http://www.rodrigo-silveira.com/gwt-unable-connect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- www.000webhost.com Analytics Code -->
<script type="text/javascript" src="http://stats.hosting24.com/count.php"></script>
<noscript><a href="http://www.hosting24.com/"><img src="http://stats.hosting24.com/count.php" alt="web hosting" /></a></noscript>
<!-- End Of Analytics Code -->

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/54 queries in 0.248 seconds using disk: basic
Object Caching 1800/1885 objects using disk: basic

Served from: www.rodrigo-silveira.com @ 2012-05-20 00:21:31 -->
