Tuesday 24 June 2014

Building a Simple C program in ZinjaI

Zinjai [link] is a C and C++ integrated development environment or IDE.

An IDE contains a text editor to write code, a compiler to compile code, a linker to build compiled code into an executable file and a debugger to pause a program during execution to allow a programmer to examine the program’s state.

ZinjaI screenshot

It is a Spanish language program but there is a version mostly translated into English.

Note that there is a newer version (20140620) available but it seems to have a bug that does not allow the user interface to be set to English. Update 25 Jun 2014: This bug has been fixed.

Zinjai was created for teaching programming so is good for beginners to use.

One useful feature is that you do not have to create a project to test simple C or C++ code. Just type it in and run it.

Zinjai uses the MingW GNU compilers and tools to compile and build programs. You need to know this if you download other code libraries to use with your programs.

In my post about MQO viewers [link], I posted a site where you can download the C source code for GLMetaseq.

Download sample_GL.zip from that site [link], near the bottom of the page.

We will build the sample_GL program in Zinjai so we can view a Metasequoia *.mqo file.

Download and install Zinjai.

I chose the options below. Make sure to include MingW if you do not aready have MingW installed and OpenGL since GLMetaseq requires the code libraries Zinjai adds for OpenGL support.

ZinjaI installation options

First we will create a simple program to test that Zinjai can create a program.

Click “Create simple program” on the start page, select “Empty C++ Program’s Skeleton” in the “New File: dialog’s  template list and click “Create”.

Create an empty C   program

Zinjai should open the basic code for a C++ program in the text editor.

Basic C   code

Type the following code where Zinjai highlights.

Unlike Python, C and C++ don’t care about indentation. C and C++ are case sensitive though so make sure your capitalisation is the same for the text outside the quotes.

C and C++ statements must end with a semi colon ‘;’.

cout << "A ZinjaI C++ program. Hola!" << endl;
cout << "There are " << argc << " commandline arguments." << endl;

Add code to the skeleton code and run the program

Run the code by clicking the green triangular play button on the toolbar or via Run>Run in the menu and hopefully Zinjai reports no errors.

Warnings don’t stop your program being built and executed but errors do.

No errors

To run our program the computer creates a command window (also known as a console) and the program outputs (prints) the text we placed in double quotes to that window.

Program output

The command window stays open until we press enter.

IMPORTANT: This is because Zinjai has told the command window to stay open.

There isn’t any code in our program to keep the window open so if we were to run the program outside Zinjai by double clicking on the executable file we created (*.exe for Windows) the command window would open and close rapidly.

In general a computer executes the instructions (lines of code) in a program from the top to bottom and when the last instruction is reached the program ends. In our case the computer will close the command window when the program ends.

Computers execute each instruction in a tiny fraction of a second and in our program the computer reached the last instruction very quickly and the program finished before we could see the printed text.

To see the text if running this program outside Zinjai we need to run it from a console window. The program still executes quickly and finishes but the computer doesn’t close the console window.

The executable file we just created is found at "C:\Users\<username>\zinjai\sin_titulo.exe" and will be overwritten every time you run a simple program.

Now we know Zinjai is installed correctly we can build the simpleGL program.

Close the program we just created without saving and return to Zinjai’s start page.

Click “Create new project”.

In the first dialog of the wizard give your project a name and set a folder for the project. By default the name of the project will be the name of the executable file.

Give project a name and path

In the next dialog of the wizard select the “Proyecto OpenGL” template and click “Create”.

If you didn’t select the option to include OpenGL when installing Zinjai you may not have this template choice.

Use OpenGL project template

Run the program. If all goes well you should see a console window and a window titled “Ventana OpenGL”.

OpenGL program output

When you select the OpenGL template the project is configured to find the OpenGL and freeglut libraries and headers and the names of the libraries we are using have been set for the linker.

You can study the project settings via the Run>Configure menu.

Project compiler settings



Project linker settings

Setting the correct configuration for a project can sometimes be the hardest thing for beginners to learn because if you create an empty project you have to configure all the settings yourself.

Stop the program running by clicking the red stop button in the toolbar.

Close the readme that is open in the editor but note the freeglut DLL is not be needed to run the program.

Right click on “main.cpp”, click “Detach from Project” in the popup context menu and click “Yes” to confirm.

Click File>”Open/Attach to project”, navigate to the unzipped sample_GL folder and open the three files. Confirm attaching the files to the project and also confirm copying the files to the project folder.

Attach the sample_GL files to the project



The sample_GL files are displayed in the editor

Hopefully the Mojibake in the files won’t cause any errors.

The “sample_GL.c” file is the new main file of our project since it contains the function named “main” where the execution of the program begins.

C and C++ programs require one and only one function named “main” to be present in the source code.

Before building and running any code you should examine the *.c files to make sure they do not include code that may harm your computer.

