Aug 16, 2009

Draw Text with OpenGL and Cairo

The OpenGL just supports capability to draw primitive, not text. In order to draw text on screen we need support of other package such as Cairo or Pango. The following topic describe how to use Cairo with OpenGL.
1 First we need to create a Cairo surface for drawing (text)
2 Then we will load the surface into GL texture using glTextureXXX function
3 After all, we will apply texture mapping into our primitive (for example a rectangle for displaying text)


Create Cairo Context
inline cairo_t*
create_cairo_context (int width,
int height,
int channels,
cairo_surface_t** surf,
unsigned char** buffer)
{
cairo_t* cr;

/* create cairo-surface/context to act as OpenGL-texture source */
*buffer = (unsigned char*)calloc (channels * width * height, sizeof (unsigned char));
if (!*buffer)
{
printf ("create_cairo_context() - Couldn't allocate surface-buffer\n");
return NULL;
}

*surf = cairo_image_surface_create_for_data (*buffer,
CAIRO_FORMAT_ARGB32,
width,
height,
channels * width);
if (cairo_surface_status (*surf) != CAIRO_STATUS_SUCCESS)
{
free (*buffer);
printf ("create_cairo_context() - Couldn't create surface\n");
return NULL;
}

cr = cairo_create (*surf);
if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
{
free (*buffer);
printf ("create_cairo_context() - Couldn't create context\n");
return NULL;
}

return cr;
}

Draw text into the Cairo surface and then load it into GL Texture
inline int DrawText(int x, int y, int width, int height, char *string, COLOR &textColor, COLOR &background)
{
cairo_surface_t* surface = NULL;
cairo_t* cr;
unsigned char* surfData;
GLuint textureId;

/* create cairo-surface/context to act as OpenGL-texture source */
cr = create_cairo_context (256,
256,
4,
&surface,
&surfData);

/* clear background */
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgb(cr, background.red, background.green, background.blue);
cairo_paint (cr);

cairo_move_to(cr, 256/10, 256/2);
cairo_set_font_size(cr, 30);
cairo_select_font_face(cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_source_rgb(cr, textColor.red, textColor.green, textColor.blue);
cairo_show_text(cr, string);

glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
256,
256,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
surfData);
TestEGLError("glTexImage2D");

free (surfData);
cairo_destroy (cr);

return textureId;

}

Texture Mapping
The texture mapping is so simple, we need to provide them the UV coordinate. The UV coordinate is range from 0 to 1 which 0 is the start point, and 1 is the end point. The following is an example usage


GLfloat textureCoord[] = {
f2vt(0.0f), f2vt(0.35f),
f2vt(1.0f), f2vt(0.35f),
f2vt(0.0f), f2vt(0.55f),
f2vt(1.0f), f2vt(0.55f)
};
COLOR clrText = {255,255,255};
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
GLuint textureId = DrawText(clipRect[0], clipRect[1], clipRect[2], clipRect[3], data, clrText, this->m_clrBackground);

glVertexPointer(2, VERTTYPEENUM, 0, rect);
glTexCoordPointer(2, VERTTYPEENUM, 0, textureCoord);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glDeleteTextures(1, &textureId);

Aug 15, 2009

Enable 2D Over OpenGL

In OpenGL, if we want to 2D only, we can use the Ortho matrix to set ignore the z-list. The following code snippet demo how to do that

void
glEnable2D()
{
int vPort[4];

glGetIntegerv(GL_VIEWPORT, vPort);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}

void glDisable2D()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}

Aug 10, 2009

Boot beagleboard with S-Video output

Boot beagleboard with S-Video output

setenv bootargs console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait omapfb.mode=tv:1024x768-16@60 omapdss.def_disp=tv
mmcinit
fatload mmc 0:1 0x80300000
uImage-2.6.29 bootm 0x80300000

Aug 8, 2009

How To Share Network with Beagleboard through USB

1) Follow this link to setup network connection between Beagleboard and Host
2) Setup ip forwarding in the Host (linux)
echo "Remove any previous NAT setup"
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain

