Friday, June 26, 2009

Creating and using shared library in Linux

Creating a shared library is relatively easy.  We only need to set a compilation flat to -fPIC (Position Independent Code) to create a library that is usable by other programs.

To use the shared library, however, is quite tricky in Linux.  A shared library or dynamically linked library in Windows are easy to use.  We can just place a dll file to the same folder of an executable. 

In Linux, nonetheless, things are more complicated, because Linux will never try to search for a library in a current directory.  Thus, we have to add a library direction to a search path or install it to a standard place like /usr/lib.  The latter choice needs adminstrator priviledge and not suitable if only one or two programs are to use the library.  So, we should modify a search path.

Now, the question is 'Can we modify a search path, but cause no side effect to other programs at all?'.  We are curious about this since we may have multiple libraries of the same name during testing.  A debug program may call a debug library and a release program may call release library of the same name.  Fortunately, we can do that, as shown in http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html (Section 3.5. Installing and Using a Shared Library).

For example, if a shared library is in the same current directory of an executable my_program we can call
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH  ./my_program

If the library is in another folder, such as /home/my_name, the command will be
LD_LIBRARY_PATH=/home/my_name:$LD_LIBRARY_PATH  ./my_program

Next question is 'How can we do such thing in Eclipse?'. We can do this in 'Run Configurations...'. Once we finish common configuration, we need to set an environment variable in the 'Environment' tab.
Click on the 'New' button. Set Name = LD_LIBRARY_PATH and set the Value = my_lib_dir:$LD_LIBRARY_PATH (change 'my_lib_dir' to the library directory). This is enough for Eclipse settings.

Reference
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Monday, June 01, 2009

Note on Boost's Multidimensional Array

Note on Boost's Multidimensional Array

(Jun 1, 2009)
(Last update: Mar 28, 2010)
(Last typo correction: Jan 6, 2024)

The Boost C++ library provides an elegant way to handle a multi-dimensional array.  We can access an array element in a compact way as usual (A[i][j][k], for example).  Boundary checking is performed by assertion which is typically disabled when NDEBUG flag is employed.   Because of the use of assertion mechanism, accessing elements outside the range of any dimension does not cause an exception, but a program will be terminated right away.  This makes sense because a program normally has no use to access an invalid entry and should be rewritten.  Plus, graceful stack unwinding and tracing for exception is not available as a standard way in C++ (there may be a better, standard solution about this in the future, however).  Thus, program halting is not a bad idea under a typical C++ circumstance. 

Moreover, we almost always prevent out-of-bound access explicitly in our code and there is little use to do boundary checking again, especially when speed is important.  Therefore, in a production release, we can remove the boundary checking to increase program speed by disabling assertion.  Note: Alternatively, we can disable this boundary checking by defining BOOST_DISABLE_ASSERTS.

Besides an example in Boost website, I want to add another example and more explanation that may be helpful for later reference (and people who stumble at this page).   In this example, I show that we need to pass boost::multi_array by reference explicitly.  Otherwise, modification in a called function will not have any effect (to see the difference, try removing & in a function signature of change).  Also, there is no exception thrown or caught at all.  The program will be terminated if assertion is enabled.

Another side note, but is important, about Boost's multidimensional array is that we cannot explicitly reallocate it by using = to an instance of the array.  Reassigning an array instance can be done only if both input and output arrays are of the same size.

For example, because we know only an array size during runtime, some may choose to declare a boost multidimensional array without any initial size.

boost::multi_array<double, 3> arrayTest;

Then, we know at runtime that the size is (size_x, size_y, size_z), so we reallocate the array variable by reassignment (using = ) as follows

arrayTest = boost::multi_array<double, 3>(boost::extents[size_x][size_y][size_z]);

This will not cause an error outright in a release mode without assertion, but a program is very likely to crash later on.  A correct way to dynamically reallocate the space for a multidimensional array is to use 'resize' function, as shown below.

arrayTest.resize(boost::extents[size_x][size_y][size_z]);

Notice that it is boost::extents (with s), not just boost::extent (without s).  There is boost::extent, but it is another thing.  Please don't get confused with this.

