22 September 2012

Getting started with CMake

 Working on so many projects, you might have noticed that compilation process of a project involves searching for required libraries and their paths on the system, building a bunch of source files and some of these source files depend on each other. Finally all the source files and libraries located in different folders are compiled to generate a binary file or a library file. A description of the build process is stored in a group of files.

CMake is a cross-platform build systems generator which makes it easier to build software in a unified manner on a broad set of platforms. http://www.scons.org/wiki/SconsVsOtherBuildTools provides a comparison of several software building tools available presently. Cmake is a generator: it generates native build system files like Makefile, Visual Studio or other IDE projects, etc. CMake scripting language is used to describe the build. The developer has to edit the CMakeLists.txt and invoke CMake but should not change any of the generated files directly.

CMake workflow -
1. CMake time: CMake is running and processing CMakeLists.txt
2. Build time: The build tool runs and invokes the compiler.
3. Install time: The compiled binaries are installed i.e. from the build area to an install location.
4. CPack time: CPack is running for building package.
5. Package install time: The time taken to install the package developed in previous step.

Installing CMake
For several platforms such as Windows, Linux, Mac, etc, CMake is available as a standard package or binaries which can be downloaded from its official website. You can type cmake --help in the terminal to check the version of cmake and usage information.Generally CMake path is added to the system path automatically by the installer. If its not added, then you can run it directly from the installed location.

Simple CMake
cmake_minimum_required (VERSION 2.8)
# This project uses C source code.
PROJECT (A Simple C Project)
ADD_LIBRARY (mylibrary STATIC libsource.c)
# Build executable using specified list of source files.
ADD_EXECUTABLE (simple main.c)
TARGET_LINK_LIBRARIES (simple mylibrary z m)
 
This generates makefile to compile main.c file and link it to mylibrary. To build this project in linux, just go the terminal, go the folder where this cmake is present and type
cmake .
make

CMake Commands
CMake is in essence a simple interpreter. CMake input files have an extremely simple but powerful syntax. It consists of commands, primitive flow control constructs, macros and variables. All commands have exactly the same syntax:
COMMAND_NAME (ARGUMENT1, ARGUMENT2)

You can check the cmake help on any of its command by typing
cmake --help-command add_executable
 Output: Add an executable to the project using the specified source files.

cmake --help-command project
Syntax: PROJECT(<projectName> [languageName1, languageName2])
Set a name for entire project. Additionally this sets the variables <projectName>_BINARY_DIR and <projectName>_SOURCE_DIR to the respective values. Optionally you can specify which languages your project supports. Eg - CXX for C++, C, Fortran, etc. By default C and CXX are enabled.

cmake --help-command add_library
Syntax:  ADD_LIBRARY(<name> [STATIC | SHARED | MODULE] [EXCLUDE FROM ALL] source1 source2 ... sourceN)
Adds a library target called <name> to be build from the source files listed in the command invocation. STATIC, SHARED or MODULE may be given to specify the type of library to be created. By default the library file will be created in the build tree directory corresponding to the source tree directory in which the command was invoked.

