3D: Shaders

did some research on shaders:

FROM: http://en.wikipedia.org/wiki/Shader
A shader is a set of software instructions, which is used to calculate rendering effects on GPU. Shaders can program the GPU's programmable rendering pipeline (as opposed to Fixed Function Pipeline, or FFP). Shaders replaces the FFP.

Shaders help determine the traits of a vertex or pixel. There are 3 types of shaders:
1. Vertex shaders: these are run once per vertex. manipulates position, color and tex-coordinates of vertices.
2. Geometry shaders: can add or remove vertices from a mesh (caused by plane-clipping, etc).
3. Pixel/fragment shaders: determines trait of a single pixel (color, z, alpha). typically used in scene lighting, bump-mapping, color toning.

Programming shaders can be done in the following 3D languages: OpenGL, DirectX.
1. DirectX for ATI uses HLSL (high level shader language)
2. DirectX for NVidia uses Cg (C for graphics, very similar to HLSL)
3. OpenGL uses GLSL (OpenGL Shading Language)

IPHONE: User-defined constructor/destructor

This is actually the second time I've come across this issue. Unfortunately I did not post the solution last time, so I had to go look it up again...

The WARNING:
type 'SomeClassType' has a user-defined constructor
tyep 'SomeClassType' has a user-defined destructor

The SOLUTION:
convert object declarations into pointer declarations. for example:
@interface myclass {
@private
SomeClassType myInstance;
}

change to:
@interface myclass {
@private
SomeClassType* myInstancePtr;
}

Of course, this also means you will have to manually control the instantiation & destruction of the object with new & free.

ANDROID: logcat on device

Here's another gripe. When you have both the emulator & device running, the adb logcat doesn't know which to listen to, and as a result outputs NOTHING.

to solve you'd simply close the emulator or device, whichever you aren't currently using.

also, as an added bonus, I found out how to cue up logcat via command prompt:

adb logcat -s DEVICE_NAME

ANDROID: Cannot create linked resource...

Here's the second error today. While attempting to import the Android project, or attempting to create a new Android project, I kept getting the error:

Cannot create linked resource '/.org.eclipse.jdt.core.external.folders/.link0'. The parent resource is not accessible.

Solution:
Unfortunately, this means it's time to ditch your workspace and create a new one... save your preferences (esp your key bindings), and move your Eclipse workspace to a new location. This should fix the issue.

