Example #1
0
	Color Renderer::rayTraceRecursive(Shape* scene, Ray& ray, Lights& lights, int maxReflect) {
		IntersectResult result;
		scene->Intersect(ray, &result);
		if (result.geometry) {
			Material* pMaterial = result.geometry->material;
			float reflectiveness = pMaterial->reflectiveness;
			Color color(0, 0, 0);
			std::mt19937 eng(4029349);
			std::uniform_real_distribution<float> fraction_dist;
			for (int i = 0; i < lights.size(); i++) {
				Light* pLight = lights[i];
				Color c;
				if (!pLight->shadow) {
					//no shadow
					Vector3dF incidenceNormal = pLight->incidenceNormal(result.position);
					c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal);
				} else if (pLight->softshadow) {
					Vector3dF incidenceCenter = pLight->incidence(result.position);
					Vector3dF incidenceNormal = incidenceCenter.Normalize();
					Vector3dF rayNormal(-incidenceCenter.y, incidenceCenter.x, 0);
					rayNormal = rayNormal.Normalize();
					float disToLight = 0;
					if (pLight->lightType == LightType_Point) {
						disToLight = (dynamic_cast<PointLight*>(pLight)->pos - result.position).Length();
					}
					int hitTimes = 0;
					int raysPerFan = pLight->shadowrays / 4;
					for (int quadrant = 0; quadrant < 4; quadrant++) {
						for (int r = 0; r < raysPerFan; r++) {
							float angle = quadrant * 90.0f + fraction_dist(eng) * 90.f;
							float dis = fraction_dist(eng) * pLight->radius;
							//printf("<%.1f, %.1f> ", angle, dis);
							Vector3dF d = rayNormal.rotate(incidenceNormal, PI * angle / 180.f);
							Ray shadowrays(result.position, (-incidenceCenter) + d * dis);
							shadowrays.d = shadowrays.d.Normalize();
							IntersectResult _result;
							scene->Intersect(shadowrays, &_result);
							if (_result.geometry) {
								if (disToLight && _result.distance >= disToLight) {
									continue;
								}
								hitTimes++;
							}
						}
						//printf("\n");
					}
					//printf("\n");
					c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal);
					if (hitTimes > 0) {
						//printf("%d\n", hitTimes);
						float black_ratio = hitTimes / (float)pLight->shadowrays;
						//c = c * ( 1.0f - black_ratio) + Color::Black * black_ratio;
						c = c.Modulate(Color::White * (1.0f - black_ratio));
						c = c.clamp();
					}
				}
				else {
					//normal shadow
					Vector3dF incidenceNormal = pLight->incidenceNormal(result.position);
					//Is this light visible 
					Ray shadowrays(result.position, -incidenceNormal);
					IntersectResult _result;
					scene->Intersect(shadowrays, &_result);
					bool canSample = true;
					if (_result.geometry) {
						if (pLight->lightType == LightType_Point) {
							float disToLight = (dynamic_cast<PointLight*>(pLight)->pos - result.position).Length();
							if (disToLight >= _result.distance) {
								canSample = false;
								c = Color::Black;
							}
						}
						else if (pLight->lightType == LightType_Direction) {
							canSample = false;
							c = Color::Black;
						}
					}
					if(canSample){
						c = pMaterial->Sample(ray, result.position, result.normal, incidenceNormal);
					}
				}
				color = color + c;
			}
			color = Color(color * (1.0f - reflectiveness));

			if (reflectiveness > 0 && maxReflect > 0) {
				Vector3dF r = Vector3dF(result.normal * (-2 * (result.normal.Dot(ray.d))) + ray.d);
				Ray new_ray(result.position, r);
				Color reflectedColor = rayTraceRecursive(scene, new_ray, lights, maxReflect - 1);
				assert(reflectedColor.r() >= 0 && reflectedColor.g() >= 0 && reflectedColor.b() >= 0);
				color = color + reflectedColor * reflectiveness;
			}
			return color;
		}
		else
			return Color::Black;
	}