Flow Control Constructs
A few flow control constructs, such as IF and FOREACH are used. The IF construct uses one of several types of expressions, such as boolean(NOT, AND, OR), check if command exists(COMMAND) and check if file exists(EXISTS). Expressions however cannot contain other commands. An example of commonly used IF statement would be:
IF(UNIX)
    IF(APPLE)
         SET(GUI "Cocoa"
     ELSE(APPLE)
         SET(GUI "X11"
     ENDIF(APPLE)
ELSE(UNIX)
     IF(WIN32)
          SET(GUI "Win32"
     ELSE(WIN32)
          SET(GUI "Unknown"
     ENDIF(WIN32)
ENDIF(UNIX)
MESSAGE("GUI system is ${GUI}")

This example shows simple us of IF statement and variables. FOREACH is used int the same fashion. For example if a list of executables are to be created, where every executable is created from a source file with the same name, following FOREACH would be used:

SET(SOURCES source1 source2 source3)
FOREACH(source ${SOURCES})
       ADD_EXECUTABLE(${source} ${source}.c)
ENDFOREACH(source)

Macros use a syntax of both commands and flow control constructs. MACRO construct is used to define a macro. For example, lets create a macro which creates executable from the source by linking it to libraries.

MACRO(CREATE_EXECUTABLE NAME SOURCES LIBRARIES)
      ADD_EXCUTABLE(${NAME} ${SOURCES})
      TARGET_LINK_LIBRARIES(${NAME} ${LIBRARIES})
ENDMACRO(CREATE_EXECUTABLE)
ADD_LIBRARY(mylibrary libSource.c)
CREATE_EXECUTABLE(myprogram main.c mylibrary)

Macros are not equivalent to procedures or functions from the programming languages and do not allow recursion.

Conditional Compiling
The build process also should be able to find and set locations to the system resources your project needs. All these functions are achieved in CMake using conditional compiling. E.g. -  If the project has to compile in two different modes namely DEBUG and REGULAR, you can define sections to compile in different mode based on the enabled variable.
#ifdef DEBUG
      fprintf(stderr, "The value of i is: %d\n", i);
#endif

In order to tell CMake to add -DDEBUG to compile lines, you can use the SET_SOURCE_FILE_PROPERTIES with the COMPILE_FLAGS property. But you probably do not want to edit the CMakeLists.txt every time you switch between the debug and regular build. The OPTION command creates a boolean variable that can be set before building the project. The syntax for above example will be:

OPTION(MYPROJECT_DEBUG    "Build the project using debugging code" ON)
IF(MYPROJECT_DEBUG)
    SET_SOURCE_FILE_PROPERTIES( libsource.c main.c COMPILE_FLAGS -DDEBUG)
#ENDIF(MYPROJECT_DEBUG)

The flags can be set/unset using any cmake gui component installed on the system like CMake-Gui. After using cmake command, go to that folder and initiate the gui in that folder. This will open a GUI where you can select or deselect components.

Another sample of user controlled build option
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
# This project uses C source code
PROJECT(TotallyFree C)
# Build option with default value to ON
OPTION(WITH_ACRODICT "include/acronym/dictionary/support" ON)
SET(BUILD_SHARED_LIBS true)
#build executable using specified list of source files
ADD_EXECUTABLE(Acrolibre acrolibre.c)
IF(WITH_ACRODICT)
       SET(LIBSRC acrodict.h acrodict.c)
       ADD_LIBRARY(acrodict ${LIBSRC})
       ADD_EXECUTABLE(Acrodictlibre acrolibre.c)
       TARGET_LINK_LIBRARIES(Acrodictlibre acrodict)
       SET_TARGET_PROPERTIES(Acrodictlibre PROPERTIES COMPILE_FLAGS "-DUSE_ACRODICT")
ENDIF(WITH_ACRODICT)

Another common type of variable is a PATH which specifies the location of some file on the system. If the program relies on the the file Python.h, this would be put in cmake file like this -
FIND_PATH(PYTHON_INCLUDE_PATH  Python.h    /usr/include   /usr/local/include)

FIND_PATH command is used to find a directory containing the named file. A cache entry named by <VAR> is created to store the result of this command. If the file in a directory is found, the result is stored in the variable and the search will not be repeated unless the variable is cleared. If nothing is found, the result will be <VAR>-NOTFOUND and the search will be attempted again the next time find_path is invoked with the same variable.

But the above command looks for that file in only those folder for the current project. So you'll have to add the same line for every project. To avoid this, you can include other CMake files, called modules. CMake comes with several useful modules, from the type that searches for different packages to the type that actually performs some tasks or define MACROS. For the list of all modules, check the Modules subdirectory of CMake. E.g. - FindPythonLibs.cmake which finds python libraries and header files on almost every system.

Handling Subdirectories
As a software developer, you probably organize source code in subdirectories. Different subdirectories can represent libraries, executables, testing or even documentation. We can enable or disable subdirectories to build parts of project and skip other parts. To tell CMake to process a subdirectory, use SUBDIRS comand. This command tells CMake to go to the specified subdirectory and find the CMakeLists.txt file.
The toplevel project looks something like this -
PROJECT(MyProject C)
SUBDIRS(SomeLibrary)
INCLUDE_DIRECTORIES(SomeLibrary)
ADD_EXECUTABLE(MyProgram main.c)
TARGET_LINK_LIBRARY(MyProgram MyLibrary)

INCLUDE_DIRECTORIES command tells the compiler where to find the header files for main.c

Lets see an example to cover all the steps covered till now. The CMake file has to be written for project called Zlib.

PROJECT(ZLIB)
#source files for zlib
SET(ZLIB_SRC adler32.c   gzio.c   inftrees.c   uncompr.c   compress.c   infblock.c   infutil.c   zutil.c   crc32.c   infcodes.c   deflate.c   inffast.c   inflate.c   trees.c )
ADD_LIBRARY(zlib ${ZLIB_SRCS})
ADD_EXECUTABLE(example example.c)
TARGET_LINK_LIBRARIES(example zlib)

ZLib needs unistd.h on some platforms. So a test has to be added to the project.

INCLUDE( ${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
CHECK_INCLUDE_FILE( "unistd.h" HAVE_UNISTD_H)
IF(HAVE_UNISTD_H)
    ADD_DEFINITION(-DHAVE_UNISTD_H)
ENDIF(HAVE_UNISTD_H)

Also, something has to be done abou the shared libraries on Windows. ZLIB needs to be compiled with -DZLIB_DLL, for proper export macros. So the following options have to be added.

OPTION(ZLIB_BUILD_SHARED)
  "Build ZLIB shared" ON)
IF(WIN32)
    IF(ZLIB_BUILD_SHARED)
         SET(ZLIB_DLL 1)
    ENDIF(ZLIB_BUILD_SHARED)
ENDIF(WIN32)
IF(ZLIB_DLL)
      ADD_DEFINITION(-DZLIB_DLL)
ENDIF(ZLIB_DLL)

This is a very simple example and will get you started with cmake for your basic projects. CMake is capable of doing several other tasks. It can now do platform independent TRY_RUN and TRY_COMPILE builds, wich come in handy when you want to test the capabilities of the system. CMake natively supports C and C++ and with a little effort, it can generate builds for most available languages. 
 
 











8 August 2012

Build MySQL Plugin for Qt(4.7.3) on Windows

The QtSql module uses driver plugins to communicate with the different database APIs. Since Qt's SQL Module API is database-independent, all database-specific code is contained within these drivers. Several drivers are supplied with Qt and other drivers can be added. The source for building QMYSQL plugin is provided on the qt repository and also along with the qt-everywhere-opensource archive. Here we'll see how to build the QMYSQL plugin using installed MySQL libraries.

Follow the given steps to build the plugin -
1. Download the following softwares/sources.
      a) QtSDK (if not installed) from http://qt.nokia.com/downloads.
      b) My SQL Community Server (e.g. - mysql-5.5.20-win32.msi) from http://dev.mysql.com/downloads/mysql/. Make sure it is 32 bit version as 64 bit is not supported yet.
      c) Qt-Everywhere-Opensource zip file so that you may have the complete plugin source. This is optional as you can download selected source later using QtSDK package manager.

2. Mostly, Qt Sources are not installed with the QtSDK, so you'll have to install the sources before proceeding. To install the sources -
     a) Open 'Maintain Qt SDK' program from start menu.
     b) Select the Qt Sources you want to install and follow the wizard.

Remember to mark the correct version of Qt Sources.

3. Install the downloaded MySQL. Install it in C:\MySql or any other location without any space in between.  Providing library path creates problem when there is space in between so better avoid it.

