Thursday, 31 May 2012

Getting Started with EGL on the Raspberry pi

So i finally go my raspberry pi and my plan is to port my NGL library to it, the main difference is that NGL is using Qt and OpenGL 3.2 core profile and the pi will use OpenGL ES and EGL. Having never used EGL I decides to do a bit of rtfm and read the spec as well as some of the demo programs that come with the pi. The following is a basic introduction to getting started with EGL and using the pi in general. All the code for this post can be found here


EGL getting started

EGL is used as an interface between OpenGL (and other Khronos API's) and the base system (in this case the pi). It is responsible for accessing the display hardware and other synchronisation of the display / graphics context. In the case of the pi we use it to access the display hardware and use OpenGL or OpenVG with it.

All of the functions for this are stored in the header file  egl.h as shown below
#include <EGL/egl.h>
On the debian "squeeze" image of the OS these headers can be found in /opt/vc/include, we also need to add the EGL library to our build using the flags -L/opt/vc/lib -lEGL (more on this later in the Makefile section).

Accessing the display

Almost all the EGL functions require a valid display pointer to do their work, this is stored using the EGLDisplay typedef (it's actually a void * ).

We can get one of these using the following code
EGLDisplay display;
// get an EGL display connection
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(display !=EGL_NO_DISPLAY);
If this is successful it should return a valid display, else the EGL_NO_DISPLAY value will be returned.

EGL initialisation 

Now we have a valid display connection we can initialise EGL and query what version we have, this is done with the following code.
// now lets initialise EGL and get the versions
int major;
int minor;
EGLBoolean result;

result = eglInitialize(display, &major, &minor);
assert(result != EGL_FALSE );
std::cout<<"Major version "<<major<<" minor "<<minor<<"\n";
On my version of the pi it gives the following output
Major version 1 minor 4

Configurations

Now we have initialised EGL we can query the different configurations available to use. This is done using the eglGetConfigs function which works in two different modes. The first mode will allow us to get how many configs there are, and the second will fill a buffer with all of the different configs. This is done in the the following code
EGLint numConfigs;
// first we call getConfigs with a NULL to see how many configs we have
result=eglGetConfigs(display,NULL,0,&numConfigs);
assert(result != EGL_FALSE );
std::cout<< "number of configs found "<<numConfigs<<"\n";
// now we create a buffer to store all our configs
EGLConfig *configs = new EGLConfig[numConfigs];
// and copy them into our buffer (don't forget to delete once done)
result=eglGetConfigs(display,configs,numConfigs,&numConfigs);
assert(result != EGL_FALSE );

......

// don't forget to delete once done
delete [] configs;

We can now gather the information from each of the configs using the eglGetConfigAttrib function. This requires you to pass in the attribute you wish to query and will return the value if set. The following code queries the attributes available on the pi (some that are in the spec are not on the pi)

for(int i=0; i<numConfigs; ++i)
{
 std::cout<<"Config #"<<i<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_BUFFER_SIZE,&value);
 std::cout<<"Buffer Size "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_RED_SIZE,&value);
 std::cout<<"Red Size "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_GREEN_SIZE,&value);
 std::cout<<"Green Size "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_BLUE_SIZE,&value);
 std::cout<<"Blue Size "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_ALPHA_SIZE,&value);
 std::cout<<"Alpha Size "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_CONFIG_CAVEAT,&value);
 switch(value)
 {
  case  EGL_NONE : std::cout<<"EGL_CONFIG_CAVEAT EGL_NONE\n"; break;
  case  EGL_SLOW_CONFIG : std::cout<<"EGL_CONFIG_CAVEAT EGL_SLOW_CONFIG\n"; break;
 }
 eglGetConfigAttrib(display,configs[i],EGL_CONFIG_ID,&value);
 std::cout<<"Config ID "<<value<<"\n";

 eglGetConfigAttrib(display,configs[i],EGL_DEPTH_SIZE,&value);
 std::cout<<"Depth size "<<value<<"\n";

 eglGetConfigAttrib(display,configs[i],EGL_MAX_PBUFFER_WIDTH,&value);
 std::cout<<"Max pbuffer width "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_MAX_PBUFFER_HEIGHT,&value);
 std::cout<<"Max pbuffer height "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_MAX_PBUFFER_PIXELS,&value);
 std::cout<<"Max pbuffer pixels "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_NATIVE_RENDERABLE,&value);
 std::cout<<"Native renderable "<<std::string(value ? "true" : "false")<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_NATIVE_VISUAL_ID,&value);
 std::cout<<"Native visual ID "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_NATIVE_VISUAL_TYPE,&value);
 std::cout<<"Native visual type "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_SAMPLE_BUFFERS,&value);
 std::cout<<"Sample Buffers "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_SAMPLES,&value);
 std::cout<<"Samples "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_SURFACE_TYPE,&value);
 std::cout<<"Surface type "<<value<<"\n";
 eglGetConfigAttrib(display,configs[i],EGL_TRANSPARENT_TYPE,&value);

}
This give a sample output like this (a full listing can be seen here or in the file output.txt in the code bundle)
Config #0
Buffer Size 32
Red Size 8
Green Size 8
Blue Size 8
Alpha Size 8
EGL_CONFIG_CAVEAT EGL_NONE
Config ID 1
Depth size 24
Max pbuffer width 2048
Max pbuffer height 2048
Max pbuffer pixels 4194304
Native renderable true
Native visual ID 37928
Native visual type 12344
Sample Buffers 0
Samples 0
Surface type 1639

