C & ARToolkit introduction

What you should obtain


Links, Books

  • a really usefull link for C: faq comp.lang.c
  • a really usefull book for C: B. W. Kernighan & D.M. Ritchie "The C language"
  • Google is your friend!

Installing the camera and ARToolkit on your machine

TO DO - just wait for the cameras!

The C language, what is this?

First, few words for those who discover the C-language. C is an old language, invented in 1978 by Dennis Ritchie for the UNIX systems. Several norms have been proposed to define it, the most famous one is the ANSI (American National Standards Institute) norm. Nowadays, C is still used because this is a "low level" programming langage (no polymorphism, no objects, no references...) and a really powerfull one. It is mostly used for real-time and embedded applications.

One important difference with the JAVA is that you can manage pointers in C, and YOU have to control the memory (allocation / desallocation). Be methodic and take care of your pointers and of your memory!

To compile a C program, gcc is going to be used. This is probably the most used C compiler in the world, and this one tries to respect the ANSI norm (for instance, a big part of your linux and your applications are compiled with it). It exists a lot of other compilers, like Visual C++, ICC, Intel, Watcom..., some are more powerfull, some are more adapted to embedded applications. As always into the fantastic world of linux, you are free to choose.

To write your program, just use your favorite text editor. The most used on linux are certainly XEmacs and Vim.

How to structure a C program?

Of course, each programmer has his preferences. You can put all the source code in one file (good luck when your source code will go over 5000 lines), or you can separate the code into several files. A structured architecture is going to be provided in order to simplify your work and to not waste your time in understanding how a Makefile works (it could be a challenging problem!!!), but, as always you are free to change it if you want.

Basically, our architecture is going to be:
  • a makefile, to compile your project
  • a "inc" directory, where you have to put your header files (.h)
  • a "src" directory, where you have to put your source files (.c). After a compilation, you will also find (.o) files, which are object files needed by the compiler to create your executable.
  • a "bin" directory, where your executable file is going to be created.

I don't understand nothing, do you have a really simple example?

Download helloworld.tar.gz, uncompress it with tar zxvf helloworld.tar.gz. Go in your helloWorld directory, type make your program is compiling and the executable is created into the bin directory. Test your program: go in the bin directory and type ./main. "Hello World" should appear into your console.

Take the time to open the Makefile, all the (.c) files and the (.h) one. You should notice several things:
  • into the Makefile, you can change the name of your executable. Try it.
  • try also to change the message printed into your console.

make compiles your program, make clean deletes all the (.o) files and your executable.

Let's do AR now

Download prakt02_default.tgz, uncompress it. This is the basic test provided with ARToolkit (and slightly modified) to test marker detection and to have your first experience with augmented reality! The global architecture is exactly the same than for the helloworld application. Here again, take your time to open all the different files.

The Makefile is a little bit more complicated. Now, ARToolkit is used, that's why you must say to the compiler where to find the header files and the compiled library. Also, to render the scene, opengl is used with 'glut'. Here again, the library needs to be included during the compilation (-lGL -lGLU -lglut).

Have a look to the (.c) files and to the (.h) file. Compile the program, and run it. You should see a virtual cube on your marker, magic no?!

What you have to do...

You are going to apply some simple geometric transformations to your virtual object. Observe the existing code and try to add some keyboard inputs such like:
  • you can resize the virtual object (increase or decrease the size)
  • you can translate the virtual object. The OpenGL function used to translate is glTranslatef (GLdouble x, GLdouble y, GLdouble z);
  • you can switch to another glut object. The cube is often used but glut allows you to use some other ones:
    glutSolidSphere (GLdouble r, GLint m, GLint p);
    glutSolidCone (GLdouble r, GLdouble h, GLint m, GLint p);
    glutSolidTorus (GLdouble rIn, GLdouble rOut, GLint m, GLint p);
    glutSolidTeapot (GLdouble size);
    Try these objects, try to understand what all the parameters are (Google is your friend!). Note that you can replace all Solid by Wire in order to see the wireframed object.
  • rotate the object from the 3-axis X, Y and Z. The OpenGL function used to rotate is glRotatef (GLdouble angle, GLdouble x, GLdouble y, GLdouble z);

  • Rotation order: apply three rotations to initialise your cube and try again with applying the same rotations in the inverse order. Is this the same result? Why?

  • OpenGL coordinate system: try to put the rotation before the translation into your code, and the rotation after the translation. Use both transformations into your application and observe the behaviour of your virtual object... Is that the same result? Why?