4. After installation is complete you are ready to build plugin. There are two ways in which you may proceed.
   a)   Run the following commands in command prompt. Change them according to you environment.
         i)   set mysql=c:\\mysql\\MySQL_Server_55
         ii)  cd C:\QtSDK\QtSources\4.7.4\src\plugins\sqldrivers\mysql\
         iii) qmake "INCLUDEPATH+=%sql%\\include" "LIBS+=%mysql%\\lib\\libmysql.lib" -o Makefile        mysql.pro
         iv) mingw32-make
         v)  qmake "INCLUDEPATH+=%sql%\\include" "LIBS+=%mysql%\\lib\libmysql.lib" -o Makefile mysql.pro "CONFIG+=release"
         vi) mingw32-make

   b) If the above method doesn't work, you can compile the plugin using the QtCreator. Go to the project location (i.e. C:\qt-everywhere-opensource-src-4.8.2\qt-everywhere-opensource-src-4.8.2\src\plugins\sqldrivers\mysql, if you have extracted it from qt-everywhere-opensource or C:\QtSDK\QtSources\4.7.4\src\plugins\sqldrivers\mysql\, if you have installed sources from Maintain Qt SDK) and open the mysql.pro file in QtCreator.
      i) You have to add mysql installed library to your project. To do this right click on the project and click on Add Library.
      ii) Add the library as shown in the images below - Initially select the External library option.

Then add the mysql library path -
Click on the next after specifying the path as above. Finally this library will be added to the pro file.

Now compile the project. This will generate the output as libqsqlmysqld4.a and libqsqlmysqld4.dll.

c) Copy above two files to C:\QtSDK\Desktop\Qt\4.7.4\mingw\plugins\sqldrivers from both debug as well as release build.

d) Copy libmysql.dll from MySql installed folder to C:\Windows folder.

Now you are ready to code using sql plugin.

Compile this qt code to check if the MySql plugin has been detected successfully.

#include <QtCore/QCoreApplication>
#include <QtSQL>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug()<<QSqlDatabase::drivers();
    return a.exec();
}

Note - Don't forget to add QT += sql to your project file.




5 July 2012

Setting up Nvidia Apex SDK on Visual Studio 2010

APEX is a multi-platform, scalable dynamics framework. Rather than providing a low-level API that requires a physics programmer, APEX creates an environment where artists can create complex, high-level, dynamic systems without any programming. APEX is completely artist focused by providing the artist with familiar and easy to use authoring tools.
APEX consists of two major components:
  • the authoring component, provides high-level authoring of dynamic systems through DCC plug-ins (3dsMax/Maya), standalone tools, or game engine plug-ins.
  • the runtime component, consists of a modular SDK which includes the framework that supports all APEX modules and provides a render interface to allow minimal integration into game engines.
Here I'll show you how to setup the SDK so that you can start using Apex SDK in Visual Studio in your c++ programs.

Download following files from you Apex account -
1. Nvidia PhysX sdk installer (mostly named as PhysX_2.8.4.6_for_PC_Core.msi). If  you are using Apex  1.1 SDK, then you need to install PhysX 2.8.4 and not later version.
2. Then you need Apex SDK (mostly named as APEXSDK-1.1-Build112-PhysX_2.8.4-WIN-VC9.zip).
3. Latest Microsoft DirectX SDK which can be downloaded from here.

Install DirectX SDK, Nvidia PhysX and then Apex SDK. Now you need to add Nvidia PhysX installed location to your system path. To do this, go to System Properties->Advanced System Settings->Environment Variable. Click on New in the top list. Add the variable name NXPATH and variable value as <Location> of your physx sdk(For my case it was "C:\Program Files (x86)\NVIDIA Corporation\NVIDIA PhysX SDK\v2.8.4_win").


Now you are ready to open the visual studio sample projects given with ApexSDK.
  1. Go to your apex installed location/samples/compiler\vc9WIN32-PhysX_2.8.4 or /samples/compiler\vc9WIN64-PhysX_2.8.4 folder. Open the Apex_Samples project. This project consists of 8 sub projects. 
  2. Right click on the properties of SampleRenderer-MT. Go to C/C++->General->Additional Include Directories. Replace the directX include path with the one on your system. (For me it was C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include).
  3. Similarly replace the directx include path in the properties of project "SamplePlatform-MT".
Now compile your projects and you are ready to go. Mostly the project names in the properties are different from the one which are built e.g. ApexHelloWorld sample builds with the name ApexHelloWorldDebug.exe So you'll have to change this name in properties so that you may debug them directly from your visual studio editor. The build location is in ApexSDK home location/bin.


1 July 2012

Creating animated splash screen in Qt

The QSplashScreen widget in Qt provides a splash screen that can be shown during application startup. A splash screen is a widget that is usually displayed when an application is being started. Splash screens are often used for applications that have long start up times to provide the user with feedback that the application is loading. The splash screen appears in the center of the screen. It may be useful to add the Qt::WindowStaysOnTopHint to the splash widget's window flags if you want to keep it above all the other windows on the desktop.

Many times you might feel to add animated splash screens for better look of the splash screen. This can be achieved in multiple ways. One way is to make your own splash screen class by inheriting from QSplashScreen and painting the screen as you wish. I would show a relatively simple approach just by changing the series of images with changing time.

To get a series of images, use a video making tool like After Effect or Sony Vegas. Design your complete splash screen as a video using these tools. When you are ready, publish this video and in publish settings, change the output to png or jpg mode. This will render your video as series of image files. Now you just need to copy these images in your project folder so that they can be easily available while loading splash.

For my case, I copied all my images in icons/splash/ folder. The image names follow the following pattern
SplashScreen_#####. Where ##### is the sequence of image.


QString name = "./icons/splash/SplashScreen_000";
QStringList fileNames;
for(int i=0; i<100; i++)
{
    if(i<10)
       fileNames << (name+QString("0%1").arg(i));
    else
       fileNames << (name+QString("%1").arg(i));
}


Here I read all the image file names into a list. Make sure you don't add the splash images to your resources file as they will be packaged into your build and would consume a lot of useless space. Moreover, if the count of your splash images is too much, then if would fail to compile. So its better to read it from the folder itself.


QSplashScreen *splashScreen = new QSplashScreen(QPixmap(":/icons/splashscreen.png"));
splashScreen->show();
QTime finishingTime = QTime::currentTime().addSecs(5);
int count = 0;
while(QTime::currentTime()<=finishingTime)
{
    if(count>299)
      splashScreen->setPixmap(QPixmap(":/icons/splashscreen.png"));
    else
      splashScreen->setPixmap(QPixmap(fileNames[count/3]));
    count++;
}
splashScreen->hide();



