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