Example #2
0
void DotSceneLoader::processLight(TiXmlElement *XMLNode, SceneNode *pParent)
{
    // Process attributes
    String name = getAttrib(XMLNode, "name");
    String id = getAttrib(XMLNode, "id");

    // Create the light
    Light *pLight = mSceneMgr->createLight(name);
    if(pParent)
        pParent->attachObject(pLight);

    String sValue = getAttrib(XMLNode, "type");
    if(sValue == "point")
        pLight->setType(Light::LT_POINT);
    else if(sValue == "directional")
        pLight->setType(Light::LT_DIRECTIONAL);
    else if(sValue == "spot")
        pLight->setType(Light::LT_SPOTLIGHT);
    else if(sValue == "radPoint")
        pLight->setType(Light::LT_POINT);

    pLight->setVisible(getAttribBool(XMLNode, "visible", true));
    pLight->setCastShadows(getAttribBool(XMLNode, "castShadows", true));

    TiXmlElement *pElement;

    // Process position (?)
    pElement = XMLNode->FirstChildElement("position");
    if(pElement)
        pLight->setPosition(parseVector3(pElement));

    // Process normal (?)
    pElement = XMLNode->FirstChildElement("normal");
    if(pElement)
        pLight->setDirection(parseVector3(pElement));

    // Process colourDiffuse (?)
    pElement = XMLNode->FirstChildElement("colourDiffuse");
    if(pElement)
        pLight->setDiffuseColour(parseColour(pElement));

    // Process colourSpecular (?)
    pElement = XMLNode->FirstChildElement("colourSpecular");
    if(pElement)
        pLight->setSpecularColour(parseColour(pElement));

    // Process lightRange (?)
    pElement = XMLNode->FirstChildElement("lightRange");
    if(pElement)
        processLightRange(pElement, pLight);

    // Process lightAttenuation (?)
    pElement = XMLNode->FirstChildElement("lightAttenuation");
    if(pElement)
        processLightAttenuation(pElement, pLight);

    // Process userDataReference (?)
    pElement = XMLNode->FirstChildElement("userDataReference");
    if(pElement)
        ;//processUserDataReference(pElement, pLight);
}
// single frame code
int ClientGame::runGameFrame()
{
    // Frame Start ---------------------------------------------------------
    float gameTimeBetweenFrames = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds(); // time spent in ios before resuming this thread
    float gameThreadPreDrawFrameTime = 0;
	float gameThreadDrawFrameTime = 0;
	float gameThreadDrawWaitFrameTime = 0;

	// cache root scene node pointer
    RootSceneNode *proot = RootSceneNode::Instance();
    
    //Start Logging events for this frame if requested
    if(m_pContext->getLog()->m_activateOnNextFrame)
    {
        m_pContext->getLog()->m_isActivated = true;
        m_pContext->getLog()->m_activateOnNextFrame = false;
    }
    
    // CLOSED_WINDOW event will be pushed into global event queue if user closes window after this call
    m_pContext->getApplication()->processOSEventsIntoGlobalEventQueue();
    
    //Create Physics Events
    {
        Handle hphysStartEvent("EVENT", sizeof(Event_PHYSICS_START));
        Event_PHYSICS_START *physStartEvent = new(hphysStartEvent) Event_PHYSICS_START ;
        
        physStartEvent->m_frameTime = m_frameTime;
        Events::EventQueueManager::Instance()->add(hphysStartEvent, Events::QT_GENERAL);
    }
    // Create UPDATE event
    {
        Handle hupdateEvent("EVENT", sizeof(Event_UPDATE));
        Event_UPDATE *updateEvent = new(hupdateEvent) Event_UPDATE ;
        
        updateEvent->m_frameTime = m_frameTime;
        
        //Push UPDATE event onto general queue
        Events::EventQueueManager::Instance()->add(hupdateEvent, Events::QT_GENERAL);
    }
    // Create SCENE_GRAPH_UPDATE event 
    {
        Handle hsgUpdateEvent("EVENT", sizeof(Event_SCENE_GRAPH_UPDATE));
        Event_SCENE_GRAPH_UPDATE *sgUpdateEvent = new(hsgUpdateEvent) Event_SCENE_GRAPH_UPDATE ;
        
        sgUpdateEvent->m_frameTime = m_frameTime;
        //Push event into general queue
        Events::EventQueueManager::Instance()->add(hsgUpdateEvent, Events::QT_GENERAL);
    }
    
    //Assign camera
    Handle hCam = CameraManager::Instance()->getActiveCameraHandle();
    CameraSceneNode *pcam = CameraManager::Instance()->getActiveCamera()->getCamSceneNode();
    
    // Push Event_CALCULATE_TRANSFORMATIONS
    {
        Handle hctevt("EVENT", sizeof(Event_CALCULATE_TRANSFORMATIONS));
        /*Event_CALCULATE_TRANSFORMATIONS *ctevt = */ new(hctevt) Event_CALCULATE_TRANSFORMATIONS ;
        
        Events::EventQueueManager::Instance()->add(hctevt, Events::QT_GENERAL);
    }

    
    // Process general events (Draw, Update, Calculate transformations...)
    Handle gqh = Events::EventQueueManager::Instance()->getEventQueueHandle("general");
    while (!gqh.getObject<Events::EventQueue>()->empty())
    {
        Events::Event *pGeneralEvt = gqh.getObject<Events::EventQueue>()->getFront();
        // this code is in process of conversion to new event style
        // first use new method then old (switch)
        if (Event_UPDATE::GetClassId() == pGeneralEvt->getClassId())
        {
            // UPDATE
            // Update game objects
            m_pContext->getGameObjectManager()->handleEvent(pGeneralEvt);
        }
        else if (Event_CALCULATE_TRANSFORMATIONS::GetClassId() == pGeneralEvt->getClassId())
        {
            
            // for all scene objects to calculate their absolute (world) transformations
            // for skins to calculate their matrix palettes
            proot->handleEvent(pGeneralEvt);
            
            //SkyVolume::Instance()->handleEvent(pGeneralEvt);
            
            // Generate Drawing Events

			// Push Event_PRE_GATHER_DRAWCALLS
			{
				Handle hctevt("EVENT", sizeof(Event_PRE_GATHER_DRAWCALLS));
				Event_PRE_GATHER_DRAWCALLS *ctevt =  new(hctevt) Event_PRE_GATHER_DRAWCALLS ;
        
				PE::Events::EventQueueManager::Instance()->add(hctevt, Events::QT_GENERAL);

				ctevt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform;
				ctevt->m_eyePos = pcam->m_worldTransform.getPos();
				
			}

            {
                Handle hdrawZOnlyEvt("EVENT", sizeof(Event_GATHER_DRAWCALLS_Z_ONLY));
                Event_GATHER_DRAWCALLS_Z_ONLY *drawZOnlyEvt = new(hdrawZOnlyEvt) Event_GATHER_DRAWCALLS_Z_ONLY ;
                
                drawZOnlyEvt->m_pZOnlyDrawListOverride = 0;

				RootSceneNode *pRoot = RootSceneNode::Instance();

				if (pRoot->m_lights.m_size)
				{
					PrimitiveTypes::Bool foundShadower = false;
					for(PrimitiveTypes::UInt32 i=0; i<(pRoot->m_lights.m_size); i++){
						Light *pLight = pRoot->m_lights[i].getObject<Light>();
						if(pLight->castsShadow()){

							drawZOnlyEvt->m_projectionViewTransform = (pLight->m_viewToProjectedTransform * pLight->m_worldToViewTransform);
							drawZOnlyEvt->m_eyePos = pLight->m_base.getPos();
							foundShadower=true;
							break;
						}
						if(!foundShadower){
							drawZOnlyEvt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform;
							drawZOnlyEvt->m_eyePos = pcam->m_worldTransform.getPos();
						}
					}
				}
				else
				{
					drawZOnlyEvt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform;
					drawZOnlyEvt->m_eyePos = pcam->m_worldTransform.getPos();
				}
                drawZOnlyEvt->m_parentWorldTransform.loadIdentity();
                Events::EventQueueManager::Instance()->add(hdrawZOnlyEvt);
            }
            
            // After the transformations are done. We can put a DRAW event in the queue
            // Push DRAW event into message queue because camera has updated transformations
            {
                Handle hdrawEvt("EVENT", sizeof(Event_GATHER_DRAWCALLS));
                Event_GATHER_DRAWCALLS *drawEvt = new(hdrawEvt) Event_GATHER_DRAWCALLS(m_pContext->m_gameThreadThreadOwnershipMask) ;
                
                drawEvt->m_frameTime = m_frameTime;
                drawEvt->m_gameTime = m_gameTime;
                
                drawEvt->m_drawOrder = EffectDrawOrder::First;
                
                //Camera *pcam = hcam.getObject<Camera>();
                drawEvt->m_projectionViewTransform = pcam->m_viewToProjectedTransform * pcam->m_worldToViewTransform;

                drawEvt->m_eyePos = pcam->m_worldTransform.getPos();
				drawEvt->m_projectionTransform = pcam->m_viewToProjectedTransform;
				drawEvt->m_eyeDir = pcam->m_worldTransform.getN();
                drawEvt->m_parentWorldTransform.loadIdentity();
                drawEvt->m_viewInvTransform = pcam->m_worldToViewTransform.inverse();
                
				//Commented out by Mac because I'm pretty sure this does nothing but am afraid to delete it...
				static bool setCameraAsLightSource = false;
				RootSceneNode *pRoot = RootSceneNode::Instance();
				if (setCameraAsLightSource && pRoot->m_lights.m_size)
				{
					Light *pLight = pRoot->m_lights[0].getObject<Light>();

					drawEvt->m_projectionViewTransform = (pLight->m_viewToProjectedTransform * pLight->m_worldToViewTransform);
					drawEvt->m_eyePos = pLight->m_base.getPos();
				}
				
                Events::EventQueueManager::Instance()->add(hdrawEvt);
            }
            
            {
                Handle hphysicsEndEvt("EVENT", sizeof(Event_PHYSICS_END));
                /*Event_PHYSICS_END *physicsEndEvt = */ new(hphysicsEndEvt) Event_PHYSICS_END ;
                
                Events::EventQueueManager::Instance()->add(hphysicsEndEvt);
            }
            
        }

		else if (Event_PRE_GATHER_DRAWCALLS::GetClassId() == pGeneralEvt->getClassId())
        {
			proot->handleEvent(pGeneralEvt);
		}
        
        else if (Event_GATHER_DRAWCALLS::GetClassId() == pGeneralEvt->getClassId()
			|| Event_GATHER_DRAWCALLS_Z_ONLY::GetClassId() == pGeneralEvt->getClassId())
        {
			bool zOnly = Event_GATHER_DRAWCALLS_Z_ONLY::GetClassId() == pGeneralEvt->getClassId();
			
            Event_GATHER_DRAWCALLS *pDrawEvent = NULL;
			Event_GATHER_DRAWCALLS_Z_ONLY *pDrawZOnlyEvent = NULL;
			if (zOnly)
			{
				pDrawZOnlyEvent = (Event_GATHER_DRAWCALLS_Z_ONLY *)(pGeneralEvt);
				DrawList::ZOnlyInstance()->reset();

			}
			else
			{
				pDrawEvent = (Event_GATHER_DRAWCALLS *)(pGeneralEvt);
				DrawList::Instance()->reset();
			}

			if (pDrawEvent)
				EffectManager::Instance()->m_currentViewProjMatrix = pDrawEvent->m_projectionViewTransform;
          
			// Draw 1st order
			proot->handleEvent(pGeneralEvt);

			// for non z only we do several draw order passes
			if (pDrawEvent)
			{
				/*
				// Manual draw pass
				pDrawEvent->m_drawOrder = EffectDrawOrder::Manual;
			
				// Draw SkyVolume
				//SkyVolume::Instance()->handleEvent(pGeneralEvt);
				*/

				EffectManager::Instance()->m_doMotionBlur = true;

				// Draw Last order
				pDrawEvent->m_drawOrder = EffectDrawOrder::Last;
			
				proot->handleEvent(pGeneralEvt);
			}

			// this code will make sure draw thread know we are done
			// only do it for DRAW event since is last draw event
			// and in case we don't do multithreading, we just execute the draw thread function

			if (!zOnly)
			{
				gameThreadPreDrawFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds();

				static bool s_RenderOnGameThread = false; // if this is true, render thread will never wake up

				#if PYENGINE_2_0_MULTI_THREADED
					g_drawThreadLock.lock(); // wait till previous draw is finished
					//PEINFO("Game thread got g_drawThreadLock\n");
				#endif

				// this thread now can have control of rendering context for a little bit
				// we will pass down this variable to different functions to let them know that we have both contexts
				m_pContext->getGPUScreen()->AcquireRenderContextOwnership(m_pContext->m_gameThreadThreadOwnershipMask);
				 
				gameThreadDrawWaitFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds();
				
				#if PE_ENABLE_GPU_PROFILING
					// finalize results of gpu profiling. we want to do it in this thread to avoid race condition
					// since we are accessing debug renderer. 
					Profiling::Profiler::Instance()->finalize(Profiling::Group_DrawCalls);
					Profiling::Profiler::Instance()->finalize(Profiling::Group_DrawThread);
				#endif

                PE::IRenderer::checkForErrors("");

				// send this event to objects so that they have ability to work with graphics resources
				// since this thread has ownership of dx thread
				Event_PRE_RENDER_needsRC preRenderEvt(m_pContext->m_gameThreadThreadOwnershipMask);
				m_pContext->getGameObjectManager()->handleEvent(&preRenderEvt);
				proot->handleEvent(&preRenderEvt);
				
                PE::IRenderer::checkForErrors("");

				//FPS
				{
					float fps = (1.0f/m_frameTime);
					sprintf(PEString::s_buf, "%.2f FPS", fps);
					DebugRenderer::Instance()->createTextMesh(
						PEString::s_buf, true, false, false, false, 0, 
						Vector3(.75f, .05f, 0), 1.0f, m_pContext->m_gameThreadThreadOwnershipMask);
				}

                PE::IRenderer::checkForErrors("");

				//LUA Command Server, Server
				PE::GameContext *pServer = &PE::Components::ServerGame::s_context;
				{
					sprintf(PEString::s_buf, "Lua Command Receiver Ports: Client: %d Server: %d", m_pContext->getLuaCommandServerPort(), pServer->getLuaEnvironment() ? pServer->getLuaCommandServerPort():0);
					DebugRenderer::Instance()->createTextMesh(
						PEString::s_buf, true, false, false, false, 0,
						Vector3(.0f, .05f, 0), 1.0f, m_pContext->m_gameThreadThreadOwnershipMask);
				}

                PE::IRenderer::checkForErrors("");

				if (pServer->getLuaEnvironment()) // check if server context was initialized
				{
					ServerNetworkManager *pServerNetw = (ServerNetworkManager*)(pServer->getNetworkManager());
					pServerNetw->debugRender(m_pContext->m_gameThreadThreadOwnershipMask, 0, .1f);
				}
                
                PE::IRenderer::checkForErrors("");

				{
					ClientNetworkManager* pClientNetworkManager = (ClientNetworkManager* )(m_pContext->getNetworkManager());
					pClientNetworkManager->debugRender(m_pContext->m_gameThreadThreadOwnershipMask, 0.5f, .1f);
				}
                
                PE::IRenderer::checkForErrors("");

				//gameplay timer
				{
					sprintf(PEString::s_buf, "GT frame wait:%.3f pre-draw:%.3f+render wait:%.3f+render:%.3f+post-render:%.3f = %.3f sec\n", m_gameTimeBetweenFrames, m_gameThreadPreDrawFrameTime, m_gameThreadDrawWaitFrameTime, m_gameThreadDrawFrameTime, m_gameThreadPostDrawFrameTime, m_frameTime);
					DebugRenderer::Instance()->createTextMesh(
						PEString::s_buf, true, false, false, false, 0,
						Vector3(.0f, .075f, 0), 1.0f, m_pContext->m_gameThreadThreadOwnershipMask);
				}
				
				//debug draw root and grid
				DebugRenderer::Instance()->createRootLineMesh();// send event while the array is on the stack

				// call this to potentially generate meshes that were scheduled in debug draw of lines
				DebugRenderer::Instance()->postPreDraw(m_pContext->m_gameThreadThreadOwnershipMask);

                PE::IRenderer::checkForErrors("");

				// done synchronization, give RC back
				m_pContext->getGPUScreen()->ReleaseRenderContextOwnership(m_pContext->m_gameThreadThreadOwnershipMask);
				
				DrawList::swap();

				#if PYENGINE_2_0_MULTI_THREADED
					if (!s_RenderOnGameThread) // this variable will dynamically keep other thread waiting
						g_drawThreadCanStart = true;
					else
						runDrawThreadSingleFrame(*m_pContext); // tun on game thread
					//PEINFO("Game thread releasing g_drawThreadLock\n");
					g_drawThreadLock.unlock(); // release render thread lock
					g_drawCanStartCV.signal();
				#else
					runDrawThreadSingleFrame(*m_pContext);
				#endif

				gameThreadDrawFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds();
			}
        }
        else if (Event_FLY_CAMERA::GetClassId() == pGeneralEvt->getClassId())
        {
            Event_FLY_CAMERA *pRealEvent = (Event_FLY_CAMERA *)(pGeneralEvt);
            pcam->m_base.moveForward(pRealEvent->m_relativeMove.getZ());
            pcam->m_base.moveRight(pRealEvent->m_relativeMove.getX());
            pcam->m_base.moveUp(pRealEvent->m_relativeMove.getY());
        }
        else if (Event_ROTATE_CAMERA::GetClassId() == pGeneralEvt->getClassId())
        {
            Event_ROTATE_CAMERA *pRealEvent = (Event_ROTATE_CAMERA *)(pGeneralEvt);
            pcam->m_base.turnUp(pRealEvent->m_relativeRotate.getY());
            pcam->m_base.turnAboutAxis(-pRealEvent->m_relativeRotate.getX(), RootSceneNode::Instance()->m_worldTransform.getV());
        }
        else if (Event_CLOSED_WINDOW::GetClassId() == pGeneralEvt->getClassId())
        {
            m_runGame = false;
			break;
        }
        else if (Event_SCENE_GRAPH_UPDATE::GetClassId() == pGeneralEvt->getClassId())
        {
            // this event is meant for scene graph
            proot->handleEvent(pGeneralEvt);
        }
        else if (Event_PHYSICS_END::GetClassId() == pGeneralEvt->getClassId())
        {
#ifdef PYENGINE_USE_PHYSX
            // Try fetching data here.. if not available yet, set some flag, so tht on next PHYSICS_START we dont run simulate
            runPhysXSim = Physics::GetResults();
#endif
        }
        else if (Event_PHYSICS_START::GetClassId() == pGeneralEvt->getClassId())
        {
#ifdef PYENGINE_USE_PHYSX
            Physics::UpdateControllers();
            Physics::UpdateKinematics();
            Physics::UpdateForceFields(frameTime);
            // Update Simulation
            Physics::Update(frameTime);
            // game object's event handlers will synch back to physx actors in this call
            GameObjectManager::Instance()->handleEvent(pGeneralEvt);
#endif
        }
#ifdef PYENGINE_USE_PHYSX
        else if (Event_PHYSICS_COLLISION::GetClassId() == pGeneralEvt->getClassId())
        {
            GameObjectManager::Instance()->handleEvent(pGeneralEvt);
        }
#endif
        else
        {
            // unknown event
            // pass it to both game object manager and scene graph
            
           m_pContext->getGameObjectManager()->handleEvent(pGeneralEvt);
            proot->handleEvent(pGeneralEvt);
            
        } // end of old event style handling
        
        gqh.getObject<Events::EventQueue>()->destroyFront();
    }
    
    // Events are destoryed by destroyFront() but this is called every frame just in case
    gqh.getObject<Events::EventQueue>()->destroy();
    
    // End of frame --------------------------------------------------------
    
    // add memory defragmentation here
    // after this all pointers must be recalculated from handles
    
    //Stop logging events for this frame if was requested to log in this frame
    m_pContext->getLog()->m_isActivated = false;
    
	float gameThreadPostDrawFrameTime = m_hTimer.getObject<Timer>()->TickAndGetTimeDeltaInSeconds();
    
	m_frameTime = gameTimeBetweenFrames + gameThreadPreDrawFrameTime + gameThreadDrawWaitFrameTime + gameThreadDrawFrameTime + gameThreadPostDrawFrameTime;
	
    if (m_frameTime > 10.0f)
        m_frameTime = 0.1f;
    m_gameTimeBetweenFrames = gameTimeBetweenFrames;
    m_gameThreadPreDrawFrameTime = gameThreadPreDrawFrameTime;
	m_gameThreadDrawWaitFrameTime = gameThreadDrawWaitFrameTime;
	m_gameThreadDrawFrameTime = gameThreadDrawFrameTime;
	m_gameThreadPostDrawFrameTime = gameThreadPostDrawFrameTime;

	m_gameTime += m_frameTime;

	if (!m_runGame)
	{
		PE::GameContext *pServer = &PE::Components::ServerGame::s_context;
		if (pServer->getGame())
		{
			((ServerGame *)(pServer->getGame()))->m_runGame = false;
		}

		// this is the last iteration of game thread, wait for all other threads to be done with current frame
		#if PYENGINE_2_0_MULTI_THREADED
			g_drawThreadLock.lock(); // wait till previous draw is finished
			g_drawThreadShouldExit = true;
			
			g_drawThreadLock.unlock(); // release render thread lock
			// wake up render thread
			g_drawCanStartCV.signal();
			
			while (!g_drawThreadExited)
			{
				//wait until the draw thread exits
			}
		#endif
	}

	m_pContext->getApplication()->exit(); // this will close the window
	return 0;

}
 void execute() const {
     _light->off();
 }