The code looks okay to me and the website seems reputable so I’ll take the risk.

Click the run button to compile, build and execute the program.

There are a few warnings but the program executes. Good stuff.

sample_GL program executing

There isn’t any model displayed and no way to select a file so we need to study the code to find out what the program needs to show a model.

Stop the program executing by clicking Zinjai’s stop button (otherwise you have to close the two windows) and display sample_GL.c in the text editor.

Go to the “main” function.

int main(int argc, char *argv[])
{
 // ‰Šú‰»
 glutInit(&argc,argv);          // OpenGL‰Šú‰»
 glutInitWindowPosition(100, 50);       // ƒEƒBƒ“ƒhƒE‚Ì•\Ž¦ˆÊ’u
 glutInitWindowSize(640, 480);        // ƒEƒBƒ“ƒhƒE‚̃TƒCƒY
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); // ƒfƒBƒXƒvƒŒƒCÝ’è
 glutCreateWindow("MQO Loader for OpenGL");     // ƒEƒBƒ“ƒhƒE‚̐¶¬

 // ƒ‚ƒfƒ‹‚ð•\Ž¦‚³‚¹‚鏀”õ
 mqoInit();           // GLMetaseq‚̏‰Šú‰»
 g_mqoModel = mqoCreateModel("ninja.mqo",1.0);  // ƒ‚ƒfƒ‹‚̃[ƒh

 // I—¹ˆ—ŠÖ”‚̐ݒè
 atexit(Quit);

 // ƒR[ƒ‹ƒoƒbƒNŠÖ”‚̐ݒè
 glutDisplayFunc(Draw);   // •`‰æˆ—ŠÖ”‚̐ݒè
 glutIdleFunc(Draw);    // ƒAƒCƒhƒ‹Žž‚̏ˆ—ŠÖ”‚̐ݒè
 glutReshapeFunc(Reshape);  // ƒEƒBƒ“ƒhƒE•ÏŒ`Žž‚̏ˆ—‚ðs‚¤ŠÖ”‚̐ݒè
 glutKeyboardFunc(Keyboard);  // ƒL[“ü—ÍŽž‚̏ˆ—ŠÖ”‚̐ݒè
 glutMouseFunc(Mouse);   // ƒ}ƒEƒX“ü—ÍŽž‚̏ˆ—ŠÖ”‚̐ݒè
 glutMotionFunc(Motion);   // ƒ}ƒEƒXƒhƒ‰ƒbƒOŽž‚̏ˆ—ŠÖ”‚̐ݒè

 // ƒCƒxƒ“ƒg‘Ò‚¿‚Ì–³ŒÀƒ‹[ƒv‚É“ü‚é
 glutMainLoop();

 return 0;
}

The file name “ninja.mqo” has been hardcoded in the program.

The program only looks for a file with that name.

There isn’t any path (C:\…\) in the name so for the program to find the file it must be in the same folder as the executable file.

You could copy the “ninja.mqo” file from the unzipped sample_GL folder you downloaded to the same folder as the executable but if you have another *.mqo file you can copy it instead and rename it “ninja.mqo”.

Alternately you could copy your *.mqo file to the same folder as the executable and change the file name in the code to your *.mqo file name and rebuild the program.

Where is the executable file?

The executable file will be in the project folder but in a folder with a name set in the project configuration.

Go to Run>Configure and click the General tab.

The path for the executable is “debug.w32\”.  Clicking the button with the ellipsis (…) should show you the folder but in this case it shows the folder from where we copied the source code files.

Executable path

The folder is named “debug” since our project is configured to create an executable that can be traced in a debugger.

A program you wish to trace in a debugger has to be built as a debug version because the compiler has to insert extra instructions into the executable for the debugger.

The other standard executable version is “release” which is so called since this is the program you release to the public. The release version is smaller since it does not contain the extra instructions for the debugger.

You can change which version of the program you wish to build by changing the setting in the project configuration and rebuilding the program.

Set project to build a debug or release executable

Copy “ninja.mqo” to the same folder with the executable.

Double click on the executable file in the “debug.w32” folder to run it and see the Ninja displayed.

Ninja

Close the program and now run the program from Zinjai by clicking the “Run” button.

The Ninja model is not displayed even though the “ninja.mqo” file is in the same folder with the executable.

This is because of another project setting that you must be aware of - the project’s working folder.

Click Run>Configure and click the “General” tab to find the “Working directory” setting.

Working directory setting

At the moment no directory is set so the project will use the directory containing the project file, *.zpr.

You can test this by copying “ninja.mqo” to the folder with the source code files and then running the program from Zinjai. The Ninja model should now be displayed.

Change the working directory using the button with the ellipsis (…) to the “debug.32” folder and run the program from Zinjai and you should now see the Ninja.