I have taken a timer of 5 seconds to show how the splash images would change to give a feel of animation. Moreover you can ignore the count/3 part in the code. I rendered my splash images at 20fps, so I had to adjust the timing with number of images. You can adjust this based on your design. This method seems simple but I believe its better and simple to overload the QSplashScreen class and design everthing in modular form.

25 June 2012

Common Qt related queries

While using Qt, programmers tend to forget lot of small things, which they need to search again and again while coding. So I compiled some of these issues which I came across in this document.

->Creating modal dialogs in Qt
       CustomMessageBox customMessageBox(..., parent, Qt::Dialog);
       customMessageBox.setWindowModality(Qt::ApplicationModal);
       customMessageBox.exec();

-> Regular expression to check whether MAC address exists in a string
   <string>.contains(QRegExp("(([0-9A-Fa-f]{2}[-:]){5}[0-9A-Fa-f]{2})|(([0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})"))

-> Saving QPixmap as file. -

    QPixmap myImage(":/test.jpg");
     myImage.save("newTest.jpg");

Or
   QByteArray bytes;
   QBuffer buffer(&bytes);
   buffer.open(QIODevice::WriteOnly);
   pixmap.save(&buffer, "PNG");


-> Creating simple thread in Qt -
   Create a class inheriting QThread with a function void run().  The content of this function runs on a thread.
   class HelloThread: public QThread
    {
      Q_OBJECT
      private:
            void run();
    }

     void HelloThread::run()
    {
              qDebug()<<"Hello from worker thread" <<thread()->currentThreadId();
    }

    int main(int argc, char *argv[])
   {
         QCoreApplication app(argc, argv);
         HelloThread thread;
         thread.start();
         qDebug()<<"hello from GUI thread"<<app.thread()->currentThreadId();
         thread.wait();
         return 0;
    }

-> Difference between two QDateTime values
       use    QDateTime::daysTo() or secsTo().

-> Disabling a window
       mainWindow->setEnabled(false);
    If there are multiple windows, its better to disable them in pieces.

->  Redirection operator(<<, >>) overloading in a class
      Add a operator overloading friend function to the class as -
     friend std::ostream& operator<<(std::ostream &out, const MyClass &rhs);

     After defining this function, as -
     std::ostream& operator<<(std::ostream &out, const MyClass &rhs)
     {
           out<<rhs.name;
     }

   The class's objects can be used with << operator.

-> Deploying Qt application on windows
    Compile your project in release mode.
    Add resources and settings to your application as shown here.
    Then use dependency walker to check for the dll dependencies of your application. Copy these dlls into the folder of the executable.
    Finally use setup creating softwares like Inno Setup Compiler to package everything in a single executable.

->  View QTreeWidget as read only 
  treeWidget->editTriggers(QAbstractItemView::NoEditTriggers);

-> Change column width of QTreeWidget
   header()->resizeSection(int logicalIndex, int size);

-> Getting QGraphicsTextItem length 
   int length = my_graphics_text_item.toPlainText().size()


-> Find index of a value in QComboBox 
  int QComboBox::findText(const QString &text, Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly | Qt::MatchCaseSensitive) is the function used to get index of the string value in QComboBox.

-> Implementing an Alarm functionality in Qt
// alarm.h
#include <QThread>
#include <QDateTime>
#include <QTime>
#include <QMutex>
#include <QDebug>

class Alarm : public QThread
{
    Q_OBJECT
public:
    Alarm(QTime time, QObject *parent = 0);
    void setEndTime(QTime time);
public slots:
    void stopAlarm();
signals:
    void alarmRing();
protected:
    void run();
private:
    QTime endTime;
    bool stopAlarmFlag;
    QMutex mutex;
};




 // alarm.cpp

#include "alarm.h"

Alarm::Alarm(QTime time, QObject *parent) : QThread(parent)
{
    endTime = time;
    stopAlarmFlag = false;
}

void Alarm::setEndTime(QTime time)
{
    mutex.lock();
    endTime = time;
    mutex.unlock();
}

void Alarm::run()
{
    while(1)
    {
        qDebug()<<"Run";
        if(QTime::currentTime()>=endTime)
        {
            emit alarmRing();
            return;
        }
        sleep(1);
    }

}

void Alarm::stopAlarm()
{
    this->exit();
}




-> Implementing a drag drop functionality between Qt widgets
   When the drag starts in a Qt widget, a new drag is created where mime data is fed into the event. The drop event in another widget reads these mime data. The code below show how to create a drag event with some mime data - 

In the views mouse event create a new drag object to contain the data you want moved,
QDrag* drag = new QDrag( this );
QByteArray ba;
QDataStream* data = new QDataStream(&ba, QIODevice::WriteOnly);
*data << m_slideIndex;
QMimeData* myMimeData = new QMimeData;
    myMimeData->setData("application/x-thumbnaildatastream", ba);
drag->setMimeData( myMimeData );
drag->setPixmap( thumb );
drag->setHotSpot( thumb.rect().center() );
if ( drag->exec() == Qt::IgnoreAction )
{
    qDebug() << "DRAG CANCELLED";
    m_dragging = false;
}
drag->deleteLater();
delete data;


-> Implementing a drag drop functionality between Qt widgets

  A simple display message
   QMessageBox msgBox;
   msgBox.setText("The document has been modified.");
   msgBox.exec();

  A document modified message - 
  QMessageBox msgBox;
  msgBox.setText("The document has been modified.");
  msgBox.setInformativeText("Do you want to save your changes?");
  msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
  msgBox.setDefaultButton(QMessageBox::Save);
  int ret = msgBox.exec();
  switch (ret) 
  {
   case QMessageBox::Save:
       // Save was clicked
       break;
   case QMessageBox::Discard:
       // Don't Save was clicked
       break;
   case QMessageBox::Cancel:
       // Cancel was clicked
       break;
   default:
       // should never be reached
       break;
  }

  A Warning message box -