void SignedDistanceFieldText::CreateScene()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);

    // Create the Octree component to the scene. This is required before adding any drawable components, or else nothing will
    // show up. The default octree volume will be from (-1000, -1000, -1000) to (1000, 1000, 1000) in world coordinates; it
    // is also legal to place objects outside the volume but their visibility can then not be checked in a hierarchically
    // optimizing manner
    scene_->CreateComponent<Octree>();

    // Create a child scene node (at world origin) and a StaticModel component into it. Set the StaticModel to show a simple
    // plane mesh with a "stone" material. Note that naming the scene nodes is optional. Scale the scene node larger
    // (100 x 100 world units)
    Node* planeNode = scene_->CreateChild("Plane");
    planeNode->SetScale(Vector3(100.0f, 1.0f, 100.0f));
    StaticModel* planeObject = planeNode->CreateComponent<StaticModel>();
    planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl"));
    planeObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));

    // Create a directional light to the world so that we can see something. The light scene node's orientation controls the
    // light direction; we will use the SetDirection() function which calculates the orientation from a forward direction vector.
    // The light will use default settings (white light, no shadows)
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f)); // The direction vector does not need to be normalized
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);

    // Create more StaticModel objects to the scene, randomly positioned, rotated and scaled. For rotation, we construct a
    // quaternion from Euler angles where the Y angle (rotation about the Y axis) is randomized. The mushroom model contains
    // LOD levels, so the StaticModel component will automatically select the LOD level according to the view distance (you'll
    // see the model get simpler as it moves further away). Finally, rendering a large number of the same object with the
    // same material allows instancing to be used, if the GPU supports it. This reduces the amount of CPU work in rendering the
    // scene.
    const unsigned NUM_OBJECTS = 200;
    for (unsigned i = 0; i < NUM_OBJECTS; ++i)
    {
        Node* mushroomNode = scene_->CreateChild("Mushroom");
        mushroomNode->SetPosition(Vector3(Random(90.0f) - 45.0f, 0.0f, Random(90.0f) - 45.0f));
        mushroomNode->SetScale(0.5f + Random(2.0f));
        StaticModel* mushroomObject = mushroomNode->CreateComponent<StaticModel>();
        mushroomObject->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl"));
        mushroomObject->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml"));

        Node* mushroomTitleNode = mushroomNode->CreateChild("MushroomTitle");
        mushroomTitleNode->SetPosition(Vector3(0.0f, 1.2f, 0.0f));
        Text3D* mushroomTitleText = mushroomTitleNode->CreateComponent<Text3D>();
        mushroomTitleText->SetText("Mushroom " + String(i));
        mushroomTitleText->SetFont(cache->GetResource<Font>("Fonts/BlueHighway.sdf"), 24);

        mushroomTitleText->SetColor(Color::RED);
        
        if (i % 3 == 1)
        {
            mushroomTitleText->SetColor(Color::GREEN);
            mushroomTitleText->SetTextEffect(TE_SHADOW);
            mushroomTitleText->SetEffectColor(Color(0.5f, 0.5f, 0.5f));
        }
        else if (i % 3 == 2)
        {
            mushroomTitleText->SetColor(Color::YELLOW);
            mushroomTitleText->SetTextEffect(TE_STROKE);
            mushroomTitleText->SetEffectColor(Color(0.5f, 0.5f, 0.5f));
        }

        mushroomTitleText->SetAlignment(HA_CENTER, VA_CENTER);
    }

    // Create a scene node for the camera, which we will move around
    // The camera will use default settings (1000 far clip distance, 45 degrees FOV, set aspect ratio automatically)
    cameraNode_ = scene_->CreateChild("Camera");
    cameraNode_->CreateComponent<Camera>();

    // Set an initial position for the camera scene node above the plane
    cameraNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f));
}
void TextureLitMaterial::render(GameObject* pGameObject, Camera* pCamera) {
    if (!_diffuseTexture) return;

    _shader->use();

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _diffuseTexture->getId());
    glUniform1i (_diffMapLoc, 0);
    glUniform1f(_diffuseTilingLoc, _diffuseTiling);

    if (normalMap) {
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, _normalMapTexture->getId());
        glUniform1i (_normalMapLoc, 1);
        glUniform1f(_normalTilingLoc, _normalTiling);
    }

    if (specularMap) {
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_2D, _specularMapTexture->getId());
        glUniform1i (_specMapLoc, 2);
        glUniform1f(_specularTilingLoc, _specularTiling);
    }

    if (Renderer::getShadowDepthMapFar()) {
        glActiveTexture(GL_TEXTURE3);
        glBindTexture(GL_TEXTURE_2D, Renderer::getShadowDepthMapFar());
        glUniform1i (_depthMapLocFar, 3);
    }

    if (Renderer::getShadowDepthMapFar()) {
        glActiveTexture(GL_TEXTURE4);
        glBindTexture(GL_TEXTURE_2D, Renderer::getShadowDepthMapNear());
        glUniform1i (_depthMapLocNear, 4);
    }

    if (Renderer::getShadowDepthMapMid()) {
        glActiveTexture(GL_TEXTURE5);
        glBindTexture(GL_TEXTURE_2D, Renderer::getShadowDepthMapMid());
        glUniform1i (_depthMapLocMid, 5);
    }

	glUniform1f(_matSmoothLoc, _smoothness);
	glUniform1f(_matShineLoc, _shininess);
	glUniform1f(_matAmbLoc, _ambient);
    glUniform1f(_hasNormMapLoc, normalMap);
    glUniform1f(_hasSpecMapLoc, specularMap);

    //pass in light data
    int index = 0;

    DualLinkList<Light> list = Light::GetLightList();



    DualLinkNode<Light>* cn = list.startNode;

    //GLfloat near_plane = 1.0f, far_plane = 25.0f;

    while(cn!=NULL && index < MGE_MAX_LIGHTS)
    {
        Light* light = (Light*)cn;

        if(!light->IsActive())//do not render with inactive lights
        {
            cn = cn->nextNode;
            continue;
        }

        string indexString ="LightArray[" + std::to_string(index) + "]";
        GLuint loc;

        int lightType = light->getType();


        if (lightType == MGE_LIGHT_DIRECTIONAL)
        {
            loc = _shader->getUniformLocation(indexString + ".type");
            glUniform1i(loc,lightType);

            loc = _shader->getUniformLocation(indexString + ".color");
            glUniform3fv(loc,1,glm::value_ptr(light->getColor()));

            loc = _shader->getUniformLocation(indexString + ".direction");
            glUniform3fv(loc,1,glm::value_ptr(light->getDirection()));
            //loc = _shader->getUniformLocation(indexString + ".position");
            //glUniform3fv(loc,1,glm::value_ptr(light->getLocalPosition()));

            glm::mat4 lightProjection, lightView;
            lightView = Light::GetDirectionalViewMatrix();
            glm::mat4 lightSpaceMatrix;


            lightProjection = Renderer::GetFarShadowOrtho();
            lightSpaceMatrix = lightProjection * lightView;
            glUniformMatrix4fv(_lightMatLocFar, 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));

            lightProjection = Renderer::GetNearShadowOrtho();
            lightSpaceMatrix = lightProjection * lightView;
            glUniformMatrix4fv(_lightMatLocNear, 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));

            lightProjection = Renderer::GetMidShadowOrtho();
            lightSpaceMatrix = lightProjection * lightView;
            glUniformMatrix4fv(_lightMatLocMid, 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
            ++index;
        }
        else
        if ((!pGameObject->ignoreNonDirLights) && lightType == MGE_LIGHT_POINT)
        {
            glm::vec3 lightPos = light->getWorldPosition();
            float dist = glm::distance(lightPos, pGameObject->getWorldPosition());

            if(dist > light->getFalloff() + pGameObject->GetRenderBound().radius)
            {
                cn = cn->nextNode;
                continue;
            }

            loc = _shader->getUniformLocation(indexString + ".type");
            glUniform1i(loc,lightType);

            loc = _shader->getUniformLocation(indexString + ".color");
            glUniform3fv(loc,1,glm::value_ptr(light->getColor()));

            loc = _shader->getUniformLocation(indexString + ".position");
            glUniform3fv(loc,1,glm::value_ptr(lightPos));

            loc = _shader->getUniformLocation(indexString + ".attenuation");
            glUniform3fv(loc,1,glm::value_ptr(light->getAttenuation()));

            ++index;
        }
        //++index;
        cn = cn->nextNode;
    }

    glUniform1i(_shader->getUniformLocation("lightCount"),index);

	//set view pos
	glUniform3fv(_viewPosLoc, 1, glm::value_ptr(pCamera->getWorldPosition()));

	//color
	glUniform4fv(_colorLoc,1,glm::value_ptr(color));

    //pass in all MVP matrices separately
    glUniformMatrix4fv ( _projMatLoc,  1, GL_FALSE, glm::value_ptr(pCamera->getProjection()));
    glUniformMatrix4fv ( _viewMatLoc,  1, GL_FALSE, glm::value_ptr(pCamera->getView()));
    glUniformMatrix4fv ( _modelMatLoc, 1, GL_FALSE, glm::value_ptr(pGameObject->getWorldTransform()));


    //now inform mesh of where to stream its data
    pGameObject->getMesh()->streamToOpenGL(0, 1, 2, 3);

    //glGetError();

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, 0);
}
Example #7
0
int main(){
	try{
		ILogger::Init();
		Settings::Call().Parse();
		ResourceManager::Call().AddPath("Data/shaders", "Shader");
		ResourceManager::Call().AddPath("Data/textures", "Image");

		{
			Window myWindow;
			Image Crate;
			Texture CrateTexture;
			Text FPSText, MousePosText;
			Clock FrameClock, FpsClock;
		
			Input myInput;
			myInput.Init(myWindow);

			Renderer& myRenderer = Renderer::Call();
			myRenderer.Init(myWindow);
		
			Crate.LoadFromFile("crate.jpg");
			CrateTexture.LoadFromImage(Crate);

			Light l;
			l.SetPosition(Vector3F(1,3,1.5));
			l.SetDiffuse(Color(1.f,1.f,1.f));
			l.SetRange(8);

			Shader ColorShader;
			ColorShader.Compile("shaderColor.vs", "shaderColor.fs");
			ColorShader.Bind();
			ColorShader.SendColor("ambientColor", myRenderer.GetSpecifications().mAmbientColor);
			ColorShader.SendFloat("constantAtt", l.GetAttenuationConstant());
			ColorShader.SendFloat("linearAtt", l.GetAttenuationLinear());
			ColorShader.SendFloat("quadraticAtt", l.GetAttenuationQuadratic());
			ColorShader.SendFloat("range", l.GetRange());
	
			ColorShader.SendVector3("lightPosition", l.GetPosition());
			ColorShader.SendColor("lightColor", l.GetDiffuse());
			ColorShader.UnBind();

			Object obj1;
			obj1.MakeCube("cube", ColorShader);
			obj1.GetMaterial().mAmbient = Color(0.f, 0.08f, 0.08f);
			obj1.GetMaterial().mDiffuse = Color(0.f, 0.8f, 0.8f);
			obj1.GetMaterial().mSpecular = Color(0.0f, 0.5f, 0.5f);
			obj1.GetMaterial().mShininess = 50.f;

			Camera cam;
			cam.LookAt(Vector3F(0.5f,0,1), Vector3F(-2.5f,2,4));
		
			FPSText.SetSize(12);
			FPSText.SetPosition(10,10);
			MousePosText.SetSize(12);
			MousePosText.SetPosition(10,22);

			while(myWindow.IsOpened()){
				ElapsedTime = FrameClock.GetElapsedTime();
				FrameClock.Reset();

				if(FpsClock.GetElapsedTime() > 1.f){
					FPSText.SetText(String(1.f/ElapsedTime));
					FpsClock.Reset();
				}

			
				while(myInput.GetEvent()){
					if(myInput.GetEventType() == sf::Event::Closed)
						myWindow.Close();

					if(myInput.IsKeyHit(Space))
						if(!paused){
							paused = true;
							FrameClock.Pause();
						}else{
							paused = false;
							FrameClock.Resume();
						}
				}

				MousePosText.SetText(String("X : ")+myInput.GetMouseX()+" Y : "+myInput.GetMouseY());
			
				MousePosText.Draw();
				FPSText.Draw();
				obj1.Draw();

				myRenderer.BeginScene(myRenderer.GetSpecifications().mAmbientColor);
					myRenderer.Render();
				myRenderer.EndScene();
			}
		}
	}catch(Exception e){
		std::cout << e.what() << std::endl;
		system("PAUSE");
	}

	Renderer::Kill();
	ResourceManager::Kill();
	Settings::Kill();
	ILogger::Kill();
	#ifdef _DEBUG
		MemoryManager::Kill();
	#endif

    return 0;
}
Example #8
0
 void setCurrentStateAsBaseValue(void)
 {
     setAsBaseValue(mLight->getSpecularColour());
 }
