00001 // ------------------------------------------------------------ 00002 // 00003 // Ivf++ lighting 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/IvfSphere.h> 00019 #include <ivf/IvfComposite.h> 00020 #include <ivf/IvfMaterial.h> 00021 #include <ivf/IvfLighting.h> 00022 #include <ivf/IvfMesh.h> 00023 #include <ivf/IvfLightingState.h> 00024 #include <ivf/IvfRasterization.h> 00025 00026 #include <ivfmath/IvfVec3d.h> 00027 00028 using namespace std; 00029 00030 // ------------------------------------------------------------ 00031 // Window class definition 00032 // ------------------------------------------------------------ 00033 00034 IvfSmartPointer(CExampleWindow); 00035 00036 class CExampleWindow: public CIvfWindow { 00037 private: 00038 00039 // Camera movement state variables 00040 00041 int m_beginX; 00042 int m_beginY; 00043 00044 double m_angleX; 00045 double m_angleY; 00046 double m_moveX; 00047 double m_moveY; 00048 double m_zoomX; 00049 double m_zoomY; 00050 00051 CIvfCameraPtr m_camera; 00052 CIvfCompositePtr m_scene; 00053 CIvfLightPtr m_light; 00054 CIvfLightingPtr m_lighting; 00055 CIvfSpherePtr m_lightSphere; 00056 00057 CIvfVec3d m_direction; 00058 double m_speed; 00059 public: 00060 CExampleWindow(int X, int Y, int W, int H) 00061 :CIvfWindow(X, Y, W, H) {}; 00062 00063 virtual void onInit(int width, int height); 00064 virtual void onResize(int width, int height); 00065 virtual void onRender(); 00066 00067 // Mouse event methods 00068 00069 virtual void onMouseDown(int x, int y); 00070 virtual void onMouseMove(int x, int y); 00071 virtual void onMouseUp(int x, int y); 00072 00073 // Keyboard events 00074 00075 virtual void onKeyboard(int key, int x, int y); 00076 00077 // Timer events 00078 00079 virtual bool onTimeout0(); 00080 }; 00081 00082 // ------------------------------------------------------------ 00083 // Window class implementation 00084 // ------------------------------------------------------------ 00085 00086 void CExampleWindow::onInit(int width, int height) 00087 { 00088 // State variables 00089 00090 m_angleX = 0.0f; 00091 m_angleY = 0.0f; 00092 m_moveX = 0.0f; 00093 m_moveY = 0.0f; 00094 m_zoomX = 0.0f; 00095 m_zoomY = 0.0f; 00096 00097 // Initialize Ivf++ camera 00098 00099 m_camera = new CIvfCamera(); 00100 m_camera->setPosition(0.0, 0.0, 9.0); 00101 m_camera->setPerspective(60.0, 0.1, 40.0); 00102 00103 // Create a materials 00104 00105 CIvfMaterialPtr redMaterial = new CIvfMaterial(); 00106 redMaterial->setDiffuseColor(1.0f, 0.0f, 0.0f, 1.0f); 00107 redMaterial->setSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); 00108 redMaterial->setAmbientColor(0.5f, 0.0f, 0.0f, 1.0f); 00109 00110 CIvfMaterialPtr greenMaterial = new CIvfMaterial(); 00111 greenMaterial->setDiffuseColor(0.0f, 1.0f, 0.0f, 1.0f); 00112 greenMaterial->setSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); 00113 greenMaterial->setAmbientColor(0.0f, 0.5f, 0.0f, 1.0f); 00114 00115 CIvfMaterialPtr blueMaterial = new CIvfMaterial(); 00116 blueMaterial->setDiffuseColor(0.0f, 0.0f, 1.0f, 1.0f); 00117 blueMaterial->setSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); 00118 blueMaterial->setAmbientColor(0.0f, 0.0f, 0.5f, 1.0f); 00119 00120 CIvfMaterialPtr yellowMaterial = new CIvfMaterial(); 00121 yellowMaterial->setDiffuseColor(1.0f, 1.0f, 0.0f, 1.0f); 00122 yellowMaterial->setSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); 00123 yellowMaterial->setAmbientColor(0.5f, 0.5f, 0.0f, 1.0f); 00124 00125 CIvfMaterialPtr whiteMaterial = new CIvfMaterial(); 00126 whiteMaterial->setDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); 00127 whiteMaterial->setSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); 00128 whiteMaterial->setAmbientColor(0.5f, 0.5f, 0.5f, 1.0f); 00129 00130 // Create scene composite 00131 00132 m_scene = new CIvfComposite(); 00133 00134 // Create a sphere representing the light 00135 00136 CIvfLightingStatePtr lightState = new CIvfLightingState(); 00137 lightState->setLighting(false); 00138 00139 m_lightSphere = new CIvfSphere(); 00140 m_lightSphere->setMaterial(whiteMaterial); 00141 m_lightSphere->setRadius(0.1); 00142 m_lightSphere->setRenderState(lightState); 00143 m_lightSphere->setPosition(-2.0, 0.0, 2.0); 00144 m_scene->addChild(m_lightSphere); 00145 00146 // Create a sphere in the middle 00147 00148 CIvfSpherePtr sphere = new CIvfSphere(); 00149 sphere->setRadius(1.0); 00150 sphere->setMaterial(redMaterial); 00151 sphere->setStacks(12); 00152 sphere->setSlices(20); 00153 m_scene->addChild(sphere); 00154 00155 // Create a room 00156 00157 CIvfMeshPtr floor = new CIvfMesh(); 00158 floor->setMeshType(CIvfMesh::MT_ORDER_2); 00159 floor->setMeshResolution(30,30); 00160 floor->createMesh(10.0, 10.0); 00161 floor->setMaterial(redMaterial); 00162 floor->setPosition(0.0, -3.0, 0.0); 00163 00164 m_scene->addChild(floor); 00165 00166 CIvfMeshPtr roof = new CIvfMesh(); 00167 roof->setMeshType(CIvfMesh::MT_ORDER_2); 00168 roof->setMeshResolution(30,30); 00169 roof->createMesh(10.0, 10.0); 00170 roof->setMaterial(greenMaterial); 00171 roof->setPosition(0.0, 3.0, 0.0); 00172 roof->setRotationQuat(0.0, 0.0, 1.0, 180.0f); 00173 m_scene->addChild(roof); 00174 00175 CIvfMeshPtr wall1 = new CIvfMesh(); 00176 wall1->setMeshType(CIvfMesh::MT_ORDER_2); 00177 wall1->setMeshResolution(30,30); 00178 wall1->createMesh(10.0, 6.0); 00179 wall1->setMaterial(blueMaterial); 00180 wall1->setPosition(0.0, 0.0, -5.0); 00181 wall1->setRotationQuat(1.0, 0.0, 0.0, 90.0f); 00182 m_scene->addChild(wall1); 00183 00184 CIvfMeshPtr wall2 = new CIvfMesh(); 00185 wall2->setMeshType(CIvfMesh::MT_ORDER_2); 00186 wall2->setMeshResolution(30,30); 00187 wall2->createMesh(10.0, 6.0); 00188 wall2->setMaterial(blueMaterial); 00189 wall2->setPosition(0.0, 0.0, 5.0); 00190 wall2->setRotationQuat(1.0, 0.0, 0.0, -90.0f); 00191 m_scene->addChild(wall2); 00192 00193 CIvfMeshPtr wall3 = new CIvfMesh(); 00194 wall3->setMeshType(CIvfMesh::MT_ORDER_2); 00195 wall3->setMeshResolution(30,30); 00196 wall3->createMesh(6.0, 10.0); 00197 wall3->setMaterial(yellowMaterial); 00198 wall3->setPosition(5.0, 0.0, 0.0); 00199 wall3->setRotationQuat(0.0, 0.0, 1.0, 90.0f); 00200 m_scene->addChild(wall3); 00201 00202 CIvfMeshPtr wall4 = new CIvfMesh(); 00203 wall4->setMeshType(CIvfMesh::MT_ORDER_2); 00204 wall4->setMeshResolution(30,30); 00205 wall4->createMesh(6.0, 10.0); 00206 wall4->setMaterial(yellowMaterial); 00207 wall4->setPosition(-5.0, 0.0, 0.0); 00208 wall4->setRotationQuat(0.0, 0.0, 1.0, -90.0f); 00209 m_scene->addChild(wall4); 00210 00211 // Create a light 00212 00213 m_lighting = CIvfLighting::getInstance(); 00214 00215 m_light = m_lighting->getLight(0); 00216 m_light->setType(CIvfLight::LT_POINT); 00217 m_light->setLightPosition(-2.0, 0.0, 2.0); 00218 m_light->setSpotCutoff(70.0f); 00219 m_light->setSpotExponent(20.0f); 00220 m_light->setDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); 00221 m_light->setAmbientColor(0.2f, 0.2f, 0.2f, 1.0f); 00222 m_light->enable(); 00223 00224 CIvfRasterizationPtr rasterOps = CIvfRasterization::getInstance(); 00225 rasterOps->enableCullFace(); 00226 rasterOps->setCullFace(CIvfRasterization::CF_BACK); 00227 00228 // Setup moving light 00229 00230 m_direction.setComponents(1.0, 1.0, 1.0); 00231 m_speed = 0.06; 00232 00233 enableTimeout(0.01, 0); 00234 } 00235 00236 // ------------------------------------------------------------ 00237 void CExampleWindow::onResize(int width, int height) 00238 { 00239 m_camera->setViewPort(width, height); 00240 m_camera->initialize(); 00241 } 00242 00243 // ------------------------------------------------------------ 00244 void CExampleWindow::onRender() 00245 { 00246 m_camera->render(); 00247 m_lighting->render(); 00248 m_scene->render(); 00249 } 00250 00251 // ------------------------------------------------------------ 00252 void CExampleWindow::onMouseDown(int x, int y) 00253 { 00254 m_beginX = x; 00255 m_beginY = y; 00256 } 00257 00258 // ------------------------------------------------------------ 00259 void CExampleWindow::onMouseMove(int x, int y) 00260 { 00261 m_angleX = 0.0; 00262 m_angleY = 0.0; 00263 m_moveX = 0.0; 00264 m_moveY = 0.0; 00265 m_zoomX = 0.0; 00266 m_zoomY = 0.0; 00267 00268 if (this->isLeftButtonDown()) 00269 { 00270 m_angleX = (x - m_beginX); 00271 m_angleY = (y - m_beginY); 00272 m_beginX = x; 00273 m_beginY = y; 00274 00275 m_camera->rotatePositionY(m_angleX/100.0); 00276 m_camera->rotatePositionX(m_angleY/100.0); 00277 00278 this->redraw(); 00279 } 00280 00281 if (this->isRightButtonDown()) 00282 { 00283 if (this->getModifierKey()==CIvfWidgetBase::MT_SHIFT) 00284 { 00285 m_zoomX = (x - m_beginX); 00286 m_zoomY = (y - m_beginY); 00287 } 00288 else 00289 { 00290 m_moveX = (x - m_beginX); 00291 m_moveY = (y - m_beginY); 00292 } 00293 00294 m_beginX = x; 00295 m_beginY = y; 00296 00297 m_camera->moveSideways(m_moveX/100.0); 00298 m_camera->moveVertical(m_moveY/100.0); 00299 m_camera->moveDepth(m_zoomY/50.0); 00300 00301 this->redraw(); 00302 } 00303 } 00304 00305 // ------------------------------------------------------------ 00306 void CExampleWindow::onMouseUp(int x, int y) 00307 { 00308 m_angleX = 0.0; 00309 m_angleY = 0.0; 00310 m_moveX = 0.0; 00311 m_moveY = 0.0; 00312 m_zoomX = 0.0; 00313 m_zoomY = 0.0; 00314 } 00315 00316 // ------------------------------------------------------------ 00317 void CExampleWindow::onKeyboard(int key, int x, int y) 00318 { 00319 float angle; 00320 float exponent; 00321 00322 switch (key) { 00323 case 'l': 00324 if (m_light->getType()==CIvfLight::LT_POINT) 00325 m_light->setType(CIvfLight::LT_SPOT); 00326 else 00327 m_light->setType(CIvfLight::LT_POINT); 00328 break; 00329 case 'a': 00330 angle = m_light->getSpotCutoff(); 00331 angle += 5.0f; 00332 cout << "Angle = " << angle << endl; 00333 m_light->setSpotCutoff(angle); 00334 break; 00335 case 'z': 00336 angle = m_light->getSpotCutoff(); 00337 angle -= 5.0f; 00338 cout << "Angle = " << angle << endl; 00339 m_light->setSpotCutoff(angle); 00340 break; 00341 case 's': 00342 exponent = m_light->getSpotExponent(); 00343 exponent += 1.0f; 00344 cout << "Exponent = " << exponent << endl; 00345 m_light->setSpotExponent(exponent); 00346 break; 00347 case 'x': 00348 exponent = m_light->getSpotExponent(); 00349 exponent -= 1.0f; 00350 cout << "Exponent = " << exponent << endl; 00351 m_light->setSpotExponent(exponent); 00352 break; 00353 case 'd': 00354 m_speed += 0.01; 00355 break; 00356 case 'c': 00357 m_speed -= 0.01; 00358 break; 00359 default: 00360 break; 00361 } 00362 } 00363 00364 // ------------------------------------------------------------ 00365 bool CExampleWindow::onTimeout0() 00366 { 00367 CIvfVec3d pos; 00368 double x, y, z; 00369 double ex, ey, ez; 00370 00371 pos = m_lightSphere->getPosition(); 00372 pos = pos + m_direction * m_speed; 00373 00374 pos.getComponents(x, y, z); 00375 m_direction.getComponents(ex, ey, ez); 00376 00377 if ((x>4.8)||(x<-4.8)) 00378 ex = -ex; 00379 00380 if ((y>2.8)||(y<-2.8)) 00381 ey = -ey; 00382 00383 if ((z>4.8)||(z<-4.8)) 00384 ez = -ez; 00385 00386 m_direction.setComponents(ex, ey, ez); 00387 00388 m_lightSphere->setPosition(pos); 00389 pos.getComponents(x, y, z); 00390 m_light->setPosition(x, y, z); 00391 m_light->setSpotDirection(ex, ey, ez); 00392 00393 this->redraw(); 00394 00395 return true; 00396 } 00397 00398 // ------------------------------------------------------------ 00399 // Main program 00400 // ------------------------------------------------------------ 00401 00402 int main(int argc, char **argv) 00403 { 00404 // Create Ivf++ application object. 00405 00406 CIvfApplicationPtr app = new CIvfApplication(IVF_DOUBLE|IVF_RGB); 00407 00408 // Create a window 00409 00410 CExampleWindowPtr window = new CExampleWindow(0, 0, 512, 512); 00411 00412 // Set window title and show window 00413 00414 window->setWindowTitle("Ivf++ Lighting example"); 00415 window->show(); 00416 00417 // Enter main application loop 00418 00419 app->run(); 00420 00421 return 0; 00422 }