Other solutions I've found online:
- Reinstalling Eclipse (overkill)
- Reinstalling Android SDK (probably won't help)
- eclipse.exe -clean (doesn't clean the workspace)

Nevertheless, you should try the -clean method, just in case it works for you.


ANDROID: Could not find *.apk!

SEVERAL very annoying errors popped up today as I was dev-ing for Android. This post describes & solves the first of these errors.

Description of Error:
While attempting to build the android project the following message will pop up in the Console

[2009-11-02 16:28:51 - AndroidGL]Android Launch!
[2009-11-02 16:28:51 - AndroidGL]adb is running normally.
[2009-11-02 16:28:51 - AndroidGL]Could not find ********.apk!

Solution:
Make sure your project imported the Android 1.6 library correctly. That is, under your project, you should see 'Android 1.6', which expands and displays 'android.jar'.

If it says Referenced Libraries > android.jar, you will need to fix this by manually altering the .classpath for the project.

Open .classpath for the project and type the following:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<kind="src" path="src">
<kind="src" path="gen">
<kind="con" path="com.android.ide.eclipse.adt.
ANDROID_FRAMEWORK">
<kind="output" path="bin">
</classpath>

The important line is the 3rd classpathentry, which is the actual link to the Android SDK libraries.

glFrustum vs PerspectiveFovRH

I was a bit stumped when I stumbled into PowerVR's iPhone SDK for OGL ES 1.1. namely, I wasn't sure what PerspectiveFovRH was for... I messed around with the numbers a little, and discovered the relationship between PerspectiveFovRH and the usual glFrustum method:

glFrustum(frustumLeft, frustumRight, frustumBottom, frustumTop, frustumNear, frustumFar)

is the same as:

float fovy = 2 * atanf( (frustumTop - frustumBottom) / (2 * frustumNear) );
PerspectiveFovRH(fovy, 320/480, frustumNear, frustumFar, OGL, false);

COCOA: OpenGL View

I tried to render a box in OpenGL, and for some strange reason, the depth test wasn't working at all. Finally I googled the problem, and found out it was caused by the Interface Builder... this is why I avoid IB when developing...

Here's what the screen-capture looked like, even though I had enabled GL_DEPTH_TEST



basically you have to set the depth bit of the OpenGLView to be > 0 bit (which is default!?). While I was at it, I also changed the color to 32bit.

Win32: Setting up OpenGL's GLUT

it's been a very long time since my previous posts. i had to recently install opengl on my windows xp environment, and found there were actually very little documentation on this subject. so here's a tutorial to getting things started in opengl & glut.

CHECK FOR OpenGL:

1. when you install visual studios, you should already have the following libraries and DLLs:
- OpenGL32.lib (in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib, etc)
- GLU32.lib (in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib, etc)
2. make sure you see the following dll's in C:\Windows\System32
- OpenGL32.dll
- GLU32.dll

BUILD & INSTALL GLUT:

1. goto http://www.opengl.org/resources/libraries/glut/glut_downloads.php
- i downloaded 3.7.6 from http://www.xmission.com/~nate/glut.html
- download glut-3.7.6-src.zip
2. unzip glut-3.7.6/ directory onto the desktop
3. open glut.dsw
4. build the glut32 project

if you have visual studios 6, you should be fine. however, if you have visual studio 9.0 like me, you'll end up with an error during file copy, so you have to do some manual copying and pasting...

1. inside the [[DESKTOP]]/glut-3.7.6/ directory navigate to:
- [[DESKTOP]]/glut-3.7.6/lib/glut/Debug
2. copy glut32.dll into C:\Windows\System32
3. Copy glut32.lib into C:\Program Files\Microsoft Visual Studio 9.0\VC\lib
4. Copy [[DESKTOP]]/glut-3.7.6/include/GL/glut.h to C:\Program Files\Microsoft Visual Studio 9.0\VC\include\GL\glut.h

after this you should be able to start compiling the samples from the OpenGL red book.

WINDOWS: Registry

To add something to the RIGHT CLICK context menu, we can change the registry.

In my particular instance, I am looking to add a QUICK COMMAND that will run the JAD file in MPowerPlayer.

1. Goto: My Computer > HKEY_CLASSES_ROOT > jadfile
2. Expand jadfile > shell, and add a key "Run with MPowerPlayer"
3. Add a key under "Run with MPowerPlayer" called "command"
4. On the right, double click (Default), add the following data: java -jar C:\\mpowerplayer\\player.jar "%1"

That's all. Now right click on the JAD file and you should see your new command "Run with MPowerPlayer.

NOTE: you will want to change the directory location of mpowerplayer\player.jar to match your own.

Here's the entire structure after you are done (added 'Edit' command for comparison):

My Computer
----L HKEY_CLASSES_ROOT
---------L jadfile
--------------L shell
------------------L Run with MPowerPlayer
-----------------------L command = java -jar ... (see above)
------------------L Edit
-----------------------L command = notepad.exe "%1"

IPHONE: Saving data on exit

Totatlly forgot how to do this, so I had to look it up...

Use the following methods to catch application exit notifications:
- (void)applicationWillTerminate:(UIApplication *)application

Use this method to catch application interrupt notification:
- (void)applicationWillResignActive:(UIApplication *)application

Use this method to catch application resume notification:
- (void)applicationDidBecomeActive:(UIApplication *)application

Grep recursive search

find . | xargs grep -s "text to grep"

POSTGRESQL: Removing POSTGRESQL

The following manual uninstallation guide was grabbed from 2 separate sites. One is for removing 8.3, and the other for removing 8.4.

In Mac OSX: (Assuming Default Locations)

Via uninstaller:

1) In the installation directory, there will be a uninstall-postgresql.app file will be there, executing (double clicking) that will uninstall the postgresql installation.

Manual Uninstallation:

1) Stop the server
sudo /sbin/SystemStarter stop postgresql-8.3