Example #9
0
 void setValue(const Vector4& val)
 {
     mLight->setAttenuation(val.x, val.y, val.z, val.w);
 }
Example #10
0
 void setValue(const ColourValue& val)
 {
     mLight->setSpecularColour(val);
 }
Example #11
0
 void applyDeltaValue(const ColourValue& val)
 {
     setValue(mLight->getSpecularColour() + val);
 }
Example #12
0
 void setCurrentStateAsBaseValue(void)
 {
     setAsBaseValue(mLight->getDiffuseColour());
 }
Example #13
0
 void applyDeltaValue(const ColourValue& val)
 {
     setValue(mLight->getDiffuseColour() + val);
 }
Example #14
0
 void setValue(const ColourValue& val)
 {
     mLight->setDiffuseColour(val);
 }
Example #15
0
 void setCurrentStateAsBaseValue(void)
 {
     setAsBaseValue(mLight->getSpotlightFalloff());
 }
Example #16
0
 void applyDeltaValue(const Vector4& val)
 {
     setValue(mLight->getAs4DVector() + val);
 }
Example #17
0
    //-----------------------------------------------------------------------
    MovableObject* LightFactory::createInstanceImpl( const String& name, 
        const NameValuePairList* params)
    {

        Light* light = OGRE_NEW Light(name);
 
        if(params)
        {
            NameValuePairList::const_iterator ni;

            // Setting the light type first before any property specific to a certain light type
            if ((ni = params->find("type")) != params->end())
            {
                if (ni->second == "point")
                    light->setType(Light::LT_POINT);
                else if (ni->second == "directional")
                    light->setType(Light::LT_DIRECTIONAL);
                else if (ni->second == "spotlight")
                    light->setType(Light::LT_SPOTLIGHT);
                else
                    OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                        "Invalid light type '" + ni->second + "'.",
                        "LightFactory::createInstance");
            }

            // Common properties
            if ((ni = params->find("position")) != params->end())
                light->setPosition(StringConverter::parseVector3(ni->second));

            if ((ni = params->find("direction")) != params->end())
                light->setDirection(StringConverter::parseVector3(ni->second));

            if ((ni = params->find("diffuseColour")) != params->end())
                light->setDiffuseColour(StringConverter::parseColourValue(ni->second));

            if ((ni = params->find("specularColour")) != params->end())
                light->setSpecularColour(StringConverter::parseColourValue(ni->second));

            if ((ni = params->find("attenuation")) != params->end())
            {
                Vector4 attenuation = StringConverter::parseVector4(ni->second);
                light->setAttenuation(attenuation.x, attenuation.y, attenuation.z, attenuation.w);
            }

            if ((ni = params->find("castShadows")) != params->end())
                light->setCastShadows(StringConverter::parseBool(ni->second));

            if ((ni = params->find("visible")) != params->end())
                light->setVisible(StringConverter::parseBool(ni->second));

            if ((ni = params->find("powerScale")) != params->end())
                light->setPowerScale(StringConverter::parseReal(ni->second));

            if ((ni = params->find("shadowFarDistance")) != params->end())
                light->setShadowFarDistance(StringConverter::parseReal(ni->second));


            // Spotlight properties
            if ((ni = params->find("spotlightInner")) != params->end())
                light->setSpotlightInnerAngle(StringConverter::parseAngle(ni->second));

            if ((ni = params->find("spotlightOuter")) != params->end())
                light->setSpotlightOuterAngle(StringConverter::parseAngle(ni->second));

            if ((ni = params->find("spotlightFalloff")) != params->end())
                light->setSpotlightFalloff(StringConverter::parseReal(ni->second));
        }

        return light;
    }
