Commits

dbacchet  committed 4a829fc

updated simple renderer with camera manipulator

  • Participants
  • Parent commits 3e97b5c

Comments (0)

Files changed (7)

File sources/opengl2_samples/test7_simplerenderer/GLCameraManipulator.h

+#ifndef __DBGLTrackBallManipulator__
+#define __DBGLTrackBallManipulator__
+// /////////////////////////////////////////////////////////////////////// //
+// Copyright (c) 2012, Davide Bacchet (davide.bacchet@gmail.com)           //
+// All rights reserved.                                                    //
+//                                                                         //
+// The software is released under the Creative Commons Attribution         //
+// NonCommercial (CC BY-NC) license. The full license text is available    //
+// at http://creativecommons.org/licenses/by-nc/3.0/legalcode              //
+//                                                                         //
+// You are free to distribute and adapt the work under the conditions:     //
+// * Redistributions of source code must retain the above copyright notice //
+// * You must attribute the work in the manner specified by the author     //
+// * You may not use this work for commercial purposes.                    //
+//                                                                         //
+// Commercial Usage:                                                       //
+// To use this software as part of a commercial product, you must          //
+// obtain a written agreement from the author.                             //
+// /////////////////////////////////////////////////////////////////////// //
+
+// trackball manipulator; add the pan/zoom functionality to the standard trackball
+
+
+#include "vmath.h"
+
+#include "GLTrackball.h"
+
+
+/// @class GLCameraManipulator 
+/// trackball 
+template <typename real_type=float>
+class GLCameraManipulator
+{
+public:
+
+    enum eMode {
+            evRotate,   ///< rotate mode
+            evPan,      ///< pan the manipulator
+            evZoom,     ///< zoom mode
+            evModeNum
+    };
+
+public:
+
+    /// standard constructor
+    GLCameraManipulator()
+    : trackball()
+    , currMode(evRotate)
+    , radius(10.0)
+    , center(0.0,1.0,0.0)
+    {}
+    /// destructor
+    virtual ~GLCameraManipulator()
+    {}
+    
+    /// begin the dragging
+    virtual void beginDrag(real_type x, real_type y)
+    {
+        if (currMode==evRotate)
+            trackball.beginDrag(x,y);
+        else if (currMode==evPan || currMode==evZoom)
+        {
+            anchorPan = center; // set anchor point to the current position
+            anchorPanSS = Vector3<real_type>(-x,-y,0.0);
+            incremPan = Vector3<real_type>(0,0,0);
+        }
+    }
+    
+    /// mouse drag
+    virtual void drag(real_type x, real_type y)
+    {
+        if (currMode==evRotate)
+            trackball.drag(x,y);
+        else if (currMode==evPan)
+        {
+            Vector3<real_type> delta = Vector3<real_type>(-x,-y,0.0)-anchorPanSS;
+            incremPan = delta*radius; // compensate with radius to 'normalize' the translation (effective when connected to a camera) 
+            incremPan = trackball.getRotation().inverse()*incremPan; // to use object local orientation
+            center = anchorPan+incremPan;
+        }
+        else if (currMode==evZoom)
+        {
+            radius += radius*(anchorPanSS.y+y)/100; // too minimalistic zoom implementation (+y here because in the camera manipualtor the y coord is inverted)
+            if (radius<0.1) radius=0.1;
+        }
+    }
+    
+    /// get current center
+    Vector3<real_type> getCenter( void ) 
+    {
+        return center;
+    }
+    /// get current rotation
+    Matrix4<real_type> getRotation( void ) 
+    {
+        return trackball.getRotation().inverse();
+    }
+    /// get current transformation
+    Matrix4<real_type> getTransformation( void ) 
+    {
+        currentTransf = trackball.getRotation().inverse();
+        Vector3<real_type> offsetRad = currentTransf*Vector3<real_type>(0.0,0.0,radius); // radius offset in local orientation
+        currentTransf.setTranslation(center+offsetRad);
+        return currentTransf;
+    }
+
+    void setMode( eMode mode )
+    { 
+        currMode = mode;
+    }
+
+    // ///////////////////////////////////// //
+    // camera manipulator placement routines //
+    // ///////////////////////////////////// //
+
+    // set the current transform given camera position, target and up vector
+    void setLookAt( const Vector3<real_type> &camPos, const Vector3<real_type> &target, const Vector3<real_type> &up)
+    {
+        // update trackball rotation
+        Vector3<real_type> z = camPos-target;
+        z.normalize();
+        Vector3<real_type> y = up;
+        y.normalize();
+        Vector3<real_type> x = y.crossProduct(z); 
+        if (x.lengthSq()<1e-6)
+            return; // return if up vector (y) and z are parallel
+        x.normalize();
+        y = z.crossProduct(x);
+        trackball.currentRot.at(0,0) = x.x; trackball.currentRot.at(0,1) = y.x; trackball.currentRot.at(0,2) = z.x; 
+        trackball.currentRot.at(1,0) = x.y; trackball.currentRot.at(1,1) = y.y; trackball.currentRot.at(1,2) = z.y; 
+        trackball.currentRot.at(2,0) = x.z; trackball.currentRot.at(2,1) = y.z; trackball.currentRot.at(2,2) = z.z; 
+        // set center and radius
+        center = target;
+        radius = (camPos-target).length();
+    }
+
+
+protected:
+    
+    // member variables
+    eMode currMode;               ///< manipulator current mode
+    
+    real_type           radius;      ///< trackball radius
+    Vector3<real_type>  center;      ///< trackball center (current pan value)
+    Vector3<real_type>  anchorPan;   ///< anchor point for pan
+    Vector3<real_type>  anchorPanSS; ///< anchor point for pan (screen-space)
+    Vector3<real_type>  incremPan;   ///< increment for pan
+
+    Matrix4<real_type>  currentTransf;  ///< current transformation matrix
+
+    GLTrackball<real_type> trackball;   ///< manage rotations
+        
+};
+
+
+typedef GLCameraManipulator<float>  GLCameraManipulatorf;
+typedef GLCameraManipulator<double> GLCameraManipulatord;
+
+#endif

