<?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>Last Stop</title>
	<atom:link href="http://laststop.spaceislimited.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://laststop.spaceislimited.org</link>
	<description>it&#039;s going to be a long ride</description>
	<lastBuildDate>Wed, 28 Jan 2009 13:21:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Programming Pong in C and OpenGL &#8211; Part VI</title>
		<link>http://laststop.spaceislimited.org/2009/01/19/programming-pong-in-c-and-opengl-part-vi/</link>
		<comments>http://laststop.spaceislimited.org/2009/01/19/programming-pong-in-c-and-opengl-part-vi/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 13:32:23 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Technical Nonsense]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[pong]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=57</guid>
		<description><![CDATA[Here&#8217;s the last part of my multi-part series on programming your very own pong clone in c and opengl!  It&#8217;s been a long time coming, so I hope you enjoy.  There&#8217;s lots of improvements in this version including a completely custom old-style &#8220;LED Alarm Clock&#8221; scoreboard, flashes on bounce, funky changing colors, improved collision detection, [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_61" class="wp-caption aligncenter" style="width: 409px"><a href="http://laststop.spaceislimited.org/wp-content/uploads/2009/01/timgl_05.png"><img class="size-full" title="Awesome Flashy Pong!" src="http://laststop.spaceislimited.org/wp-content/uploads/2009/01/timgl_05.png" alt="The latest version of my sample clone with scoreboard, etc." width="399" height="414" /></a><p class="wp-caption-text">The latest version of my sample clone!</p></div>
<p>Here&#8217;s the last part of my multi-part series on programming your very own pong clone in c and opengl!  It&#8217;s been a long time coming, so I hope you enjoy.  There&#8217;s lots of improvements in this version including a completely custom old-style &#8220;LED Alarm Clock&#8221; scoreboard, flashes on bounce, funky changing colors, improved collision detection, and a round ball! <img src='http://laststop.spaceislimited.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><span id="more-57"></span></p>
<p>Here&#8217;s the code!</p>
<pre class="brush: c">

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;math.h&gt;

#include &lt;OpenAL/al.h&gt;
#include &lt;GLUT/glut.h&gt;

#define PADDLE_MOVE_SPEED 350
#define CLEAR_COLOR_DECAY 2.0
#define BALL_RADIUS 10
#define BALL_FACETS 60
#define START_SPEED 200

int lastFrameTime = 0, windowWidth = 0, windowHeight = 0, now = 0;
float midWidth = 0, midHeight = 0;
float elapsedTime = 0, elapsedMilliSeconds = 0;
char player1Move = 0, player2Move = 0;
float player1V = 0, player2V = 0;

float PI = 3.14159265358979323846264;

//scores
int player1Score = 0, player2Score = 0;

//the following variables calculate a random starting projectile trajectory
float randomDirection;
long longMax = 0x7fffffff;	//max of longs 2^31-1 (2^(n-1)-1 for 2&#039;s complement) float trajectory[2] = {0, 0};

float projMove[2] = {0, 0};
double trajectory[2] = {0, 0};
short moveSpeed = START_SPEED;

//glitz and glamour
float player1ColorDirection[3];
float player2ColorDirection[3];
float player1Color[3];
float player2Color[3];
float colorMoveSpeed = 2.0;
double vectorLength1 = 0;
double vectorLength2 = 0;

float ballColorDirection[3];
float ballColor[3];
double ballVectorLength = 0;

//background explosion color
float clearColor[3];

int i = 0;

//scoreboard
char player1Num1[7] = {1, 1, 1, 0, 1, 1, 1};	//digital display set to zero, (each segment is enabled or disabled)
char player1Num2[7] = {1, 1, 1, 0, 1, 1, 1};
char player2Num1[7] = {1, 1, 1, 0, 1, 1, 1};	//digital display set to zero, (each segment is enabled or disabled)
char player2Num2[7] = {1, 1, 1, 0, 1, 1, 1};

//digit representations
char digit0[7] = {1, 1, 1, 0, 1, 1, 1};
char digit1[7] = {0, 0, 1, 0, 0, 0, 1};
char digit2[7] = {0, 1, 1, 1, 1, 1, 0};
char digit3[7] = {0, 1, 1, 1, 0, 1, 1};
char digit4[7] = {1, 0, 1, 1, 0, 0, 1};
char digit5[7] = {1, 1, 0, 1, 0, 1, 1};
char digit6[7] = {1, 1, 0, 1, 1, 1, 1};
char digit7[7] = {0, 1, 1, 0, 0, 0, 1};
char digit8[7] = {1, 1, 1, 1, 1, 1, 1};
char digit9[7] = {1, 1, 1, 1, 0, 1, 1};

void setSpaceEffect(void) {
for (i=0; i &lt; 3; i++) {
player1ColorDirection[i] = (float) random() / (float) 0x7fffffff; //random vector
player2ColorDirection[i] = (float) random() / (float) 0x7fffffff;
ballColorDirection[i] = (float) random() / (float) 0x7fffffff;
}
//figure out vector lenngth
for (i=0; i &lt; 3; i++) {
vectorLength1 += player1ColorDirection[i] * player1ColorDirection[i];
vectorLength2 += player2ColorDirection[i] * player2ColorDirection[i];
ballVectorLength += ballColorDirection[i] * ballColorDirection[i];
}
sqrt(vectorLength1);
sqrt(vectorLength2);
sqrt(ballVectorLength);
//normalize vector
for (i=0; i &lt; 3; i++) {
player1ColorDirection[i] /= vectorLength1;
player2ColorDirection[i] /= vectorLength2;
ballColorDirection[i] /= ballVectorLength;
}
}

void calculateColor(float color[3], float colorDirection[3]) {
//caculate the next color based on the direction and elapsed time values
for (i=0; i &lt; 3; i++) {
color[i] += colorDirection[i] * colorMoveSpeed * elapsedTime;
if (color[i] &gt; 1) {
color[i] = 1;
colorDirection[i] *= -1;
}
else if (color[i] &lt; 0) {
color[i] = 0;
colorDirection[i] *= -1;
}
}
}

void calculateClearColor(float color[3]) {
for (i=0; i &lt; 3; i++) {
color[i] -= CLEAR_COLOR_DECAY * elapsedTime;
if(color[i] &lt; 0)
color[i] = 0;
}
}

void setClearColor(float color[3]) {
for (i=0; i &lt; 3; i++) {
color[i] = 1.0;
}
}

void resetProjectile(void) {
//set starting random trajectory
randomDirection = 2 * PI * (float) random() / (float) 0x7fffffff;
trajectory[0] = (float) cos(randomDirection);
trajectory[1] = (float) sin(randomDirection);
projMove[0] = midWidth;
projMove[1] = midHeight;
}

/*draw a digital (a la clock style) digit some place specified by x and y
*the enabled array is which segments of the display are enabled (counted starting from top left in a snake/8 fasion)
*
* 1 -
* 0| |2
* 3 -
* 4| |6
* 5 -
*/
void drawDigit(char enabled[7], float x, float y) {
glPushMatrix();
glTranslatef(x, y, 0);	//position digit to be drawn
//draw digital number (a la digital clock) segment by segment
glColor3f(1.0, 1.0, 1.0);
//draw segment 5
if(enabled[5]) {
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(10,0);
glVertex2f(10,2);
glVertex2f(0,2);
glEnd();
}

//draw segment 3
if(enabled[3]) {
glBegin(GL_QUADS);
glVertex2f(0,9);
glVertex2f(10,9);
glVertex2f(10,11);
glVertex2f(0,11);
glEnd();
}

//draw segment 1
if(enabled[1]) {
glBegin(GL_QUADS);
glVertex2f(0,18);
glVertex2f(10,18);
glVertex2f(10,20);
glVertex2f(0,20);
glEnd();
}

//draw segment 4
if(enabled[4]) {
glBegin(GL_QUADS);
glVertex2f(0,2);
glVertex2f(2,2);
glVertex2f(2,9);
glVertex2f(0,9);
glEnd();
}

//draw segment 0
if(enabled[0]) {
glBegin(GL_QUADS);
glVertex2f(0,11);
glVertex2f(2,11);
glVertex2f(2,20);
glVertex2f(0,20);
glEnd();
}

//draw segment 6
if(enabled[6]) {
glBegin(GL_QUADS);
glVertex2f(8,2);
glVertex2f(10,2);
glVertex2f(10,9);
glVertex2f(8,9);
glEnd();
}

//draw segment 2
if(enabled[2]) {
glBegin(GL_QUADS);
glVertex2f(8,11);
glVertex2f(10,11);
glVertex2f(10,20);
glVertex2f(8,20);
glEnd();
}

glPopMatrix();
}

void setDigitEnablePattern(char enabled[7], char digit) {

switch(digit) {
case 0:
for(i=0; i&lt;7; i++) {
enabled[i] = digit0[i];
}
break;
case 1:
for(i=0; i&lt;7; i++) {
enabled[i] = digit1[i];
}
break;
case 2:
for(i=0; i&lt;7; i++) {
enabled[i] = digit2[i];
}
break;
case 3:
for(i=0; i&lt;7; i++) {
enabled[i] = digit3[i];
}
break;
case 4:
for(i=0; i&lt;7; i++) {
enabled[i] = digit4[i];
}
break;
case 5:
for(i=0; i&lt;7; i++) {
enabled[i] = digit5[i];
}
break;
case 6:
for(i=0; i&lt;7; i++) {
enabled[i] = digit6[i];
}
break;
case 7:
for(i=0; i&lt;7; i++) {
enabled[i] = digit7[i];
}
break;
case 8:
for(i=0; i&lt;7; i++) {
enabled[i] = digit8[i];
}
break;
case 9:
for(i=0; i&lt;7; i++) {
enabled[i] = digit9[i];
}
break;
}
}

void drawScore(char player1, char player2) {

if(player1 &lt; 10) {
setDigitEnablePattern(player1Num1, 0);
setDigitEnablePattern(player1Num2, player1);
}
else if (player1 &lt; 100) {
setDigitEnablePattern(player1Num1, player1 / 10);
setDigitEnablePattern(player1Num2, player1 - ((player1/10) * 10));
}
else {	//max out at 99
setDigitEnablePattern(player1Num1, 9);
setDigitEnablePattern(player1Num2, 9);
}

if(player2 &lt; 10) {
setDigitEnablePattern(player2Num1, 0);
setDigitEnablePattern(player2Num2, player2);
}
else if (player2 &lt; 100) {
setDigitEnablePattern(player2Num1, player2 / 10);
setDigitEnablePattern(player2Num2, player2 - ((player2/10) * 10));
}
else {	//max out at 99
setDigitEnablePattern(player2Num1, 9);
setDigitEnablePattern(player2Num2, 9);
}

drawDigit(player1Num1, (windowWidth/4)-15, 20);
drawDigit(player1Num2, (windowWidth/4)+5, 20);
drawDigit(player2Num1, ((windowWidth/4)*3)-15, 20);
drawDigit(player2Num2, ((windowWidth/4)*3)+5, 20);

}

void display(void)
{
//get window parameters
windowWidth = glutGet(GLUT_WINDOW_WIDTH);
windowHeight = glutGet(GLUT_WINDOW_HEIGHT);

midWidth = windowWidth/2;
midHeight = windowHeight/2;

//start timing code
if (lastFrameTime == 0) {
lastFrameTime = glutGet(GLUT_ELAPSED_TIME);
resetProjectile();	//since this is the fist time, this is actually a set <img src='http://laststop.spaceislimited.org/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />
player1V = midHeight;
player2V = midHeight;
//initialize the space effect colors
setSpaceEffect();
glClearColor(0.0, 0.0, 0.0, 0.0);	//set clear color to black
}

now = glutGet(GLUT_ELAPSED_TIME);
elapsedMilliSeconds = now - lastFrameTime;
elapsedTime = elapsedMilliSeconds/1000.0f;
lastFrameTime = now;

calculateClearColor(clearColor);
glClearColor(clearColor[0], clearColor[1], clearColor[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glShadeModel(GL_FLAT);

//draw score
drawScore(player1Score, player2Score);

//calculate move distances
switch (player1Move) {
case 1:		//move up
player1V += PADDLE_MOVE_SPEED * elapsedTime;
break;
case -1:	//move up
player1V -= PADDLE_MOVE_SPEED * elapsedTime;
break;
default:	//do nothing
break;
}
//check out of bounds
if (player1V &gt; windowHeight-50) {
//bounce back
player1Move = -1;
}
if (player1V &lt; 0+50) {
//bounce back other way
player1Move = 1;
}

switch (player2Move) {
case 1:		//move up
player2V += PADDLE_MOVE_SPEED * elapsedTime;
break;
case -1:	//move up
player2V -= PADDLE_MOVE_SPEED * elapsedTime;
break;
default:	//do nothing
break;
}
//check out of bounds
if (player2V &gt; windowHeight-50) {
//bounce back
player2Move = -1;
}
if (player2V &lt; 0+50) {
//bounce back other way
player2Move = 1;
}

//create and position player 1
glPushMatrix();

calculateColor(player1Color, player1ColorDirection);
glColor3f(player1Color[0], player1Color[1], player1Color[2]);	//player 1 color

glTranslatef(30.0f, player1V, 0.0f);

glBegin(GL_QUADS);
glVertex2f(-10, -50);
glVertex2f(-10, 50);
glVertex2f(10, 50);
glVertex2f(10, -50);
glEnd();

glPopMatrix();

//create and position player 2
glPushMatrix();

calculateColor(player2Color, player2ColorDirection);
glColor3f(player2Color[0], player2Color[1], player2Color[2]);	//player 2 color

glTranslatef(windowWidth-30, player2V, 0.0f);

glBegin(GL_QUADS);
glVertex2f(-10, -50);
glVertex2f(-10, 50);
glVertex2f(10, 50);
glVertex2f(10, -50);
glEnd();

glPopMatrix();

/***************************************
*	Projectile CODE!!!
*
***************************************/

//calculate move distances
projMove[0] += moveSpeed * trajectory[0] * elapsedTime;
projMove[1] += moveSpeed * trajectory[1] * elapsedTime;

//create and move projectile
glPushMatrix();

calculateColor(ballColor, ballColorDirection);
glColor3f(ballColor[0], ballColor[1], ballColor[2]);	//player 1 color

glTranslatef(projMove[0], projMove[1], 0.0f);

glBegin(GL_TRIANGLE_FAN);
for(i=0; i &lt; 360; i += 360 / BALL_FACETS) {
glVertex2f(sin(i * PI / 180) * BALL_RADIUS, cos(i * PI / 180) * BALL_RADIUS);
}
glEnd();

glPopMatrix();

//set bounds for projectile
if (projMove[0] &gt; (windowWidth)) {	//player 1 scored - out of bounds right
player1Score++;
moveSpeed = START_SPEED;
printf(&quot;Player 1 Scored!  Score: %f &quot;, player1Score);
resetProjectile();
}

else if (projMove[0] &lt; (0)) {		//player 2 scored - out of bounds left
player2Score++;
moveSpeed = START_SPEED;
resetProjectile();
}

else if (projMove[1] &gt; (windowHeight-10)) {	//out of bounds top
trajectory[1] *= -1;
projMove[1] -= 0.5;
}

else if (projMove[1] &lt; (10)) {	//out of bounds bottom
trajectory[1] *= -1;
projMove[1] += 0.5;
}

//collision detection code
else if (projMove[0] &lt; 50 &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; projMove[0] &gt; 49) {		//intersecting with line of left paddle
if (projMove[1] &lt;= player1V + 50 &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; projMove[1] &gt;= player1V-50) {
trajectory[0] *= -1;
moveSpeed += 30;
setClearColor(clearColor);
projMove[0] += 0.5;
}
}

else if (projMove[0] &gt; windowWidth-50 &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; projMove[0] &lt; windowWidth-49) {		//intersecting with line of right paddle
if (projMove[1] &lt;= player2V + 50 &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; projMove[1] &gt;= player2V-50) {
trajectory[0] *= -1;
moveSpeed += 30;
setClearColor(clearColor);
projMove[0] -= 0.5;
}
}

/******************************
*  END PROJECTILE CODE
*
******************************/

glutSwapBuffers();

}

void reshape(int width, int height)
{
glViewport(0, 0, width, height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
}

void idle(void)
{
glutPostRedisplay();
}

void keyboard(unsigned char key, int x, int y) {
switch (key) {
case &#039;w&#039;:
//do something
player1Move=1;
glutPostRedisplay();
break;
case &#039;s&#039;:
//do something
player1Move=-1;
glutPostRedisplay();
break;
case &#039;o&#039;:
//do something
player2Move=1;
glutPostRedisplay();
break;
case &#039;l&#039;:
//do something
player2Move=-1;
glutPostRedisplay();
break;
default:
//some other key
break;
}

}

void keyboardup(unsigned char key, int x, int y) {
switch (key) {
case &#039;w&#039;:
//do something
player1Move=0;
glutPostRedisplay();
break;
case &#039;s&#039;:
player1Move=0;
glutPostRedisplay();
break;
case &#039;o&#039;:
player2Move=0;
glutPostRedisplay();
break;
case &#039;l&#039;:
player2Move=0;
glutPostRedisplay();
break;
default:
//some other key
break;
}

}

int main(int argc, char** argv)
{
glutInit(&amp;amp;amp;amp;amp;amp;amp;amp;argc, argv);

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(500, 500);

glutCreateWindow(&quot;Tim GL&quot;);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardup);
glutIdleFunc(idle);

glutMainLoop();
return EXIT_SUCCESS;
}
</pre>
<p>I delayed so long because I wanted to refactor this code to better separate components and functions, but I didn&#8217;t get the time to do so.  (That&#8217;s why I should do it that way from the start!)  You can get a direct copy of the binary <a title="TimGL 0.5!" href="/downloads/TimGL_0.5.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2009/01/19/programming-pong-in-c-and-opengl-part-vi/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Connecting to MS SQL Server from Java Recipe</title>
		<link>http://laststop.spaceislimited.org/2008/11/28/connecting-to-ms-sql-server-from-java-recipe/</link>
		<comments>http://laststop.spaceislimited.org/2008/11/28/connecting-to-ms-sql-server-from-java-recipe/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 01:26:43 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Technical Nonsense]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[connect]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[ms sql server]]></category>
		<category><![CDATA[recipe]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sql server]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=44</guid>
		<description><![CDATA[I thought I&#8217;d provide a recipe for how to connect to SQL Server from Java.  The following is a quick, relatively clean way to connect to Microsoft&#8217;s SQL Server from Java without going through too much voodoo&#8211;as is often the case when trying to connect to MS SQL Server through a non-microsoft language.  Luckily, Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I&#8217;d provide a recipe for how to connect to SQL Server from Java.  The following is a quick, relatively clean way to connect to Microsoft&#8217;s SQL Server from Java without going through too much voodoo&#8211;as is often the case when trying to connect to MS SQL Server through a non-microsoft language.  Luckily, Microsoft provides a pure Java JDBC driver for connecting to it&#8217;s server!  You can find it <a title="MS SQL JDBC 2005" href="http://msdn.microsoft.com/en-us/data/aa937724.aspx" target="_blank">here</a>.  Don&#8217;t forget to properly include in your Java project!  Also, even though it&#8217;s the MS SQL 2k3 driver, it works perfectly fine with MS SQL 2000 (so you might as well just use this driver).</p>
<p><span id="more-44"></span></p>
<pre class="brush: java">

/*
* Main.java
*
* Created on November 27, 2008, 3:56 PM
*
*/

package sqlserversample;

import java.sql.*;
import com.microsoft.sqlserver.jdbc.*;

/**
*
* @author Timothy M. Rodriguez
*/

public class Main {

/* jdbc driver name and database url
* ms sql uses port 1433
* replace &quot;mysqlserver&quot; with the ip and host of your database
* if connecting from a *nix box, don&#039;t forget to use the FQDN and not just the NetBIOS host
* if not, the ip is a safe bet
*/
private static final String DATABASE_URL = &quot;jdbc:sqlserver://mysqlserver:1433&quot;;
private static final String DRIVER = &quot;com.microsoft.sqlserver.jdbc.sqlserverdriver&quot;;

//used to connect to the database
private static Connection connection = null;
//used to execute queries on the database
private static Statement statement = null;
//this object is used to store your result sets
private static ResultSet resultSet = null;
//this object is used to stored data about the table
private static ResultSetMetaData metaData = null;

/** Creates a new instance of Main */
public Main() {
//default constructor
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

try {
// load the driver class

//this should work, but doesn&#039;t, not sure why, let me know in the comments if you do
// Class.forName(DRIVER);
// instead i created it this way
SQLServerDriver sqlServerDriver = new SQLServerDriver();
/*
* I manually created a SQLServerDriver instance, this is due to
* complications with the classpath establish connection to db
*/
DriverManager.registerDriver(sqlServerDriver);
connection = DriverManager.getConnection(DATABASE_URL,
&quot;user&quot;, &quot;password&quot;);

// create the statement for querying
statement = connection.createStatement();

//put your query string in the executeQuery method argument
resultSet = statement.executeQuery(&quot;SELECT TOP 10 * FROM Table&quot;);
metaData = resultSet.getMetaData();
//I didn&#039;t use the metadata object, but showed you how to create it
//the metaData object can be used to get column names and indices, column types, etc.

while(resultSet.next()) {
//the get object method is useful if you don&#039;t want to bother with the column type
System.out.println(resultSet.getObject(3).toString());
}

} catch (SQLException sqlException) {
//couldn&#039;t connect to the db or execute a query
sqlException.printStackTrace();
/* in a real webapp, you don&#039;t want to be printing stack traces
* instead print a nice error page that doesn&#039;t include internal information
*  For example, &quot;oops, it blew up&quot;
*/
}
}
}
</pre>
<p>That&#8217;s it, I hope that helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/11/28/connecting-to-ms-sql-server-from-java-recipe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Election 2008</title>
		<link>http://laststop.spaceislimited.org/2008/11/02/election-2008/</link>
		<comments>http://laststop.spaceislimited.org/2008/11/02/election-2008/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 18:59:57 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Awesome]]></category>
		<category><![CDATA[2008]]></category>
		<category><![CDATA[barack]]></category>
		<category><![CDATA[barack obama]]></category>
		<category><![CDATA[change]]></category>
		<category><![CDATA[democrat]]></category>
		<category><![CDATA[election]]></category>
		<category><![CDATA[obama]]></category>
		<category><![CDATA[vote]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=39</guid>
		<description><![CDATA[
I&#8217;ve never seen a candidate motivate so many people.  It is liberating to see people of all ages, races, and geography standing up in unison.
Barack Obama is in a unique position to carry our voices beyond deaf ears and shape a better America.
Vote on November 4th, 2008.
Vote for Change.
]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.telegraph.co.uk/news/picturegalleries/worldnews/3274893/Barack-Obama-campaigns-in-the-rain-in-Chester-Pennsylvania.html"><img class="aligncenter size-full wp-image-40" title="Barack Obama in the Pouring Rain" src="http://laststop.spaceislimited.org/wp-content/uploads/2008/11/raining_1016733i.jpg" alt="" width="349" height="225" /></a></p>
<p>I&#8217;ve never seen a candidate motivate so many people.  It is liberating to see people of all ages, races, and geography standing up in unison.</p>
<p>Barack Obama is in a unique position to carry our voices beyond deaf ears and shape a better America.</p>
<p>Vote on November 4th, 2008.</p>
<p>Vote for Change.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/11/02/election-2008/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A New Way To Surf &#8211; LP</title>
		<link>http://laststop.spaceislimited.org/2008/10/12/a-new-way-to-surf-lp/</link>
		<comments>http://laststop.spaceislimited.org/2008/10/12/a-new-way-to-surf-lp/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 19:09:42 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[LPlayer]]></category>
		<category><![CDATA[Technical Nonsense]]></category>
		<category><![CDATA[LP]]></category>
		<category><![CDATA[lpxml]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[standard]]></category>
		<category><![CDATA[tv]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=8</guid>
		<description><![CDATA[
Everyone&#8217;s talking about IP TV and how it&#8217;s going to revolutionize things.  We&#8217;ll be able to get our TV anywhere, any way, but the reality has fallen short of the promise.   Your ISP may be beaming Digital channels down to you over IP, but the experience is largely unique to your ISP. [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://laststop.spaceislimited.org/wp-content/uploads/2008/10/video-tv.png"><img class="size-full wp-image-32 aligncenter" title="Old School TV" src="http://laststop.spaceislimited.org/wp-content/uploads/2008/10/video-tv.png" alt="Gotta love it!" width="314" height="346" /></a></p>
<p>Everyone&#8217;s talking about IP TV and how it&#8217;s going to revolutionize things.  We&#8217;ll be able to get our TV anywhere, any way, but the reality has fallen short of the promise.   Your ISP may be beaming Digital channels down to you over IP, but the experience is largely unique to your ISP.  <strong>Your cable box is not a TV Content browser</strong>, no matter how much it tries to be.  Heck, you can&#8217;t even take your Time Warner Cable box and easily connect it to a Comcast user&#8217;s home.  The <em>spirit</em> of the IP in <em>IP</em>TV is sorely missing.</p>
<p>That&#8217;s why I&#8217;m working on a better way&#8211;and I need your help.</p>
<p>There are several standards regarding IPTV (and they are used), but while they focus on <em>delivering</em> the content, they do not focus on the <em>programming</em>.  If you&#8217;re looking at the web to solve your problem, don&#8217;t look there either.  Every single news or content producer has their own site with their own way of accessing it.  You need accounts, you need a pretty hefty browser, and you need to wade through a different interface each and every time.</p>
<h3>There is no way to channel surf on the web.</h3>
<h2><span id="more-8"></span></h2>
<h2>What about RSS?</h2>
<p>RSS is great!  I love it, but it drastically changes consumption of media, albeit in a very Web way.  TiVO&#8217;s and DVR&#8217;s help bridge this gap on the classic TV side, but what about programming?  Sometimes I don&#8217;t want to pick what to watch.  Sometimes I just want to flip through channels and see what&#8217;s on.  RSS does not replace programming.  (I&#8217;d also like to take this moment to give a big shout-out to <a title="Miro" href="http://www.miro.com" target="_blank">Miro</a>, which is an amazing application for automagically downloading and managing video RSS feeds.) We need something more.</p>
<h2>A New Way to <em>Surf</em></h2>
<p>What we need is a format for serving up programming that goes beyond a fixed stream.  We need a way of mixing up content, and the web.  We also need a better way of consuming it all.  Without giving it an official name, I&#8217;m going to call this protocol LP.  Imagine if you could pull down a link to your favorite channel&#8217;s programming and view content live.  It&#8217;s not a stream, it&#8217;s a url your LP player goes to and it contains all the information you need to find out what&#8217;s playing now on your favorite channel.  Heck, why stop with now?  Maybe it&#8217;s all pre-recorded and you can skip to what&#8217;s playing later?  Maybe, you want to see what was on before?  Who needs a DVR?  The content should stay available and you should be able to consume it.  What I&#8217;m talking about is a REST API for navigating video and audio content.</p>
<h3><strong>A Trudge Through the Mud</strong></h3>
<p><span style="text-decoration: line-through;">I first started writing this post four months ago and I kept putting it off.</span> Then I wrote some more and put it off a few more months.  I had all these ideas in my head and I wanted to get them all out in one go.  I wanted to have a working prototype of an LP Server and Player, of the &#8220;LPXML&#8221; format, and have all the whizz-bang features I wanted to put into it.  The fact of the matter is I&#8217;m busy and it will take me forever to settle my ideas if I don&#8217;t just start and get something out there.  So I&#8217;m going to start with just the basics of what I think this &#8220;informal&#8221; standard should look like.</p>
<p>And I&#8217;m definitely looking for feedback.</p>
<p>What I&#8217;m proposing is that an LP player take a link to a website (e.g. www.spaceislimited.org/lplayer/) and this will be the root of the lplayer REST interface for my site (the link is hypothetical btw).  The Lplayer application (this could even be Miro if this catches on) would then know the following structure for the REST inteface.</p>
<p>lplayer/now/ &#8211; This verb will respond with a page that will contain the URL of the content that is currently now playing.  For example, the Lplayer goes to lplayer/now/ and get this response:</p>
<p>&lt;code&gt;</p>
<p>&lt;a href=&#8221;http://spaceislimited.org/videos/awesomevid1.lpxml&#8221; /&gt;</p>
<p>That&#8217;s it.  Nothing else.  Maybe eventually we&#8217;ll specify an XML doctype and wrap it in something like:</p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;</p>
<p>&lt;lp version=&#8221;0.1&#8243; xmlns:lpxml=&#8221;http://www.lpxml.org/lpxml.dtd&#8221;&gt;</p>
<p>&lt;program&gt;http://spaceislimited.org/videos/awesomevid1.lpxml&lt;/program&gt;</p>
<p>&lt;elapsed&gt;20&lt;/elapsed&gt;</p>
<p>&lt;/lp&gt;</p>
<p>&lt;/code&gt;</p>
<p>The player would then follow that link to get the content and some meta data about the content.  It would also  use the elapsed value to sync up with how far into the program everyone is.  Of course, if it&#8217;s a live stream, the elapsed value may not be necessary.  The program link might look something like this:</p>
<p>&lt;code&gt;</p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;</p>
<p>&lt;lp version=&#8221;0.1&#8243; xmlns:lpxml=&#8221;http://www.lpxml.org/lpxml.dtd&#8221;&gt;</p>
<p>&lt;content size=&#8221;small&#8221; codec=&#8221;quicktime&#8221; bitrate=&#8221;100k&#8221;&gt;http://spaceislimited.org/videos/awesomevid1_lowres.mov&lt;content/&gt;</p>
<p>&lt;content size=&#8221;medium&#8221; codec=&#8221;quicktime&#8221; bitrate=&#8221;200k&#8221;&gt;http://spaceislimited.org/videos/awesomevid1_mediumres.mov&lt;content/&gt;</p>
<div>
<p>&lt;content size=&#8221;high&#8221; codec=&#8221;quicktime&#8221; bitrate=&#8221;300k&#8221;&gt;http://spaceislimited.org/videos/awesomevid1_highres.move&lt;content/&gt;</p>
<p>&lt;language&gt;en-us&lt;/language&gt;</p>
<p>&lt;title&gt;Awesome Vid &#8211; 1&lt;/title&gt;</p>
<p>&lt;description&gt;This is part one of an awesome video I made and you should check it out.&lt;/description&gt;</p></div>
<p>&lt;/lp&gt;</p>
<p>&lt;/code&gt;</p>
<p>Depending on the player, it can choose one of three files to stream, each with a different bitrate.  For example, if you had an LPlayer on your iPhone, maybe it would choose the 100k stream, while your home computer might opt for the 300k stream.  Also, the rest of the meta-data is standard stuff which could be used within the application.</p>
<p>So what happens when the video is done?  Simple, the player would then go fetch the /lplayer/now/ link again and get what&#8217;s playing now!  If it still sees the same entry, it might wait a few seconds and try again (maybe your lp server site is so awesome it&#8217;s having trouble responding).  Or the application could try /lplayer/next/ and get what&#8217;s playing next.  That way, your iPhone can start buffering what&#8217;s next a few seconds before!</p>
<h2>A Call to Arms</h2>
<p>I&#8217;m publishing this as an informal standard and I&#8217;d love to see your comments behind this.  More than that, I&#8217;d love to see people who are willing to work on this with me on setting up a community around this and implementing a free server and player for the &#8220;LP&#8221; standard.  For this standard to work, it needs to be open, simple, and platform and codec agnostic.  I haven&#8217;t said anything about needing to use the QuickTime codec or having to choose a standard bitrate.  This is about discovery and enabling the player to make the right choice.  Attached is the standard&#8211;plain and simple for now.  In the coming weeks I&#8217;m going to work on <span style="text-decoration: line-through;">getting a site</span> (<a title="LPXML.ORG" href="http://www.lpxml.org" target="_blank">lpxml.org</a>), wiki, forum, and <span style="text-decoration: line-through;">mailing list</span> (lpxml [at] googlegroups [dot] com) setup so we as a community can work on this.  I hope you&#8217;ll join me.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/10/12/a-new-way-to-surf-lp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>An Unlikely Monopoly &#8211; What&#8217;s Wrong with Google AdSense</title>
		<link>http://laststop.spaceislimited.org/2008/07/30/an-unlikely-monopoly-whats-wrong-with-google-adsense/</link>
		<comments>http://laststop.spaceislimited.org/2008/07/30/an-unlikely-monopoly-whats-wrong-with-google-adsense/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 01:31:33 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Rants]]></category>
		<category><![CDATA[adsense]]></category>
		<category><![CDATA[advertising]]></category>
		<category><![CDATA[ask]]></category>
		<category><![CDATA[bidvertiser]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[monopoly]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=24</guid>
		<description><![CDATA[
There&#8217;s an elephant in the room when it comes to the internet.  Microsoft wishes it was them, Yahoo&#8217;s just had too much to drink, and there&#8217;s a big purple elephant in the corner &#8212; Google.

A Blogger&#8217;s Worst Nightmare
It&#8217;s a blogger&#8217;s worst nightmare.  One day you open up your e-mail and receive a message [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://laststop.spaceislimited.org/wp-content/uploads/2008/07/elephant.jpg"><img class="aligncenter size-full wp-image-25" title="Google, The Purple Elephant" src="http://laststop.spaceislimited.org/wp-content/uploads/2008/07/elephant.jpg" alt="" width="400" height="183" /></a></p>
<p>There&#8217;s an elephant in the room when it comes to the internet.  Microsoft wishes it was them, Yahoo&#8217;s just had too much to drink, and there&#8217;s a big purple elephant in the corner &#8212; Google.</p>
<p><span id="more-24"></span></p>
<h3>A Blogger&#8217;s Worst Nightmare</h3>
<p>It&#8217;s a blogger&#8217;s worst nightmare.  One day you open up your e-mail and receive a message from the Google AdSense team notifying you that your AdSense account has been disabled.  Your heart sinks and your stomach is in your throat.  The problem is we didn&#8217;t <em>do</em> anything.  (I say we because <a title="La Disputa" href="http://ladisputa.spaceislimited.org" target="_blank">La Disputa</a> and <a title="Last Stop" href="http://laststop.spaceislimited.org" target="_blank">Last Stop</a> share an AdSense account.)  The AdSense e-mail also provides little chance of recourse.  Basically, they provide a link for &#8220;more information&#8221;.  The link explains in roundabout ways that you were a risk to advertisers and then goes on to indirectly say that you committed click fraud.  They don&#8217;t offer any details as to how they came to this conclusion.  Suffice it to say, they have their ways.</p>
<p>Scrambling to get our AdSense account back we quickly filed an appeal.  We didn&#8217;t know what to say, but we guessed and assumed that maybe our parents clicked our ads since we told them we make money on advertising on ads, but we failed to mention &#8220;please don&#8217;t click our ads&#8221;.  The reason for this seems plausible enough, so we wrote up an appeal assuming that this must be it and said we fully support removing any earnings they deemed fraudulent and that we would be sure to always tell people <em>not</em> to click our ads in the future.  We really thought we&#8217;d be okay, this was just a one-off thing.  Heck, we started our blogs only a few months ago and our earnings were really insignificant.  Two days later we get another e-mail saying our appeal was denied.   And with Google, you only get one appeal.    We were screwed.  I&#8217;ve read other blogs saying sometimes people have gotten lucky on the second or third try, but this didn&#8217;t look good.</p>
<p>The truth is we probably made a mistake in assuming (you know what happens when you <em>assume</em>) when coming up with an excuse, as upon conferring with our parents, we now know they <em>weren&#8217;t</em> clicking our ads.  But the truth was we didn&#8217;t know.  In fact, we said that in our appeal.  With Google&#8217;s lack of information, we probably will never know.</p>
<h3>The Only Game In Town</h3>
<p>In a haste to get advertising back, I scoured the net for AdSense alternatives.  I knew Google was pretty much the best out there, but I didn&#8217;t know just how desolate the field really was.  The only half-way decent options require a huge amount of traffic and the rest are absolute junk.  You can tell just by looking at their website.  And if you look at the big bloggers, they fully support diversifying your ad networks, but <a title="Self Made Blogger" href="http://selfmademinds.com/200801/income-breakdown-for-december-2007/" target="_blank">they</a> make most of their money from AdSense.  As far as blogs go, we were DOA.</p>
<p>I read up some more on Google Appeals and decided to try again.  This time I took a more careful approach, I reviewed our traffic logs and found out that social networking spikes can trip off the google &#8220;invalid click detector&#8221;.  I submitted our traffic logs and said that after conferring with our parents we realized they didn&#8217;t click on our ads.  The appeal was very cordial and polite and we were hoping against hope we&#8217;d get our account enabled.  It&#8217;s been several weeks.</p>
<p>And we never got a response.</p>
<h3>No Warning</h3>
<p>It&#8217;s strange, but being at the mercy of Google has been a rude awakening.  It reminded me of a conversation I had where I argued that any company of large enough size eventually becomes evil.  My roommate at the time, knowing I really liked Google, quipped, &#8220;How about Google and their &#8216;Don&#8217;t Be Evil&#8217;?&#8221;.  I said, it&#8217;d happen eventually.</p>
<h3>Eventually</h3>
<p>No, I don&#8217;t think we&#8217;re their yet, but we are starting to see signs of Google increasingly not having the best interests of it&#8217;s customer&#8217;s at heart.  Google has finally ceded censorship and privacy concerns in China and I know of several people who have many big complaints against the Big G.  I think Google&#8217;s a great company, with some of the best engineers around, but there&#8217;s no denying that for Google (or any company) it gets harder and harder to not be evil the more money there is on the table.  But this isn&#8217;t a story of Google being evil.  It&#8217;s a case of poor service.  Seriously, Google didn&#8217;t give us a warning saying they were starting to see invalid click activity.  Hell, if they know what it is, why not remove it from our earnings?  They never gave us a second chance and reinstated our account.  We never physically spoke to someone.  It was disabled.  That&#8217;s it.  No number to call, no e-mail address, just an appeal form and automated responses.</p>
<h3>The Whole Internet at One&#8217;s Whimsy</h3>
<p>I guess I&#8217;m glad it happened now.  Imagine if this blog took off overnight and really started to rake in money.  Now what if I quit my job to blog full-time only to find this all happen to me two weeks later?  To understand the gravity of this remember that Google has my Social Security number and now that I&#8217;m blocked, I&#8217;m blocked for <strong>life</strong>.  This means I don&#8217;t have a good way to monetize any webapp I might come up with or another blog idea.  This can happen to <strong>anyone</strong> and it&#8217;s the primary reason why you should diversify your ad inventory.  The problem is there really isn&#8217;t a good alternative.  To even get to the point of blogging full-time, you really need Google.  In fact, the internet is very largely dependent on Google.  Not for search, but for AdSense.  This is especially true when you consider the low-end.  A startup today won&#8217;t qualify for the other &#8220;big&#8221; ad networks, they just don&#8217;t have enough volume.  And without advertising, startups have a very chicken-and-egg problem.  This can (and probably is) stifling innovation on the internet.  With Google as it&#8217;s sole competitor in online advertising, who decides keyword pricing?  Who decides pay-out ratios?  Who decides whether you&#8217;re a risk or not?  Certainly not the market.</p>
<h3>No Competiton</h3>
<p>Here&#8217;s a list of the options I&#8217;ve tried.</p>
<ul>
<li>Yahoo &#8211; They&#8217;re taking applications, but people on the internet are saying they&#8217;re not hearing back from them.  It&#8217;s been this way for months.  I know, I&#8217;ve tried too.</li>
<li>Ask &#8211; They have an advertising platform, but I can&#8217;t find the sign-up page anymore.  I don&#8217;t think it&#8217;s public.  If someone else knows, please clue me in.</li>
<li>Microsoft &#8211; You have to be a big player and they&#8217;re a similar to Yahoo, taking on little more ad inventory until they can figure out how to compete against Google.</li>
<li>Clicksor &#8211; They sent me an e-mail saying my e-mail address was incorrect.  I reapplied and fixed it and they haven&#8217;t gotten back to me.</li>
<li>Bidvertiser &#8211; The only people who got back to me.  I&#8217;ve set up my ads.  I&#8217;ve earned <em>zero</em> dollars.</li>
<li>I&#8217;ve tried a few others on this <a title="AdSense Alternatives" href="http://www.rosswalker.co.uk/adsense_top10/" target="_blank">list</a>, but I usually don&#8217;t qualify, or they&#8217;re too sheisty looking for me to try.</li>
</ul>
<p>Effectively, there&#8217;s absolutely no competition.  I&#8217;m not the first one to realize this.  There&#8217;s a very good write-up <a title="Goohoosoft?" href="http://www.precursorblog.com/content/debunking-google-yahoo-antitrust-myths" target="_blank">here</a>.</p>
<h3>How Did we get Here?</h3>
<p>Upset, I tried to figure out just why Google didn&#8217;t have ample competition in this space.  It&#8217;s funny, because a few days later this <a title="What Microsoft wants from Yaho" href="http://www.techuser.net/microsoft-yahoo.html" target="_blank">article</a> showed up on Slashdot.  This article is a great explanation of the sordid love affair of Microsoft, Yahoo, and Google.  Basically, Yahoo controls the patent for contextual advertising.  (Contextual advertising is nothing more than a patent on mining the advertiser&#8217;s page to discover it&#8217;s content and then placing a targeted ad on that website.)  It&#8217;s an important patent and it&#8217;s orders of magnitude more effective at targeted advertising than just letting the website owner declare they&#8217;re content at sign-up.  The crazy outcome of all of this is that, due to an undisclosed settlement, Google ended up the only person able to action on this patent even though Google doesn&#8217;t own it.  This was absolutely eye-opening and one of the strangest patent stories I&#8217;ve ever heard of.</p>
<p>For the time being, it looks like we&#8217;re stuck with the unlikely monopoly.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/07/30/an-unlikely-monopoly-whats-wrong-with-google-adsense/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Programming Pong in C and OpenGL &#8211; Part V</title>
		<link>http://laststop.spaceislimited.org/2008/07/22/programming-pong-in-c-and-opengl-part-v/</link>
		<comments>http://laststop.spaceislimited.org/2008/07/22/programming-pong-in-c-and-opengl-part-v/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 00:42:40 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Technical Nonsense]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[pong]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=23</guid>
		<description><![CDATA[It’s been a while since I last updated on this, but hopefully you’ve brushed up on your C and OpenGL skills.  Here you&#8217;ll find the entire source code to a pong implementation in C and OpenGL.
Enjoy!

In interest of actually finally getting this post out the door, I’m just going to post the code!  This is [...]]]></description>
			<content:encoded><![CDATA[<p>It’s been a while since I last updated on this, but hopefully you’ve brushed up on your C and OpenGL skills.  Here you&#8217;ll find the entire source code to a pong implementation in C and OpenGL.</p>
<h3>Enjoy!</h3>
<p><span id="more-23"></span></p>
<p>In interest of actually finally getting this post out the door, I’m just going to post the code!  This is actually a snapshot of the code from a month or so back and I apologize for not tidying it up.  The reason I’m using a snapshot from a while back is because I have a newer, more glitzy version with a scoreboard and some simple effects that aren’t really necessary to get the basic game down.  I will post that code in a future post though when I’ve polished it up a bit more!  This is also most definitely not up to proper coding standards, but it gets the job done.  It was a late night hack-fest, so please disregard the lack of neatness!</p>
<h3>A word on use..</h3>
<p>You’re free to use the code however you like.  If you use it though, I would most definitely appreciate it if you post a link to <a title="Last Stop" href="http://laststop.spaceislimited.org" target="_blank">Last Stop</a> on your website or blog and a mention in the credits of the application.  Please also credit the references to Timothy M. Rodriguez.  You don’t have to do this, but it’d be nice.  I’d also very much love an e-mail or comment letting me know about your project!</p>
<h3>On to the Code!</h3>
<blockquote><p>#include &lt;stdlib.h&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;math.h&gt;</p>
<p>#include &lt;GLUT/glut.h&gt;</p>
<p>static int lastFrameTime = 0, windowWidth = 0, windowHeight = 0, now = 0;<br />
static float midWidth = 0, midHeight = 0;<br />
static float elapsedTime = 0, elapsedMilliSeconds = 0;<br />
static char player1Move = 0, player2Move = 0;<br />
static float player1V = 0, player2V = 0;</p>
<p>static float PI = 3.14159265358979323846264;</p>
<p>//scores<br />
static int player1Score = 0, player2Score = 0;</p>
<p>//the following variables calculate a random starting projectile trajectory<br />
static float randomDirection;<br />
static long longMax = 0&#215;7fffffff;    //max of longs 2^31-1 (2^(n-1)-1 for 2&#8217;s complement) static float trajectory[2] = {0, 0};</p>
<p>static float projMove[2] = {0, 0};<br />
static double trajectory[2] = {0, 0};<br />
static char moveSpeed = 70;</p>
<p>void resetProjectile(void) {<br />
//set starting random trajectory<br />
randomDirection = 2 * PI * (float) random() / (float) 0&#215;7fffffff;<br />
trajectory[0] = (float) cos(randomDirection);<br />
trajectory[1] = (float) sin(randomDirection);<br />
projMove[0] = midWidth;<br />
projMove[1] = midHeight;<br />
}</p>
<p>void display(void)<br />
{<br />
//get window parameters<br />
windowWidth = glutGet(GLUT_WINDOW_WIDTH);<br />
windowHeight = glutGet(GLUT_WINDOW_HEIGHT);</p>
<p>midWidth = windowWidth/2;<br />
midHeight = windowHeight/2;</p>
<p>//start timing code<br />
if (lastFrameTime == 0) {<br />
lastFrameTime = glutGet(GLUT_ELAPSED_TIME);<br />
resetProjectile();    //since this is the fist time, this is actually a set <img src='http://laststop.spaceislimited.org/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /><br />
}</p>
<p>now = glutGet(GLUT_ELAPSED_TIME);<br />
elapsedMilliSeconds = now &#8211; lastFrameTime;<br />
elapsedTime = elapsedMilliSeconds/1000.0f;<br />
lastFrameTime = now;</p>
<p>glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glShadeModel(GL_FLAT);</p>
<p>//calculate move distances<br />
switch (player1Move) {<br />
case 1:        //move up<br />
player1V += 150 * elapsedTime;<br />
break;<br />
case -1:    //move up<br />
player1V -= 150 * elapsedTime;<br />
break;<br />
default:    //do nothing<br />
break;<br />
}<br />
//check out of bounds<br />
if (player1V &gt; (windowHeight/2)-50) {<br />
//bounce back<br />
player1Move = -1;<br />
}<br />
if (player1V &lt; -(windowHeight/2)+50) {<br />
//bounce back other way<br />
player1Move = 1;<br />
}</p>
<p>switch (player2Move) {<br />
case 1:        //move up<br />
player2V += 150 * elapsedTime;<br />
break;<br />
case -1:    //move up<br />
player2V -= 150 * elapsedTime;<br />
break;<br />
default:    //do nothing<br />
break;<br />
}<br />
//check out of bounds<br />
if (player2V &gt; (windowHeight/2)-50) {<br />
//bounce back<br />
player2Move = -1;<br />
}<br />
if (player2V &lt; -(windowHeight/2)+50) {<br />
//bounc back other way<br />
player2Move = 1;<br />
}</p>
<p>//create and position player 1<br />
glPushMatrix();</p>
<p>glColor3ub(255, 0, 0);    //red</p>
<p>glTranslatef(0.0f, player1V, 0.0f);</p>
<p>glBegin(GL_QUADS);<br />
glVertex2f(20.0f, (midHeight-50));<br />
glVertex2f(20.0f, (midHeight+50));<br />
glVertex2f(50.0f, (midHeight+50));<br />
glVertex2f(50.0f, (midHeight-50));<br />
glEnd();</p>
<p>glPopMatrix();</p>
<p>//create and position player 2<br />
glPushMatrix();</p>
<p>glColor3ub(0, 0, 255);    //blue</p>
<p>glTranslatef(0.0f, player2V, 0.0f);</p>
<p>glBegin(GL_QUADS);<br />
glVertex2f(windowWidth-20.0f, (midHeight-50));<br />
glVertex2f(windowWidth-20.0f, (midHeight+50));<br />
glVertex2f(windowWidth-50.0f, (midHeight+50));<br />
glVertex2f(windowWidth-50.0f, (midHeight-50));<br />
glEnd();</p>
<p>glPopMatrix();</p>
<p>/***************************************<br />
*    Projectile CODE!!!<br />
*<br />
***************************************/</p>
<p>//calculate move distances<br />
projMove[0] += moveSpeed * trajectory[0] * elapsedTime;<br />
projMove[1] += moveSpeed * trajectory[1] * elapsedTime;</p>
<p>//create and move projectile<br />
glPushMatrix();</p>
<p>glColor3ub(255, 255, 255);</p>
<p>glTranslatef(projMove[0], projMove[1], 0.0f);</p>
<p>glBegin(GL_QUADS);<br />
glVertex2f(-10, -10);<br />
glVertex2f(10, -10);<br />
glVertex2f(10, 10);<br />
glVertex2f(-10, 10);<br />
glEnd();</p>
<p>glPopMatrix();</p>
<p>//set bounds for projectile<br />
if (projMove[0] &gt; (windowWidth)) {    //player 1 scored &#8211; out of bounds right<br />
player1Score++;<br />
printf(&#8221;Player 1 Scored!  Score: %f &#8220;, player1Score);<br />
printf(&#8221;projMove[0] %f projMove[1] %f &#8220;, projMove[0], projMove[1]);<br />
resetProjectile();<br />
}</p>
<p>if (projMove[0] &lt; (0)) {        //player 2 scored &#8211; out of bounds left<br />
player2Score++;<br />
resetProjectile();<br />
}</p>
<p>if (projMove[1] &gt; (windowHeight)) {    //out of bounds top<br />
resetProjectile();<br />
}</p>
<p>if (projMove[1] &lt; (0)) {    //out of bounds bottom<br />
resetProjectile();<br />
}</p>
<p>//collision detection code</p>
<p>/******************************<br />
*  END PROJECTILE CODE<br />
*<br />
******************************/</p>
<p>glutSwapBuffers();</p>
<p>}</p>
<p>void reshape(int width, int height)<br />
{<br />
glViewport(0, 0, width, height);</p>
<p>glMatrixMode(GL_PROJECTION);<br />
glLoadIdentity();<br />
gluOrtho2D(0, width, 0, height);<br />
glMatrixMode(GL_MODELVIEW);<br />
}</p>
<p>void idle(void)<br />
{<br />
glutPostRedisplay();<br />
}</p>
<p>void keyboard(unsigned char key, int x, int y) {<br />
switch (key) {<br />
case &#8216;w&#8217;:<br />
//do something<br />
player1Move=1;<br />
glutPostRedisplay();<br />
break;<br />
case &#8217;s&#8217;:<br />
//do something<br />
player1Move=-1;<br />
glutPostRedisplay();<br />
break;<br />
case &#8216;a&#8217;:<br />
player1Move=0;<br />
glutPostRedisplay();<br />
break;<br />
case &#8216;o&#8217;:<br />
//do something<br />
player2Move=1;<br />
glutPostRedisplay();<br />
break;<br />
case &#8216;l&#8217;:<br />
//do something<br />
player2Move=-1;<br />
glutPostRedisplay();<br />
break;<br />
case &#8216;k&#8217;:<br />
player2Move=0;<br />
glutPostRedisplay();<br />
break;<br />
default:<br />
//some other key<br />
break;<br />
}</p>
<p>}</p>
<p>void keyboardup(unsigned char key, int x, int y) {<br />
switch (key) {<br />
case &#8216;i&#8217;:<br />
//do something<br />
player1Move=0;<br />
glutPostRedisplay();<br />
break;<br />
case &#8216;u&#8217;:<br />
player2Move=0;<br />
glutPostRedisplay();<br />
break;<br />
default:<br />
//some other key<br />
break;<br />
}</p>
<p>}</p>
<p>int main(int argc, char** argv)<br />
{<br />
glutInit(&amp;argc, argv);</p>
<p>glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);<br />
glutInitWindowSize(500, 500);</p>
<p>glutCreateWindow(&#8221;Tim GL&#8221;);</p>
<p>glutDisplayFunc(display);<br />
glutReshapeFunc(reshape);<br />
glutKeyboardFunc(keyboard);<br />
glutKeyboardUpFunc(keyboardup);<br />
glutIdleFunc(idle);</p>
<p>glutMainLoop();<br />
return EXIT_SUCCESS;<br />
}</p></blockquote>
<p>Well that&#8217;s a lot of code, but don&#8217;t be intimidated!  If you read through it (maybe a couple of times), you&#8217;ll start to understand it.  The main loop is short and sweet.  We start glut, create a window with it, and then register callback functions for displaying the game, reshaping (what to do if someone changes the size of the window), and for keyboard downpress and release events (keyboard func and keyboardupfunct).  Our display function then pretty much does all the work, and I use a bunch of global variables to keep track of state, such as where the projectile and the paddles are.  There&#8217;s also some brute force vanilla collision detection, which I hope you can appreciate.  The funny part is that most real collision detection systems use this concept, called the bounding box.  In pong, the bounding box of the paddle <em>is</em> the paddle.</p>
<p>You can get a compiled Mac OS X version <a title="Pong for Mac OS X" href="http://laststop.spaceislimited.org/downloads/TimGL.zip" target="_self">here</a>, but if you have your IDE setup right a straight copy and paste <em>should</em> work.  (If you had to make any changes, please let me know.)</p>
<p>Let any and all questions loose in the comments..</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/07/22/programming-pong-in-c-and-opengl-part-v/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Why I&#8217;m Falling in Love with Futures</title>
		<link>http://laststop.spaceislimited.org/2008/07/11/why-im-falling-in-love-with-futures/</link>
		<comments>http://laststop.spaceislimited.org/2008/07/11/why-im-falling-in-love-with-futures/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 21:13:07 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Illogical Finance]]></category>
		<category><![CDATA[alternative energy]]></category>
		<category><![CDATA[contracts]]></category>
		<category><![CDATA[economics]]></category>
		<category><![CDATA[futures]]></category>
		<category><![CDATA[gas]]></category>
		<category><![CDATA[oil]]></category>
		<category><![CDATA[shadow pricing]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=22</guid>
		<description><![CDATA[It&#8217;s costing us more for everything.  And as consumers, we&#8217;re finding ourselves harder and harder pressed to make ends meet.  But there&#8217;s a silver lining in the thunder clouds of roaring inflation. Even though it&#8217;ll be a rough couple of years, the high price of gas and oil is already bringing about some change.
You see, [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s costing us more for everything.  And as consumers, we&#8217;re finding ourselves harder and harder pressed to make ends meet.  But there&#8217;s a silver lining in the thunder clouds of roaring inflation. Even though it&#8217;ll be a rough couple of years, the high price of gas and oil is already bringing about some <a title="The death of the suv" href="http://blog.wired.com/cars/2008/06/rising-gas-pric.html" target="_blank">change</a>.</p>
<p>You see, in America, and much of the rest of the world, energy <em>is</em> currency. Without rehashing the standard chain at length: oil is gas, it is jet fuel, and it is used to transport, grow, heat, light, build just about everything.</p>
<h3>But you know that.</h3>
<p>Here&#8217;s the interesting thing that&#8217;s happened in the last 15 or so years,<span id="more-22"></span> the development of the derivatives market (no, not <a title="U + Me = Us .. Calculus" href="http://en.wikipedia.org/wiki/Derivative" target="_self">those</a>, <a title="Exchange Traded Derivatives" href="http://en.wikipedia.org/wiki/Derivative_%28finance%29#Exchange_traded_derivatives" target="_blank">these</a>), and along with that, the <em>futures</em> variety.</p>
<p>A future is, quite simply, an obligation to buy X quantiy of Y product (usually a commodity) at Z point in the future. Put in English, a contract (the proper name for futures is futures contract) to by 100Million barrels of Oil for $160 dollars a barrel on 01 September 2008.</p>
<h3>So what&#8217;s the big deal?</h3>
<p>By watching the futures market, you have an indicator of the price at some point in the future of a specific commodity. Classically, in markets, you only had the price of something today and the price it was in the past, not the price in the future. This is a big deal, because as long as the future&#8217;s market points to the price of oil in the future going up, the price today will have pressure to move up. (Assuming people don&#8217;t think the futures market is wrong&#8211;which it can be.)</p>
<h3>Speculation!</h3>
<p>So while people go on yelling and screaming about speculation in the markets, I have one question for you. If you were betting on the price of oil in the future, wouldn&#8217;t you bet on it going up? Sure, the <em>speculators</em>, are driving up the price of oil trying to make money&#8211;but it isn&#8217;t unwarranted. This isn&#8217;t speculation, it&#8217;s research. Brazil, India, China, Russia, and several other major countries are now exploding in economic development, and with that comes increased need for oil. We are 4% of the world&#8217;s population and yet we consume 25% of the global supply! Surely, this isn&#8217;t sustainable. This is why you see ex-big-oil moguls singing a different <a title="The Plan" href="http://www.pickensplan.com/" target="_blank">tune</a>. Oil is a finite resource with extraordinary&#8211;and growing&#8211;demand. Cold, hard, simple, economics. If you had the money, you&#8217;d bet this way too. Do I like that the price of oil, gas, and everything is going up? No! I&#8217;m stretched pretty good as it is. But this may be good for the environment.</p>
<h3>Alternative Energy</h3>
<p>A word on alternative energy. Why hasn&#8217;t Solar Power, Wind Power, or other alternative energy taken off? One reason, price. You see, while the newest and best solar panel may be 12% efficient, or whatever it is, (by the way, power plants are horribly inefficient as well), what matters is how that compares to the current infrastructure. So lets say, after you run all the math, a solar power plant will cost $1 per kWH and an existing plant is $0.70 per kWH, there is no reason for power producers to switch I know, I want them to also. After all, there&#8217;s more than plenty enough environmental reasons. But it&#8217;s still cheaper to burn stuff. What&#8217;s more of a shame is that for producers to switch to solar they it needs to be <em>substantially</em> cheaper to make up for the current investment in other, less clean, technologies. Unfortunately, there&#8217;s other things that aren&#8217;t quite fair, such as tax breaks for existing energy producers that are not there for solar power providers, but these also represent a current investment (in the form of lobbying&#8211;oh joy) by energy providers.</p>
<p>This is why I&#8217;m excited, though! As oil goes up, the economics of all these pricing scenarios changes. And one can hope that this will price alternative energy into the picture. So the future&#8217;s market is helping to accelerate changes in the market at large, and maybe, just maybe, there&#8217;ll be enough change before the ocean levels rise and NY finds itself building a wall around Manhattan. (And I am by no means saying &#8220;Crisis Averted&#8221; on the Global Warming issue!)</p>
<h3>Not So Fast</h3>
<p>It&#8217;s great to huff and puff about how great free markets are and how the ultimately seem to be triumphing&#8211; just as they do in theory&#8211;but this has one simple cornerstone. Oil is a finite resource. In fact, the classics of economics are finite resources, <em>infinite</em> demand, but what if oil was so plentiful that we wouldn&#8217;t face this scenario for 50 years? Would we curb production &#8220;just to save the environment&#8221; or &#8220;satisfy those hippie jerks&#8221;? The plain and simple answer is <strong>No</strong>. Or at least, probably not in time. Why? Because there&#8217;s no price applied to economic damage. In fact, the whole process of doing so is called &#8220;Shadow Pricing&#8221; as if it&#8217;s some black art, but there is a <em>real</em> cost to economic damage&#8211;it&#8217;s just not immediately evident, or easy to quantify. Environmental damage wouldn&#8217;t be priced until well after the fact. It&#8217;s just human nature, we don&#8217;t curb our habits until we feel the <strong><em>shock</em></strong>. This is why things like carbon markets and agreement between countries to curb C02 emissions are important&#8211;because they are not priced in the markets.</p>
<p>Luckily for the planet, oil production may have finally peaked.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/07/11/why-im-falling-in-love-with-futures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming Pong in C and OpenGL &#8211; Part IV</title>
		<link>http://laststop.spaceislimited.org/2008/07/01/programming-pong-in-c-and-opengl-part-iv/</link>
		<comments>http://laststop.spaceislimited.org/2008/07/01/programming-pong-in-c-and-opengl-part-iv/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 13:00:29 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[pong]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=21</guid>
		<description><![CDATA[OpenGL
OpenGL is the Open Graphics Library and it is maintained by the Kronos Group, which is a consortium of top-tier companies that include board members such as ATI nVidia, Apple, IBM, and more.  Microsoft used to be on the consortium, but left and decided to make DirectX, a competing closed graphics library that only [...]]]></description>
			<content:encoded><![CDATA[<h2>OpenGL</h2>
<p>OpenGL is the Open Graphics Library and it is maintained by the Kronos Group, which is a consortium of top-tier companies that include board members such as ATI nVidia, Apple, IBM, and more.  Microsoft used to be on the consortium, but left and decided to make DirectX, a competing closed graphics library that only runs on Windows (at least without some sort of emulation layer or wrapper like Wine or Cedega).</p>
<p><span id="more-21"></span></p>
<p>First off, OpenGL is a huge thing to master (and I am nowhere near mastery).  I can’t explain everything about it in one post (or even in hundreds), but I strongly encourage you to get the OpenGL “<a type="amzn">Red Book</a>” to start out.  The “Red Book” is the official and definitive guide to OpenGL and is a must have for any graphics programmer.  I also recommend the <a type="amzn">K&amp;R C Programming book</a> and, if you’re interested in the back-end math, the <a type="amzn">Real-Time Rendering book</a>.</p>
<p>That being said, in our pong clone, we only use a few OpenGL functions.  I’m going to  list them and tell you what they do, but it may take until the next post to really understand how they work.</p>
<p>First, a word about primitives.  OpenGL has only a few key primitives that you can draw with, but that&#8217;s okay, because you can use the primitives to draw more complex shapes!</p>
<p>The OpenGL primitives are:</p>
<ul>
<li>Points &#8211; a simple point in space</li>
<li>Lines &#8211; a 2-dimension line (although it can occupy 3-dimensional space)</li>
<li>Polygons &#8211; a polygon is a simple 2-dimensional shape comprised of 3 or more points.  Triangles, or 3-point polygons, deserve special attention, because OpenGL will break up any other polygon into a combination of triangles.  For example, a square can be broken up into two triangles along its diagonal.  Just about every object you see in OpenGL is comprised of triangles!</li>
</ul>
<p>So let&#8217;s draw a simple quadrilateral!  In OpenGL, you draw polygons by calling a function whenever you want to draw a polygon and then creating a bunch of points in space to create that polygon.  Once you&#8217;re done, you call another function to say you&#8217;re done.</p>
<p>Here&#8217;s an example for drawing a rectangle (our pong paddle):</p>
<blockquote><p><span>glBegin</span><span>(</span>GL_QUADS<span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(-</span><span>10</span><span>, -</span><span>50</span><span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(-</span><span>10</span><span>, </span><span>50</span><span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(</span><span>10</span><span>, </span><span>50</span><span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(</span><span>10</span><span>, -</span><span>50</span><span>);</span></p>
<p><span><span> </span></span>glEnd<span>();</span></p></blockquote>
<p>We start by calling glBegin() and sending it GL_QUADS to indicate we want to draw a quadrilateral.  This basically tells OpenGL take every four points I send you and make a quad out of it.  We then call glVertex2f() and send it the coordinates of a two-dimensional point.  the 2f indicates that this is the glVertex function which takes 2 floating point values as its arguments (or inputs).  We then call glVertex2f() once for all four of each of our points and then call glEnd() when we&#8217;re done.</p>
<p>We could have optionally set a color before we began to draw that quadrilateral (the default is black on black) by calling this function:</p>
<blockquote><p>glColor3ub<span>(</span><span>255</span><span>, </span><span>0</span><span>, </span><span>0</span><span>);<span> </span></span><span>//red</span></p></blockquote>
<p>Again we see the OpenGL naming convention of starting off a function with gl and then ending it with letters and numbers that indicate its arguments.  In this case the 3ub means 3 unsigned bytes.  Each unsigned byte is positive (hence unsigned) and can go from 0 to 255.  The order of the bytes indicate the amount of Red, Green, and Blue respectively that will mix to give you your final color.  (Color theory is another big subject matter I can post more about in another post, so let me know in the comments!)</p>
<p>Two other functions that are usually called at the beginning of every display function are:</p>
<blockquote><p><span>glClear</span><span>(</span>GL_COLOR_BUFFER_BIT<span> | </span>GL_DEPTH_BUFFER_BIT<span>);</span></p>
<p><span><span> </span></span>glShadeModel<span>(</span><span>GL_FLAT</span><span>);</span></p></blockquote>
<p>glClear(), quite simply is a function that clears the screen and uses the values specified as its argument for doing so.</p>
<p>glShadeModel() specifies the shading model for how vertexes (points) are shaded or lit.  In this case, we&#8217;re going for a simple flat colored 2-d look so we use GL_FLAT.  This paints everything on screen with whatever colors specified and doesn&#8217;t do anything fancy.  It&#8217;s sort of like painting in mspaint on Windows.</p>
<blockquote><p>glPushMatrix<span>();</span></p>
<p>glPopMatrix();</p>
<p><span><span> </span></span>glTranslatef<span>(</span><span>30.0f</span><span>, 10.</span><span>0f, 0.0f</span><span>);</span></p></blockquote>
<p>glPush and Pop Matrix() are important functions.  They allow you to draw something as if you are starting from scratch with a new coordinate system.  Think about our pong paddle.  When you want to draw it some place else, do you really want to respecify the coordinates for how it&#8217;s drawn?  You could instead <em>push</em> a matrix (a set of points) on the stack, then <em>translate</em> (or move), to a new location and draw the object as you would anywhere else, and then finally <em>pop</em> the matrix which will draw the set of points translated (moved) by the glTranslatef() function.  This is a little hard to understand (and explain), so I&#8217;ll give an example.</p>
<p>In Part II we talked about drawing a box that moved across the screen.  We could draw our box as a point in a 2-dimensional plane.  For example, let&#8217;s make a square that is 4 across centered at the origin (0,0).  So it&#8217;s points are, going counter-clockwise, (1,1), (-1,1), (-1,-1), (1,-1).  Rather than figuring out how to move it along for every frame.  We can do this.</p>
<blockquote><p>glPushMatrix<span>();</span></p>
<p><span> </span></p>
<p><span><span> </span></span>glColor3ub<span>(</span><span>255</span><span>, </span><span>0</span><span>, </span><span>0</span><span>);<span> </span></span><span>//red</span></p>
<p><span> </span></p>
<p><span><span> </span></span>glTranslatef<span>(</span><span>x, 0.0f, </span><span>0.0f</span><span>);</span></p>
<p><span> </span></p>
<p><span><span> </span></span><span>glBegin</span><span>(</span>GL_QUADS<span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(1,1</span><span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(-1,1</span><span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(</span><span>-1,-1</span><span>);</span></p>
<p><span><span> </span></span>glVertex2f<span>(</span><span>1,-1</span><span>);</span></p>
<p><span><span> </span></span>glEnd<span>();</span></p>
<p><span> </span></p>
<p><span><span> </span></span>glPopMatrix<span>();</span></p></blockquote>
<p>So we push a matrix (a set of points) on the stack, switch the drawing color to red, then Translate x units in the x-direction (horizontal) and then set the drawing mode to GL_QUADS and push the points of our square as it is centered at the origin, and finally pop the matrix!  This has OpenGL do all the work of moving our square x units to the right.</p>
<p>Okay, that&#8217;s enough for now.  I encourage you to scour the web and read up more before we get to our next post, where I&#8217;ll finally post the code and go through it!</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/07/01/programming-pong-in-c-and-opengl-part-iv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming Pong in C and OpenGL &#8211; Part III</title>
		<link>http://laststop.spaceislimited.org/2008/06/27/programming-pong-in-c-and-opengl-part-iii/</link>
		<comments>http://laststop.spaceislimited.org/2008/06/27/programming-pong-in-c-and-opengl-part-iii/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 15:35:17 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[pong]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=20</guid>
		<description><![CDATA[Sorry for the delay in this post, but here’s Part III.
For reference, you probably want to start out with Part’s II and I here and here.
Last we left off I said I’d get into some of the basic mechanics of GLUT and OpenGL, so let’s hit the ground running.
GLUT
GLUT, or the Graphics Library Utility Toolkit, [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry for the delay in this post, but here’s Part III.</p>
<p>For reference, you probably want to start out with Part’s II and I <a title="Programming Pong Part II" href="http://laststop.spaceislimited.org/2008/06/02/programming-pong-in-c-and-opengl-part-ii/" target="_blank">here</a> and <a title="Programming Pong in C and OpenGL - Part I" href="http://laststop.spaceislimited.org/2008/05/17/programming-a-pong-clone-in-c-and-opengl-part-i/" target="_blank">here</a>.</p>
<p>Last we left off I said I’d get into some of the basic mechanics of GLUT and OpenGL, so let’s hit the ground running.</p>
<h3>GLUT</h3>
<p>GLUT, or the Graphics Library Utility Toolkit, is a cross-platform C library for generating windows and handling IO events.  Basically, GLUT was written so you can get to learning OpenGL very quickly without having to spend enormous amounts of time learning how to handle mouse or keyboard actions in your current OS, or worse, learn how to setup a simple GUI just so you can see your work.  On top of making these tasks simpler, GLUT is, as I mentioned, cross-platform.  This means that you can take your code and recompile it on another OS as long as you have the appropriate GLUT library referenced in your IDE.  There are currently versions of GLUT created for Linux, OS X, Windows, and probably even more operating systems.</p>
<p>So how do we create a simple window?</p>
<p><span id="more-20"></span></p>
<p>Here’s a snippet of code for how to do just that!</p>
<blockquote><p>int main(int argc, char** argv)<br />
{<br />
glutInit(&amp;argc, argv);</p>
<p>glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);<br />
glutInitWindowSize(500, 500);</p>
<p>glutCreateWindow(&#8221;Tim GL&#8221;);</p>
<p>glutDisplayFunc(display);<br />
glutReshapeFunc(reshape);<br />
glutKeyboardFunc(keyboard);<br />
glutKeyboardUpFunc(keyboardup);<br />
glutIdleFunc(idle);</p>
<p>glutMainLoop();<br />
return EXIT_SUCCESS;<br />
}</p></blockquote>
<p>You start off with your regular main function in C.  Then you call the glutInit function and pass it is passed any parameters you may have passed to main.  For this tutorial you won’t be needing any, so don’t worry about it.  If you need to find out more, check out the GLUT Documentation.</p>
<p>Next, you pass the glutInitDisplayMode() function a “logically OR-ed” value of GLUT_RGBA, GLUT_DOUBLE, and GLUT_DEPTH.  If you don’t know what logically OR-ed means, just think of it as smooshing all these flags together to set the display mode with all of these properties.  (If you want an in-depth explanation of this, just ask and I’ll put up a post about it!).</p>
<p>After this, we set the pixel dimensions (size) of the window to 500&#215;500 pixels with the line “glutInitWindowSize(500,500);”.  We next set the window’s title bar with “glutCreateWindow(”Tim GL”);”  You can set either of these last two functions to whatever value you wish!</p>
<p>Next, is the pretty interesting part.  And to understand it you need to understand a little bit about Call-Back functions.  Call-Back functions are functions that hold a pointer to another function and call it when some event happens.  (This is also why Call-Back functions are usually regarded as “Event-Driven Programming”.)  To explain this it’s best to show you by example.  I’ll start with the glutKeyboardFunc(keyboard).  Whenever a key is pressed down, we have set glutKeyboardFunc() to call ANOTHER function called keyboard that WE have defined.  The function is not show here, but we will get to that in the next post!  Suffice it to say, our keyboard function will handle certain things like “what to do when the up arrow is pressed” in our Pong clone.</p>
<p>It is important to understand that we can’t just write a function that constantly checks the keyboard like this</p>
<blockquote><p>while(TRUE) {</p>
<p>whatIsTheKeyboardDoing();</p>
<p>}</p></blockquote>
<p>because we’d be in an infinite loop and never be able to do anything else.  The Call-Back function allows us to be “called back” whenever someone presses the keyboard.</p>
<p>Now that we’ve explained that, the rest of the functions are easy to describe:</p>
<ul>
<li>glutDisplayFunc() is called most of the time and is the function that paints our screen with whatever we tell it to with OpenGl</li>
<li>glutReshapeFunc() is what is called whenever the user resizes the window (In case we need to do anything special if the user all of a sudden changes the screen size on us.)</li>
<li>glutKeyboardFuncUp() is a tricky one, and it’s what is called whenever a key is “depressed”, or let go.  This is a subtle point, but it is useful to know when someone presses a key and let’s go of one.  Without this, you wouldn’t be able to tell when someone was holding a key.</li>
<li>glutIdleFunc()  this is the function that is called whenever there is nothing to do!</li>
</ul>
<p>So that’s it!  That’s about all you need to know for GLUT for now!  Check out the next post for OpenGL.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/06/27/programming-pong-in-c-and-opengl-part-iii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>To Hell &amp; Back &#8211; A Story of Windows Vista</title>
		<link>http://laststop.spaceislimited.org/2008/06/16/to-hell-back-a-story-of-windows-vista/</link>
		<comments>http://laststop.spaceislimited.org/2008/06/16/to-hell-back-a-story-of-windows-vista/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 15:22:39 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Rants]]></category>
		<category><![CDATA[Technical Nonsense]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[problems]]></category>
		<category><![CDATA[vista]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=19</guid>
		<description><![CDATA[I recently helped my nephew Peter do a massive overhaul/upgrade of his current PC.  We basically rebuilt his PC and the only thing he kept was his recently purchased insane-o vid card and his hard drive.  Several hours later we had his new PC up and running&#8211;hardware wise at least.
One of the orders [...]]]></description>
			<content:encoded><![CDATA[<p>I recently helped my nephew Peter do a massive overhaul/upgrade of his current PC.  We basically rebuilt his PC and the only thing he kept was his recently purchased insane-o vid card and his hard drive.  Several hours later we had his new PC up and running&#8211;hardware wise at least.</p>
<p>One of the orders of the day&#8211;much to my dismay&#8211;was to install Windows Vista.  I advised him not too, but he got his aunt to get it for him for his birthday and he rationalized his defiance of my advice on DirectX 10.  (Truth be told, I sabotaged myself by telling him it was one of the only neat features of Vista, outside of massive memory footprint and overall sluggishness.)</p>
<p>And so our journey began..</p>
<p>I&#8217;d like to tell you it didn&#8217;t take us in excess of 2 days to get Vista installed.  I mean, I&#8217;ve been building PCs for years now and I&#8217;m a recent grad of Computer Engineering (I know the two aren&#8217;t the same, but still..).  Piece of cake, right?</p>
<p><strong>Wrong</strong>.</p>
<p><span id="more-19"></span></p>
<p>To be fair (to myself and Microsoft), I had helped him install Vista on his PC after he got his video card a few short months ago, but after we changed all the hardware from under it, it refused to boot.  Which left us with the odd job of installing Vista fresh off an upgrade CD.  I knew from previous reading on the web, it would probably only take a call to Microsoft and that they were quite helpful in arranging for you to keep your upgrade in these circumstances, so we marched onward.</p>
<h3>First things first..</h3>
<p>First things first, stick the CD in the tray, make sure the BIOS is set to boot from CD, and let boot.  Okay great, we got the usual install screens, but then Vista says it detects a previous version of Windows installed.  It then asks me to boot into it and install Vista from there.  Fair enough, except I <em>can&#8217;t</em> boot from Vista now!  We then chose the option to install Vista and have it verified later.  This worked great, full of progress for about 20 minutes, after which, it hung.  We then went on to try everything to get it installed.  Including just plain trying over and over again.  Sometimes we got a little bit further, but it always hung.  I thought maybe his Vista CD got too scratched up and it was bad.  I burned a copy of an ISO I had (a legit one from a student/Microsoft coop my school runs) and tried the same thing with that.  No dice.  Being that major OEMs don&#8217;t ship install CDs anymore (a ridiculous practice) we couldn&#8217;t go back and install his copy of Media Center Edition again and upgrade off that.  I went home and hunted for some Win2k or XP cds, but I had no serial keys.</p>
<p>While I was home hunting for software, my nephew was calling Microsoft.  The first thing they told him was, take out the memory, you have too much.  Too much?  Vista basically begs for 4 gigs or more (we had exactly 4, for the record). What do you mean Vista won&#8217;t install with 4 gigs.  &#8220;Preposterous,&#8221; I said to my nephew when I got back.  &#8220;There&#8217;s no way.  XP installs just fine with 4 gigs!,&#8221; I yelled.  We eventually even tried just putting two sticks or RAM in to see what happened.  Still issues.  We continued to try to fiddle with the machine for several more hours before I caved and said, &#8220;Let&#8217;s just call MS Tech Support and see what they say.  We&#8217;ll get someone <em>real</em> on the phone this time.&#8221;</p>
<p>Before I get started, I do have to say, MS Tech support was very nice (yes, even the team in India we were eventually forwarded too).  But again, the first thing we were told was &#8220;Too much memory.  Take all the sticks out and put one back in.&#8221;  Upset, I agreed and took everything out except for one stick.</p>
<p>Eventually, Vista installed just fine.</p>
<h2>Vista just can&#8217;t address 4 Gigs of memory on install!</h2>
<p>I told the tech this is a major regression, considering XP installs just fine.   The tech then proceeded on as if it were not a bug, but just an issue of our hardware setup.  Keep in mind, the Tech did not ask us what our board, or our processor, was until much later in the process.  The first thing they said was take all the sticks out.  After some bickering, I eventually got the tech to let me in on the little secret that Vista can&#8217;t address that much memory on installation and that it is a known issue that was resolved in the SP1 discs.  Is it just me, or is this an absolutely horrendous oversight?  I&#8217;m not going to rehash the standard Vista bashing, but this just goes to show why firms and home users alike are staying away from Vista.  The irony is that despite it&#8217;s massive delays, Vista was rushed.  A lot of this has to do with the fact that they threw away all their work and restarted with a far smaller scope than originally intended for Longhorn, but there plain simply still wasn&#8217;t enough time.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/06/16/to-hell-back-a-story-of-windows-vista/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Programming Pong in C and OpenGL &#8211; Part II</title>
		<link>http://laststop.spaceislimited.org/2008/06/02/programming-pong-in-c-and-opengl-part-ii/</link>
		<comments>http://laststop.spaceislimited.org/2008/06/02/programming-pong-in-c-and-opengl-part-ii/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 01:50:22 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[game programming]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[loop]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[pong]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[This]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=17</guid>
		<description><![CDATA[This is the second part in what should be a four part series on how to program your very own Pong clone.  The first article went over setting up your environment in your favorite OS, now this part gets into some of the mechanics or details on how to actually get started.
Before I start [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second part in what should be a four part series on how to program your very own Pong clone.  The first article went over setting up your environment in your favorite OS, now this part gets into some of the mechanics or details on how to actually get started.</p>
<p>Before I start with anything, we have to think about simple animation.  In fact, <a title="Animation" href="http://en.wikipedia.org/wiki/Animation" target="_blank">animation</a> is just simply a series of static images, with each image slightly displaced from the last.</p>
<p>So what does that mean?<span id="more-17"></span></p>
<p>For example, if I&#8217;m going to <span style="text-decoration: line-through;">draw</span> animate a ball falling from mid-air, I would first start with an image of the ball in mid-air, precisely as it would look the moment it began to fall.  The next <em>frame</em>, or image, would be exactly that, but with the ball a little bit lower down.  I would then continue to draw sequential images of the ball, with each image showing it a little bit further than the last.  This is how <strong>every</strong> moving image you see works (well, just about).  A series of images is drawn in front of you, quick enough that you can&#8217;t tell.</p>
<p>So the next question is, what&#8217;s quick enough?  It turns out, this isn&#8217;t such a simple question.  In fact, the answer is different for different animals!  But for humans, it turns out, about 30fps, or 30 frames-per-second, is what it takes to fool us.  The movies you see in the theatre are (at-the-moment anyways) displayed at 24fps, but most computer screens require 60fps to prevent you from seeing the flicker (some, like myself, need an 85Hz (fps) refresh rate, others up to 120!).  The reasons for these differences has a lot to do with the way the image is drawn and the way your eye views things.  It&#8217;s a pretty involved topic, but if you guys would like me to go into it more, let me know in the comments.</p>
<h3>A Simple Animation Loop</h3>
<p>Taking what we just learned, let&#8217;s think about how to draw a box moving across the screen.  Let&#8217;s pretend we have a function that draws a box centered at a point we specify on the screen (in 2-D Space).  It&#8217;s C function prototype would look something like this:</p>
<blockquote><p>void drawbox(int x, int y);</p></blockquote>
<p>So if we were going to draw a box that just infinitely moved to the right (or at least until it was off screen).  We might decide to create a loop that drew it a little bit further each time.  That might look something like this:</p>
<blockquote><p>#define TRUE 1</p>
<p>int x=0;</p>
<p>while(TRUE) {</p>
<p>drawbox(0+x, 0);</p>
<p>x++;</p>
<p>}</p></blockquote>
<p>This little snippet of code, runs an infinite loop and draws a box at a point 0+x, 0 and then increments x.  Let&#8217;s look a little further.  First it draws a box at point(0,0) since x is 0 on first count.  Then x is incremented and the loop goes on again.  Next, it draws a box at (1,0) and increments x.  And so on.  Congratulations, you just made your first animation loop!</p>
<h3>Marching Onward</h3>
<p>In the beginning, video games were hand-coded in assembly directly to a particular hardware.  This had a lot of benefits, primarily speed, which was very important when hardware was relatively expensive.  But as computers progressed and the market expanded, it became necessary to program for a multitude of different hardwares.  And this is when a nasty problem reared it&#8217;s head.  You see, when you decide to have the computer draw something on the screen, it doesn&#8217;t just do it instantaneously.  The computer has to go and draw each individual pixel on the screen (also a topic for another discussion).</p>
<p>This</p>
<p style="padding-left: 30px;">takes</p>
<p style="padding-left: 60px;">time.</p>
<p>Moreover, the time it takes on your brand-spanking new ultra-super processor is not the same time it takes your friend down the street who isn&#8217;t as <em>enthusiastic</em> as you are.  This is a problem, because if you set up all your animations expecting the processor to draw 30 frames per second on your machine.  It&#8217;s going to run at less than that on your friends machine.  (In fact, there&#8217;s some math that shows it will be a fraction/multiple of their refresh rate).  Great, so your fast-action shoot-em-up just got stuck in the mud.</p>
<h3>What&#8217;s a game programmer to do?</h3>
<p>There&#8217;s a really simple answer to all of this&#8211;use our friend (archenemy) time.  You see, rather than making your animation speed depend on the animation loop (which depends on your processor speed), have the your animation be a fixed function of time.</p>
<p>Take another look at our first example.  The movement speed of the box can really be expressed as 1 unit in the x direction per loop iteration.  Really what we want is for the box to move some number of units in the x direction per second (our hour if you like).  To do this we need to express our box movement as a function of time and then know how long its been since the computer last drew the box.  Essentially, we want our animation loop to look like this.</p>
<blockquote><p>#define TRUE 1</p>
<p>int speed = 1;     //1 unit per second</p>
<p>int x = 0;</p>
<p>startTime = 0;</p>
<p>elapsedTime = 0;</p>
<p>while(TRUE) {</p>
<p>startTime = getTime();</p>
<p>x += speed * elapsedTime;</p>
<p>drawbox(0+x, 0)</p>
<p>elapsedTime = getTime() &#8211; startTime;</p>
<p>}</p></blockquote>
<p>As you can see, this simple example becomes a lot more complicated once we add timing to the mix.  First, we defined a universal speed for our box.  We still kept the x value, as this represents the boxes point in space, not it&#8217;s speed.  Then we created variables for keep track when we started our animation loop and how long we were in it.  We&#8217;re also assuming we have a function that gives us the time, called getTime() here, and that it returns us the current time in seconds.</p>
<p>First we enter our loop and fetch our start time from the getTime() function.  Next we set our x position based on how long it&#8217;s been since our last loop.  We multiply our elapsedTime by the speed of our box and add that <em>distance</em> to our x-position.  Then, we draw our box at it&#8217;s new position.  Finally, we figure out how long it took us to draw that box by setting our elapsed time equal to the current time minus the time we started drawing the box.  Now, no matter the computer, our box will move along the screen at the same speed.  Note, this does not mean the animation is fluid!  If your friend&#8217;s computer is really slow (and I mean really if it can&#8217;t draw a box) it may only get to draw a box once every 5 seconds.  By then, our box may already be off the screen!</p>
<p>So I hope that&#8217;s enough for you to digest for a while. Stay tuned for my next post on some of the basic mechanics of GLUT and OpenGL.  Until then, it might be useful to brush up on your C programming on the interwebs!</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/06/02/programming-pong-in-c-and-opengl-part-ii/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Technology of a 3D Engine</title>
		<link>http://laststop.spaceislimited.org/2008/05/22/technology-of-a-3d-engine/</link>
		<comments>http://laststop.spaceislimited.org/2008/05/22/technology-of-a-3d-engine/#comments</comments>
		<pubDate>Thu, 22 May 2008 14:49:10 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Technical Nonsense]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[engine]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[scenegraph]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=15</guid>
		<description><![CDATA[
There&#8217;s a great article on Beyond3D about the technology of a 3D engine.  The article&#8217;s split up into parts and part two was just released (after a several month wait!).  Part one discusses a lot of the general concepts for a 3D engine design in an easy to read and abstract level, but [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://laststop.spaceislimited.org/wp-content/uploads/2008/05/400px-octree2.png"><img class="aligncenter size-full wp-image-16" title="400px-octree2" src="http://laststop.spaceislimited.org/wp-content/uploads/2008/05/400px-octree2.png" alt="Lions and Tigers and Octrees!  Oh My!" width="400" height="230" /></a></p>
<p>There&#8217;s a great article on Beyond3D about the technology of a 3D engine.  The article&#8217;s split up into parts and part two was just released (after a several month wait!).  Part one discusses a lot of the general concepts for a 3D engine design in an easy to read and abstract level, but part two goes into deeper detail.  Both make for interesting reads, though part two sort of jumps into an ocean at no discernible point.  (It covers scenegraphs I know, but why start there?  Why not animation?  Look for my own part two of programming a pong clone to animation and early concepts in game programming.)</p>
<ul>
<li><a title="Tech of a 3D Engine - Part 1" href="http://www.beyond3d.com/content/articles/98" target="_blank">Part One</a></li>
<li><a title="Tech of a 3d Engine - Part 2" href="http://beyond3d.com/content/articles/102" target="_blank">Part Two</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/05/22/technology-of-a-3d-engine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Programming Pong in C and OpenGL &#8211; Part I</title>
		<link>http://laststop.spaceislimited.org/2008/05/17/programming-a-pong-clone-in-c-and-opengl-part-i/</link>
		<comments>http://laststop.spaceislimited.org/2008/05/17/programming-a-pong-clone-in-c-and-opengl-part-i/#comments</comments>
		<pubDate>Sun, 18 May 2008 00:48:35 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[glut]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[pong]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=13</guid>
		<description><![CDATA[
If you ever wanted to program your own video game, this is a good place to start.  I remember when I started learning programming it was surprisingly difficult to find out how to make an honest and simple game.  In fact, after reading most programming books, the only type of game you could [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://laststop.spaceislimited.org/wp-content/uploads/2008/05/pongactionshot.png"><img class="aligncenter size-full wp-image-14" title="Pong" src="http://laststop.spaceislimited.org/wp-content/uploads/2008/05/pongactionshot.png" alt="Unbelievable Action!" width="499" height="518" /></a></p>
<p>If you ever wanted to program your own video game, this is a good place to start.  I remember when I started learning programming it was surprisingly difficult to find out how to make an honest and simple game.  In fact, after reading most programming books, the only type of game you could make would be a <a href="http://en.wikipedia.org/wiki/Zork">Zork</a> clone.</p>
<blockquote><p>You are in a dank cave and you can see nothing, but you hear a walrus in the distance.</p>
<p>What do you do?</p>
<ol>
<li>Look for the walrus.</li>
<li>Watch <a href="http://www.imdb.com/title/tt0118715/">The Big Lebowski</a></li>
<li>Decide that the walrus is Paul.</li>
</ol>
</blockquote>
<p>This is not to knock Zork in any way!  Zork is a clever, well written, and extremely well thought out game (even if my pseudo-quote isn&#8217;t).  But in a world where we&#8217;re spoiled by moving objects, you want to know how to move and interact with something on screen.  The problem is it takes a lot of different knowledge sets to get the job done.  But in this post, you&#8217;ll get started learning how to make your very own <a title="Pong" href="http://http//en.wikipedia.org/wiki/Pong" target="_blank">Pong</a> clone.<span id="more-13"></span></p>
<h3>A Few Notes..</h3>
<p>First, a few notes about setting up.  I&#8217;m writing this tutorial from the Mac OS X perspective.  However, everything we are about to code is, essentially, <strong>cross-platform</strong>.  This is because, it is written using plaing old C, OpenGL, and GLUT.  All of these things are themselves cross-platform, and therefore, can be compiled anywhere you have a C compiler (OpenGL and GLUT are just C libraries).</p>
<h3>Setting up your environment</h3>
<h4>Mac OS X</h4>
<p>For some reason, this always seems to be the hardest part whenever learning something new in programming.  Fortunately, I found a great blog post that makes setting up XCode for compiling an app using OpenGL and GLUT very easy.  Read all about setting up your <a title="XCode with OpenGL and GLUT" href="http://blog.onesadcookie.com/2007/12/xcodeglut-tutorial.html" target="_blank">XCode</a>.</p>
<h4>Windows</h4>
<p>The process in Windows is actually a bit easier (gasp!) than in Mac OS X and there&#8217;s plenty of resources available on Google for getting setup.  Here&#8217;s one in <a title="Setting up OpenGL and GLUT in Windows" href="http://csf11.acs.uwosh.edu/cs371/visualstudio/" target="_blank">particular</a>.</p>
<h4>Linux</h4>
<p>Here&#8217;s something unusual, you guys get a <a title="OpenGL and GLUT in Linux" href="http://www.youtube.com/watch?v=p4hA-lcKTmE" target="_blank">video</a>.</p>
<p>Congratulations, the hardest part is done!  In my next blog post.  We&#8217;ll start to get knee deep in game programming concepts.</p>
<h2>Update!</h2>
<p><a title="Programming a Pong Clone - Part II" href="http://laststop.spaceislimited.org/2008/06/02/programming-pong-in-c-and-opengl-part-ii/" target="_self">Part II</a> is Up!</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/05/17/programming-a-pong-clone-in-c-and-opengl-part-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Condos, You Know What Your Problem is?</title>
		<link>http://laststop.spaceislimited.org/2008/05/13/condos-you-know-what-your-problem-is/</link>
		<comments>http://laststop.spaceislimited.org/2008/05/13/condos-you-know-what-your-problem-is/#comments</comments>
		<pubDate>Tue, 13 May 2008 18:08:12 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Rants]]></category>
		<category><![CDATA[capitalism]]></category>
		<category><![CDATA[communism]]></category>
		<category><![CDATA[condominiums]]></category>
		<category><![CDATA[condos]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/?p=6</guid>
		<description><![CDATA[I was driving to work today watching all the advertisements for newly created condos in nearby towns when I started craving one.  This has been a recurring theme.  I want a condo.  Then I thought about it more and was completely lambasted.  What on earth do I want a Condo for? [...]]]></description>
			<content:encoded><![CDATA[<p>I was driving to work today watching all the advertisements for newly created condos in nearby towns when I started craving one.  This has been a recurring theme.  I want a condo.  Then I thought about it more and was completely lambasted.  What on earth do I want a Condo for?  Think about it. You spend 30 years paying a mortgage, only to have the privilege of paying forever ongoing rent in the form of maintenance.</p>
<p>Sure, that maintenance goes to something.  It pays for the pool, the trash collectors, the gym, and the <em>community</em>.   Some Condos even go so far as to have Supermarkets, Starbucks, and Ice Cream Shops right below.   Oh, the horrible convenience!</p>
<p>But that word <em>community</em> is the clincher.   The gyms at these places are usually terrible, and what happens if you want to go to your own gym?  Or, hell, get a Bowflex, or whatever it is <a title="Chuck Norris Facts!" href="http://www.chucknorrisfacts.com/" target="_blank">Chuck Norris</a> is selling now?  You can, but you&#8217;re not going to get any of your maintenance money back.  It&#8217;s assigned for the <em>community</em>. And tomorrow, the community may decide it needs more maintenance.</p>
<p><strong>Then it occurred to me.</strong></p>
<p>Condos are nothing more than little communist societies.   They are the absolutely hypocritical hallmark of capitalistic American wealth.  And we <em>love </em>them.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/05/13/condos-you-know-what-your-problem-is/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java SE 6 on Mac OS X</title>
		<link>http://laststop.spaceislimited.org/2008/05/01/java-se-6-on-mac-os-x/</link>
		<comments>http://laststop.spaceislimited.org/2008/05/01/java-se-6-on-mac-os-x/#comments</comments>
		<pubDate>Thu, 01 May 2008 01:26:57 +0000</pubDate>
		<dc:creator>Timothy M. Rodriguez</dc:creator>
				<category><![CDATA[Technical Nonsense]]></category>

		<guid isPermaLink="false">http://laststop.spaceislimited.org/2008/05/01/java-se-6-on-mac-os-x/</guid>
		<description><![CDATA[
Today Apple finally added support for Java SE 6.  This has been a long time coming and lots of people were clamoring that Apple abandoned Java.  While it&#8217;s true that Jobs said Java was a &#8220;ball and chain,&#8221; the context was very much that of the iPhone.  And Java, despite ubiquity in [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://laststop.spaceislimited.org/wp-content/uploads/2008/05/fishing-eagle2.jpg" alt="The Eagle has Landed" /></p>
<p>Today Apple finally added support for Java SE 6.  This has been a long time coming and lots of people were clamoring that Apple abandoned Java.  While it&#8217;s true that Jobs said Java was a &#8220;ball and chain,&#8221; the context was very much that of the iPhone.  And Java, despite ubiquity in the phone market, really hasn&#8217;t done much.</p>
<p>There are some caveats to this update though.   It&#8217;s only compatible with Leopard (Mac OS X.5) and it&#8217;s only compatible with 64Bit Intel processors.</p>
<p>But if you&#8217;re a Java developer on Mac OS X who&#8217;s been getting long in the tooth waiting for this, get going.</p>
<p>The eagle has landed.</p>
]]></content:encoded>
			<wfw:commentRss>http://laststop.spaceislimited.org/2008/05/01/java-se-6-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
