1 #ifndef __Dot3Bump_H__ 2 #define __Dot3Bump_H__ 3 4 #include "SdkSample.h" 5 6 using namespace Ogre; 7 using namespace OgreBites; 8 9 class _OgreSampleClassExport Sample_Dot3Bump : public SdkSample 10 { 11 public: 12 Sample_Dot3Bump()13 Sample_Dot3Bump() 14 : mMoveLights (true) 15 { 16 mInfo["Title"] = "Bump Mapping"; 17 mInfo["Description"] = "Shows how to use the dot product blending operation and normalization cube map " 18 "to achieve a bump mapping effect. Tangent space computations made through the guide of the tutorial " 19 "on bump mapping from http://users.ox.ac.uk/~univ1234 by paul.baker@univ.ox.ac.uk."; 20 mInfo["Thumbnail"] = "thumb_bump.png"; 21 mInfo["Category"] = "Lighting"; 22 mInfo["Help"] = "Left click and drag anywhere in the scene to look around. Let go again to show " 23 "cursor and access widgets. Use WASD keys to move."; 24 } 25 getRequiredPlugins()26 StringVector getRequiredPlugins() 27 { 28 StringVector names; 29 if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl")) 30 names.push_back("Cg Program Manager"); 31 return names; 32 } 33 testCapabilities(const RenderSystemCapabilities * caps)34 void testCapabilities(const RenderSystemCapabilities* caps) 35 { 36 if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM))) 37 { 38 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment programs, " 39 "so you cannot run this sample. Sorry!", "Dot3BumpSample::testCapabilities"); 40 } 41 42 if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") && 43 !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") && 44 !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0") && 45 !GpuProgramManager::getSingleton().isSyntaxSupported("glsl") && 46 !GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) 47 { 48 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model needed for this sample, " 49 "so you cannot run this sample. Sorry!", "Dot3BumpSample::testCapabilities"); 50 } 51 } 52 frameRenderingQueued(const FrameEvent & evt)53 bool frameRenderingQueued(const FrameEvent& evt) 54 { 55 if (mMoveLights) 56 { 57 // rotate the light pivots 58 mLightPivot1->roll(Degree(evt.timeSinceLastFrame * 30)); 59 mLightPivot2->roll(Degree(evt.timeSinceLastFrame * 10)); 60 } 61 62 return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! 63 } 64 itemSelected(SelectMenu * menu)65 void itemSelected(SelectMenu* menu) 66 { 67 if (menu == mMeshMenu) 68 { 69 // change to the selected entity 70 mObjectNode->detachAllObjects(); 71 mObjectNode->attachObject(mSceneMgr->getEntity(mMeshMenu->getSelectedItem())); 72 73 // remember which material is currently selected 74 int index = std::max<int>(0, mMaterialMenu->getSelectionIndex()); 75 76 // update the material menu's options 77 mMaterialMenu->setItems(mPossibilities[mMeshMenu->getSelectedItem()]); 78 79 mMaterialMenu->selectItem(index); // select the material with the saved index 80 } 81 else 82 { 83 // set the selected material for the active mesh 84 ((Entity*)mObjectNode->getAttachedObject(0))->setMaterialName(menu->getSelectedItem()); 85 } 86 } 87 checkBoxToggled(CheckBox * box)88 void checkBoxToggled(CheckBox* box) 89 { 90 if (StringUtil::startsWith(box->getName(), "Light", false)) 91 { 92 // get the light pivot that corresponds to this checkbox 93 SceneNode* pivot = box->getName() == "Light1" ? mLightPivot1 : mLightPivot2; 94 SceneNode::ObjectIterator it = pivot->getAttachedObjectIterator(); 95 96 while (it.hasMoreElements()) // toggle visibility of light and billboard set 97 { 98 MovableObject* o = it.getNext(); 99 o->setVisible(box->isChecked()); 100 } 101 102 } 103 else if (box->getName() == "MoveLights") 104 { 105 mMoveLights = !mMoveLights; 106 } 107 } 108 109 protected: 110 setupContent()111 void setupContent() 112 { 113 // create our main node to attach our entities to 114 mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 115 116 setupModels(); 117 setupLights(); 118 setupControls(); 119 120 mCamera->setPosition(0, 0, 500); 121 122 #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS 123 setDragLook(true); 124 #endif 125 } 126 127 128 loadResources()129 void loadResources() 130 { 131 #ifdef INCLUDE_RTSHADER_SYSTEM 132 Ogre::StringVector groupVector = Ogre::ResourceGroupManager::getSingleton().getResourceGroups(); 133 Ogre::StringVector::iterator itGroup = groupVector.begin(); 134 Ogre::StringVector::iterator itGroupEnd = groupVector.end(); 135 Ogre::String shaderCoreLibsPath; 136 137 138 for (; itGroup != itGroupEnd; ++itGroup) 139 { 140 Ogre::ResourceGroupManager::LocationList resLocationsList = Ogre::ResourceGroupManager::getSingleton().getResourceLocationList(*itGroup); 141 Ogre::ResourceGroupManager::LocationList::iterator it = resLocationsList.begin(); 142 Ogre::ResourceGroupManager::LocationList::iterator itEnd = resLocationsList.end(); 143 bool coreLibsFound = false; 144 145 // Find the location of the core shader libs 146 for (; it != itEnd; ++it) 147 { 148 if ((*it)->archive->getName().find("RTShaderLib") != Ogre::String::npos) 149 { 150 shaderCoreLibsPath = (*it)->archive->getName() + "/"; 151 coreLibsFound = true; 152 break; 153 } 154 } 155 156 // Core libs path found in the current group. 157 if (coreLibsFound) 158 break; 159 } 160 161 #endif 162 } 163 unloadResources()164 void unloadResources() 165 { 166 167 } 168 setupModels()169 void setupModels() 170 { 171 StringVector matNames; 172 173 matNames.push_back("Examples/BumpMapping/MultiLight"); 174 matNames.push_back("Examples/BumpMapping/MultiLightSpecular"); 175 matNames.push_back("Examples/OffsetMapping/Specular"); 176 matNames.push_back("Examples/ShowUV"); 177 matNames.push_back("Examples/ShowNormals"); 178 matNames.push_back("Examples/ShowTangents"); 179 180 #ifdef INCLUDE_RTSHADER_SYSTEM 181 matNames.push_back("RTSS/NormalMapping_SinglePass"); 182 matNames.push_back("RTSS/NormalMapping_MultiPass"); 183 #endif 184 185 186 mPossibilities["ogrehead.mesh"] = matNames; 187 mPossibilities["knot.mesh"] = matNames; 188 189 matNames.clear(); 190 matNames.push_back("Examples/Athene/NormalMapped"); 191 matNames.push_back("Examples/Athene/NormalMappedSpecular"); 192 matNames.push_back("Examples/Athene/NormalMappedSpecular"); 193 matNames.push_back("Examples/ShowUV"); 194 matNames.push_back("Examples/ShowNormals"); 195 matNames.push_back("Examples/ShowTangents"); 196 #ifdef INCLUDE_RTSHADER_SYSTEM 197 matNames.push_back("RTSS/Athene/NormalMapping_SinglePass"); 198 matNames.push_back("RTSS/Athene/NormalMapping_MultiPass"); 199 #endif 200 201 mPossibilities["athene.mesh"] = matNames; 202 203 for (std::map<String, StringVector>::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) 204 { 205 // load each mesh with non-default hardware buffer usage options 206 MeshPtr mesh = MeshManager::getSingleton().load(it->first, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 207 HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); 208 209 // build tangent vectors for our mesh 210 unsigned short src, dest; 211 if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) 212 { 213 mesh->buildTangentVectors(VES_TANGENT, src, dest); 214 // this version cleans mirrored and rotated UVs but requires quality models 215 // mesh->buildTangentVectors(VES_TANGENT, src, dest, true, true); 216 } 217 218 // create an entity from the mesh and set the first available material 219 Entity* ent = mSceneMgr->createEntity(mesh->getName(), mesh->getName()); 220 ent->setMaterialName(it->second.front()); 221 } 222 } 223 setupLights()224 void setupLights() 225 { 226 mSceneMgr->setAmbientLight(ColourValue::Black); // disable ambient lighting 227 228 // create pivot nodes 229 mLightPivot1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 230 mLightPivot2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 231 232 Light* l; 233 BillboardSet* bbs; 234 235 // create white light 236 l = mSceneMgr->createLight(); 237 l->setPosition(200, 0, 0); 238 l->setDiffuseColour(1, 1, 1); 239 l->setSpecularColour(1, 1, 1); 240 // create white flare 241 bbs = mSceneMgr->createBillboardSet(); 242 bbs->setMaterialName("Examples/Flare"); 243 bbs->createBillboard(200, 0, 0)->setColour(ColourValue::White); 244 245 mLightPivot1->attachObject(l); 246 mLightPivot1->attachObject(bbs); 247 248 // create red light 249 l = mSceneMgr->createLight(); 250 l->setPosition(40, 200, 50); 251 l->setDiffuseColour(1, 0, 0); 252 l->setSpecularColour(1, 0.8, 0.8); 253 // create white flare 254 bbs = mSceneMgr->createBillboardSet(); 255 bbs->setMaterialName("Examples/Flare"); 256 bbs->createBillboard(50, 200, 50)->setColour(ColourValue::Red); 257 258 mLightPivot2->attachObject(l); 259 mLightPivot2->attachObject(bbs); 260 } 261 setupControls()262 void setupControls() 263 { 264 mTrayMgr->showCursor(); 265 266 // make room for the controls 267 mTrayMgr->showLogo(TL_TOPRIGHT); 268 mTrayMgr->showFrameStats(TL_TOPRIGHT); 269 mTrayMgr->toggleAdvancedFrameStats(); 270 271 // create a menu to choose the model displayed 272 mMeshMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Mesh", "Mesh", 370, 290, 10); 273 for (std::map<String, StringVector>::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) 274 mMeshMenu->addItem(it->first); 275 276 // create a menu to choose the material used by the model 277 mMaterialMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Material", "Material", 370, 290, 10); 278 279 // create checkboxes to toggle lights 280 mTrayMgr->createCheckBox(TL_TOPLEFT, "Light1", "Light A")->setChecked(true, false); 281 mTrayMgr->createCheckBox(TL_TOPLEFT, "Light2", "Light B")->setChecked(true, false); 282 mTrayMgr->createCheckBox(TL_TOPLEFT, "MoveLights", "Move Lights")->setChecked(true, false); 283 284 // a friendly reminder 285 StringVector names; 286 names.push_back("Help"); 287 mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); 288 289 mMeshMenu->selectItem(0); // select first mesh 290 } 291 cleanupContent()292 void cleanupContent() 293 { 294 // clean up properly to avoid interfering with subsequent samples 295 for (std::map<String, StringVector>::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) 296 MeshManager::getSingleton().unload(it->first); 297 mPossibilities.clear(); 298 } 299 300 std::map<String, StringVector> mPossibilities; 301 SceneNode* mObjectNode; 302 SceneNode* mLightPivot1; 303 SceneNode* mLightPivot2; 304 bool mMoveLights; 305 SelectMenu* mMeshMenu; 306 SelectMenu* mMaterialMenu; 307 }; 308 309 #endif 310