int ret = QMessageBox::warning(this, tr("My Application"),
                                tr("The document has been modified.\n"
                                   "Do you want to save your changes?"),
                                QMessageBox::Save | QMessageBox::Discard
                                | QMessageBox::Cancel,
                                QMessageBox::Save);

  An error message box -
  QErrorMessage errorMessage;
  errorMessage.showMessage("Same resource can't be imported twice");
  errorMessage.exec();
  return;

Adding Signals and Slots to QGraphicsItem

Signals and slots are used for communication between objects. The signals and slots mechanism is a central feature of Qt and probably the part that differs most from the features provided by other frameworks. A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in response to a particular signal. 


The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene. It provides a light-weight foundation for writing your own custom items. This includes defining the item's geometry, collision detection, its painting implementation and item interaction through its event handlers.


When we want to create a graphics item of our own, we can inherit from QGraphicsItem. QGraphicsItem is an abstract class. So two functions namely, 

virtual QRectF boundingRect() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

These two functions have to be defined in the class which inherits from QGraphicsItem. But QGraphicsItem is not inherited from QObject, so we can't add signals or slots to this. So we need to inherit our class from QObject as well to access the signal slot functionality. QGraphicsObject is a predefined class which does the same thing but it is relatively slow as it has lot of other signals which you might not require. So, I prefer going for my own class which derives from both QGraphicsItem and QObject. The class below is a sample class to do so. 
 
class MyGraphicsObject : public QGraphicsItem, public QObject
{
     Q_OBJECT
     Q_INTERFACES(QGraphicsItem)
public:
     MyGraphicsObject(QGraphicsItem *parent = 0);

private:
     virtual QRectF boundingRect() const;
     virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

}; 



After defining this class, you can add signals/slots of your choices.


21 March 2012

Installing FLANN on Ubuntu 11.10

FLANN is a library for performing fast approximate nearest neighbor searches in high dimensional spaces. It contains a collection of algorithms we found to work best for nearest neighbor search and a system for automatically choosing the best algorithm and optimum parameters depending on the dataset. FLANN is written in C++ and contains bindings for the following languages: C, MATLAB and Python. 

I noticed two ways of installing FLANN on ubuntu namely the easy way and the hard way. Lets start with the hard way.

1. Install the basic dependencies
  • cmake
  • libhdf5-serial-dev
  • python-numpy (for python bindings)
  • python-h5py
2. Now download the latest version of flann from http://www.cs.ubc.ca/~mariusm/index.php/FLANN/FLANN. 
3. Extract it in a folder and run 'cmake' command in that folder.
    If all the dependencies and PATH are defined in your system, it will install neatly.
4. If it shows errors, open the Makefile and  check if you have defined all the paths. 'cmake' command will give you errors on which you may need to install other dependencies. Keep repeating until you make through. :-P

Easy way is to install FLANN from the PCL repository.
1. Open the terminal and type -
    sudo add-apt-repository ppa:v-launchpad-jochen-sprickerhof-de/pcl
2. Now update your repository by typing -
    sudo apt-get update
3. Now go to your synaptic package manager, and search for flann. Check it and install it.


8 February 2012

Setting up DirectX SDK in Visual Studio 2010

Microsoft DirectX is a collection of application programming interfaces (APIs) for handling tasks related to multimedia, especially game programming and video, on Microsoft platforms. The DirectX software development kit (SDK) consists of runtime libraries in redistributable binary form, along with accompanying documentation and headers for use in coding. Originally, the runtimes were only installed by games or explicitly by the user. Direct3D 9Ex, Direct3D 10, and Direct3D 11 are only available for Windows Vista and Windows 7 because each of these new versions was built to depend upon the new Windows Display Driver Model that was introduced for Windows Vista. The new Vista/WDDM graphics architecture includes a new video memory manager supporting virtualization of graphics hardware for various applications and services like the Desktop Window Manager.

Download and install the latest DirectX SDK binary from microsoft's website - http://msdn.microsoft.com/en-us/directx/aa937788.

After installation of SDK, you can run DxDiag.exe to check your current DirectX settings or for any existing problems.

Setting up the include and library directories on Visual Studio -
1. You can add the include settings and library settings of the directx sdk present in your program files folder individually for every project. This is advisable if you are working on a serious project. But if you are lazy to do so, you can add it to the global settings so that it is incorporated in all your projects.
2. Open the "Property Manager" from the View menu.

3. Expand the project/configuration tree and select the "Microsoft.Cpp.X.user" user file. Right click and select "Properties".

4. Add the DirectX SDK include directory to the "VC++ Directories">"Include Directories" -
   $(DXSDK_DIR)Include
   Add the DirectX SDK library directory to the "VC++ Directories">Library Directories" -
   $(DXSDK_DIR)Lib\x86

5. Now, open your DirectX project and add the DirectX linker settings to it.
   Expand the "Linker" section and select "Input" and under "Additional Dependencies" add the necessary lib files -
  d3d11.lib
  d3dx11.lib
  dxerr.lib

Now you are ready to start coding with DirectX.

You can download sample files from here and include them in an empty project to see how a DirectX code looks like. This is a simple code which just displays a blank DirectX screen.


14 January 2012

Unity3d - Removing Render Texture alpha

 If you want to apply the Render Texture to a GUITexture object so it will be sized to the screen with other GUITexture objects. But GUITextures don't have indpendent materials or shaders so you won't be able to remove the alpha which is added to the render texture. Just setting the color of the GUITexture and the Render Texture camera to white and 100% still leaves the Render Texture transparent. So you can remove the alpha values from that render texture using the following script.




var alpha = 1.0;
private var mat : Material;

function Start ()
{
    mat = new Material(
        "Shader \"Hidden/Clear Alpha\" {" +
        "Properties { _Alpha(\"Alpha\", Float)=1.0 } " +
        "SubShader {" +
        "    Pass {" +
        "        ZTest Always Cull Off ZWrite Off" +
        "        ColorMask A" +
        "        SetTexture [_Dummy] {" +
        "            constantColor(0,0,0,[_Alpha]) combine constant }" +
        "    }" +
        "}" +
        "}"
    );
}