File sources/opengl2_samples/test7_simplerenderer/GLMaterial.cpp

         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
+        // add anisotropic filtering
+        /// \warning NOT SAFE!!! no check if the extension is available
+        GLfloat fLargest;
+        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
+        fLargest = fLargest>4.0f ? 4.0f : fLargest; // limit to 4 the anisotropic filtering
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
+
         stbi_image_free(data);
 
         // add to map and return 

File sources/opengl2_samples/test7_simplerenderer/GLTrackball.h

         return currentRot;
     }
 
-protected:
+public:
     
     // member variables
     

File sources/opengl2_samples/test7_simplerenderer/glfw_utils.cpp

     context.mouse_posx = x;
     context.mouse_posy = context.height-y;
 
-    context.dragging = (context.mouse_button==MOUSE_BUTTON_LEFT);
+    context.dragging = (context.mouse_button!=MOUSE_BUTTON_NONE);
 }
 
 
     {
         context.mouse_button = MOUSE_BUTTON_LEFT;
         if (button==GLFW_MOUSE_BUTTON_MIDDLE)
-            context.mouse_button = MOUSE_BUTTON_CENTER;
+            context.mouse_button = MOUSE_BUTTON_MIDDLE;
         if (button==GLFW_MOUSE_BUTTON_RIGHT)
             context.mouse_button = MOUSE_BUTTON_RIGHT;
     }
             context.current_key = (char)KEY_TAB;
         else if (key == GLFW_KEY_ENTER)
             context.current_key = (char)KEY_ENTER;
+        else if (key == GLFW_KEY_LSHIFT || key == GLFW_KEY_RSHIFT)
+            context.current_key = (char)KEY_SHIFT;
+        else if (key == GLFW_KEY_LCTRL || key == GLFW_KEY_RCTRL)
+            context.current_key = (char)KEY_CTRL;
+        else if (key == GLFW_KEY_LALT || key == GLFW_KEY_RALT)
+            context.current_key = (char)KEY_ALT;
+        else if (key == GLFW_KEY_LSUPER || key == GLFW_KEY_RSUPER)
+            context.current_key = (char)KEY_SUPER;
+    }
+    else
+    {
+        context.current_key = (char)0;
     }
 }
 

File sources/opengl2_samples/test7_simplerenderer/glfw_utils.h

 
 #define MOUSE_BUTTON_NONE   0
 #define MOUSE_BUTTON_LEFT   1
-#define MOUSE_BUTTON_CENTER 2
+#define MOUSE_BUTTON_MIDDLE 2
 #define MOUSE_BUTTON_RIGHT  3
 
-#define KEY_BACKSPACE 0x01
-#define KEY_DELETE    0x02
-#define KEY_TAB       0x03
-#define KEY_ENTER     0x04
+#define KEY_BACKSPACE 1
+#define KEY_DELETE    2
+#define KEY_TAB       3
+#define KEY_ENTER     4
+#define KEY_SHIFT     5
+#define KEY_CTRL      6
+#define KEY_ALT       7
+#define KEY_SUPER     8 // windows key of apple command key
 
 
 #define ARB_TO_CORE(fun) if (!fun && fun##ARB) fun = fun##ARB;

File sources/opengl2_samples/test7_simplerenderer/main.cpp

 #include "GLTimer.h"
 #include "GLTransform.h"
 #include "GLTrackball.h"