A correct way to copy contents from one array to another

As discussed earlier, reassigning Boost's multi-dimensional array may cause an error unless both input and output arrays are equal in size.  Thus, a proper way for reassignment is:

// Assume that the input array is of size: size_x, size_y, and size_z.
// 1. resize an output array
outArray.resize( boost::extents[size_x][size_y][size_z] );

// 2. now, we can copy contents of an input array by using =
outArray = inArray;

Side note: assigning initial contents of an array when it is declared.

Assigning contents to an array when it is declared is not considered reassignment.  Hence, such operation is correctly executed as long as the dimensionality is matched.

// This content assignment is correct, provided that the dimensionality of the input array is three in this case.
boost::multi_array<double, 3> outArray = inArray;

The above operation implicitly initialized the size of the outArray to be the same as that of inArray.  It is important to note that such implicit size initialization can be done at the declaration only.  If we do not assign any content to the array, the length of each dimension is zero.  Consequently, content assignment int the following example is an incorrect use.

boost::multi_array<double, 3> outArray;    // since we say nothing else here, the length of the array in each dimension is zero.
outArray = inArray;    // The assignment is not done at the declaration time.  Therefore, this is reassignment.
                       // If inArray size does not match with outArray, the error will occur.

How can we know the size of Boost's multi dimensional array

The size of the array comes in two folds: dimensionality and the array length of each dimension.

  • To obtain dimensionality
    int nNumDims = A.dimensionality;

  • Now, obtain the array length of the ith dimension
    int nLengh = A.shape()[i];

    The following example obtains and prints out dimensionality and lengths of an array

    int nNumDims = A.dimensionality;

    cout << "Dimensionality = " << nNumDims << endl;

    // Report size list
    for (int i = 0; i != nNumDims; ++i) {
         cout << "Size( " << i << " ) = " << A.shape()[i] << endl;
    }

Pitfall: Be careful when Boost's multi-dimensional array is a class member

Suppose class MyArray has a three dimensional array as a member.  Copying contents from one instance of MyArray to another implies copying Boost's multi-dimensional array, as well.
So, make sure that the dimensionalities of input and output arrays match before copying.  Alternatively, we need to copy the contents of MyArray instance at declaration.  See section 'A correct way to copy centents from one array to another' and its side note for detail.

Example:
MyArray outArray;
MyArray inArray;

// Do something with inArray
// ...

// Now, try to save the contents of inArray to outArray
outArray = inArray;  // Beware! There is reassignment of the array inside. 
                     // We have to make sure that all Boost's multi dimensional arrays inside inArray and outArray match in size.

As discussed in the side note above, however, the following code has no problem.
MyArray inArray;

// Do something with inArray
// ...

// Now, try to save the contents of inArray to outArray
MyArray outArray = inArray;  // Correct!  There is no array reassignment, but array initialization at declaration.


=============================================

The following code is an example about assertion and exception throw related to Boost's multi dimensional array.

#include "boost/multi_array.hpp"

using namespace std;

typedef boost::multi_array<double, 3> array3_double;

void change(array3_double& A);
void causeException(array3_double& A);    // In fact, it's not an exception.  Program will be aborted immediately if assertion is enabled.

int main() {
    // Notice that it is extents, not just extent.
    array3_double A(boost::extents[4][3][2]);

    int values = 0;
    for(int i = 0; i != 4; ++i)
        for(int j = 0; j != 3; ++j)
            for(int k = 0; k != 2; ++k)
                A[i][j][k] = values++;

    change(A);

    // Delete this block if you don't want a program to halt.
    // Note: there is no exception thrown.  Program will be just terminated.
    {
        try {
            causeException(A);
        } catch(std::exception ex) {
            cout << "Exception caught:" << endl;
            cout << ex.what() << endl;
        }
    }

    cout << A[3][2][1] << endl; // check this if you pass by value
    return 0;
}

// The parameter is passed by reference.  This is important as the change of A in this function
//   will not affect the
original copy if we pass by value (without using & in the parameter). 
// If we pass by value, the whole thing in
the original copy will be copied to a local copy of
//   this function.