echo "Setup NAT to forward packets from usb0 <---> eth0"
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
iptables --append FORWARD --in-interface usb0 -j ACCEPT

echo "Enable packet forwarding in the kernel"
echo 1 >> /proc/sys/net/ipv4/ip_forward

3) In the board add route to the host
route add default gw 192.168.99.100

4) In the board set the DNS search to be same as the host so that it can resolve host to name
cat /etc/resolve.conf
nameserver 192.168.1.1

That's all :-)

How To Setup Beagleboard Network through USB

1) Boot up the board
2) In the board type
ifconfig usb0 [ip_here] netmask [mask here] up
i.e. ifconfig usb0 192.168.99.100 netmask 255.255.255.0 up
3) In the host environment (linux) type
ifconfig usb0 [ip_here] netmask [netmask here] up
ifconfig usb0 192.168.99.101 netmask 255.255.255.0 up

Then you can ssh to the board with `ssh root@192.168.99.100

Aug 1, 2009

Boot the Beagleboard with NFS through USB

You need a USB cable and serial cable to connect from Beagleboard to your Linux host
Install
- NFS
- bridge-utils

1) Add file ifcfg-usb0 into /etc/sysconfig/network-scripts/
DEVICE=usb0
IPADDR=192.168.99.100            # Replace with your Linux host's IP address
NETMASK=255.255.255.0
ONBOOT=no
TYPE=USB
BOOTPROTO=none
USERCTL=no
IPV6INIT=no
PEERDNS=yes
NM_CONTROLLED=no
TYPE=Ethernet

2) Add the ifcfg-br0 into /etc/sysconfig/network-script
# Ethernet Bridge
DEVICE=br0
ONBOOT=no
SEARCH="localhost"              # Replace with your search domains
BOOTPROTO=none
NETMASK=255.255.255.0           # Replace with your subnet's netmask
IPADDR=192.168.99.100           # Replace with your Linux host's IP address
USERCTL=no
PEERDNS=yes
IPV6INIT=no
GATEWAY=192.168.1.1             # Replace with your subnet's gateway
TYPE=Ethernet
DNS1=192.168.1.1                # Replace with your subnet's DNS
DOMAIN='localhost'                 # Replace with your Linux host's domain(s)
NM_CONTROLLED=no


4) Add br0 into /etc/init.d
#!/bin/bash

# Source function library.
. /etc/rc.d/init.d/functions

RETVAL=0

# Check if all what named needs running
start()
{
   /usr/sbin/brctl addbr br0
   /usr/sbin/brctl addif br0 eth0
   /sbin/ifup eth0
   /sbin/ifup br0
   return 0;
}

stop() {
   /sbin/ifdown br0
   /sbin/ifdown eth0
   /usr/sbin/brctl delbr br0
}


restart() {
 stop
 start
} 

# See how we were called.
case "$1" in
 start)
  start
  ;;
 stop)
  stop
  ;;
 restart)
  restart
  ;;
 *)
         echo $"Usage: $0 {start|stop|restart}"
  exit 3
esac

exit $RETVAL

3) Setup NFS: add following line to /etc/exports
/data/nfs *(rw,no_root_squash,no_all_squash,async)

4) Create directory /data/nfs and tar your root filesystem to /data/nfs

5) Type following commands to restart the NFS service
#service rpcbind restart
#service nfs restart

6) On BeagleBoard console type following command.
OMAP3 beagleboard.org # setenv bootargs console=ttyS2,115200n8 root=/dev/nfs rw nfsroot=192.168.99.100:/data/nfs ip=192.168.99.101::255.255.255.0 nolock,rsize=1024,wsize=1024 rootdelay=2

7) OMAP3 beagleboard.org # saveenv

8) OMAP3 beagleboard.org # mmcinit

9) OMAP3 beagleboard.org # fatload mmc 0 0x80300000 uImage

10) OMAP3 beagleboard.org # bootm 0x80300000

11) While the board is booting up, type ifconfig until you see the usb0 device is up. Then type `brctl addif br0 usb0`.

And enjoy the filesystem over NFS

Reference from http://elinux.org/Mount_BeagleBoard_Root_Filesystem_over_NFS_via_USB