Saturday, December 27, 2008

gluPerspective to glFrustrumf

gluPerspective is a nice, intuitive helper function for setting the projection matrix in OpenGL. However, it's part of the glu library, which doesn't seem to be (readily) available for the iPhone (OpenGL ES).

Here is how to call glFrustrumf with the values you would give to gluPerspective:

float fov = 45;
float near = 0.01, far = 10;
float aspect = (float)windowWidth / (float)windowHeight;

// glPerspective(fov, aspect, near, far);

top = tan(toRad(fov)) * near;
bottom = -top;
left = aspect * bottom;
right = aspect * top;

glFrustumf(left, right, bottom, top, near, far);

Saturday, December 20, 2008

"error: syntax error before '*' token"

I recently began porting Jumper to the iPhone as a winter project. After adding another source file (Level.c in this case), I started getting thousands of build errors, along the lines of:

error: syntax error before '@' token
error: syntax error before '*' token

These were from files in /Developer/Platforms/iPhoneSimulator.platform/..., which was not encouraging. Something weird was going on.

Actually, it was really simple. Turns out that should have been Level.m, not .c. Whoops.

Saturday, December 13, 2008

Drawing triangles for height maps

Two ways of drawing triangles for HeightMap h1:

Simple, like this:

----
|/|/
----



int ndx = 0;
for (int r = 0; r < h1->rows-1; r ++) {
glBegin(GL_TRIANGLE_STRIP); {
for (int c = 0; c < h1->cols; c ++, ndx ++) {
int cols = h1->cols;
glVertex3fv(h1->verts[ndx+cols].xyz);
glVertex3fv(h1->verts[ndx].xyz);
}
glEnd();
}
}



More complex, but lends itself to simplification over distance, like this:

----
|\/|
----
|/\|
----



for (int r = 1; r < h1->rows-1; r += 2) {
for (int c = 1; c < h1->cols-1; c += 2) {
int cols = h1->cols;
int mid = r*cols + c;
glBegin(GL_TRIANGLE_FAN); {
glVertex3fv(h1->verts[mid].xyz);
glVertex3fv(h1->verts[mid-1].xyz);
glVertex3fv(h1->verts[mid-cols-1].xyz);
glVertex3fv(h1->verts[mid-cols].xyz);
glVertex3fv(h1->verts[mid-cols+1].xyz);
glVertex3fv(h1->verts[mid+1].xyz);
glVertex3fv(h1->verts[mid+cols+1].xyz);
glVertex3fv(h1->verts[mid+cols].xyz);
glVertex3fv(h1->verts[mid+cols-1].xyz);
glVertex3fv(h1->verts[mid-1].xyz);
}
glEnd();
}
}

Tuesday, December 9, 2008

Keep ssh connections open

While in college, I've had to do a lot of work by sshing into school machines. Unfortunately, they allow a rather short "idle" time before they kick me out of whatever I was doing (littering my code folders with .swp files in the process :-P)

While one way around this is to run all your sessions in screen, it's still annoying to me to have my sessions freeze every time I go for a snack.

Fortunately, you can keep your sessions open by putting the following into ~/.ssh/config on your (client) machine:

ServerAliveInterval 60

According to the man page:
"Sets a timeout interval in seconds after which if no data has been received from the server, ssh will send a message through the encrypted channel to request a response from the server."

Sunday, November 23, 2008

Wireframe mode in OpenGL

Here's an easy way to have a togglable wireframe mode in OpenGL (useful for debuging):

bool isWire = true;
...
if (isWire) {
glPolygonMode(GL_FRONT, GL_LINE);
glPolygonMode(GL_BACK, GL_LINE);
}
...(draw)...
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_FILL);

Sunday, November 2, 2008

xrandr for external windows (thinkpad t61)

For reference, here are my bash aliases for setting up external monitors on my Thinkpad T61:


alias lcd='xrandr --addmode VGA 1280x1024 && xrandr --output LVDS --auto && xrandr --output VGA --mode 1280x1024 --left-of LVDS'
alias internal='xrandr --output VGA --off && xrandr --output TMDS-1 --off && xrandr --output LVDS --auto'
alias dual_lcd='xrandr --output LVDS --off && xrandr --output VGA --mode 1280x1024 && xrandr --output TMDS-1 --mode 1280x1024 --left-of VGA'


LVDS: internal screen
VGA: DSUB (blue) (on left of laptop or a dock)
TMDS-1: DVI (white) (on a dock)

lcd: one external monitor (the DSUB slot on the left)
dual_lcd: two external monitors (via a dock)
internal: just the internal screen

Note: Only two screens can be active at once (you'll get an error if you try to add a third; that's why the shortcuts are so complicated)

Making your own programs float in awesome window manager

I do a fair bit of graphics/game coding in my spare time (and occasionally for classes). These don't fit well into tiling environments, since I usually want them to be a specific resolution, and in-front of all other windows. Fortunately, there's an easy way to do this with the awesome window manager (note: this is with version 2.3).

The normal way of making things float in awesome is like this:

rule { name = "Gimp" float = true }


However, this didn't work so well for my stuff. I tried variations of a.out (which I swore I got to work before...wish I'd backed up that conf file...) to no avail. However, you can also use xproperties, obtainable from xprop (run xprop in a terminal, click on the window you want info for, and the x properties will be printed in the terminal).

For my current project, this gave me:

$ xprop
WM_STATE(WM_STATE):
window state: Normal
icon window: 0x0
_AWESOME_PROPERTIES(STRING) = "0010000000"
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW
WM_LOCALE_NAME(STRING) = "C"
WM_HINTS(WM_HINTS):
Initial state is Normal State.
WM_NORMAL_HINTS(WM_SIZE_HINTS):
user specified location: 100, 100
user specified size: 800 by 600
WM_CLIENT_MACHINE(STRING) = "Gecko"
WM_ICON_NAME(STRING) = "Asteroid Game"
WM_NAME(STRING) = "Asteroid Game"


In the rules section of ~/.awesomerc, I added the following:

rule {xproperty_name = "WM_NAME" xproperty_value="Asteroid Game" float = true }


It worked! (A bit tedious to add for each new app you work on, but better than nothing for now....I'll update post if I figure out how my old a.out trick worked).