How to use some special keys with Glut...

To use some special keys with Glut (directionnal keys, F1, F2, Home, Insert...), you need to use a special function. In your simpleFunction.c file, write a special function:
void specialKeyEvent(int key, int x, int y) {
 if (key == GLUT_KEY_LEFT) {printf("Left key is pressed\n);}
And you must "initialise" this function in your main:

See here for a whole description of the special keys with Glut.

Pointer, array, adress, help!

A pointer is a variable and his value is an adress! A pointer to an int is something like that:
int * p_int;
Each variable, structure in C has an adress. To get the value of a pointer, the operator * is used. Just have a look at this code:
   int a = 4; // the variable a is 4
   int *p = &a; // the pointer p is initialised with the adress of the variable a
   int b; // definition of the variable b, not initialised
   b = *p; //the value of a pointed by b is put in b. The value of b is 4 now.

It is also possible to define pointers on function, but a such technique is not usefull for the praktikum.

You may have some problems in C with the arrays and the pointers. This is NOT the same thing! "Arrays automatically allocate space, but can't be relocated or resized. Pointers must be explicitly assigned to point to allocated space (perhaps using malloc), but can be reassigned (i.e. pointed at different objects) at will, and have many other uses besides serving as the base of blocks of memory." (from the excellent faq comp.lang.c website)

C not allows you to passed an array as a parameter of a function, arguments are passed by value: it means that a copy of the parameters is done. You can't modify the parameters. The solution is to use pointers.

To deal with matrices, you can use several solution:
  • allocate memory to have a 1d-array. Access to the (i,j) elements is given by i*number_of_lines + j. This is the simplest solution, but not the most "natural".
  • allocate an array of pointers which point on a 1d-arrays. Here, you will have real 2d-arrays, easy to use.
  • deal directly with array and pointer. I will not recommand this solution since you don't really control the allocation and size of your arrays.

void changeMatrix(double * matrix, int n)
int i,j;
 for (i=0; i<n; i++)
  for (j=0; j<n; j++)
   matrix[i*n+j] = 1.0;

void main()
  double * testMatrix;
  int i,dim;

  // memory allocation
  dim = 2;
  testMatrix = malloc(dim * sizeof(double));
  changeMatrix(testMatrix, dim);

  // memory free

void changeMatrix(double ** matrix, int n)
int i,j;
for (i=0; i<n; i++)
  for (j=0; j<n; j++)
   matrix[i][j] = 1.0;  

void main()
  double ** testMatrix;
  int i,dim;

  // memory allocation
  dim = 2;
  testMatrix = malloc(dim * sizeof(double*));
  for (i = 0; i < dim; i++)
    testMatrix[i] = malloc(dim * sizeof(double));

  changeMatrix(testMatrix, dim);

  // memory free
  for (i = 0; i < dim; i++)

This method can look a little strange if you are not used to code in C. But with a such solution, you have the control of your memory and of your pointer. You can modify it, move it quickly and quite naturally.

Here some comments and some problems found in your code:
  • try to not use global variables. Return a global variable in a function is totally useless!
  • void changeMatrix(double matrix[3][4]) is allowed in C. But be really carefull! C doesn't allow to pass an array as argument. In fact here, you don't pass an array, but a pointer: your "array" (matrix[3][4]) is implicitly converted to a pointer which points to the adress of the array. Writting voidchangeMatrix(double matrix[][4]) means exatly the same thing. Even if you have the feeling to control the size, you don't!

-- MartinWagner - 18 Apr 2005 -- MichaelAron - 19 May 2005
Topic revision: r14 - 20 May 2005, MichaelAron
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Medieninformatik-Wiki? Send feedback