Makefile

To build the program the following makefile was used, it includes the correct paths and libs
CC=g++
CFLAGS=-c -Wall -O3 -I/usr/local/include -I/opt/vc/include -Iinclude/ngl -Isrc/ngl -Isrc/shaders -DNGL_DEBUG
LDFLAGS=-L/opt/vc/lib -lEGL
SOURCES=$(shell find ./ -name *.cpp)
OBJECTS=$(SOURCES:%.cpp=%.o)
EXECUTABLE=EGLgetConfig

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
 $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
 $(CC) $(CFLAGS) $< -o $@

clean :
 rm -f *.o $(EXECUTABLE)

That it for now but here is a sneak preview of NGL almost working

Wednesday, 21 March 2012

Using the Maya API with Qt Creator

I've just started writing next terms Maya API lectures and decided it would be a good idea to use Qt Creator as the ide for development as it's our main IDE. It also has the advantage of automatically creating the make file required for the projects and helping to make multi platform builds easier to manage.

Qt Creator Project file
qmake and Qt Creator both use the .pro file for the projects. In this case I'm going to create builds for both Linux 64bit and Mac OSX. qmake uses the pre-fix values linux-g+-64 for all flags relating to linux 64 bit and macx for Mac OSX. 

The following .pro file shows how this is done.
# This file is split into Three sections
# The first configures Qt and the source files for all platforms
# The second is the linux build
# The third the mac build
# (if your using windows you will need to add a fourth one!)
# first lets remove Qt core and gui not going to need it
QT       -= core gui
# set the variable for the Maya Location, this will be different depending
# upon the platform / version of maya used
TARGET = HelloMaya
# for for mac we need a bundle so change the name
macx:TARGET=HelloMaya.bundle
# here we add the source files (and headers if required)
SOURCES+=HelloMaya.cpp
# these are defines required by Maya to re-define some C++
# stuff, we will add some more later to tell what platform
# we are on as well
DEFINES+=REQUIRE_IOSTREAM \
         _BOOL
# These are the maya libs we need to link to, this will change depending
# upon which maya framework we use, just add them to the end of
# this list as required and they will be added to the build
MAYALIBS=-lOpenMaya \
        -lFoundation

# now tell linux we need to build a lib
linux-g++-64:TEMPLATE = lib

# this tells qmake where maya is
linux-g++-64:MAYALOCATION=/usr/autodesk/maya2011-x64/
# under linux we need to use the version of g++ used to build maya
# in this case g++412
linux-g++-64:QMAKE_CXX = g++412
# set the include path for linux
linux-g++-64:INCLUDEPATH += $$MAYALOCATION/include \
                        /usr/X11R6/include
# set which libs we need to include
linux-g++-64:LIBS += -L$$MAYALOCATION/lib \
                   $$MAYALIBS
# tell maya we're building for linux
linux:DEFINES+=linux

# tell maya we're building for Mac
macx:DEFINES+=OSMac_
macx:MAYALOCATION=/Applications/Autodesk/maya2011
macx:CONFIG -= app_bundle
macx:INCLUDEPATH+=$$MAYALOCATION/devkit/include
# under mac we need to build a bundle, to do this use
# the -bundle flag but we also need to not use -dynamic lib so
# remove this
macx:LIBS +=-bundle
mac:LIBS -=-dynamiclib

macx:LIBS += -L$$MAYALOCATION/Maya.app/Contents/MacOS \
             $$MAYALIBS