function OnPostRender()
{
    GL.PushMatrix();
    GL.LoadOrtho();
    mat.SetFloat( "_Alpha", alpha );
    mat.SetPass(0);
    GL.Begin( GL.QUADS );
    GL.Vertex3( 0, 0, 0.1 );
    GL.Vertex3( 1, 0, 0.1 );
    GL.Vertex3( 1, 1, 0.1 );
    GL.Vertex3( 0, 1, 0.1 );
    GL.End();
    GL.PopMatrix();

Apply this script to camera of whose render texture is to be taken.

Installing Kinect on Windows(OpenNI) with Unity Wrapper

Real application of Kinect starts when you integrate it with any gaming engine. For a head start, OpenNI provides a wrapper in C# to be used in Unity3D gaming engine. They have also given a sample code for Ogre. You can start working on them after few simple steps of installation.

The fastest way to get started with this is to install the Zigfu bundle and Wrapper for OpenNI in Unity.
1. Download and install the latest zigfu development bundle from http://www.zigfu.com/devtools.html. This bundle install OpenNI, NITE and sensor drivers for kinect.
2. Now download the Zigfu Unity3D wrapper and extract it in your project. It contains sample scenes for help.
Now you can start developing your own motion sensing applications and games.

If you want to go with the latest OpenNI drivers and wrappers, you'll have to install them individually.
1. Download OpenNI module from http://75.98.78.94/Downloads/OpenNIModules.aspx. Select "OpenNI Binaries" in the first drop down box, then select the stable/unstable release and then download the specific module according to your system. If you want to work with PCL also, download this module from http://pointclouds.org/downloads/windows.html in the OpenNI column.
2. Now select the "OpenNI Compliant Middleware Binaries"  and download the middleware binary for your system.
3. Select the "OpenNI Compliant Hardware Binaries" and download stable/unstable release according to your system. If you want to work with PCL, you'll have to download it separately from http://pointclouds.org/downloads/windows.html under the sensor column.
4. Install all these downloaded binaries in the order in which they were downloaded.
5. Now you'll have to download the Unity3d wrapper from https://github.com/OpenNI/UnityWrapper according to your version of binaries.
6. Extract this and include in your project to get started with using kinect for application development.
7. Or you can download the Sinbad sample in Ogre from https://github.com/OpenNI/SampleAppSinbad to get started in Ogre gaming engine.

12 January 2012

Unity3d - Displaying output of one camera as background of other camera

Unity is an integrated authoring tool for creating 3D video games or other interactive content such as architectural visualizations or real-time 3D animations. Unity's development environment runs on Microsoft Windows and Mac OS X, and the games it produces can be run on Windows, Mac, Xbox 360, PlayStation 3, Wii, iPad, iPhone, as well as the Android platform. It can also produce browser games that use the Unity web player plugin, supported on mac and Windows but not Linux. The web player is also used for deployment as Mac widgets.

I was working with a problem where I needed to display the output of one camera as the background image of the other camera. The concepts used in this method are applicable at lot of places during the game development like showing the mirror effect in car races or the score board. 

I would suggest to go through the following links before using this method. The following links will give a rough idea about the Camera, GUI Texture, Render Texture and Layers in Unity.

Setup your scene with the Main Camera showing your game objects. After this follow these steps to create the background using a different Camera  -

1. Create a new camera (GameObject->Create Other-> Camera), and name it "Background Camera".

2. Create a new GUI Texture (GameObject->Create Other->GUI Texture), and name it "Background Image".

3. Click the "Layer" dropdown menu in the Background Image's inspector pane, and select "Add Layer".

4. In the next free "User Layer" slot, create a new layer name called "Background Image". This will be directly under the layer named "Terrain" if you haven't yet added any others.

5. Select your Background Image in the hierarchy, and give it the desired texture, and set the x, y, width and height under "Pixel Inset" so that it fills the screen appropriately.

6. Near the top of the inspector window, Use the layer dropdown menu to assign your "Background Image" layer that you defined earlier to this game object.

7. Now select your Background Camera in the hierarchy, and adjust these settings in the inspector:
   * Un-check Flare Layer and Audio Listener (but leave GUILayer enabled)
   * Set Clear Flags to Solid Color
   * Set Depth to -1
   * Set Culling Mask, first to "Nothing", and then to "Background Image"

8. Now Select your other (Main) camera and in the inspector:
   * Set its Clear Flags to "Depth Only"
   * Click its culling mask setting, and un-check "Background Image". This should result in the culling mask displaying as "Mixed..."

9. Now your system should display the Background GUI Texture as the background of the main camera. Since, this GUI Texture is the background for the present camera, you can change it dynamically from the script to display any other video texture or Render Texture from other camera. Render Texture is  used to render the camera view to a texture which can be displayed somewhere else.

10. Create a new Render Texture by Assets->Create->Render Texture. Give a proper name to this render texture and edit the properties according to your needs.

11. Now setup the scene and a camera whose output you want to display as the background in the Main Camera.

12. Go to the 'Target Texture'  option of this new camera and assign the render texture you created to it.

13. Now make a script which assigns this render texture as GUI Texture to the Background Image you created earlier. 

10 December 2011

Weblinks for downloading 3D models for Games

While making a game or working with any game engine, you'll need 3D models for your project. I have listed some of the websites which I came across while searching for 3D models across the web. If you find anything new or interesting to be shared, please list them in your comments. Though some of them are not free, I found them pretty useful.
1. http://e2-productions.com/repository/modules/PDdownloads/
2. http://www.katorlegaz.com/3d_models/index.php
3. http://www.sharecg.com/b/6/Textures?PSID=c72202065a0071c54d10bc27e4798f32
4. http://opengameart.org/
5. http://www.dexsoft-games.com/
6. http://www.frogames.net/
7. http://archive3d.net/
8. http://www.turbosquid.com/
9. http://www.3dlinks.com/
10. http://www.mega-tex.nl/
11. http://3d-resources.com/

26 November 2011

OpenCL in Windows


OpenCL support is provided by the Graphics Driver you are using. Most Nvidia drivers these days come with OpenCL support and they even provide their SDKs for OpenCL. For Nvidia, you'll have to follow the following to get the OpenCL working  -

1. Go to Nvidia OpenCL site(http://developer.nvidia.com/opencl) and check for their latest drivers with OpenCL support and also other tools you want to install.

2. Download the latest GPU Computing SDK from the Nvidia site and install them.

3. This is the link for code samples related to OpenCL - http://developer.download.nvidia.com/compute/opencl/sdk/website/samples.html. Though these samples also come along with GPU Computing SDK. You may see an icon on your desktop named NVIDIA GPU Computing SDK Browser. You can open this browser and go to OpenCL tab to see the examples working. The source and project files for these examples are presesnt in C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.0\ folder. The required library files and header may be found along with the samples or in the C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.0\shared\ folder.


If you're not sure if you Graphics card supports OpenCL or whether it is enabled, you can download a software called GPU Caps Viewer from here. This shows you all the features and information of your graphics card with a feature to enable or disable the OpenCL as well as CUDA support. It also contains some binaries so that you may test them. It looks something like this -




If your graphics card doesn't support OpenCL, then you have the option of installing Intel's OpenCL SDKs which uses CPU for the task. The installation steps for Inter OpenCL SDK are -
1. Install the pre-requisites for the SDK ie.
   i) Microsoft Windows Installer 3.1 or more
  ii) Microsoft Visual C++ 2008 run-time libraries or more
 iii) Java SE Runtime Environment 6 Update 27 or more
 The installer prompts you if anything is missing. You must have the administrative priviledge while installing the SDK.