Example #18
0
 void setCurrentStateAsBaseValue(void)
 {
     setAsBaseValue(mLight->getAs4DVector());
 }
Example #19
0
void TextureShader::render(RenderState* rstate,
        RenderData* render_data, Material* material) {
    Mesh* mesh = render_data->mesh();
    Texture* texture = material->getTexture("main_texture");
    glm::vec3 color = material->getVec3("color");
    float opacity = material->getFloat("opacity");
    glm::vec4 material_ambient_color = material->getVec4("ambient_color");
    glm::vec4 material_diffuse_color = material->getVec4("diffuse_color");
    glm::vec4 material_specular_color = material->getVec4("specular_color");
    float material_specular_exponent = material->getFloat("specular_exponent");

    if (texture->getTarget() != GL_TEXTURE_2D) {
        std::string error = "TextureShader::render : texture with wrong target.";
        throw error;
    }

    bool use_light = false;
    Light* light;
    if (render_data->light_enabled()) {
        light = render_data->light();
        if (light->enabled()) {
            use_light = true;
        }
    }

    mesh->generateVAO();

    if (use_light) {
        GL(glUseProgram(program_light_->id()));
    } else {
        GL(glUseProgram(program_no_light_->id()));
    }

    GL(glActiveTexture (GL_TEXTURE0));
    GL(glBindTexture(texture->getTarget(), texture->getId()));

    if (use_light) {
        glm::vec3 light_position = light->getVec3("world_position");
        glm::vec4 light_ambient_intensity = light->getVec4("ambient_intensity");
        glm::vec4 light_diffuse_intensity = light->getVec4("diffuse_intensity");
        glm::vec4 light_specular_intensity = light->getVec4(
                "specular_intensity");

        glUniformMatrix4fv(u_mvp_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mvp));
        glUniformMatrix4fv(u_mv_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mv));
        glUniformMatrix4fv(u_mv_it_, 1, GL_FALSE, glm::value_ptr(rstate->uniforms.u_mv_it));
        glUniform3f(u_light_pos_, light_position.x, light_position.y,
                light_position.z);

        glUniform1i(u_texture_, 0);
        glUniform3f(u_color_, color.r, color.g, color.b);
        glUniform1f(u_opacity_, opacity);

        glUniform4f(u_material_ambient_color_, material_ambient_color.r,
                material_ambient_color.g, material_ambient_color.b,
                material_ambient_color.a);
        glUniform4f(u_material_diffuse_color_, material_diffuse_color.r,
                material_diffuse_color.g, material_diffuse_color.b,
                material_diffuse_color.a);
        glUniform4f(u_material_specular_color_, material_specular_color.r,
                material_specular_color.g, material_specular_color.b,
                material_specular_color.a);
        glUniform1f(u_material_specular_exponent_, material_specular_exponent);
        glUniform4f(u_light_ambient_intensity_, light_ambient_intensity.r,
                light_ambient_intensity.g, light_ambient_intensity.b,
                light_ambient_intensity.a);
        glUniform4f(u_light_diffuse_intensity_, light_diffuse_intensity.r,
                light_diffuse_intensity.g, light_diffuse_intensity.b,
                light_diffuse_intensity.a);
        glUniform4f(u_light_specular_intensity_, light_specular_intensity.r,
                light_specular_intensity.g, light_specular_intensity.b,
                light_specular_intensity.a);

        glBindVertexArray(mesh->getVAOId());
    } else {
        glUniformMatrix4fv(u_mvp_no_light_, 1, GL_FALSE,
                glm::value_ptr(rstate->uniforms.u_mvp));

        glUniform1i(u_texture_no_light_, 0);
        glUniform3f(u_color_no_light_, color.r, color.g, color.b);
        glUniform1f(u_opacity_no_light_, opacity);
        glBindVertexArray(mesh->getVAOId());
    }

    GL(glDrawElements(render_data->draw_mode(), mesh->indices().size(), GL_UNSIGNED_SHORT,
            0));
    GL(glBindVertexArray(0));

    checkGlError("TextureShader::render");
}
Example #20
0
 void setValue(Real val)
 {
     mLight->setSpotlightOuterAngle(Radian(val));
 }