The computer opens a console window and an OpenGL window for the program. Sample_GL outputs error information (in Mojibake) to the console so it is useful but we can change the project configuration so that the console window is not created.

Go to the project configuration via Run>Configure and click the “Linkage” tab. Uncheck/untick the “It is a console program” setting and click “OK” to apply the change.

Change project configuration to not create console window

Now when you run the program, which will be rebuilt because you changed a project setting, only the OpenGL window is displayed.

Having a hardcoded file name is not very user friendly so I will change the code so we can open any *.mqo file.

The “main” function for a C or C++ program can have two parameters - an integer and an array of strings(text).

They are usually named “argc” and “argv” but could be named otherwise if you wish.

In our simple program test we printed the value of “argc” to the console. This parameter is the count of command line arguments.

This count always includes the executable so in our simple test program there was a count of one.

All the names of the command line arguments are stored in the “argv” array.

We can make use of these parameters to pass a filename from the command line to our program.

Here is the modified “main” function.

int main(int argc, char *argv[])
{
 // ‰Šú‰»
 glutInit(&argc,argv);          // OpenGL‰Šú‰»
 glutInitWindowPosition(100, 50);       // ƒEƒBƒ“ƒhƒE‚Ì•\Ž¦ˆÊ’u
 glutInitWindowSize(640, 480);        // ƒEƒBƒ“ƒhƒE‚̃TƒCƒY
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); // ƒfƒBƒXƒvƒŒƒCÝ’è
 glutCreateWindow("MQO Loader for OpenGL");     // ƒEƒBƒ“ƒhƒE‚̐¶¬

 // ƒ‚ƒfƒ‹‚ð•\Ž¦‚³‚¹‚鏀”õ
 mqoInit();           // GLMetaseq‚̏‰Šú‰»
 if (argc > 1){
  g_mqoModel = mqoCreateModel( argv[1],1.0);
 }
 else {
  g_mqoModel = mqoCreateModel("ninja.mqo",1.0);  // ƒ‚ƒfƒ‹‚̃[ƒh
 }
 // I—¹ˆ—ŠÖ”‚̐ݒè
 atexit(Quit);

 // ƒR[ƒ‹ƒoƒbƒNŠÖ”‚̐ݒè
 glutDisplayFunc(Draw);   // •`‰æˆ—ŠÖ”‚̐ݒè
 glutIdleFunc(Draw);    // ƒAƒCƒhƒ‹Žž‚̏ˆ—ŠÖ”‚̐ݒè
 glutReshapeFunc(Reshape);  // ƒEƒBƒ“ƒhƒE•ÏŒ`Žž‚̏ˆ—‚ðs‚¤ŠÖ”‚̐ݒè
 glutKeyboardFunc(Keyboard);  // ƒL[“ü—ÍŽž‚̏ˆ—ŠÖ”‚̐ݒè
 glutMouseFunc(Mouse);   // ƒ}ƒEƒX“ü—ÍŽž‚̏ˆ—ŠÖ”‚̐ݒè
 glutMotionFunc(Motion);   // ƒ}ƒEƒXƒhƒ‰ƒbƒOŽž‚̏ˆ—ŠÖ”‚̐ݒè

 // ƒCƒxƒ“ƒg‘Ò‚¿‚Ì–³ŒÀƒ‹[ƒv‚É“ü‚é
 glutMainLoop();

 return 0;

Now run the program to rebuild it. The Ninja is displayed.

Navigate to the “debug.32” folder in File Explorer, copy a different *.mqo file to it and then open a command window. In Windows 8.1 a command window can be opened from File Explorer’s “File” menu.

Open a command window for the debug32 folder

At the prompt type the name of the executable file followed by a space and then the filename of the *.mqo file and press enter.

Run the program from the coomand line with a file name

You should see the model from that *.mqo file displayed.

You can also pass a filename to the program without using the command window if you drag and drop the file onto the executable file in File Explorer.

You can pass a the filename to the program when running it from Zinjai by adding the filename as an argument for the program in the project configuration.

Click Run>Configure and click the “General” tab. Add the filename in the “Arguments for execution:” setting or check/tick “Always ask for arguments before running”.

The file you add must be located in the working directory if you do not enter its full path.

Set a program argument in the project configuration



Model by Mira Studios


To display *.png or *.jpg textures on the models we need to download the libjpeg and libpng headers and libraries for MingW, set the project configuration to find the headers and libraries, add the library names in the “Linkage” project setting and change these defines in “GLMetaseq.h” from “0” to “1”.

#define DEF_USE_LIBJPEG   0   // libjpeg‚ÌŽg—pi1:Žg—p 0:–¢Žg—pj
#define DEF_USE_LIBPNG   0   // libpng ‚ÌŽg—pi1:Žg—p 0:–¢Žg—pj




No comments:

Post a Comment