There are several sections to the .pro file above, mainly these are to make it easier to add to the project when needed. The two main distinctions between the linux and the Mac OSX version are how the plugin should be generated. Under linux the plugin is a normal shared object file (.so), however the mac version requires a bundle. To do this the -bundle flag is used and we also need to ensure that the extension .bundle is added to the Target.

Finally we need to add some defines to the build, depending upon the platform we need to either use -DOSMac_ or -Dlinux as well as the two flags REQUIRE_IOSTREAM which includes the correct iostream library for using std::cout and _BOOL to re-define bool.

Test Program
The following test program will send a message to both the shell maya was run from and the maya command window.

#include <maya/MSimple.h>
#include <maya/MIOStream.h>
#include <maya/MGlobal.h>

// This is a macro to create a simple command
// the compiler expands it to a bunch of code

DeclareSimpleCommand( HelloMaya , "NCCA", "Maya 2011"); 

MStatus HelloMaya::doIt( const MArgList& )
{
  std::cout<<"This should come from the shell\n";
  MGlobal::displayInfo("Hello Maya in the maya command shell");
  return MS::kSuccess;
}
Once this program is build depending upon the platform there should be a plugin ready to load in the maya plugin manager. The image below show this and the info set from the Command above
We now have two options to execute the loaded command. In the mel window we can invoke the command as follows, For the mel version
And for the python version we need to import the maya.cmds module first.


Thursday, 15 March 2012

Using Flex with Qt

I've got a large project to work on which will require quite a bit of parsing / scanning of files so I've decided to teach myself flex and bison. So far I've read the first chapter of the excellent book Flex and Bison and the first example is as follows
/* from the flex and bison book do a word count */

%{
int chars=0;
int words=0;
int lines=0;
%}

%%