Example #21
0
    SampledSpectrum PathTracingRenderer::Job::contribution(const Scene &scene, const WavelengthSamples &initWLs, const Ray &initRay, IndependentLightPathSampler &pathSampler, ArenaAllocator &mem) const {
        WavelengthSamples wls = initWLs;
        Ray ray = initRay;
        SurfacePoint surfPt;
        SampledSpectrum alpha = SampledSpectrum::One;
        float initY = alpha.importance(wls.selectedLambda);
        SampledSpectrumSum sp(SampledSpectrum::Zero);
        uint32_t pathLength = 0;
        
        Intersection isect;
        if (!scene.intersect(ray, &isect))
            return SampledSpectrum::Zero;
        isect.getSurfacePoint(&surfPt);
        
        Vector3D dirOut_sn = surfPt.shadingFrame.toLocal(-ray.dir);
        if (surfPt.isEmitting()) {
            EDF* edf = surfPt.createEDF(wls, mem);
            SampledSpectrum Le = surfPt.emittance(wls) * edf->evaluate(EDFQuery(), dirOut_sn);
            sp += alpha * Le;
        }
        if (surfPt.atInfinity)
            return sp;

        while (true) {
            ++pathLength;
            if (pathLength >= 100)
                break;
            Normal3D gNorm_sn = surfPt.shadingFrame.toLocal(surfPt.gNormal);
            BSDF* bsdf = surfPt.createBSDF(wls, mem);
            BSDFQuery fsQuery(dirOut_sn, gNorm_sn, wls.selectedLambda);
            
            // Next Event Estimation (explicit light sampling)
            if (bsdf->hasNonDelta()) {
                float lightProb;
                Light light;
                scene.selectLight(pathSampler.getLightSelectionSample(), &light, &lightProb);
                SLRAssert(!std::isnan(lightProb) && !std::isinf(lightProb), "lightProb: unexpected value detected: %f", lightProb);
                
                LightPosQuery lpQuery(ray.time, wls);
                LightPosQueryResult lpResult;
                SampledSpectrum M = light.sample(lpQuery, pathSampler.getLightPosSample(), &lpResult);
                SLRAssert(!std::isnan(lpResult.areaPDF)/* && !std::isinf(xpResult.areaPDF)*/, "areaPDF: unexpected value detected: %f", lpResult.areaPDF);
                
                if (scene.testVisibility(surfPt, lpResult.surfPt, ray.time)) {
                    float dist2;
                    Vector3D shadowDir = lpResult.surfPt.getDirectionFrom(surfPt.p, &dist2);
                    Vector3D shadowDir_l = lpResult.surfPt.shadingFrame.toLocal(-shadowDir);
                    Vector3D shadowDir_sn = surfPt.shadingFrame.toLocal(shadowDir);
                    
                    EDF* edf = lpResult.surfPt.createEDF(wls, mem);
                    SampledSpectrum Le = M * edf->evaluate(EDFQuery(), shadowDir_l);
                    float lightPDF = lightProb * lpResult.areaPDF;
                    SLRAssert(!Le.hasNaN() && !Le.hasInf(), "Le: unexpected value detected: %s", Le.toString().c_str());
                    
                    SampledSpectrum fs = bsdf->evaluate(fsQuery, shadowDir_sn);
                    float cosLight = absDot(-shadowDir, lpResult.surfPt.gNormal);
                    float bsdfPDF = bsdf->evaluatePDF(fsQuery, shadowDir_sn) * cosLight / dist2;
                    
                    float MISWeight = 1.0f;
                    if (!lpResult.posType.isDelta() && !std::isinf(lpResult.areaPDF))
                        MISWeight = (lightPDF * lightPDF) / (lightPDF * lightPDF + bsdfPDF * bsdfPDF);
                    SLRAssert(MISWeight <= 1.0f, "Invalid MIS weight: %g", MISWeight);
                    
                    float G = absDot(shadowDir_sn, gNorm_sn) * cosLight / dist2;
                    sp += alpha * Le * fs * (G * MISWeight / lightPDF);
                    SLRAssert(!std::isnan(G) && !std::isinf(G), "G: unexpected value detected: %f", G);
                }
            }
            
            // get a next direction by sampling BSDF.
            BSDFQueryResult fsResult;
            SampledSpectrum fs = bsdf->sample(fsQuery, pathSampler.getBSDFSample(), &fsResult);
            if (fs == SampledSpectrum::Zero || fsResult.dirPDF == 0.0f)
                break;
            if (fsResult.dirType.isDispersive()) {
                fsResult.dirPDF /= WavelengthSamples::NumComponents;
                wls.flags |= WavelengthSamples::LambdaIsSelected;
            }
            alpha *= fs * absDot(fsResult.dir_sn, gNorm_sn) / fsResult.dirPDF;
            SLRAssert(!alpha.hasInf() && !alpha.hasNaN(),
                      "alpha: %s\nlength: %u, cos: %g, dirPDF: %g",
                      alpha.toString().c_str(), pathLength, absDot(fsResult.dir_sn, gNorm_sn), fsResult.dirPDF);
            
            Vector3D dirIn = surfPt.shadingFrame.fromLocal(fsResult.dir_sn);
            ray = Ray(surfPt.p, dirIn, ray.time, Ray::Epsilon);
            
            // find a next intersection point.
            isect = Intersection();
            if (!scene.intersect(ray, &isect))
                break;
            isect.getSurfacePoint(&surfPt);
            
            dirOut_sn = surfPt.shadingFrame.toLocal(-ray.dir);
            
            // implicit light sampling
            if (surfPt.isEmitting()) {
                float bsdfPDF = fsResult.dirPDF;
                
                EDF* edf = surfPt.createEDF(wls, mem);
                SampledSpectrum Le = surfPt.emittance(wls) * edf->evaluate(EDFQuery(), dirOut_sn);
                float lightProb = scene.evaluateProb(Light(isect.obj));
                float dist2 = surfPt.getSquaredDistance(ray.org);
                float lightPDF = lightProb * surfPt.evaluateAreaPDF() * dist2 / absDot(ray.dir, surfPt.gNormal);
                SLRAssert(!Le.hasNaN() && !Le.hasInf(), "Le: unexpected value detected: %s", Le.toString().c_str());
                SLRAssert(!std::isnan(lightPDF)/* && !std::isinf(lightPDF)*/, "lightPDF: unexpected value detected: %f", lightPDF);
                
                float MISWeight = 1.0f;
                if (!fsResult.dirType.isDelta())
                    MISWeight = (bsdfPDF * bsdfPDF) / (lightPDF * lightPDF + bsdfPDF * bsdfPDF);
                SLRAssert(MISWeight <= 1.0f, "Invalid MIS weight: %g", MISWeight);
                
                sp += alpha * Le * MISWeight;
            }
            if (surfPt.atInfinity)
                break;
            
            // Russian roulette
            float continueProb = std::min(alpha.importance(wls.selectedLambda) / initY, 1.0f);
            if (pathSampler.getPathTerminationSample() < continueProb)
                alpha /= continueProb;
            else
                break;
        }
        
        return sp;
    }