sudo launchctl unload /Library/LaunchDaemons/com.edb.launchd.postgresql-
8.4.plist

2) Remove menu shortcuts
sudo rm -rf /Applications/PostgreSQL/8.3
sudo rm -rf /Applications/PostgreSQL/8.4

3) Remove the ini file
sudo rm -rf /etc/postgres-reg.ini
sudo rm -f /etc/postgres-reg.ini

4) Removing startup items
sudo rm -rf /Library/StartupItems/postgresql-8.3
sudo rm -f /Library/LaunchDaemons/com.edb.launchd.postgresql-8.4.plist

5) Remove the data and installed files
sudo rm -rf /Library/PostgreSQL/8.3
sudo rm -rf /Library/PostgreSQL/8.4

6) Delete the user postgres
sudo dscl . delete /Users/postgres

SYMBIAN: NewLC vs. NewL

It all has to do with the way you implement NewLC and NewL, but the STANDARD difference between NewLC and NewL is whether or not you have to CleanupStack->pop the object created.

Let's first start with the typical implementation of NewL and NewLC

static CObject* newL();
CObject* CObject::NewL() {
----CObject* self = NewLC();
----CleanupStack::Pop(self);
----return self;
}

static CObject* newLC();
CObject* CObject::NewLC() {
----CObject* self = new (ELeave)CObject();
----CleanupStack::PushL(self);
----self->Construct();
----return self;
}


As such, you would instantiate a CObject by using either of the following:

CObject* obj = CObject::NewL();


or

CObject* obj = CObject::NewLC();
// do something with obj that may require cleanup ie. cptrArray->AppendL(obj);
CleanupStack::Pop(obj);


If you do not pop the object, the stack will be messed up and you'll have a very difficult time figuring out why that is.

C++: CONST CAST

Spent about 20 minutes trying to figure out why this wasn't compiling.

void CImageLoader::LoadImageL(const TDesC& filename) {
----TDesC* tmp = &filename; // COMPILER ERROR
}


It's because filename is CONST. So we'll have to 'unconst' it for this line to work:

TDesC* tmp = &(const_cast(filename));

OPENGL ES: Basics

Here's how I usually set up my quads:

Coordinates
D C
A B

Vertices
A B
D C

Here's are the coordinates:
vertices = {-1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1};
coords = {TEX(0, 0), TEX(255, 0), TEX(255, 255), TEX(0, 255)}; // assumes 256x256 texture image
normal = {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1};
triangles = {1, 0, 3, 1, 3, 2};

Where TEX(u,v) is defined as (GLbyte)( (u) - 128 ) , (GLbyte)( (v) - 128 )

Draw code

glMatrixMode(GL_MODELVIEW);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_BYTE, 0, vertices);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_BYTE, 0, coordinates);

glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_BYTE, 0, normals);

glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_BYTE, triangles);

OS X: Splitting & Joining large files

Took me a VERY long time to figure this out, but...

Problem: Files over 4GB cannot be dragged onto your external HDD if the external HDD is using FAT32 file-system.

Solution: Split the file up using terminal into chunks smaller than 4GB and transfer as usual. You can use terminal to join the file up again at a later time.

To split the file up into 1GB chunks:
split -b 1024m filename.file PREFIX_

To join the file from the separated chunks:
cat sub1 sub2 sub3 sub4 > output.file

I read somewhere the older macs cannot handle splits larger than 2047mb. This is not true on my mac because I just made chunks that are 3gb FTW.

MYSQL: Installing MySQL 4.1.22 on OS X 10.5

1. to remove MySQL 5.0, see previous post.
2. download the MySQL 4.1.22 installer from MySQL website.
3. install mysql-standard-4.1.22...i686.pkg
4. install mysqlStartupItem.pkg
5. set up MySQL config. In command prompt type:
sudo pico /etc/my.cnf

6. paste the following 4 lines into pico:
[mysqld]
default-character-set=utf8
[client]
default-character-set=utf8

7. exit pico & save file (ctrl+x, Yes for save)
8. now we can start the MySQL server using sudo:
sudo /Library/StartupItems/MySQLCOM/MySQLCOM start

9. open up command prompt, and enter mysql by typing:
/usr/local/mysql/bin/mysql -u root