void change(array3_double& A) {
    int nNumDims = A.dimensionality;
    cout << "Dimensionality = " << nNumDims << endl;

    // Report size list
    for (int i = 0; i != nNumDims; ++i) {
        cout << "Size( " << i << " ) = " << A.shape()[i] << endl;
    }

    // Report total size
    cout << "Total size = " << A.num_elements() << endl;

    A[3][2][1] = 99;

    return;
}

void causeException(array3_double& A) {
    int k = 7;

    A[5][5][k] = 9999;

    return;
}


=============================================

Pinyo Taeprasartsit

(This document can be viewed at my blog and Google docs)
(Feel free to leave comment or question in my blog.  Don't worry if it is an old post.  I get a notification of your comment in my mailbox and tend to answer questions from the reader.
Google docs version is better for printing.)

Monday, May 18, 2009

SetPixel in Vista 64 bits

(May 18, 2009)

SetPixel in Vista 64 bits is affected by Aero Glass capability. If we disable Aero Glass, SetPixel will work correctly only around half of the bitmap. For example, if our image is of size 512 x 512, only the first or the second half of the bitmap plane will work fine. In my machine, columns 257 and later will not get affected by SetPixel.

This is a long standing bug in Vista 64 bits, as discussed at http://social.msdn.microsoft.com/Forums/en-US/windowsuidevelopment/thread/4ac40f47-6b44-46c4-869d-38a594d9a4f3.

Workaround is just enabling the Aero Glass theme or use FillRect of size 1 pixel, as shown
http://social.msdn.microsoft.com/Forums/en-US/windowsuidevelopment/thread/9100f5cc-dbc9-4b4a-a46f-23c434d76e87/

Friday, March 13, 2009

Create Virtual Drive in Windows by Mounting Directory

(Mar 13, 2009)

To create a virtual drive in Windows from a directory, we can use the Command Prompt in Windows and input

subst drive_letter: folder_path


For example, if we want to create a virtual z drive from a directory d:\temp, we can issue a command

subst z: d:\temp

To remove the virtual drive, we can use

subst drive_letter: /D

For example subst z: /D


//=================================

More details are available from http://www.askvg.com/create-a-virtual-drive-for-your-desired-folder-in-my-computer-using-subst-command/

Monday, March 02, 2009

Using TortoiseSVN

Using TortoiseSVN

(Mar 2, 2009)

Although GUI of TortoiseSVN is very good, it may not be intuitive for some people.  Here, I discussed some aspects of TortoiseSVN that may be important to a beginner in a version control system.

  1. Repository and working files (files we are working with) are stored in different places.  This aspect will be obvious if we are working on other version control systems, such as MS SourceSafe, because server and client interfaces are separated in the first place.  In that case, we have to set up a server and then use a client interface to connect to the server.

    For TortoiseSVN, however, this may be a bit confusing since TortoiseSVN can act as both server and client at the same time and on the same machine . A place to store a repository and working files seem to be just a folder.  Nonetheless, the behavior of server-client is still preserved and the repository and working files must be in different places.

  2. TortoiseSVN integrates itself to a Windows Explorer.  There is nothing to call from Windows' start menu.  Its behavior is changed according to the items we are interacting with.  For example, if we right click in an empty area in a folder, its menu will allow us to 'Create repository here'.  If we click on a checked out file, its menu will allow us to update from or commit to a repository.

  3. Don't try to add files by going to a working folder.  This must be done in a repository folder.  Basically, a brand new file is not associated with any repositories.  TortoiseSVN will not know where the new file should go.  Thus, we have to call a repository first.  This can be done by going to a repository folder, right click on an empty space, choose 'TortoiseSVN=>Repo-browser'.  When we arrive there, right click on the file pane and choose 'Add file...'. Notice that TortoiseSVN is very obsessed with right clicking on something.

  4. Although a file is added, it remains a normal file in a normal folder.  TortoiseSVN does not associate any version-control features to the file directly. 

  5. Version-control features will be available to working folders only.  In addition, working folders can be created by checking out things from a repository.  Note that pre-existing files in the folder may be perished.  Make sure you copy the files to somewhere else before doing so.  Alternatively, just check out items to another folder, preferably a brand-new one.

  6. We use a version-control system because we want to track change and revert to previous files, if needed.  For TortoiseSVN, reverting can be done at a working folder, not a repository.  This makes sense because a single repository may be checked out to many places.  Going to the repository will give TortoiseSVN no information about a target place.  Note that reverting to a single target is reasonable.  Why?  This is because it is normal that we want to check if reverting will fix an issue.  If so, we can commit the reverted file to a repository again with some check-in note.

    To execute version reverting, go to a target item, right click on it, and choose 'TortoiseSVN=>Show log'.  Then find a desired revision in a log, right click on the revision, and choose 'Revert to this revision'.

  7. A checked out folder is equipped with version-control features.  When we create a new file in the folder, it will mark with '?' on its icon to indicate that it is not a repository.  If it is not supposed to be in a repository, you can tell TortoiseSVN to ignore it.  Otherwise, you can add it to the repository.  This time, we can do it directly by right clicking on the file and choose an appropriate command.  ( Now, you see that TortoiseSVN is 'right-clicking oriented', right? :P )