Example #22
0
 void applyDeltaValue(Real val)
 {
     setValue(mLight->getSpotlightOuterAngle().valueRadians() + val);
 }
 void undo() const {
     _light->on();
 }
Example #24
0
 void setCurrentStateAsBaseValue(void)
 {
     setAsBaseValue(mLight->getSpotlightOuterAngle().valueRadians());
 }
void TerrainShader::LoadLight(Light& light, float ambientLight)
{
	LoadVector(location_lightPosition, light.GetPosition());
	LoadVector(location_lightColor, light.GetColor());
	LoadFloat(location_ambientLight, ambientLight);
}
Example #26
0
 void setValue(Real val)
 {
     mLight->setSpotlightFalloff(val);
 }
Example #27
0
void LoadLight(TiXmlElement *element)
{
    Light *light = NULL;
    
    // name
    const char* name = element->Attribute("name");
    printf("Light [");
    if ( name ) printf("%s",name);
    printf("]");
    
    // type
    const char* type = element->Attribute("type");
    if ( type ) {
        if ( COMPARE(type,"ambient") ) {
            printf(" - Ambient\n");
            AmbientLight *l = new AmbientLight();
            light = l;
            for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) {
                if ( COMPARE( child->Value(), "intensity" ) ) {
                    Color c(1,1,1);
                    ReadColor( child, c );
                    l->SetIntensity(c);
                    printf("   intensity %f %f %f\n",c.r,c.g,c.b);
                }
            }
        } else if ( COMPARE(type,"direct") ) {
            printf(" - Direct\n");
            DirectLight *l = new DirectLight();
            light = l;
            for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) {
                if ( COMPARE( child->Value(), "intensity" ) ) {
                    Color c(1,1,1);
                    ReadColor( child, c );
                    l->SetIntensity(c);
                    printf("   intensity %f %f %f\n",c.r,c.g,c.b);
                } else if ( COMPARE( child->Value(), "direction" ) ) {
                    Point3 v(1,1,1);
                    ReadVector( child, v );
                    l->SetDirection(v);
                    printf("   direction %f %f %f\n",v.x,v.y,v.z);
                }
            }
        } else if ( COMPARE(type,"point") ) {
            printf(" - Point\n");
            PointLight *l = new PointLight();
            light = l;
            for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) {
                if ( COMPARE( child->Value(), "intensity" ) ) {
                    Color c(1,1,1);
                    ReadColor( child, c );
                    l->SetIntensity(c);
                    printf("   intensity %f %f %f\n",c.r,c.g,c.b);
                } else if ( COMPARE( child->Value(), "position" ) ) {
                    Point3 v(0,0,0);
                    ReadVector( child, v );
                    l->SetPosition(v);
                    printf("   position %f %f %f\n",v.x,v.y,v.z);
                }
            }
        } else {
            printf(" - UNKNOWN\n");
        }
    }
    
    if ( light ) {
        light->SetName(name);
        lights.push_back(light);
    }
    
}
Example #28
0
 void applyDeltaValue(Real val)
 {
     setValue(mLight->getSpotlightFalloff() + val);
 }