[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n    { chars++; lines++; }
.     { chars++; }

%%
int main(int argc, char **argv)
{
  yylex();
  printf("Word count %8d %8d %8d\n",lines,words,chars);
  return 0;
}

To build and compile this we use the following command line
flex -o wc.c wc.l
gcc -o WordCount wc.c -lfl
This works fine, but as I use QtCreator as my ide I really want to configure Qt to do this all for me. QtCreator does have some limited lex and yacc support however I really wanted to use flex and bison, so need to add my own compiler to the qmake build system via the Qt project. To do this we use the QMAKE_EXTRA_COMPILERS flag in the project and build our own compile chain, the following extract shows how this works
# the is the name of the exe we want
TARGET=WordCount
# this is the source fed to the flex syste
FLEXSOURCES+=wc.l
# we then add this to the other files for editing
OTHER_FILES+=$$FLEXSOURCES

###########################################################################################
# now we are going to create a Qt compiler ojbect for the EXTRA_COMPILERS FLAG
# this basically has a number of attributes which we need to set as outlined below
###########################################################################################
# this flag list the sources we wish to input to this custom compiler, in this case listed above
# in the FLEXSOURCES variable
flex.input = FLEXSOURCES
# now we need to say what files to output, for flex we want to create the .c
flex.output = ${QMAKE_FILE_BASE}.c
# this is the actual compile command we wish to call in this case it wil be
# flex -o (output).c input.l
flex.commands = flex  -o ${QMAKE_FILE_IN_BASE}.c ${QMAKE_FILE_IN}
# once this compiler has been run we need to add the output files to the linker stage in this case
# as we are generating .c files we just add it to the SOURCES variable and it will be compiled
flex.variable_out = SOURCES
# this flag ensures that the extra compiler is run before the main c one (as we need to have the .c files
# generated by flex before we use the gcc compiler)
flex.CONFIG += target_predeps
# this tells the make clean command what files to remove
flex.clean =  ${QMAKE_FILE_IN_BASE}.c
# this is just the name of the extra compiler used in the make file (make flex for example)
flex.name = flex
# finally add this to the qmake project so it will have the makefile generated
QMAKE_EXTRA_COMPILERS += flex
# we need the fl lib for flex
LIBS+=-lfl
# tell qt we usign gcc
QMAKE_LINK=gcc
# this just cleans out some things for mac
CONFIG += console
CONFIG -= app_bundle

And that is about it, now I've got to read the rest of the book, but at least it makes the coding easier!

Tuesday, 6 March 2012

Setting OpenGL Formats in Qt

Got asked how to enable multi-sampling in my demos the other day, and realised that I hadn't shared this information in any of my lectures so I thought I would write it up here.

OpenGL has a number of extensions which allow a number of different rendering features to be enabled. For example we can do stereo, accumulation  multisampling and much more.

In Qt we do this by using the QGLFormat class and we can enable it for a specific QGLWidget, or for all widgets we create. For this example I will generate a default format and then create a widget to use the format. This code would be put in main.cpp in my demos (will update them soon) before the creation of the MainWindow class.

QGLFormat glf = QGLFormat::defaultFormat();
glf.setSampleBuffers(true);
glf.setSamples(4);
QGLFormat::setDefaultFormat(glf);
Now when we create the GLWindow in the ngl:: demos this will be used for all windows created. Finally we need to enable GL_MULTISAMPLE when rendering which can be done using the following code
glEnable(GL_MULTISAMPLE);
This method can also be used to enable things such as the new OpenGL core profile (under linux and windows for Qt 4.7 and with Qt 4.8 this will also work on the mac eventually, as long as you have Lion). You should be able to see from the documentation all the other features which can be enabled in this way.

Tuesday, 21 February 2012

A bit of Parsing

In yesterdays post I taked about some updates to the ShaderLib to allow registering of the uniforms, and as I was driving into work I decided to add some more code to parse the shader source and look for any lines containing the word uniform and automatically add it to the uniforms list.

The glsl spec contains a full list of the grammar for glsl, and we can break down the declaration of uniforms to the following
// easy case
// uniform type name;
uniform vec3 position;

// more difficult case
// uniform type name[ ];

#define numLights 10
uniform Lights lights[numLights];

//or

uniform Lights lights[3];

The simple case of a single uniform is easy to parse and can be accomplished by reading the shader source and looking for lines containing the uniform keyword.

The array version however is more complex as we need to determine if we have one of two different cases. Either a hard coded array value or a constant defined by a #define statement.

The lucky thing is that the #define must always be executed before it is used, so we can store these values and do a lookup on them.

The downside of this is the fact that each element of the array must be registered.

This is further compounded by the fact that the data type may be a structure. I'm not going to worry about the structure side of things and only worry with accessing normal arrays of the type uniform vec3 points[3] for example.

Lets get a boost++
In general C++ string processing is not that good, however there are several really good libraries in boost that allow loads of different string processing. For this example I'm going to use boost::tokenizer ,boost::format, boost::split and boost::lexical_cast, all of these are header only templated classes so don't require external compiled libs and all work well with the usual stl containers.

Overview of the process
I've created a new method for the ShaderProgram class which will loop for each attached shader and grab the shader source code string (the whole shader is stored as a single std::string ) this is then split based on the tokens \n\r and a space.
Each line is then searched to find the following keywords "uniform" and "#define". The code to do this is as follows.
void ShaderProgram::autoRegisterUniforms()
{

  unsigned int size=m_shaders.size();
  const std::string *source;
  std::vector<std::string> lines;

  boost::char_separator<char> sep(" \t\r\n");
  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;

  for(unsigned int i=0; i<size; ++i)
  {
   /// first grab all of the shader source for this program
    source=m_shaders[i]->getShaderSource();
    // and split on new lines
    boost::split(lines, *source, boost::is_any_of("\n\r"));

    // now we loop for the strings and tokenize looking for the uniform keyword
   // or the #define keyword
   std::vector<std::string>::iterator start=lines.begin();
    std::vector<std::string>::iterator end=lines.end();
    std::map<std::string,int> defines;

    while(start!=end)
    {
      if(start->find("#define") !=std::string::npos)
      {
        int value;
        std::string define;
        if( parseHashDefine(*start,define,value) )
         {
          defines[define]=value;
        }
      }
      // see if we have uniform in the string
      else if (start->find("uniform") !=std::string::npos)
      {
        parseUniform(*start,defines);
      }
      // got to the next line
      ++start;
     }
  }
}
To find if the string contains our keywords we use the std::string find method which will return a value not equal to std::string::npos if found (basically the index but we don't need that).

If this is found we can process the respective values.
Parsing #define
To store any #define values I'm going to use a std::map<std::string, int>  to store the value, and also make the assumption that we will always have the form #define name [int]. This is a very safe assumption as array subscripts must always be positive and in the case of glsl most implementations only allow very small arrays.

The overall process is quite simple, I tokenise the string as above, however now we copy this to a std::vector <std::string>  using the assign method and then use the subscript to access the elements we want, as shown below

bool ShaderProgram::parseHashDefine(
                                    const std::string &_s,
                                    std::string &o_name,
                                    int &o_value
                                    ) const
{
  // typedef our tokenizer for speed and clarity
  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
  // these are the separators we are looking for (not droids ;-)
  boost::char_separator<char> sep(" \t\r\n");
  // generate our tokens based on the separators above
  tokenizer tokens(_s, sep);
  // now we will copy them into a std::vector to process
  std::vector <std::string> data;
  // we do this as the tokenizer just does that so we can't get size etc
  data.assign(tokens.begin(),tokens.end());
  // we are parsing #define name value so check we have this format
  // we should as the glsl compiler will fail if we don't but best to be sure
  if(data.size() !=3)
  {
    return false;
  }
  else
  {
    //            data [0]     [1]   [2]
    // we are parsing #define name value
    o_name=data[1];
    o_value=boost::lexical_cast<int> (data[2]);
    // all was good so return true
    return true;
  }
}
You will notice that the boost::lexical_cast is used to convert the string into an integer, and that both the values are returned to the main program and stored in the defines map ready to be passed into the next function to process the uniforms.
ParseUniform method
The parseUniform method is split into two sections, we first check to see if the string has a [ or not as this will depend upon the parse method. If no [] is present we can process in a similar way to above, however if there is an array we need to further refine the parse, and then loop and register all the uniforms. For example the following glsl code
#define numIndices 4
int indices[numIndices];
would need all the uniforms registered so we would register
indices[0]
indices[1]
indices[2]
indices[3]
The following code shows the complete method
void ShaderProgram::parseUniform(
                                  const std::string &_s,
                                  const std::map <std::string,int> &_defines
                                )
{
 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;

 // first lets see what we need to parse
 if(_s.find("[") ==std::string::npos)
 {
   boost::char_separator<char> sep(" \t\r\n;");
   // generate our tokens based on the seperators above
   tokenizer tokens(_s, sep);
   // now we will copy them into a std::vector to process
   std::vector <std::string> data;
   // we do this as the tokenizer just does that so we can't get size etc
   data.assign(tokens.begin(),tokens.end());
   // uniform type name
   // we should as the glsl compiler will fail if we don't but best to be sure
   if(data.size() >=3)
   {
     registerUniform(data[2]);
   }
 }
 else
 {
   boost::char_separator<char> sep(" []\t\r\n;");
   // generate our tokens based on the separators above
   tokenizer tokens(_s, sep);
   // now we will copy them into a std::vector to process
   std::vector <std::string> data;
   // we do this as the tokenizer just does that so we can't get size etc
   data.assign(tokens.begin(),tokens.end());
   // uniform type name
   // we should as the glsl compiler will fail if we don't but best to be sure
   if(data.size() >=3)
   {
     // so in this case data[3] is either a number or a constant
     int arraySize=0;
     // so we try and convert it if it's not a number
     try
     {
       arraySize=boost::lexical_cast<int> (data[3]);
     }
     // catch and lookup in the uniform array
     catch(boost::bad_lexical_cast)
     {
       std::map <std::string, int >::const_iterator def=_defines.find(data[3]);
       if(def !=_defines.end())
       {
         arraySize=def->second;
       }
     } // end catch
    // now loop and register each of the uniforms
     for(int i=0; i<arraySize; ++i)
     {
       // convert our uniform and register
       std::string uniform=boost::str(boost::format("%s[%d]") %data[2] %i);
       registerUniform(uniform);
     }
   }

 }
}
Most of the code is similar to the other parse methods, however we use the fact that boost::lexical_cast throws and exception to check to see if we have a number or a string as the size of the array, first I try the cast, if this throws a boost::bad_lexical_cast exception we look to see if we have the value stored in our defines list.
Conclusions and Future work
This works quite well and is fairly robust (as the glsl compiler will fail if the code is wrong anyway), however as mentioned above it doesn't cope with registering uniforms which have structures. I may refine this at a later date to cope with these but it would require storing each structure and element of that structure and registering each element.

This will eventually be made redundant due to the use of the new glsl Uniform Buffer Objects however at present my mac doesn't support them so will have to wait.

I may also just write a full glsl parser using the excellent boost::spirit library one day as an exercise in  parser writing (as I quite enjoy writing parsers)

This code has been integrated into ngl and the latest source tree has been updated to inclue it all.

Monday, 20 February 2012

ngl::ShaderLib update

Just a quick post to explain some updates to the ngl::ShaderLib sub-system. First of all this doesn't break any existing code, but has in some situations increased frame rate by 10-15%.

First a bit of background, all of the shader lib functions use the getUniformLocation function to query the location of the uniform in the current program and use this GLuint offset to load the values to the uniform in the shader.

This works ok, and generally this only called at the start of the program so doesn't cause too much of a bottleneck. However in most of the demos we load the Model/View/Projection matrix to the Shader each time we move something, and the MVP value will be loaded using the following code (from the ngl:: source)

void ShaderProgram::setUniformMatrix4fv(
                                          const char* _varname,
                                          size_t _count,
                                          bool _transpose,
                                          const float* _value
                                        ) const
{
  glUniformMatrix4fv(getUniformLocation(_varname),_count,_transpose,_value);
}
Here the getUniformLocation is called and doesn't need to be if we pre-cache the value. To do this ngl::ShaderProgram has a new attribute added to it as follows
std::map <std::string, GLuint> m_registeredUniforms;
To use this, once the shader is loaded, compiled and linked we must set it to be active and we can then register the uniform as follows (this will usually be done in the GLWindow::initalizeGL method)
(*shader)["MultipleLights"]->use();
shader->setShaderParam1f("Normalize",1);
shader->registerUniform("MultipleLights","MVP");
shader->registerUniform("MultipleLights","MV");
shader->registerUniform("MultipleLights","M");
shader->registerUniform("MultipleLights","normalMatrix");
shader->registerUniform("MultipleLights","viewerPos");

This will register the uniforms, now when we load the matrix values to the shaders, we can use the "registered" versions of the functions which will look up the values in the map and use the uniform's stored there. This will work unless the shader source is changed and re-compiled. In that case they will need to be re-registered.

void GLWindow::loadMatricesToShader(
                                     ngl::TransformStack &_tx
                                   )
{
  ngl::ShaderLib *shader=ngl::ShaderLib::instance();
  (*shader)["MultipleLights"]->use();
  ngl::Matrix MV;
  ngl::Matrix MVP;
  ngl::Mat3x3 normalMatrix;
  ngl::Matrix M;
  M=_tx.getCurrentTransform().getMatrix();
  MV=_tx.getCurrAndGlobal().getMatrix()*m_cam->getViewMatrix() ;
  MVP=MV*m_cam->getProjectionMatrix();
  normalMatrix=MV;
  normalMatrix.inverse();
  normalMatrix.transpose();
  shader->setRegisteredUniformFromMatrix("MV",MV);
  shader->setRegisteredUniformFromMatrix("M",M);
  shader->setRegisteredUniformFromMatrix("MVP",MVP);
  shader->setRegisteredUniformFromMat3x3("normalMatrix",normalMatrix);
  shader->setRegisteredUniformVec3("viewerPos",m_cam->getEye().toVec3());
}

Operator Overloading in C++ Part 4

previously we have discussed the different types of operator overloading and the differences between the Member operators and Free operators. In this part we are going to implement a basic * Scalar operator which will multiply each of the Vec3 components by a floating point scalar value. In the .h file we can implement the following definition for the operator
/// @brief * float operator
Vec3  operator*(float _rhs) const;
and for the .cpp file the following
/// @brief * float operator
Vec3 Vec3::operator*(float _rhs) const
{
  return Vec3(m_x*_rhs,m_y*_rhs,m_z*_rhs);
}
Testing this using the following code results in
std::cout<<"b*2== "<<b*2<<"\n";
b*2== [4,6,8] 
However if we try to write the following
std::cout<<"2*a ="<<2*a<<" b*2== "<<b*2<<"\n";
We get the following compiler error error: no match for 'operator*' in '2 * a' This is due to the fact that we have no operator for scalar * Vec3. To solve this problem we can generate a Free function version of the operator and a scale method to scale the vector by a scalar value.
/// @param[in} _s the value to scale components by
Vec3 scale(float _s) const;

Vec3 operator *(float _lhs, const Vec3 &_rhs);

/// in the .cpp file
Vec3 operator *(float _lhs, const Vec3 &_rhs)
{
  return _rhs.scale(_lhs);
}
In most cases it will be best to implement both operators as free functions so we would have the following extra methods
Vec3 operator *(float _lhs, const Vec3 &_rhs)
{
  return _rhs.scale(_lhs);
}

Vec3 operator *(const Vec3 &_lhs,float _rhs)
{
  return _lhs.scale(_rhs);
}
As you can see both methods require the extra scale method, however if we use the free function version we can remove the member operator. In some cases this will not be required (for example if the operands are of the same type)