This document can be view in my blog or Google docs.
(Use my blog to comment and Google docs for printing)


Sunday, January 04, 2009

Compiler issue: Nested template specialization in GCC

(Jan 4, 2009)

I tried to declare a vector that has another container in it. For example,
vector<vector<int>> vecInt;

This syntax works within MS Visual C++, but not in GCC. In GCC, the compiler says
`>>' should be `> >' within a nested template

The above error message is clear. We just need to insert space between angle brackets to fix the issue and change the above statement to
vector< vector<int> > vectInt;

However,
if the inner container is more complicated, the compiler error message
may make you wonder what is happening. For example, if the inner
container is Boost's dynamic bitset:
vector<boost::dynamic_bitset<>> vecBsRoiData;

The error message will be
vecBsRoiData' was not declared in this scope
The
error message is very confusing, but can be handled in the same way by
inserting space between angle brackets and change it to
vector< boost::dynamic_bitset<> > vecBsRoiData;

Note: in reality, we only need to insert space to the closing bracket, but doing so may make the code looks strange. Therefore, I inserted space to both opening and closing brackets.

Tuesday, December 16, 2008

Any Video Converter and CamStudio

(Dec 16, 2008)

I tried to convert AVI video files created by CamStudio to the WMV format. After searching the Internet for good candidates, I decided to use 'Any Video Converter' to do the job. It works well if the number of frames per second in an AVI file is 30.

CamStudio, however, may increase the number of frames per second if your machine is fast. To make the change, go to 'Options->Video Options' and uncheck 'Auto Adjust'.

Any Video Converter is available at http://www.any-video-converter.com
I use a free version (see the bottom of its webpage)

CamStudio is released under GPL. Its website is at http://camstudio.org/

Saturday, December 13, 2008

Issue in C++ File Stream

(Dec 13, 2008)

I encountered a strange file writing/reading issue in C++. I don't understand why closing a file and re-open it does not do its job well. After consulting with Prob (my friend), we can fix this issue by 'clear()' after 'close()'.

Saturday, November 15, 2008

The Cost of Running a PC

(Nov 15, 2008)

Knowing the cost of running a PC is important since it will help approximate the budget of an organization well. AnandTech gives a good example on cost estimation.

http://anandtech.com/casecoolingpsus/showdoc.aspx?i=3458&p=2

Sunday, November 09, 2008

ว่ากันด้วยปัญหาของการประกันราคาสินค้า

(Nov 9, 2008)

การประกันราคาสินค้าเป็นเรื่องที่ซับซ้อน เพราะถ้าหากเราประกันไว้ที่ประเทศไทยโดยรัฐจ่ายเงินชดเชยให้ ก็อาจจะมีสินค้าจากประเทศเพื่อนบ้านทะลักเข้ามาเพื่อจะขายเอากำไรจากส่วนต่าง สูบเงินจากนโยบายประกันราคาของรัฐบาลไป ดังที่จะเห็นได้จากตัวอย่างการประกันราคาปาล์มข้างล่างนี้