Example #29
0
void IGIIntegrator::Preprocess(const Scene *scene,
        const Camera *camera, const Renderer *renderer) {
    if (scene->lights.size() == 0) return;
    MemoryArena arena;
    RNG rng;
    // Compute samples for emitted rays from lights
    vector<float> lightNum(nLightPaths * nLightSets);
    vector<float> lightSampPos(2 * nLightPaths * nLightSets, 0.f);
    vector<float> lightSampComp(nLightPaths * nLightSets, 0.f);
    vector<float> lightSampDir(2 * nLightPaths * nLightSets, 0.f);
    LDShuffleScrambled1D(nLightPaths, nLightSets, &lightNum[0], rng);
    LDShuffleScrambled2D(nLightPaths, nLightSets, &lightSampPos[0], rng);
    LDShuffleScrambled1D(nLightPaths, nLightSets, &lightSampComp[0], rng);
    LDShuffleScrambled2D(nLightPaths, nLightSets, &lightSampDir[0], rng);

    // Precompute information for light sampling densities
    Distribution1D *lightDistribution = ComputeLightSamplingCDF(scene);
    for (u_int s = 0; s < nLightSets; ++s) {
        for (u_int i = 0; i < nLightPaths; ++i) {
            // Follow path _i_ from light to create virtual lights
            int sampOffset = s*nLightPaths + i;

            // Choose light source to trace virtual light path from
            float lightPdf;
            int ln = lightDistribution->SampleDiscrete(lightNum[sampOffset], &lightPdf);
            Light *light = scene->lights[ln];

            // Sample ray leaving light source for virtual light path
            RayDifferential ray;
            float pdf;
            LightSample ls(lightSampPos[2*sampOffset], lightSampPos[2*sampOffset+1],
                           lightSampComp[sampOffset]);
            Normal Nl;
            Spectrum alpha = light->Sample_L(scene, ls, lightSampDir[2*sampOffset],
                                             lightSampDir[2*sampOffset+1],
                                             camera->shutterOpen, &ray, &Nl, &pdf);
            if (pdf == 0.f || alpha.IsBlack()) continue;
            alpha /= pdf * lightPdf;
            Intersection isect;
            while (scene->Intersect(ray, &isect) && !alpha.IsBlack()) {
                // Create virtual light and sample new ray for path
                alpha *= renderer->Transmittance(scene, RayDifferential(ray), NULL,
                                                 arena, &rng);
                Vector wo = -ray.d;
                BSDF *bsdf = isect.GetBSDF(ray, arena);

                // Create virtual light at ray intersection point
                const int sqrtRhoSamples = 6;
                float rhoSamples[2*sqrtRhoSamples*sqrtRhoSamples];
                StratifiedSample2D(rhoSamples, sqrtRhoSamples, sqrtRhoSamples, rng);
                Spectrum contrib = alpha * bsdf->rho(wo,
                    sqrtRhoSamples*sqrtRhoSamples, rhoSamples) / M_PI;
                virtualLights[s].push_back(VirtualLight(isect.dg.p, isect.dg.nn, contrib,
                    isect.rayEpsilon));

                // Sample new ray direction and update weight for virtual light path
                Vector wi;
                float pdf;
                BSDFSample bsdfSample(rng);
                Spectrum fr = bsdf->Sample_f(wo, &wi, bsdfSample, &pdf);
                if (fr.IsBlack() || pdf == 0.f)
                    break;
                Spectrum contribScale = fr * AbsDot(wi, bsdf->dgShading.nn) / pdf;

                // Possibly terminate virtual light path with Russian roulette
                float rrProb = min(1.f, contribScale.y());
                if (rng.RandomFloat() > rrProb)
                    break;
                alpha *= contribScale / rrProb;
                ray = RayDifferential(isect.dg.p, wi, ray, isect.rayEpsilon);
            }
            arena.FreeAll();
        }
    }
    delete lightDistribution;
}
Example #30
0
void DockScatterPlot::device_changed(OpticalDevice* pDevice, int iReason)
{
    _pDevice=pDevice;

    if( (iReason!=LIGHT_OFF_AXIS_CHANGED) && (iReason!=OPTICAL_DEVICE_CHANGED) && (iReason!=NEW_OPTICAL_DEVICE) )
        return;

    _bBlockSignals=true;

    double dPercentField=-1;
    if(!pDevice->get_parameter("showLightOffAxis",dPercentField))
        dPercentField=0.;

    assert(dPercentField>=0);
    assert(dPercentField<=100);
    m_ui->hsImageFieldPos->setValue((int)dPercentField);

    if(iReason==NEW_OPTICAL_DEVICE)
    {
        m_ui->hsImageFieldPos->blockSignals(true);
        m_ui->hsImageFieldPos->setValue((int)dPercentField);
        m_ui->hsImageFieldPos->blockSignals(false);
    }

    QGraphicsScene* scene=m_ui->graphicsView->scene();
    scene->clear();

    Light light;
    double dTiltDegree=dPercentField*pDevice->half_field_of_view()/100.;
    pDevice->compute_light(&light,pDevice->nb_surface()-1, dTiltDegree,NB_POINTS_SCATTER_PLOT,NB_POINTS_SCATTER_PLOT);
    bool bIsInfinite=light.is_image_infinite();
    bool bIsValid=light.is_valid();
    double dPsfDiameter=light.spot_size();
    double dCenterX,dCenterY;
    double dPerfectAiryRadius=light.airy_radius();
    double dLfro=light.spot_vs_airy();
    double dFD=light.get_FD();

    if( (pDevice->nb_surface()==0) || (!bIsValid) )
    {
        m_ui->hsImageFieldPos->setValue(0);
        m_ui->qlPsfDiameter->setText("n/a");
        m_ui->qlFD->setText("n/a");
        m_ui->qlPerfectAiry->setText("n/a");
        m_ui->qlLFro->setText("n/a");

        _bBlockSignals=false;
        return;
    }

    //draw photons scatter plot
    ScatterPlot* sp=new ScatterPlot;
    sp->setZValue(10);
    int iNbPhoton=light.nb_photon();
    for (int i=0;i<iNbPhoton;i++)
    {
        Photon& rP=light.get_photon(i);
        if (rP.is_valid())
        {
            double dX,dY;

            if(bIsInfinite)
            {
                dX=rP.anglex;
                dY=rP.angley;
                sp->addPoint(-dY,dX,light.get_visual_color(rP.lambda()));
            }
            else
            {
                dX=rP.x;
                dY=rP.y;
                sp->addPoint(-dY,dX,light.get_visual_color(rP.lambda()));
            }

            assert(!isnan(dX));
            assert(!isnan(dY));
        }
    }

    if(bIsInfinite)
    {
        m_ui->qlPsfDiameter->setText(QString::number(dPsfDiameter,'g',3)+" deg");
        m_ui->qlFD->setText("n/a");
        m_ui->qlFD->setToolTip("Non applicable in infinite_image mode");
        m_ui->qlPerfectAiry->setText(QString::number(dPerfectAiryRadius*2,'g',3)+" deg");
        m_ui->qlLFro->setText(QString::number(dLfro,'g',3));
        m_ui->qlVignetting->setText(QString::number(light.vignetting(),'f',1)+" %");
    }
    else
    {
        m_ui->qlPsfDiameter->setText(QString::number(dPsfDiameter*1000.,'g',3)+" µm");
        m_ui->qlFD->setText(QString::number(dFD,'g',3));
        m_ui->qlFD->setToolTip(QString::number(dFD));
        m_ui->qlPerfectAiry->setText(QString::number(dPerfectAiryRadius*2.*1000.,'g',3)+" µm");
        m_ui->qlLFro->setText(QString::number(dLfro,'g',3));
        m_ui->qlVignetting->setText(QString::number(light.vignetting(),'f',1)+" %");
    }


    //draw bounding circle
    light.get_spot_center(dCenterY,dCenterX);
    dCenterX=-dCenterX;

    QPen qp;
    qp.setCosmetic(true);
    scene->addItem(sp);
    QGraphicsItem * pEllipse=scene->addEllipse((dCenterX-dPerfectAiryRadius),(dCenterY-dPerfectAiryRadius),dPerfectAiryRadius*2.,dPerfectAiryRadius*2.,qp);
    pEllipse->setZValue(20);

    QRectF rsp=sp->boundingRect();
    QRectF rellipse((dCenterX-dPerfectAiryRadius),(dCenterY-dPerfectAiryRadius),dPerfectAiryRadius*2.,dPerfectAiryRadius*2.);
    QRectF rtotal= rsp | rellipse;
    enlarge(rtotal,1.1);

    scene->setSceneRect(rtotal);
    m_ui->graphicsView->fitInView(rtotal,Qt::KeepAspectRatio);

    _bBlockSignals=false;
}