EDIT: Getting it to work with OSX's installation of PHP...
Only follow the following instructions if you are having problems with the @mysql_connect method in PHP.

1. create a info.php file that calls the phpinfo(); method
----- NOTE: my version of PHP is 5.2.8
----- scroll down to the mysql section, and look for the value for key: MYSQL_SOCKET
----- MYSQL_SOCKET = /var/mysql/mysql.sock
----- goto /var/mysql and make sure mysql.sock... if the directory is missing or file is missing, you have the same problem I did. Your mysql.sock is probably inside /private/tmp...

2. in command prompt, type the following:
sudo mkdir /var/mysql
sudo chown _mysql /var/mysql

3. (OPTIONAL) in command prompt, type the following:
cp /private/tmp/mysql.sock /var/mysql/mysql.sock

4. edit the my.cnf file again, this time make sure its whole contents are the following 6 lines:
[client]
default-character-set=utf8
socket = /var/mysql/mysql.sock
[mysqld]
default-character-set=utf8
socket = /var/mysql/mysql.sock

5. restart the apache service through System Preferences > Sharing > Web Sharing

6. restart the MySQL service by typing the following 2 lines (one at a time) into command prompt:
sudo /Library/StartupItems/MySQLCOM/MySQLCOM stop
sudo /Library/StartupItems/MySQLCOM/MySQLCOM start

At this point the mysql_connect() php method should work as expected...

MYSQL: Removing MYSQL from a mac

Do the following in the terminal:

1. sudo rm /usr/local/mysql
2. sudo rm -rf /usr/local/mysql*
3. sudo rm -rf /Library/StartupItems/MySQLCOM
4. sudo rm -rf /Library/PerformancePanes/My*
5. (Edit /etc/hostconfig) sudo vi /etc/hostconfig (Remove line MYSQLCOM=-YES)
6. sudo rm -rf /Library/Reciepts/mysql*
7. sudo rm -rf /Library/Reciepts/MySQL*

SQL: MySQL + USERS + MAC

when installing mysql for the very first time, you will need to create a root password in order to enter the mysql database:

mysqladmin -u ROOT_USER_NAME -p ROOT_PASSWORD

sign into mysql using the following command:

mysql --user=ROOT_USER_NAME --password=ROOT_PASSWORD

once in, you want to first navigate to the mysql database:

use mysql;

you can now insert more users to your liking by using the following commands:

create user 'SUB_USER_NAME'@'LOCALHOST';

set that person's password by using:

set password for 'SUB_USER_NAME'@'LOCALHOST' = PASSWORD('SUB_USER_PASSWORD');

now to give all permissions for the new user...

grant all privileges on *.* to 'SUB_USER_NAME'@'LOCALHOST' IDENTIFIED BY 'SUB_USER_PASSWORD' WITH GRANT OPTION;

or if you want to just grant certain privileges (in this case, SELECT):

grant SELECT on *.* to 'SUB_USER_NAME'@'LOCALHOST' IDENTIFIED BY 'SUB_USER_PASSWORD';

if you made a mistake, you can revoke the privileges by doing this:

revoke all privileges, grant option from 'SUB_USER_NAME'@'LOCALHOST';

NOTE:
1. *.* means you are granting permission to SELECT on all databases. Alternatively you could also specify a specific database, ie. mysql.user
2. GRANT OPTION is a special command that allows the SUB_USER to grant that same permission to other users

IPHONE: NSXMLParser leak NSPlaceholderString

This is probably the most annoying leak I've every faced. With the NSXMLParser, I was getting these crazy 16 byte NSCFString leaks. The leaks traced back to [NSXMLParser parse], caused by NSPlaceholderString initWithBytes/initWithString.

I believe this is caused by the [parser:foundcharacters] method. Generally, the xml document being parsed has a bunch of \t and \n characters. It would appear these are the culprit. I got rid of the parse leaks by doing the following:

- (void)parser:(NSXMLParser*)parser foundCharacters:(NSString*)cdata {
NSString* tmp = [cdata stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if(curr && tmp && [tmp length] > 0) {
curr.content:tmp;
}
}

Where curr is the variable saving the cdata 'found characters'.