00001 // ------------------------------------------------------------ 00002 // 00003 // Ivf++ Scene graph culling example 00004 // 00005 // ------------------------------------------------------------ 00006 // 00007 // Author: Jonas Lindemann 00008 // 00009 00010 // ------------------------------------------------------------ 00011 // Include files 00012 // ------------------------------------------------------------ 00013 00014 #include <ivfui/IvfApplication.h> 00015 #include <ivfui/IvfWindow.h> 00016 00017 #include <ivf/IvfCamera.h> 00018 #include <ivf/IvfTransform.h> 00019 #include <ivf/IvfLighting.h> 00020 #include <ivf/IvfMaterial.h> 00021 #include <ivf/IvfSphere.h> 00022 #include <ivf/IvfCulling.h> 00023 00024 using namespace std; 00025 00026 // ------------------------------------------------------------ 00027 // Window class definition 00028 // ------------------------------------------------------------ 00029 00030 IvfSmartPointer(CExampleWindow); 00031 00032 class CExampleWindow: public CIvfWindow { 00033 private: 00034 00035 // Camera movement state variables 00036 00037 double m_angleX; 00038 double m_angleY; 00039 double m_moveX; 00040 double m_moveY; 00041 double m_zoomX; 00042 double m_zoomY; 00043 00044 int m_beginX; 00045 int m_beginY; 00046 00047 // Ivf++ object declarations 00048 00049 CIvfCameraPtr m_camera; 00050 CIvfCameraPtr m_externalCamera; 00051 CIvfCompositePtr m_scene; 00052 CIvfCullingPtr m_culling; 00053 CIvfLightPtr m_light; 00054 CIvfCameraPtr m_currentCamera; 00055 00056 bool m_useCulling; 00057 00058 public: 00059 CExampleWindow(int X, int Y, int W, int H) 00060 :CIvfWindow(X, Y, W, H) {}; 00061 00062 virtual void onInit(int width, int height); 00063 virtual void onResize(int width, int height); 00064 virtual void onRender(); 00065 virtual void onMouseDown(int x, int y); 00066 virtual void onMouseMove(int x, int y); 00067 virtual void onMouseUp(int x, int y); 00068 virtual void onKeyboard(int key, int x, int y); 00069 }; 00070 00071 // ------------------------------------------------------------ 00072 // Window class implementation 00073 // ------------------------------------------------------------ 00074 00075 void CExampleWindow::onInit(int width, int height) 00076 { 00077 // Initialize variables 00078 00079 m_angleX = 0.0; 00080 m_angleY = 0.0; 00081 m_moveX = 0.0; 00082 m_moveY = 0.0; 00083 m_zoomX = 0.0; 00084 m_zoomY = 0.0; 00085 00086 // Initialise culling setting 00087 00088 m_useCulling = true; 00089 00090 // Create cameras 00091 00092 m_camera = new CIvfCamera(); 00093 m_camera->setPosition(0.0, 0.0, 10.0); 00094 m_camera->setPerspective(45.0, 0.5, 100.0); 00095 m_camera->setViewPort(width, height); 00096 00097 m_externalCamera = new CIvfCamera(); 00098 m_externalCamera->setPosition(25.0, 50.0, 50.0); 00099 m_externalCamera->setPerspective(45.0, 0.5, 100.0); 00100 m_externalCamera->setViewPort(width, height); 00101 00102 m_currentCamera = m_camera; 00103 00104 // Create a materials 00105 00106 CIvfMaterialPtr material = new CIvfMaterial(); 00107 material->setDiffuseColor(0.0f, 1.0f, 0.0f, 1.0f); 00108 material->setSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); 00109 material->setAmbientColor(0.0f, 0.5f, 0.0f, 1.0f); 00110 00111 // Create scene 00112 00113 m_scene = new CIvfComposite(); 00114 00115 // Create a somewhat complex sphere 00116 00117 int i, j, k; 00118 int nNodes = 8; 00119 double distance = 20.0/(nNodes-1); 00120 00121 // Geometry is reduced by reusing the same sphere. 00122 00123 CIvfSpherePtr sphere = new CIvfSphere(); 00124 sphere->setSlices(12); 00125 sphere->setStacks(12); 00126 sphere->setMaterial(material); 00127 sphere->setRadius(0.5); 00128 00129 // Create a grid of spheres. 00130 00131 CIvfTransformPtr arrayXlt = new CIvfTransform(); 00132 CIvfTransformPtr xlt; 00133 00134 for (i=0; i<nNodes; i++) 00135 for (j=0; j<nNodes; j++) 00136 for (k=0; k<nNodes; k++) 00137 { 00138 xlt = new CIvfTransform(); 00139 xlt->setPosition( 00140 -10 + distance*i, 00141 -10 + distance*j, 00142 -10 + distance*k); 00143 xlt->addChild(sphere); 00144 arrayXlt->addChild(xlt); 00145 } 00146 00147 arrayXlt->setPosition(0.0, 0.0, -15.0); 00148 arrayXlt->setRotationQuat(0.0, 0.0, 1.0, 45.0); 00149 00150 m_scene->addChild(arrayXlt); 00151 00152 // Create culling object 00153 00154 m_culling = new CIvfCulling(); 00155 m_culling->setComposite(m_scene); 00156 m_culling->setCullView(m_camera); 00157 00158 // Create a light 00159 00160 CIvfLightingPtr lighting = CIvfLighting::getInstance(); 00161 00162 m_light = lighting->getLight(0); 00163 m_light->setType(CIvfLight::LT_DIRECTIONAL); 00164 m_light->setDirection(1.0, 1.0, 1.0); 00165 m_light->setAmbientColor(0.2f, 0.2f, 0.2f, 1.0f); 00166 m_light->enable(); 00167 } 00168 00169 // ------------------------------------------------------------ 00170 void CExampleWindow::onResize(int width, int height) 00171 { 00172 m_externalCamera->setViewPort(width, height); 00173 m_externalCamera->initialize(); 00174 } 00175 00176 // ------------------------------------------------------------ 00177 void CExampleWindow::onRender() 00178 { 00179 m_currentCamera->initialize(); 00180 00181 if (m_useCulling) 00182 m_culling->cull(); 00183 00184 m_light->render(); 00185 m_currentCamera->render(); 00186 m_scene->render(); 00187 00188 cout << "Culled objects = " << m_culling->getCullCount() << endl;; 00189 } 00190 00191 // ------------------------------------------------------------ 00192 void CExampleWindow::onMouseDown(int x, int y) 00193 { 00194 m_beginX = x; 00195 m_beginY = y; 00196 } 00197 00198 // ------------------------------------------------------------ 00199 void CExampleWindow::onMouseMove(int x, int y) 00200 { 00201 m_angleX = 0.0; 00202 m_angleY = 0.0; 00203 m_moveX = 0.0; 00204 m_moveY = 0.0; 00205 m_zoomX = 0.0; 00206 m_zoomY = 0.0; 00207 00208 if (isLeftButtonDown()) 00209 { 00210 m_angleX = (x - m_beginX); 00211 m_angleY = (y - m_beginY); 00212 m_beginX = x; 00213 m_beginY = y; 00214 00215 m_camera->rotatePositionY(m_angleX/100.0); 00216 m_camera->rotatePositionX(m_angleY/100.0); 00217 00218 redraw(); 00219 } 00220 00221 if (isRightButtonDown()) 00222 { 00223 if (getModifierKey() == CIvfWidgetBase::MT_SHIFT) 00224 { 00225 m_zoomX = (x - m_beginX); 00226 m_zoomY = (y - m_beginY); 00227 } 00228 else 00229 { 00230 m_moveX = (x - m_beginX); 00231 m_moveY = (y - m_beginY); 00232 } 00233 m_beginX = x; 00234 m_beginY = y; 00235 00236 m_camera->moveSideways(m_moveX/100.0); 00237 m_camera->moveVertical(m_moveY/100.0); 00238 m_camera->moveDepth(m_zoomY/50.0); 00239 00240 redraw(); 00241 } 00242 } 00243 00244 // ------------------------------------------------------------ 00245 void CExampleWindow::onMouseUp(int x, int y) 00246 { 00247 m_angleX = 0.0; 00248 m_angleY = 0.0; 00249 m_moveX = 0.0; 00250 m_moveY = 0.0; 00251 m_zoomX = 0.0; 00252 m_zoomY = 0.0; 00253 } 00254 00255 // ------------------------------------------------------------ 00256 void CExampleWindow::onKeyboard(int key, int x, int y) 00257 { 00258 switch (key) { 00259 case 'c': 00260 if (m_useCulling) 00261 { 00262 cout << "culling off" << endl; 00263 m_useCulling = false; 00264 } 00265 else 00266 { 00267 cout << "culling on" << endl; 00268 m_useCulling = true; 00269 } 00270 00271 redraw(); 00272 break; 00273 case 'x': 00274 if (m_currentCamera==m_camera) 00275 { 00276 m_currentCamera = m_externalCamera; 00277 } 00278 else 00279 { 00280 m_currentCamera = m_camera; 00281 } 00282 redraw(); 00283 break; 00284 default: 00285 break; 00286 } 00287 } 00288 00289 // ------------------------------------------------------------ 00290 // Main program 00291 // ------------------------------------------------------------ 00292 00293 int main(int argc, char **argv) 00294 { 00295 // Create Ivf++ application object. 00296 00297 CIvfApplicationPtr app = new CIvfApplication(IVF_DOUBLE|IVF_RGB); 00298 00299 // Create a window 00300 00301 CExampleWindowPtr window = new CExampleWindow(0, 0, 512, 512); 00302 00303 // Set window title and show window 00304 00305 window->setWindowTitle("Ivf++ Scene-graph culling example"); 00306 window->show(); 00307 00308 // Enter main application loop 00309 00310 app->run(); 00311 00312 return 0; 00313 }