2. Download the appropriate setup for your machine from Intel's site.

3. Install the setup. Mostly the SDK is installed in C:\Program Files (x86)\Intel\OpenCL SDK\ on a 64 bit system. The sample which come along with the SDK are installed in this folder - C:\Users\Public\Documents\Intel\OpenCL SDK\1.5\samples\

Now you are ready to start programming using OpenCL. Some website links are given below which might be of help.
1. The OpenCL official page on the Khronos* website. All information about latest versions of OpenCL  - http://www.khronos.org/opencl/
2. Information on the Khronos* conformance test process - http://www.khronos.org/adopters/
3. Intel OpenCL SDK Product page - http://software.intel.com/en-us/articles/intel-opencl-sdk/
4. Intel OpenCL SDK Download page  - http://software.intel.com/en-us/articles/download-intel-opencl-sdk/
5. Intel OpenCL SDK support forum - http://software.intel.com/en-us/forums/intel-opencl-sdk/
6. NVIDIA OpenCL developer zone - http://developer.nvidia.com/opencl
7. NVIDIA OpenCL developer forum - http://forums.nvidia.com/index.php?showforum=134

13 October 2011

Installing PCL on Ubuntu 11.04


Add the PCL to the repository
sudo add-apt-repository ppa:v-launchpad-jochen-sprickerhof-de/pcl
Update repository
sudo apt-get update
Install repository
sudo apt-get install libpcl-all
It would be better you add ROS to your repository before installing PCL. This add some of the optional dependencies of PCL which are there in ROS. Moreover OpenNI is also installed automatically from ROS repo which relieves you from the burden ofconnecting kinect by installing all the dependencies on by one.
ROS Diamondback repository - 
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu natty main" > /etc/apt/sources.list.d/ros-latest.list' 

$ wget http://packages.ros.org/ros.key -O - | sudo apt-key add -

$ sudo apt-get update

10 October 2011

Installing OGRE on Ubuntu 11.04

Download following files before installation -
1. Ogre SDK
2. Object Oriented Input System(OIS) Source
3. Perl Compatible Regular Expression (PCRE)
4. Install nvdia-cg-toolkit from synaptic or download from here.
5. Type this command to install other dependencies -
$ sudo apt-get install build-essential autoconf libtool libdevil-dev libfreeimage-dev libfreetype6-dev libglew1.5-dev libxaw7-dev libxrandr-dev libxt-dev libxxf86vm-dev libzzip-dev

Step 1:  Building OIS
   Extract OIS to any folder and type following commands from terminal to build.
$ ./bootstrap
$ ./configure
$ make
$ sudo make install

Step 2: Building Nvidia CG toolkit if you have downloaded the source.
 Extract into a folder and type the following commands -
$ ./configure
$ make -j4
This 4 can be any number which specifies the number of threads you want to use for the make process.
$ sudo make install
$ sudo ldconfig

Step 3: Installing PCRE
Extract the files and type the following command from the terminal -
$ ./configure --enable-utf8
$ make -j4
$ sudo make install

Make link to the shared object in /usr/lib folder by typing following command.
$ sudo ln -s /lib/x86_64-linux-gnu/libpcre.so.3 /usr/lib/libpcre.so.0
Now we are ready to install Ogre.

Step 4: Installing OGRE SDK
Extract the ogre files and type the following commands from the terminal.
$ cmake-gui .
This will open the cmake gui tool. Click on the configure button. Now all the required libraries will be configured and shown. Tick the build samples and build doc check boxes. Also check if all the required libraries are present. Now click on generate button. After generating you may close this gui.
Type following commands in terminal after exiting the gui.
$ make -j4
$ sudo make install

Step 5: Installing CEGUI
Extract the files in some folder and type the following lines from the terminal.
$ ./configure
$ make -j4
$ sudo make install

Now open .bashrc file and the following line at the end of it.
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH



Reference links -
1. http://ubuntuforums.org/showthread.php?t=1148570
2. http://www.ogre3d.org/tikiwiki/Building+Ogre+With+CMake

6 October 2011

Important links required to make own linux distibution