จาก ประชาชาติธุรกิจ วันที่ 10 พฤศจิกายน พ.ศ. 2551 ปีที่ 32 ฉบับที่ 4052

"ไชยา"ทุ่ม3,300ล้านประกันปาล์ม ตลาดปั่นป่วน-รง.ชะลอซื้อขายหวังรอราคาใหม่

วง การปาล์มน้ำมันปั่นป่วน หลัง "ไชยา" ประกาศแทรกแซงตลาดปาล์มน้ำมันด้วยการประกันราคาผลปาล์มสดสูงถึง ก.ก.ละ 3.50 บาท น้ำมันปาล์มดิบที่ ก.ก.ละ 22.50 บาท ส่งผลตลาดหยุดชะงักรอ "ส่วนต่าง" ราคาทำกำไรทันที เพราะเหตุไม่มีการตรวจสต๊อกน้ำมันปาล์ม คาดมีน้ำมันปาล์มล้นเกินอยู่ไม่ต่ำกว่า 300,000 ตัน ซื้อเสร็จแล้วไม่รู้จะระบายไปที่ไหน ขณะที่ราคาน้ำมันปาล์มมาเลเซียตก ก.ก.ละ 16-17 บาท รอการทะลักเข้าประเทศตามแนวชายแดน

(อ่านเพิ่มเติมได้ที่ http://www.matichon.co.th/prachachat/prachachat_detail.php?s_tag=02inv06101151&day=2008-11-10§ionid=0203)

YouTube Downloader and Video Converter

(Nov 9, 2008)

Jua, my roommate, asked me to help download YouTube videos about electronic stability control. I tried two software and the winner is YouTube Downloader
http://youtubedownload.altervista.org/

The tool not only downloads a flash video, but also converts it to various format. You gotta find it useful if you are still looking for a good YouTube downloading program.

Friday, October 31, 2008

How to ask professors to serve on Ph.D. committee

I have to take the comprehensive exam in the near future and need to form a Ph.D. committee. With the help from Rahul, I came up with a succinct email for this.

===========================================================

The format is

Hello Dr. [professor to ask],

I am a Ph.D. student working with Dr. [my advisor]. My work focuses on [very compact description of your thesis]. I was going through your research interests and found out about your expertise in [related expertise of professor to ask]. I would very much appreciate if you would agree to serve on my Ph.D. committee and guide me in my research. Would it be possible for you to serve on my PhD committee?

I look forward to your positive response.

Sincerely,
[my name]

===========================================================

Monday, October 27, 2008

Open Error Search Dialog in WinEdt

(Oct 27, 2008)

I closed WinEdt's error dialog at one time and could not find a way to open it again. After spending quite some times, I finally found the way. In WinEdt 5.5, go to Options->Settings. Then, we will see the 'Errors' tab. There are three things we need to check
  1. C++ style errors
  2. Extended TeX Messages
  3. TeX Source Tracking.
Finally, there is another option we have to UNcheck, 'Quick Mode'. When the 'Quick Mode' option is unchecked, error search dialog will work normally.

Sunday, May 25, 2008

Eclipse CDT + MinGW + FreeGLUT

Eclipse CDT + MinGW + FreeGLUT

[Note: if this document seems out-of-date to you, you might want to see the updated and related documents in the bottom.]

(May 24, 2008)
Today, I tried to use Eclipse CDT + MinGW + FreeGLUT to study OpenGL to build my skill for current research and future career development.  This note is created to show how I could get everything done and perhaps, it can be useful for other people.

I started with installing MinGW version 3.4.5 on Windows XP service pack 2.  During installation, we need to install only g++ to get C/C++ compiler.  We should not include the MinGW make tool if we want to make things easier when we work with source base derived from the Unix world.  In such a case, we should use MSYS (Minimal SYStem), instead [1].  However, if you want to use Eclipse CDT's make system, you have no need to worry about this.  It is interesting to note that MinGW already contains GL header files right from its package.  This makes thing very simple for those who want to quickly set things up.

Side Note: MSYS is a part of MinGW project and can be downloaded from the same download area of MinGW at Sourceforge.  

Next, I installed Eclipse CDT.  It is worth noting that we can have multiple Eclipse copies in a single machine.  We can even have each copy of Eclipse associated with one task (project or solution).  If we do not have any specific reason to share this Eclipse CDT copy with other tasks, we can just download a new copy to get only Eclipse CDT.  This can reduce complexity and confusion in the tool as well.  The figure below shows Eclipse features I used.  You can see that it is very lean because it contains only relevant features for C/C++ development.


Figure 1: Eclipse CDT features

Now, we are close to the last step: getting FreeGLUT up and running with Eclipse CDT and MinGW.  I suggest you obtain a compiled DLL from 'Temp Variable's Blog' [2].  The compiled package also comes with necessary header files, so we don't need to go else where, including the official FreeGLUT web site.  If you need to build Free Glut from scratch or need another version, please see the 'update' note at the bottom of this page.  Next, we are ready to create an Eclipse project with a very simple OpenGL program.  This is just for testing the software configuration.  To avoid confusion, I break the process down to steps:

1. Create an Eclipse project with MinGW compiler

Figure 2: When we choose to create a C or C++ project, we need to choose a compiler / toolchain we want to use.

2. Once the project is created, we probably see the default list of included files related to MinGW in the Eclipse project view.  Check if its main include folder has GL header files.  If not, we probably did something wrong.

Figure 3: Default MinGW include paths, including GL header files

3. We have to place FreeGLUT header files in an appropriate place.  We may choose to put them in the GL folder shown above, in an Eclipse project folder, or in a shared folder (so that you can have only one FreeGLUT header copy in your system).  If we choose the last choice (I chose this one too), we have to add an include directory containing FreeGLUT header files.  To do this, right click on the project item in Eclipse and select Properties.  Then, add an include directory as shown in Figure 4.

Figure 4: 'Adding include directories' can be done in C/C++ Build -> Settings -> GCC C++ Compiler -> Directories

4. Now, we need to refer to the OpenGL layer in Windows, opengl32.  This OpenGL layer will connect to a video driver in a machine.  We don't need to worry if we change a video card.  Things will be the same as long as the new video card driver supports OpenGL commands we employ.  This OpenGL layer is, in fact, a library used by a linker.  Hence, we need to set up the GCC C++ linker.  It can be done from almost the same spot shown in Figure 4.  Just scroll down from the 'GCC C++ Compiler' option to 'MinGW C++ Linker'.  Then, add two libraries: opengl32 and freeglut.  Of course, if your OpenGL project is more complicated, you probably need to add more libraries. We don't need to specify any library search path for opengl32 since they are in a system folder.  For freeglut, however, we need to specify library search path for it if it is not in a system folder.  Note that Eclipse CDT will not search for any library in its project folder.  We need to explicitly specify it for any non-system library search path.

By the way, it is interesting to note that, even if we are working on Windows 64-bit version, we still use opengl32, NOT opengl64.  This may sound odd, but it makes things easier since programs from a 32-bit world can be run seamlessly on Windows 64-bit version without any recompilation.  And for programmers, they don't need to change OpenGL configuration much; Windows will handle it by connecting to an appropriate video driver.

Figure 5: Adding more libraries to MinGW C++ Linker

5. Create the main file with a very simple usage of OpenGL.  Once again, I suggest you use the same example as in 'Temp Variable's Blog'.  The file seems to be in a book by E. Angel, Interactive Computer Graphics, A Top-Down Approach with OpenGL, Third Edition, Addison-Wesley Longman, 2003 [3].  The direct link to the file is http://www.box.net/shared/u2o7k31ogc

6. Build a project (press Ctrl + B or click the hammer button).

7. Try running your application.  You may find that there is nothing happens.  Your program just terminated.  When you try to debug it, you will see only an error message that "there is an error occurred", but no other clue.  This problem arises from a missing DLL.  It is important to know that the executable file we get will not try to search for libraries specified in the Eclipse settings.  Thus, we need to put the DLL in the executable folder  (or in a system one if you prefer).  Make sure that you have DLL copies in both Debug and Release folders.  Anyway, if you encounter 'silent errors' like this in Eclipse CDT, I recommend you run an executable file from the Windows command prompt; Windows may give you more information than Eclipse CDT.

Note: if you are new to Eclipse CDT, you may wonder how to run a program in a Debug or Release mode as you wish.  From the beginning, it will run solely in a Debug mode, even when you set the active configuration to Release.  To change the default running mode, you have to do it in the 'Run Dialog'.  It can be found from the menu bar on the top of Eclipse as shown in Figure 6.  When you go there, you may find two configurations you can choose, but still have no idea which one is Release (I had this problem before).  You can differentiate it by its location.  From the main tab, you can see a project name and 'C/C++ Application'.  The latter will tell you about an application location as shown in Figure 7.  Notice the release folder name before an executable file name.


Figure 6: 'Run Dialog' can be accessed from the menu bar.  Note: click on the arrow beside the green Run button, not the Run button itself.
Figure 7: Main tap in the 'Run Dialog' can show us the location of an executable.  We can use the location to figure out what mode it is in

References:

1. Eclipse CDT: Before You Begin, http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.cdt.doc.user/concepts/cdt_c_before_you_begin.htm
2. Temp Variable's Blog: Installing freeglut on Visual Studio 2008, http://tempvariable.blogspot.com/2008/02/installing-freeglut-on-visual-studio.html
3. E. Angel, Interactive Computer Graphics, A Top-Down Approach with OpenGL, Third Edition, Addison-Wesley Longman, 2003. (a portion of source code in the book is obtained from http://www.box.net/shared/u2o7k31ogc)


Pinyo Taeprasartsit
(May 2008, May 2010, Oct 2011)

This document can be viewed at my blog and my Google docs.  Questions, comments, and suggestions are welcomed.  Please leave a message in my blog if you have any.  Thank you.

=======

Update: [May 2010] I now have a few other documents that closely related to this one.  They discuss how to compile FreeGlut for both 32 and 64-bit applications and using more recent versions of MinGW, including the 64-bit version.  Check them out if you are interested:
  1. Eclipse CDT with MinGW x64.  If you want to use MinGW 64-bit with Eclipse, this is a document for you.
  2. Build FreeGlut 2.6.0 with MinGW in both 32 and 64 bit.  Pre-compiled binary packages are also available.  This package is newer than the one discussed in this document and come with both static and dynamic library.  Very handy if you need one.  
  3. Eclipse CDT + MinGW + FreeGlut (2).  This adds information about 64-bit version of MinGW and FreeGlut.  It shows you how to use both static and dynamic library versions of FreeGlut.  Also, if you need to easily download MinGW 4.5.0 32-bit without bothering with wget and bash as mentioned in MinGW web site.  The package provided in this document will help you with that.  This should be helpful until MinGW comes with a more polished installer.

This document can be viewed at my blog and my Google docs.  Questions, comments, and suggestions are welcomed.  Please leave a message in my blog if you have any.  Thank you.

Sunday, May 18, 2008

Enable mouse scrolling in Ubuntu 8.04 on VMWare 6.0.3

(May 18, 2008)

Last night, I installed Ubuntu 8.04 on VMWare 6.0.3 and mouse scroll did not work, even after VMWare tools were installed. My friend, P' Moo+, told me to update Ubuntu, install VMWare and do some X config. I am, however, too lazy to revert my VM to previous snapshot, so I searched Internet for a solution.

I found a topic "How To Enable Mouse Wheel Scrolling in Ubuntu 8.04 on VMware" on http://www.windowsvistaplace.com/how-to-enable-mouse-wheel-scrolling-in-ubuntu-804-on-vmware/othersoftware
This solution does help (my host machine is Windows XP, the author's is Mac OS X). In short, I have to replace

Section "InputDevice"
Identifier "Configured Mouse"
Driver "vmmouse"
[.. blah blah blah ..]
EndSection

with

Section "InputDevice"
Identifier "Configured Mouse"
Driver "vmmouse"
Option "CorePointer"
Option "Device" "/dev/input/mice"
Option "Protocol" "ImPS/2"
Option "Buttons" "5"
Option "ZAxisMapping" "4 5"
EndSection

Many thanks to 'computerboom' (the author of the article I found).

Friday, April 04, 2008

OOXML as an ISO standard. What a joke.

(April 4, 2008)

Recently, OOXML was approved as an ISO standard. At first, I thought it's okay, even though it might increase cost for software development to support two standards at the same time. However, once I found this article: http://www.robweir.com/blog/2008/03/disharmony-of-ooxml.html, I think it is really embarrassing to have OOXML as an ISO standard for document. This implies that even Microsoft itself cannot enforce reasonable standards among its own products and it did impose difficulty in software development to itself and the outside world.

I really wonder what the committee was thinking during ballot casting.

Saturday, March 22, 2008

Math Object Wrap Space in OpenOffice.org's Writer

(Mar 22, 2008)

By default, math object wrap space in OO.o's Writer is pretty annoying. If a math object is at the end of a sentence and follows by a foot stop, the foot stop will be put too far from the math object. Earlier, I needed to put it inside the problematic math object. Although the printing output was fine, it changed semantics of the math object.

OO.o, however, has a solution for this. In case we want to change a specific wrap space for a specific math object, we can right click on the math object, go to 'Option', then 'Wrap', and set 'Spacing' to zero as shown in figures below.





In case we want to set zero space as a default setting, we can use 'Styles and Formatting'. Formula setting can be accessed from 'Frame Styles' as shown below.



Reference:
http://documentation.openoffice.org/faqs/formula/016.html

Wednesday, March 19, 2008

Importance of WINVER definition in Visual Studio 2008

(Mar 19, 2008)

Recently, MIPL starts to port stuff to VS 2008. It turns out that code compiled on Vista worked 100% correct only on Vista, but on Windows XP, it showed some glitches.

This is because the default WINVER in VS 2008 is 0x0600 (Vista). Thus, when we build our code, it will perform some Vista specific links, and an executable file may not work correctly on XP.

To solve this problem, just go to StdAfx.h and put the definition of WINVER to XP:

#define WINVER 0x0501

With this definition, built executable files should work on both XP and Vista.

Tuesday, March 18, 2008

เรื่องงงๆ ใน OpenOffice

(Mar 18, 2008)

พยายามใช้ Style and Formatting ใน OpenOffice แล้วปรากฎว่าเวลาเปลี่ยนไสตล์แล้วรูปแบบตัวอักษรมันไม่ได้เปลี่ยนไปด้วยเลย ทั้งที่แต่ก่อนมันก็เปลี่ยนให้เราเอง พยายามยังไงมันก็ยังไม่ยอมเปลี่ยนให้แบบอัตโนมัติเหมือนเคย

แต่ยังไงเราก็พบว่าถ้าเราไฮไลต์มันแล้วคลิกขวา จากนั้นก็เลือก Default formatting มันก็จะจัดรูปแบบให้เราตามที่เรากำหนดไว้ ถ้าไม่อยากใช้เมาส์ จะกด Ctrl+Shft+Space ก็ได้

Alias can be a tricky problem in C++'s STL vector

(Mar 14, 2008)

Alias can be a tricky problem in C++'s STL vector.

Sometimes, I don't want to write an awkward code such as willFail.m_vecProblematic[0] all the time, so I create an alias (prob1 in this example). This alias will work fine until we push or pop elements in a vector to a certain number and the vector is needed to reallocate.

Problematic* prob1 = &( willFail.m_vecProblematic[0] );
prob1->m_vec2.push_back( 55 );
prob1->m_vec1.push_back( 11111 );

// Push an element to a vector may cause a vector to reallocate.
willFail.m_vecProblematic.push_back( Problematic );

// prob1 may not point to a correct storage, but this value assignment

// may not cause a program to crash instantly.
prob1->i = 24;

// prob1 may not point to a correct storage, and such object

// operation usually cause a program to crash
prob1->m_vec2.push_back( 66 );

Note: simple value assignment to an invalid place may not cause a program to crash so easily, but calling a method from an invalid object pointer will cause a program to crash very easily since the method table of an object is already messed up. If we want to find where a program goes wrong, we may try to call a method of a suspecious object pointer.