-#include "GLTrackballManipulator.h"
+#include "GLCameraManipulator.h"
 
 #include "vertex.h"
 
 int width = 1000;
 int height = 500;    
 
-GLCamera     camera;
-GLTrackballManipulatorf trackball;
+GLCamera             camera;
+GLCameraManipulatorf cameraManipulator;
 
 // timer
 GLTimer timer;
     }
     else // use trackball to manage camera
     {
-        Matrix4f trackballTransf = trackball.getTransformation();
+        // update camera position
+        Matrix4f trackballTransf = cameraManipulator.getTransformation();    
         camera.transform.setTransformationMatrix(trackballTransf);
-        //camera.transform.translate(Vector3f(0.0f,0.0f,10.0f));
     }
 
     // add render data
         for (unsigned int j=0; j<meshes[i]->submeshes.size(); j++)
         {
             const GLSubMesh &sm = meshes[i]->submeshes[j];
-            renderer->addRenderData( sm.material->shader->name,
-                                     sm.material->name,
-                                     sm.vertices,
-                                     sm.indices );
+            renderer->addRenderData( sm.material->shader->name, sm.material->name,
+                                     sm.vertices, sm.indices );
         }
         
     }
     float nx = 2.0f*((float)ctx.mouse_posx-ctx.width/2.0f)/w;
     float ny = 2.0f*((float)ctx.mouse_posy-ctx.height/2.0f)/w;
 
-    if (ctx.mouse_button==MOUSE_BUTTON_LEFT && !ctx.dragging)
+    if ( (ctx.mouse_button==MOUSE_BUTTON_LEFT && !ctx.dragging) )
     {
-        trackball.beginDrag(nx,ny);
+        cameraManipulator.setMode(GLCameraManipulatorf::evRotate);
+        cameraManipulator.beginDrag(nx,ny);
+    }
+    if ( (ctx.mouse_button==MOUSE_BUTTON_MIDDLE && !ctx.dragging)
+       || (ctx.mouse_button==MOUSE_BUTTON_LEFT && ctx.current_key==KEY_SHIFT  && !ctx.dragging) )
+    {
+        cameraManipulator.setMode(GLCameraManipulatorf::evPan);
+        cameraManipulator.beginDrag(nx,ny);
+    }
+    if ( (ctx.mouse_button==MOUSE_BUTTON_RIGHT && !ctx.dragging)
+       || (ctx.mouse_button==MOUSE_BUTTON_LEFT && ctx.current_key==KEY_ALT && !ctx.dragging)
+       || (ctx.mouse_button==MOUSE_BUTTON_LEFT && ctx.current_key==KEY_SUPER && !ctx.dragging) )
+    {
+        cameraManipulator.setMode(GLCameraManipulatorf::evZoom);
+        cameraManipulator.beginDrag(nx,ny);
     }
     if (ctx.dragging)
     {
-        trackball.drag(nx,ny);
+        cameraManipulator.drag(nx,ny);
     }
-    // logInfo("%4d %4d %4d %4d %4d %4d %c\n",  ctx.width,
-    //                                          ctx.height,
-    //                                          ctx.mouse_posx,
-    //                                          ctx.mouse_posy,
-    //                                          ctx.mouse_button,
-    //                                          ctx.mouse_wheel,
-    //                                          ctx.current_key);
+
+    // // update camera position
+    // Matrix4f trackballTransf = cameraManipulator.getTransformation();    
+    // camera.transform.setTransformationMatrix(trackballTransf);
 }
 
 
 
         // manage autorotate
         if (glfwGetKey('A')) {  autorotate = true;  }
-        if (glfwGetKey('R')) {  autorotate = false;  trackball.setMode(GLTrackballManipulatorf::evRotate);  }
-        if (glfwGetKey('T')) {  autorotate = false;  trackball.setMode(GLTrackballManipulatorf::evPan);  }
-        if (glfwGetKey('Z')) {  autorotate = false;  trackball.setMode(GLTrackballManipulatorf::evZoom);  }
+        if (glfwGetKey('R')) {  autorotate = false; 
+                                cameraManipulator.setLookAt( camera.transform.getPosition(), Vector3f(0.0f,0.0f,0.0f), Vector3f(0.0f,1.0f,0.0f)); }
 
         // update fps
         if (frames%100==0)
 #!/usr/bin/python
 import sys,os
-scons_rel_dir='/var/scons-local-2.1.0'
+scons_rel_dir='/var/scons-local-2.2.0'
 old_chdir=os.getcwd()
 for j in (1 << i for i in xrange(64)):
     if not os.access(os.getcwd()+'/SConstruct', os.F_OK):