1. https://help.ubuntu.com/community/LiveCDCustomization - Ubuntu Live CD Customization site
2. https://help.ubuntu.com/community/UbuntuBootupHowto - Ubuntu Boot Up Changing Site
3. http://ubuntuclub.com/files/04-Techniques.txt - Some customization techniques
4. http://ubuntuforums.org/showthread.php?t=1073838 - Remastersys steps to customize own distribution
5. http://www.ubuntugeek.com/creating-custom-ubuntu-live-cd-with-remastersys.html - Using Remastersys
6. https://help.ubuntu.com/community/Grub2 - Grub2 customization instructions
7. http://www.remastersys.com/info.html - Remastersys website for information
8. https://help.ubuntu.com/community/Kernel/Compile - Compiling kernel for greater customization
9. http://theindexer.wordpress.com/2011/04/03/to-do-list-after-installing-ubuntu-11-04-aka-natty-narwhal/ - Packages and repositories for newly installed systems
10. http://blog.sarathonline.com/2009/03/how-to-make-local-offline-repository-in.html - Making a local repository
11. http://members.iinet.net/~herman546/p20/GRUB2%20Splashimages.html - Changing grub splash screen
12. http://ubuntuguide.net/an-effective-way-changing-ubuntu-11-04-login-screen-appearance - Changing login window appearance
13. http://www.unixmen.com/linux-distributions/4/265-great-themes-for-ubuntu-904-jaunty-jackalope - Some theme installations for ubuntu
14. http://ubuntuguide.net/an-easy-way-to-addchange-grub2-background-image-in-ubuntu-11-04 - Changing grub background splash image.
15. http://www.youtube.com/watch?v=_6j05f9SccY - Improving boot time of ubuntu.
16. http://brej.org/blog/?p=158 - Creating plymouth splash screen

4 October 2011

Installing latest version of remastersys on Ubuntu 11.10

 Remastersys is a tool that can be used to do 2 things with an existing Debian,  Ubuntu or derivative installation.
  1. It can make a full system backup including personal data to a live cd or dvd that you can use anywhere and install.
  2. It can make a distributable copy you can share with friends.  This will not have any of your personal user data in it.

I haven't found any specific method to install remastersys properly. Everytime, some works and some don't. So I try different methods in this order and everytime atleast one of them works. Sounds funny but works for me.

Method 1
1. Go to this link  http://www.remastersys.com/ubuntu/remastersys.gpg.key and save this key on your disk.
2. In synaptic, go to Settings/Repositories; select "Authentication" tab and "Import Key File" just downloaded.
3. Still in synaptic, go to "Other Software" tab and click "Add", then enter the apt line and replace oneiric with either lucid, maverick, or natty to match your Ubuntu version:
    deb http://www.remastersys.com/ubuntu oneiric main
4. Leave the repositories tab and "Reload".
5. Search for "remastersys" and select for install.  Edit/Apply Marked Changes.

This might give error some times.

Method 2
1. Type the following key in the terminal to add the key of the repository to the synaptic.
    sudo wget -O - http://www.remastersys.com/ubuntu/remastersys.gpg.key | apt-key add -
2. Add the following line that corresponds to your version of Ubuntu to your /etc/apt/sources.list

#Remastersys Lucid
deb http://www.remastersys.com/ubuntu lucid main

#Remastersys Maverick

deb http://www.remastersys.com/ubuntu maverick main

#Remastersys Natty

deb http://www.remastersys.com/ubuntu natty main

#Remastersys Oneiric

deb http://www.remastersys.com/ubuntu oneiric main

3. Type the following line in the terminal
    sudo apt-get update
4. Now open the synaptic package manager and search for remastersys and install it.

If the above two methods give error. Remove the packages from your sources.list file.

Method 3
1. Go to this link http://www.remastersys.com/repository/ and download the appropriate version of remastersys. For ubuntu, it will be in karmic folder or similar other ubuntu version.
2. Double click on it so that it may open in software center directly. Now click on install.


Reference:
1. http://www.remastersys.com/

2 October 2011

Setting up Ogre Project in Visual Studio 2010

Prerequisites - 

  • Visual Studio 2010 must be installed.
  • Ogre SDK 1.7 or greater must be installed. Use this link for installation details.
Steps to setup project - 


1. Set Environment variable - 
   Run setx OGRE_HOME path_to_ogre_sdk in a command console (cmd.exe).
   Alternatively create a batch file to set the variable. 
   Filename: OgreHome.bat
   Contents: setx OGRE_HOME %CD%
                  pause
   Location: Ogre Extracted folder ( Eg:-C:\OgreSDK_vc10_v1-7-3)

2. Create a new Visual Studio Project
   Make sure the windows application is selected and empty project is checked.
  

I kept the name as OgreProject.

2. Now download the sample ogre files to be included in the project - TutorialsFramework.zip.
   After downloading this zip file, extract the file into the project folder.
   Add those files to the project by selecting Add->Existing Item...

3. Change the project configuration.
   
Switch to All Configurations:

Under General Properties, set the Character Set to Multi-Byte Character Set


Under Debuggin Configuration Properties, set the following values:
Command : $(OGRE_HOME)\Bin\$(Configuration)\$(ProjectName).exe
Working Directory: $(OGRE_HOME)\Bin\$(Configuration)
   
  Now Goto Configuration Properties->C/C++->General->Additional Include Directories add following:
  $(OGRE_HOME)\include
$(OGRE_HOME)\include\OIS
$(OGRE_HOME)\include\OGRE 
$(OGRE_HOME)\Samples\Common\include
$(OGRE_HOME)\boost_1_44

In Configuration->Linker->General->Additional Library Directories add following - $(OGRE_HOME)\lib\$(Configuration)
$(OGRE_HOME)\boost_1_44\lib

In Configuration Properties->Build Events->Post Build Event->Command Line, add:
copy "$(OutDir)\$(TargetFileName)" "$(OGRE_HOME)\Bin\$(Configuration)"


Now make some Configuration Specific Settings. Switch Configuration to Active(Debug) : 

Add Input libaries for debug : 
OgreMain_d.lib
OIS_d.lib

Configuration Properties -> Linker -> Input ->Additional Dependencies -> Release
Switch configuration from Active(debug) to Active(release).
Add input libraries for release: 
OgreMain.lib
OIS.lib

4. Now Build your project and see the output. All executables generated are sent to the Ogre SDK's->Bin Folder as all the Ogre .dll files are there. So you may execute from there as well.