Exemplo n.º 1
0
/*
void updateKeyboard() {
    
    //std::cerr << "updateKeyboard" << std::endl;
    
	if (keyboardMap['1'] == 1)
		CameraManager::getInstance().setActiveCamera(c1);
    //	if (keyboardMap['2'] == 1)
    //		CameraManager::getInstance().setActiveCamera(c2);
	if (keyboardMap['3'] == 1)
		CameraManager::getInstance().setActiveCamera(c3);
    
	CameraManager::getInstance().getActiveCamera()->updateKeyboard(keyboardMap);
    
}
*/
void _display() {
    //std::cerr << "SigmaGameEngine::display()" << std::endl;
    GLuint shaderProgramID_ = SigmaGameEngine::getInstance().getShaderProgramID();
    glUseProgram(shaderProgramID_);
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    LightManager lm = LightManager::getInstance();
    glUniform1i(glGetUniformLocation(shaderProgramID_, "light_counter"),
                lm.getLightCounter());
    glUniform3fv(glGetUniformLocation(shaderProgramID_, "light_sources_pos_array"),
                 8, lm.getLightSourcesPositionArray());
    glUniform3fv(glGetUniformLocation(shaderProgramID_, "light_sources_color_array"),
                 8, lm.getLightSourcesColorArray());
    glUniform1fv(glGetUniformLocation(shaderProgramID_, "light_sources_lux_array"),
                 8, lm.getLightSourcesLuxArray());
    
	
    CameraManager::getInstance().setActiveCamera(c1);
    
	glUniformMatrix4fv(glGetUniformLocation(shaderProgramID_, "camera_transformation"),
                       1, GL_TRUE,
                       CameraManager::getInstance().getActiveCamera()->getCameraMatrix().m);
    
    //std::cerr << "camera_transformation:\n" << CameraManager::getInstance().getActiveCamera()->getCameraMatrix() << std::endl;
    
    GameObjectManager::getInstance().render(shaderProgramID_);
    
    glutSwapBuffers();
}
void LightManager::initLightFields()
{
   LightManagerMap &lightManagers = _getLightManagers();

   LightManagerMap::Iterator iter = lightManagers.begin();
   for ( ; iter != lightManagers.end(); iter++ )
   {
      LightManager *lm = iter->value;
      lm->_initLightFields();
   }
}
Exemplo n.º 3
0
AEResult GameLightsUpdate::ShadowDirLightRenderGameObject()
{
	LightManager* lightManager = m_GameApp->GetLightManager();
	GameObjectManager* gameObjectManager = m_GameApp->GetGameObjectManager();

	if (lightManager->GetNumDirLightsWithShadows() == 0)
	{
		return AEResult::Ok;
	}

	Texture2DArray* shadowTextureArray = lightManager->GetDirLightShadowTextureArray();

	AETODO("Check return");
	RenderTarget* rtsDS[1] = { nullptr };
	m_GraphicDevice->SetRenderTargetsAndDepthStencil(1, rtsDS, m_DirLightShadowTexturesDS);

	for (auto lightIt : *lightManager)
	{
		Light* light = lightIt.second;

		if (light->GetLightType() == LightType::Directional && light->IsShadowEnabled())
		{
			DirectionalLight* dirLight = reinterpret_cast<DirectionalLight*>(light);

			uint32_t idxs[1] = { light->GetShadowTextureIndex() };
			AETODO("Check return");
			m_GraphicDevice->SetRenderTargets(1, idxs, shadowTextureArray);
			m_GraphicDevice->Clear(true, 0, true, true, AEColors::Transparent);

			for (uint32_t i = 0; i < AE_LIGHT_NUM_CASCADE_MAPS; i++)
			{
				AETODO("Check return");
				m_GraphicDevice->SetViewport(m_DirLightShadowViewports[i]);

				const LightCascadeInfo& lightCascadeInfo = dirLight->GetLightCascadeInfo();

				for (auto goIt : *gameObjectManager)
				{
					AETODO("Check return");
					ShadowLightRenderGameObject(goIt.second, lightCascadeInfo.m_CascadeViewMatrix[i], lightCascadeInfo.m_CascadeProjectionMatrix[i]);
				}
			}
		}
	}

	AETODO("Check return");
	m_GraphicDevice->ResetViewport();

	AETODO("Check return");
	m_GraphicDevice->ResetRenderTargetAndSetDepthStencil();

	return AEResult::Ok;
}
void ProcessedFFMaterial::setTextureStages(SceneState * state, const SceneGraphData& sgData, U32 pass)
{
   // We may need to do some trickery in here for fixed function, this is just copy/paste from MatInstance
#ifdef TORQUE_DEBUG
   AssertFatal( pass<mPasses.size(), "Pass out of bounds" );
#endif
   LightManager* lm = state->getLightManager();
   
   RenderPassData *rpd = mPasses[pass];
   for( U32 i=0; i<rpd->mNumTex; i++ )
   {      
      U32 currTexFlag = rpd->mTexType[i];
      if (!lm || !lm->setTextureStage(sgData, currTexFlag, i, NULL, NULL))
      {
         switch( currTexFlag )
         {
         case Material::NoTexture:
            if( mMaterial->isIFL() && sgData.miscTex )
               GFX->setTexture( i, sgData.miscTex );
            else
            {
               if (rpd->mTexSlot[i].texObject)
                  GFX->setTexture( i, rpd->mTexSlot[i].texObject );
            }
            break;

         case Material::NormalizeCube:
            GFX->setCubeTexture(i, Material::GetNormalizeCube());
            break;

         case Material::Lightmap:
            GFX->setTexture( i, sgData.lightmap );
            break;

         case Material::Cube:
            // TODO: Is this right?
            GFX->setTexture( i, rpd->mTexSlot[0].texObject );
            break;

         case Material::SGCube:
            // No cubemap support just yet
            //GFX->setCubeTexture( i, sgData.cubemap );
            GFX->setTexture( i, rpd->mTexSlot[0].texObject );
            break;

         case Material::BackBuff:
            GFX->setTexture( i, sgData.backBuffTex );
            break;
         }
      }
   }
}
LightInfo* LightManager::createLightInfo(LightInfo* light /* = NULL */)
{
   LightInfo *outLight = (light != NULL) ? light : new LightInfo;

   LightManagerMap &lightManagers = _getLightManagers();
   LightManagerMap::Iterator iter = lightManagers.begin();
   for ( ; iter != lightManagers.end(); iter++ )
   {
      LightManager *lm = iter->value;
      lm->_addLightInfoEx( outLight );
   }

   return outLight;
}
Exemplo n.º 6
0
void UtilityShader::SetupSharedParams()
{
	_Assert(NULL != effect);

	LightManager* lightMgr = gEngine->GetLightManager();

	effect->SetRawValue("ambientLight", &(lightMgr->GetFinalAmbientColor()), 0 , sizeof(Vector3));

	effect->SetRawValue("directionalLights", lightMgr->GetDirectionalLightsData(), 0, 
		MAX_NUM_DIRECTIONAL_LIGHTS * sizeof(DirectionalLightData));

	effect->SetRawValue("pointLights", lightMgr->GetPointLightsData(), 0, 
		MAX_NUM_POINT_LIGHTS * sizeof(PointLightData));
}
Exemplo n.º 7
0
AEResult GameLightsUpdate::ShadowSpotLightRenderGameObject()
{
	LightManager* lightManager = m_GameApp->GetLightManager();
	GameObjectManager* gameObjectManager = m_GameApp->GetGameObjectManager();

	if (lightManager->GetNumSpotLightsWithShadows() == 0)
	{
		return AEResult::Ok;
	}

	Texture2DArray* shadowTextureArray = lightManager->GetSpotLightShadowTextureArray();
	
	AETODO("Check return");
	RenderTarget* rtsDS[1] = { nullptr };
	m_GraphicDevice->SetRenderTargetsAndDepthStencil(1, rtsDS, m_SpotLightShadowTexturesDS);

	AETODO("Check return");
	m_GraphicDevice->SetViewport(m_SpotLightShadowViewport);

	for (auto lightIt : *lightManager)
	{
		Light* light = lightIt.second;

		if (light->GetLightType() == LightType::Spot && light->IsShadowEnabled())
		{
			uint32_t idxs[1] = { light->GetShadowTextureIndex() };
			AETODO("Check return");
			m_GraphicDevice->SetRenderTargets(1, idxs, shadowTextureArray);
			m_GraphicDevice->Clear(true, 0, true, true, AEColors::Transparent);

			for (auto goIt : *gameObjectManager)
			{
				AETODO("Check return");
				ShadowLightRenderGameObject(goIt.second, light->GetViewMatrix(), light->GetProjectionMatrix());
			}
		}
	}

	AETODO("Check return");
	m_GraphicDevice->ResetViewport();

	AETODO("Check return");
	m_GraphicDevice->ResetRenderTargetAndSetDepthStencil();

	return AEResult::Ok;
}
void SetupNighttimeLighting()
{
	SunlightValue values[] =
	{
		{ 0.0f/24.0f, glm::vec4(0.2f, 0.2f, 0.2f, 1.0f), glm::vec4(0.6f, 0.6f, 0.6f, 1.0f), g_skyDaylightColor},
		{ 4.5f/24.0f, glm::vec4(0.2f, 0.2f, 0.2f, 1.0f), glm::vec4(0.6f, 0.6f, 0.6f, 1.0f), g_skyDaylightColor},
		{ 6.5f/24.0f, glm::vec4(0.15f, 0.05f, 0.05f, 1.0f), glm::vec4(0.3f, 0.1f, 0.10f, 1.0f), glm::vec4(0.5f, 0.1f, 0.1f, 1.0f)},
		{ 8.0f/24.0f, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)},
		{18.0f/24.0f, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)},
		{19.5f/24.0f, glm::vec4(0.15f, 0.05f, 0.05f, 1.0f), glm::vec4(0.3f, 0.1f, 0.1f, 1.0f), glm::vec4(0.5f, 0.1f, 0.1f, 1.0f)},
		{20.5f/24.0f, glm::vec4(0.2f, 0.2f, 0.2f, 1.0f), glm::vec4(0.6f, 0.6f, 0.6f, 1.0f), g_skyDaylightColor},
	};

	g_lights.SetSunlightValues(values, 7);

	g_lights.SetPointLightIntensity(0, glm::vec4(0.6f, 0.6f, 0.6f, 1.0f));
	g_lights.SetPointLightIntensity(1, glm::vec4(0.0f, 0.0f, 0.7f, 1.0f));
	g_lights.SetPointLightIntensity(2, glm::vec4(0.7f, 0.0f, 0.0f, 1.0f));
}
Exemplo n.º 9
0
void SetupHDRLighting()
{
	SunlightValueHDR values[] =
	{
		{ 0.0f/24.0f, glm::vec4(0.6f, 0.6f, 0.6f, 1.0f), glm::vec4(1.8f, 1.8f, 1.8f, 1.0f), g_skyDaylightColor, 3.0f},
		{ 4.5f/24.0f, glm::vec4(0.6f, 0.6f, 0.6f, 1.0f), glm::vec4(1.8f, 1.8f, 1.8f, 1.0f), g_skyDaylightColor, 3.0f},
		{ 6.5f/24.0f, glm::vec4(0.225f, 0.075f, 0.075f, 1.0f), glm::vec4(0.45f, 0.15f, 0.15f, 1.0f), glm::vec4(0.5f, 0.1f, 0.1f, 1.0f), 1.5f},
		{ 8.0f/24.0f, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 1.0f},
		{18.0f/24.0f, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 1.0f},
		{19.5f/24.0f, glm::vec4(0.225f, 0.075f, 0.075f, 1.0f), glm::vec4(0.45f, 0.15f, 0.15f, 1.0f), glm::vec4(0.5f, 0.1f, 0.1f, 1.0f), 1.5f},
		{20.5f/24.0f, glm::vec4(0.6f, 0.6f, 0.6f, 1.0f), glm::vec4(1.8f, 1.8f, 1.8f, 1.0f), g_skyDaylightColor, 3.0f},
	};

	g_lights.SetSunlightValues(values, 7);

	g_lights.SetPointLightIntensity(0, glm::vec4(0.6f, 0.6f, 0.6f, 1.0f));
	g_lights.SetPointLightIntensity(1, glm::vec4(0.0f, 0.0f, 0.7f, 1.0f));
	g_lights.SetPointLightIntensity(2, glm::vec4(0.7f, 0.0f, 0.0f, 1.0f));
}
//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
void init()
{
	InitializePrograms();

	try
	{
		g_pScene = new Scene();
	}
	catch(std::exception &except)
	{
		printf("%s\n", except.what());
		throw;
	}

	SetupDaytimeLighting();

	g_lights.CreateTimer("tetra", Framework::Timer::TT_LOOP, 2.5f);

	glutMouseFunc(MouseButton);
 	glutMotionFunc(MouseMotion);
	glutMouseWheelFunc(MouseWheel);

	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glFrontFace(GL_CW);

	const float depthZNear = 0.0f;
	const float depthZFar = 1.0f;

	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);
	glDepthFunc(GL_LEQUAL);
	glDepthRange(depthZNear, depthZFar);
	glEnable(GL_DEPTH_CLAMP);

	//Setup our Uniform Buffers
	glGenBuffers(1, &g_lightUniformBuffer);
	glBindBuffer(GL_UNIFORM_BUFFER, g_lightUniformBuffer);
	glBufferData(GL_UNIFORM_BUFFER, sizeof(LightBlock), NULL, GL_DYNAMIC_DRAW);

	glGenBuffers(1, &g_projectionUniformBuffer);
	glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
	glBufferData(GL_UNIFORM_BUFFER, sizeof(ProjectionBlock), NULL, GL_DYNAMIC_DRAW);

	//Bind the static buffers.
	glBindBufferRange(GL_UNIFORM_BUFFER, g_lightBlockIndex, g_lightUniformBuffer,
		0, sizeof(LightBlock));

	glBindBufferRange(GL_UNIFORM_BUFFER, g_projectionBlockIndex, g_projectionUniformBuffer,
		0, sizeof(ProjectionBlock));

	glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
Exemplo n.º 11
0
//Called whenever a key on the keyboard was pressed.
//The key is given by the ''key'' parameter, which is in ASCII.
//It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to 
//exit the program.
void keyboard(unsigned char key, int x, int y)
{
	bool bChangedShininess = false;
	bool bChangedLightModel = false;
	switch (key)
	{
	case 27:
		delete g_pScene;
		g_pScene = NULL;
		glutLeaveMainLoop();
		return;
		
	case 'p': g_lights.TogglePause(g_eTimerMode); break;
	case '-': g_lights.RewindTime(g_eTimerMode, 1.0f); break;
	case '=': g_lights.FastForwardTime(g_eTimerMode, 1.0f); break;
	case 't': g_bDrawCameraPos = !g_bDrawCameraPos; break;
	case '1': g_eTimerMode = TIMER_ALL; printf("All\n"); break;
	case '2': g_eTimerMode = TIMER_SUN; printf("Sun\n"); break;
	case '3': g_eTimerMode = TIMER_LIGHTS; printf("Lights\n"); break;

	case 'l': SetupDaytimeLighting(); break;
	case 'L': SetupNighttimeLighting(); break;
	case 'k': SetupHDRLighting(); break;

	case 32:
		{
			float sunAlpha = g_lights.GetSunTime();
			float sunTimeHours = sunAlpha * 24.0f + 12.0f;
			sunTimeHours = sunTimeHours > 24.0f ? sunTimeHours - 24.0f : sunTimeHours;
			int sunHours = int(sunTimeHours);
			float sunTimeMinutes = (sunTimeHours - sunHours) * 60.0f;
			int sunMinutes = int(sunTimeMinutes);
			printf("%02i:%02i\n", sunHours, sunMinutes);
		}
		break;
	}

	g_viewPole.CharPress(key);
}
Exemplo n.º 12
0
void PxSingleActor::renderObject(SceneState* state)
{
   GFXTransformSaver saver;

   // Set up our TS render state here.
   TSRenderState rdata;
   rdata.setSceneState( state );
   //rdata.setObjScale( &getScale() );

   LightManager *lm = gClientSceneGraph->getLightManager();
   if ( !state->isShadowPass() )
      lm->setupLights( this, getWorldSphere() );

   MatrixF mat = getTransform();
   mat.scale( getScale() );
   GFX->setWorldMatrix( mat );

   mShapeInstance->animate();
   mShapeInstance->render( rdata );
   
   lm->resetLights();  
}
Exemplo n.º 13
0
void GameLightsUpdate::Update(const TimerParams& timerParams)
{
	///////////////////////////////////////////
	//Get Game Object Manager & Light Manager
	GameObjectManager* gameObjectManager = m_GameApp->GetGameObjectManager();

	LightManager* lightManager = m_GameApp->GetLightManager();

	AEAssert(gameObjectManager != nullptr);
	AEAssert(lightManager != nullptr);
	if(gameObjectManager == nullptr || lightManager == nullptr)
	{
		return;
	}

	///////////////////////////////////////////
	//Update all Light Object information
	for(auto goIt : *gameObjectManager)
	{
		UpdateGameObjectLight(goIt.second);
	}

	///////////////////////////////////////////
	//Update Light Manager
	Camera* camera = m_CameraUpdater->GetMainCamera();

	//glm::ivec2 dimension(m_GraphicDevice->GetGraphicPP().m_BackBufferWidth, m_GraphicDevice->GetGraphicPP().m_BackBufferHeight);
	//Camera camera(L"Dummy Test", glm::vec3(0.0f, 0.0f, -5.0f), glm::vec3(0.0f, 0.0f, 0.0f), AEMathHelpers::Vec3fUp, dimension, 45.0f, 1.0f, 1000.0f);
	//camera.Initialize();
	AEResult ret = lightManager->Update(camera);
	if(ret != AEResult::Ok)
	{
		AETODO("Log info");
	}

	DrawableGameComponent::Update(timerParams);
}
Exemplo n.º 14
0
void DirectionalLight::Enable(bool enable)
{
	if(enable == mIsEnabled)
	{
		return;
	}
	else
	{
		LightManager* lightMgr = gEngine->GetLightManager();
		if(enable == true)
		{
			if(lightMgr->GetActiveDirectionalLightCounts() < MAX_NUM_DIRECTIONAL_LIGHTS)
			{
				mIsEnabled = true;
				lightMgr->EnableOneDirectionalLight(true);
			}
		}
		else
		{
			mIsEnabled = false;
			lightMgr->EnableOneDirectionalLight(false);
		}
	}
}
bool ProcessedCustomMaterial::setupPass( SceneRenderState *state, const SceneData& sgData, U32 pass )
{
   PROFILE_SCOPE( ProcessedCustomMaterial_SetupPass );

   // Make sure we have a pass.
   if ( pass >= mPasses.size() )
      return false;

   ShaderRenderPassData* rpd = _getRPD( pass );
   U32 currState = _getRenderStateIndex( state, sgData );
   GFX->setStateBlock(rpd->mRenderStates[currState]);      

   // activate shader
   if ( rpd->shader )
      GFX->setShader( rpd->shader );
   else
      GFX->disableShaders();

   // Set our textures   
   setTextureStages( state, sgData, pass );   
   
   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
   GFX->setShaderConstBuffer(shaderConsts);
   
   // Set our shader constants.
   _setTextureTransforms(pass);
   _setShaderConstants(state, sgData, pass);

   LightManager* lm = state ? LIGHTMGR : NULL;
   if (lm)
      lm->setLightInfo(this, NULL, sgData, state, pass, shaderConsts);

   shaderConsts->setSafe(rpd->shaderHandles.mAccumTimeSC, MATMGR->getTotalTime());   

   return true;
}
void ProcessedCustomMaterial::setTextureStages( SceneRenderState *state, const SceneData &sgData, U32 pass )
{      
   LightManager* lm = state ? LIGHTMGR : NULL;   
   ShaderRenderPassData* rpd = _getRPD(pass);
   ShaderConstHandles* handles = _getShaderConstHandles(pass);
   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);

   const NamedTexTarget *texTarget;
   GFXTextureObject *texObject; 
   
   for( U32 i=0; i<mMaxTex; i++ )
   {            
      U32 currTexFlag = rpd->mTexType[i];
      if ( !lm || !lm->setTextureStage(sgData, currTexFlag, i, shaderConsts, handles ) )
      {
      	GFXShaderConstHandle* handle = handles->mTexHandlesSC[i];
         if ( !handle->isValid() )
         	continue;

         S32 samplerRegister = handle->getSamplerRegister();
         
         switch( currTexFlag )
         {
         case 0:
         default:
            break;

         case Material::Mask:
         case Material::Standard:
         case Material::Bump:
         case Material::Detail:
            {
               GFX->setTexture( samplerRegister, rpd->mTexSlot[i].texObject );
               break;
            }

         case Material::Lightmap:
            {
               GFX->setTexture( samplerRegister, sgData.lightmap );
               break;
            }
         case Material::Cube:
            {
               GFX->setCubeTexture( samplerRegister, rpd->mCubeMap );
               break;
            }
         case Material::SGCube:
            {
               GFX->setCubeTexture( samplerRegister, sgData.cubemap );
               break;
            }
         case Material::BackBuff:
            {
               GFX->setTexture( samplerRegister, sgData.backBuffTex );
               //if ( sgData.reflectTex )
               //   GFX->setTexture( samplerRegister, sgData.reflectTex );
               //else
               //{
               //    GFXTextureObject *refractTex = REFLECTMGR->getRefractTex( true );
               //    GFX->setTexture( samplerRegister, refractTex );
               //}
               break;
            }
         case Material::ReflectBuff:
            {
               GFX->setTexture( samplerRegister, sgData.reflectTex );
               break;
            }
         case Material::Misc:
            {
               GFX->setTexture( samplerRegister, sgData.miscTex );
               break;
            }
         case Material::TexTarget:
            {
               texTarget = rpd->mTexSlot[i].texTarget;
               if ( !texTarget )
               {
                  GFX->setTexture( samplerRegister, NULL );
                  break;
               }
               
               texObject = texTarget->getTexture();

               // If no texture is available then map the default 2x2
               // black texture to it.  This at least will ensure that
               // we get consistant behavior across GPUs and platforms.
               if ( !texObject )
                  texObject = GFXTexHandle::ZERO;

               if ( handles->mRTParamsSC[samplerRegister]->isValid() && texObject )
               {
                  const Point3I &targetSz = texObject->getSize();
                  const RectI &targetVp = texTarget->getViewport();
                  Point4F rtParams;

                  ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);
                  shaderConsts->set(handles->mRTParamsSC[samplerRegister], rtParams);
               }
              
               GFX->setTexture( samplerRegister, texObject );
               break;
            }
         }
      }
   }
}
Exemplo n.º 17
0
bool DecalManager::prepRenderImage(SceneState* state, const U32 stateKey,
                                   const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
   PROFILE_SCOPE( DecalManager_RenderDecals );

   if ( !smDecalsOn || !mData ) 
      return false;

   if (isLastState(state, stateKey))
      return false;
   setLastState(state, stateKey);

   if ( !state->isDiffusePass() && !state->isReflectPass() )
      return false;

   PROFILE_START( DecalManager_RenderDecals_SphereTreeCull );

   // Grab this before anything here changes it.
   mCuller = state->getFrustum();

   // Populate vector of decal instances to be rendered with all
   // decals from visible decal spheres.

   mDecalQueue.clear();

   const Vector<DecalSphere*> &grid = mData->getGrid();
   
   for ( U32 i = 0; i < grid.size(); i++ )
   {
      const DecalSphere *decalSphere = grid[i];
      const SphereF &worldSphere = decalSphere->mWorldSphere;
      if ( !mCuller.sphereInFrustum( worldSphere.center, worldSphere.radius ) )
         continue;

      // TODO: If each sphere stored its largest decal instance we
      // could do an LOD step on it here and skip adding any of the
      // decals in the sphere.

      mDecalQueue.merge( decalSphere->mItems );
   }

   PROFILE_END();

   PROFILE_START( DecalManager_RenderDecals_Update );

   const U32 &curSimTime = Sim::getCurrentTime();
   const Point2I &viewportExtent = state->getViewportExtent();
   Point3F cameraOffset; 
   F32   decalSize, 
         pixelRadius;
   U32 delta, diff;
   DecalInstance *dinst;

   // Loop through DecalQueue once for preRendering work.
   // 1. Update DecalInstance fade (over time)
   // 2. Clip geometry if flagged to do so.
   // 3. Calculate lod - if decal is far enough away it will not render.
   for ( U32 i = 0; i < mDecalQueue.size(); i++ )
   {
      dinst = mDecalQueue[i];

      // LOD calculation.
      // See TSShapeInstance::setDetailFromDistance for more
      // information on these calculations.
      decalSize = getMax( dinst->mSize, 0.001f );
      pixelRadius = dinst->calcPixelRadius( state );

      // Need to clamp here.
      if ( pixelRadius < dinst->calcEndPixRadius( viewportExtent ) )
      {
         mDecalQueue.erase_fast( i );
         i--;
         continue;
      }

      // We're gonna try to render this decal... so do any 
      // final adjustments to it before rendering.

      // Update fade and delete expired.
      if ( !( dinst->mFlags & PermanentDecal || dinst->mFlags & CustomDecal ) )
      {         
         delta = ( curSimTime - dinst->mCreateTime );
         if ( delta > dinst->mDataBlock->lifeSpan )         
         {            
            diff = delta - dinst->mDataBlock->lifeSpan;
            dinst->mVisibility = 1.0f - (F32)diff / (F32)dinst->mDataBlock->fadeTime;

            if ( dinst->mVisibility <= 0.0f )
            {
               mDecalQueue.erase_fast( i );
               removeDecal( dinst );               
               i--;
               continue;
            }
         }
      }

      // Build clipped geometry for this decal if needed.
      if ( dinst->mFlags & ClipDecal/* && !( dinst->mFlags & CustomDecal ) */)
      {  
         // Turn off the flag so we don't continually try to clip
         // if it fails.
		  if(!clipDecal( dinst ))
		  {
				dinst->mFlags = dinst->mFlags & ~ClipDecal;
				if ( !(dinst->mFlags & CustomDecal) )
				{
					// Clipping failed to get any geometry...

					// Remove it from the render queue.
					mDecalQueue.erase_fast( i );
					i--;

					// If the decal is one placed at run-time (not the editor)
					// then we should also permanently delete the decal instance.
					if ( !(dinst->mFlags & SaveDecal) )
					{
						removeDecal( dinst );
					}
				}       
				// If this is a decal placed by the editor it will be
				// flagged to attempt clipping again the next time it is
				// modified. For now we just skip rendering it.      
				continue;
		  }  
      }

      // If we get here and the decal still does not have any geometry
      // skip rendering it. It must be an editor placed decal that failed
      // to clip any geometry but has not yet been flagged to try again.
      if ( !dinst->mVerts || dinst->mVertCount == 0 || dinst->mIndxCount == 0 )
      {
         mDecalQueue.erase_fast( i );
         i--;
         continue;
      }

      //
      F32 alpha = pixelRadius / (dinst->mDataBlock->startPixRadius * decalSize) - 1.0f;
      if ( dinst->mFlags & CustomDecal )
      {
         alpha = mClampF( alpha, 0.0f, 1.0f );
         alpha *= dinst->mVisibility;
      }
      else
         alpha = mClampF( alpha * dinst->mVisibility, 0.0f, 1.0f );

      //
      for ( U32 v = 0; v < dinst->mVertCount; v++ )
         dinst->mVerts[v].color.set( 255, 255, 255, alpha * 255.0f );
   }

   PROFILE_END();   

   if ( mDecalQueue.empty() )
      return false;

   // Sort queued decals...
   // 1. Editor decals - in render priority order first, creation time second, and material third.
   // 2. Dynamic decals - in render priority order first and creation time second.
   //
   // With the constraint that decals with different render priority cannot
   // be rendered together in the same draw call.

   PROFILE_START( DecalManager_RenderDecals_Sort );
   dQsort( mDecalQueue.address(), mDecalQueue.size(), sizeof(DecalInstance*), cmpDecalRenderOrder );
   PROFILE_END();

   PROFILE_SCOPE( DecalManager_RenderDecals_RenderBatch );

   mPrimBuffs.clear();
   mVBs.clear();

   RenderPassManager *renderPass = state->getRenderPass();

   // Base render instance for convenience we use for convenience.
   // Data shared by all instances we allocate below can be copied
   // from the base instance at the same time.
   MeshRenderInst baseRenderInst;
   baseRenderInst.clear();   

   MatrixF *tempMat = renderPass->allocUniqueXform( MatrixF( true ) );
   MathUtils::getZBiasProjectionMatrix( gDecalBias, mCuller, tempMat );
   baseRenderInst.projection = tempMat;

   baseRenderInst.objectToWorld = &MatrixF::Identity;
   baseRenderInst.worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);

   baseRenderInst.type = RenderPassManager::RIT_Decal;      

   // Make it the sort distance the max distance so that 
   // it renders after all the other opaque geometry in 
   // the prepass bin.
   baseRenderInst.sortDistSq = F32_MAX;

   // Get the best lights for the current camera position.
   LightManager *lm = state->getLightManager();
   if ( lm )
   {
      lm->setupLights(  NULL, 
                        mCuller.getPosition(),
                        mCuller.getTransform().getForwardVector(),
                        mCuller.getFarDist() );
      lm->getBestLights( baseRenderInst.lights, 4 );
      lm->resetLights();
   }

   Vector<DecalBatch> batches;
   DecalBatch *currentBatch = NULL;

   // Loop through DecalQueue collecting them into render batches.
   for ( U32 i = 0; i < mDecalQueue.size(); i++ )
   {
      DecalInstance *decal = mDecalQueue[i];      
      DecalData *data = decal->mDataBlock;
      Material *mat = data->getMaterial();

      if ( currentBatch == NULL )
      {
         // Start a new batch, beginning with this decal.

         batches.increment();
         currentBatch = &batches.last();
         currentBatch->startDecal = i;
         currentBatch->decalCount = 1;
         currentBatch->iCount = decal->mIndxCount;
         currentBatch->vCount = decal->mVertCount;
         currentBatch->mat = mat;
         currentBatch->matInst = decal->mDataBlock->getMaterialInstance();
         currentBatch->priority = decal->getRenderPriority();         
         currentBatch->dynamic = !(decal->mFlags & SaveDecal);

         continue;
      }

      if ( currentBatch->iCount + decal->mIndxCount >= smMaxIndices || 
           currentBatch->vCount + decal->mVertCount >= smMaxVerts ||
           currentBatch->mat != mat ||
           currentBatch->priority != decal->getRenderPriority() ||
           decal->mCustomTex )
      {
         // End batch.

         currentBatch = NULL;
         i--;
         continue;
      }

      // Add on to current batch.
      currentBatch->decalCount++;
      currentBatch->iCount += decal->mIndxCount;
      currentBatch->vCount += decal->mVertCount;
   }

   // Loop through batches allocating buffers and submitting render instances.
   for ( U32 i = 0; i < batches.size(); i++ )
   {
      DecalBatch &currentBatch = batches[i];

      // Allocate buffers...

      GFXVertexBufferHandle<DecalVertex> vb;
      vb.set( GFX, currentBatch.vCount, GFXBufferTypeDynamic );
      DecalVertex *vpPtr = vb.lock();

      GFXPrimitiveBufferHandle pb;
      pb.set( GFX, currentBatch.iCount, 0, GFXBufferTypeDynamic );
      U16 *pbPtr;
      pb.lock( &pbPtr );

      // Copy data into the buffers from all decals in this batch...

      U32 lastDecal = currentBatch.startDecal + currentBatch.decalCount;

      U32 voffset = 0;
      U32 ioffset = 0;

      // This is an ugly hack for ProjectedShadow!
      GFXTextureObject *customTex = NULL;

      for ( U32 j = currentBatch.startDecal; j < lastDecal; j++ )
      {
         DecalInstance *dinst = mDecalQueue[j];

         for ( U32 k = 0; k < dinst->mIndxCount; k++ )
         {
            *( pbPtr + ioffset + k ) = dinst->mIndices[k] + voffset;            
         }

         ioffset += dinst->mIndxCount;

         dMemcpy( vpPtr + voffset, dinst->mVerts, sizeof( DecalVertex ) * dinst->mVertCount );
         voffset += dinst->mVertCount;

         // Ugly hack for ProjectedShadow!
         if ( (dinst->mFlags & CustomDecal) && dinst->mCustomTex != NULL )
            customTex = *dinst->mCustomTex;
      }

      AssertFatal( ioffset == currentBatch.iCount, "bad" );
      AssertFatal( voffset == currentBatch.vCount, "bad" );
        
      pb.unlock();
      vb.unlock();

      // DecalManager must hold handles to these buffers so they remain valid,
      // we don't actually use them elsewhere.
      mPrimBuffs.push_back( pb );
      mVBs.push_back( vb );

      // Submit render inst...

      MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();

      *ri = baseRenderInst;

      ri->primBuff = &mPrimBuffs.last();
      ri->vertBuff = &mVBs.last();

      ri->matInst = currentBatch.matInst;

      ri->prim = renderPass->allocPrim();
      ri->prim->type = GFXTriangleList;
      ri->prim->minIndex = 0;
      ri->prim->startIndex = 0;
      ri->prim->numPrimitives = currentBatch.iCount / 3;
      ri->prim->startVertex = 0;
      ri->prim->numVertices = currentBatch.vCount;

      // Ugly hack for ProjectedShadow!
      if ( customTex )
         ri->miscTex = customTex;

      // The decal bin will contain render instances for both decals and decalRoad's.
      // Dynamic decals render last, then editor decals and roads in priority order.
      // DefaultKey is sorted in descending order.
      ri->defaultKey = currentBatch.dynamic ? 0xFFFFFFFF : (U32)currentBatch.priority;
      ri->defaultKey2 = 1;//(U32)lastDecal->mDataBlock;

      renderPass->addInst( ri );
   }

   return false;
}
//Called to update the display.
//You should call glutSwapBuffers after all of your rendering to display what you rendered.
//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
void display()
{
	g_lights.UpdateTime();

	glm::vec4 bkg = g_lights.GetBackgroundColor();

	glClearColor(bkg[0], bkg[1], bkg[2], bkg[3]);
	glClearDepth(1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glutil::MatrixStack modelMatrix;
	modelMatrix.SetMatrix(g_viewPole.CalcMatrix());

	const glm::mat4 &worldToCamMat = modelMatrix.Top();
	LightBlock lightData = g_lights.GetLightInformation(worldToCamMat);

	glBindBuffer(GL_UNIFORM_BUFFER, g_lightUniformBuffer);
	glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightData), &lightData);
	glBindBuffer(GL_UNIFORM_BUFFER, 0);

	if(g_pScene)
	{
		glutil::PushStack push(modelMatrix);

		g_pScene->Draw(modelMatrix, g_materialBlockIndex, g_lights.GetTimerValue("tetra"));
	}

	{
		glutil::PushStack push(modelMatrix);
		//Render the sun
		{
			glutil::PushStack push(modelMatrix);

			glm::vec3 sunlightDir(g_lights.GetSunlightDirection());
			modelMatrix.Translate(sunlightDir * 500.0f);
			modelMatrix.Scale(30.0f, 30.0f, 30.0f);

			glUseProgram(g_Unlit.theProgram);
			glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
				glm::value_ptr(modelMatrix.Top()));

			glm::vec4 lightColor = g_lights.GetSunlightIntensity();
			glUniform4fv(g_Unlit.objectColorUnif, 1, glm::value_ptr(lightColor));
			g_pScene->GetSphereMesh()->Render("flat");
		}

		//Render the lights
		if(g_bDrawLights)
		{
			for(int light = 0; light < g_lights.GetNumberOfPointLights(); light++)
			{
				glutil::PushStack push(modelMatrix);

				modelMatrix.Translate(g_lights.GetWorldLightPosition(light));

				glUseProgram(g_Unlit.theProgram);
				glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
					glm::value_ptr(modelMatrix.Top()));

				glm::vec4 lightColor = g_lights.GetPointLightIntensity(light);
				glUniform4fv(g_Unlit.objectColorUnif, 1, glm::value_ptr(lightColor));
				g_pScene->GetCubeMesh()->Render("flat");
			}
		}

		if(g_bDrawCameraPos)
		{
			glutil::PushStack push(modelMatrix);

			modelMatrix.SetIdentity();
			modelMatrix.Translate(glm::vec3(0.0f, 0.0f, -g_viewPole.GetView().radius));

			glDisable(GL_DEPTH_TEST);
			glDepthMask(GL_FALSE);
			glUseProgram(g_Unlit.theProgram);
			glUniformMatrix4fv(g_Unlit.modelToCameraMatrixUnif, 1, GL_FALSE,
				glm::value_ptr(modelMatrix.Top()));
			glUniform4f(g_Unlit.objectColorUnif, 0.25f, 0.25f, 0.25f, 1.0f);
			g_pScene->GetCubeMesh()->Render("flat");
			glDepthMask(GL_TRUE);
			glEnable(GL_DEPTH_TEST);
			glUniform4f(g_Unlit.objectColorUnif, 1.0f, 1.0f, 1.0f, 1.0f);
			g_pScene->GetCubeMesh()->Render("flat");
		}
	}

	glutPostRedisplay();
	glutSwapBuffers();
}
Exemplo n.º 19
0
bool DecalRoad::prepRenderImage(	SceneState* state, 
                                 const U32 stateKey, 
                                 const U32 startZone,
                                 const bool modifyBaseZoneState)
{
   if (  mNodes.size() <= 1 || 
         isLastState(state, stateKey) || 
         mBatches.size() == 0 ||
         !mMatInst ||
         state->isShadowPass() )
      return false;

   // Set Last State.
   setLastState( state, stateKey );

   // Is Object Rendered?
   if ( !state->isObjectRendered( this ) )
      return false;

   RenderPassManager *renderPass = state->getRenderPass();

   // Debug RenderInstance
   // Only when editor is open.
   if ( smEditorOpen )
   {
      ObjectRenderInst *ri = renderPass->allocInst<ObjectRenderInst>();
      ri->type = RenderPassManager::RIT_Object;
      ri->renderDelegate.bind( this, &DecalRoad::_debugRender );
      state->getRenderPass()->addInst( ri );
   }

   // Normal Road RenderInstance
   // Always rendered when the editor is not open
   // otherwise obey the smShowRoad flag
   if ( !smShowRoad && smEditorOpen )
      return false;

   const Frustum &frustum = state->getFrustum();

   MeshRenderInst coreRI;
   coreRI.clear();
   coreRI.objectToWorld = &MatrixF::Identity;
   coreRI.worldToCamera = renderPass->allocSharedXform(RenderPassManager::View);
   
   MatrixF *tempMat = renderPass->allocUniqueXform( MatrixF( true ) );   
   MathUtils::getZBiasProjectionMatrix( gDecalBias, frustum, tempMat );
   coreRI.projection = tempMat;

   coreRI.type = RenderPassManager::RIT_Decal;
   coreRI.matInst = mMatInst;
   coreRI.vertBuff = &mVB;
   coreRI.primBuff = &mPB;
	
   // Make it the sort distance the max distance so that 
   // it renders after all the other opaque geometry in 
   // the prepass bin.
   coreRI.sortDistSq = F32_MAX;

	// Get the light manager and setup lights
   LightManager *lm = state->getLightManager();
   if ( lm )
   {
      lm->setupLights( this, getWorldSphere() );
		lm->getBestLights( coreRI.lights, 8 );
   }

   U32 startBatchIdx = -1;
   U32 endBatchIdx = 0;

   for ( U32 i = 0; i < mBatches.size(); i++ )   
   {
      // TODO: visibility is bugged... must fix!
      //const RoadBatch &batch = mBatches[i];
      //const bool isVisible = frustum.intersects( batch.bounds );         
      if ( true /*isVisible*/ )
      {
         // If this is the start of a set of batches.
         if ( startBatchIdx == -1 )
            endBatchIdx = startBatchIdx = i;

         // Else we're extending the end batch index.
         else
            ++endBatchIdx; 

         // If this isn't the last batch then continue.
         if ( i < mBatches.size()-1 )
            continue;
      }

      // We we still don't have a start batch, so skip.
      if ( startBatchIdx == -1 )
         continue;

      // Render this set of batches.
      const RoadBatch &startBatch = mBatches[startBatchIdx]; // mBatches[0]; 
      const RoadBatch &endBatch = mBatches[endBatchIdx]; // mBatches.last(); 

      U32 startVert = startBatch.startVert;
      U32 startIdx = startBatch.startIndex;
      U32 vertCount = endBatch.endVert - startVert;
      U32 idxCount = ( endBatch.endIndex - startIdx ) + 1;
      U32 triangleCount = idxCount / 3;

      AssertFatal( startVert + vertCount <= mVertCount, "DecalRoad, bad draw call!" );
      AssertFatal( startIdx + triangleCount < mTriangleCount * 3, "DecalRoad, bad draw call!" );

      MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>();

      *ri = coreRI;

      ri->prim = renderPass->allocPrim();
      ri->prim->type = GFXTriangleList;
      ri->prim->minIndex = 0;
      ri->prim->startIndex = startIdx;
      ri->prim->numPrimitives = triangleCount;
      ri->prim->startVertex = startVert;
      ri->prim->numVertices = vertCount;

      // For sorting we first sort by render priority
      // and then by objectId. 
      //
      // Since a road can submit more than one render instance, we want all 
      // draw calls for a single road to occur consecutively, since they
      // could use the same vertex buffer.
      ri->defaultKey =  mRenderPriority << 0 | mId << 16;
      ri->defaultKey2 = 0;

      renderPass->addInst( ri );

      // Reset the batching.
      startBatchIdx = -1;
   }   

   return false;
}
Exemplo n.º 20
0
int main(int argc, char* argv[])
{
	Graphics::WindowConfig wc;
	wc.width = 1280;
	wc.height = 720;
	wc.resizable = false;
	wc.mode = Graphics::WindowMode::WINDOW;

	Graphics::ContextConfig cc;
	cc.msaaSamples = 4;
	cc.debugContext = true;
	cc.glewExperimental = true;
	cc.coreProfileContext = true;
#ifdef _DEBUG
	cc.synchronousDebugOutput = true;
#else
	cc.synchronousDebugOutput = false;
#endif

	Graphics::RenderingSystem renderingSystem;

	if (!renderingSystem.Init(wc, cc))
	{
		fprintf(stderr, "Error while initializing renderingsystem.\n");
		return 1;
	}

	auto deferredShader = renderingSystem.CreateShaderProgram(
		Graphics::ShaderInfo::VSFS("shaders/deferred.vs", "shaders/deferred.fs", "shaders/")
		);

	auto deferredLightShader = renderingSystem.CreateShaderProgram(
		Graphics::ShaderInfo::VSFS("shaders/deferredlight.vs", "shaders/deferredlight.fs", "shaders/")
		);

	auto copyShader = renderingSystem.CreateShaderProgram(
		Graphics::ShaderInfo::VSFS("shaders/copy.vs", "shaders/copy.fs", "shaders/")
		);

	// Full-screen quad
	auto quadVertexBuffer = renderingSystem.CreateBuffer();
	renderingSystem.UpdateBuffer(quadVertexBuffer, MeshUtils::quadVertices.data(), MeshUtils::quadVertices.size() * sizeof(float), Graphics::BufferType::STATIC);

	// Postprocessing
	PostProcess_SSAO ssaoPP;
	ssaoPP.Init(renderingSystem, quadVertexBuffer);

	// Rendertargets
	auto gBufferRT = renderingSystem.CreateRenderTarget(Graphics::RenderTargetOptions::SRGB8DepthRGB8(wc.width, wc.height));
	auto tempRT = renderingSystem.CreateRenderTarget(Graphics::RenderTargetOptions::SRGB8Depth(wc.width, wc.height));

	// For per-frame shader data
	PerFrameUBO perFrameUBO;
	perFrameUBO.nearPlane = 0.1f;
	perFrameUBO.farPlane = 100.0f;
	perFrameUBO.proj = glm::perspective(45.0f, wc.width / (float)wc.height, perFrameUBO.nearPlane, perFrameUBO.farPlane);
	perFrameUBO.flags = PerFrameUBO::Flags::NormalMapping | PerFrameUBO::Flags::ParallaxMapping;

	auto perFrameUBOHandle = renderingSystem.CreateBuffer();
	renderingSystem.UpdateBuffer(perFrameUBOHandle, NULL, sizeof(perFrameUBO), Graphics::BufferType::DYNAMIC);
	renderingSystem.BindUniformBuffer(Constants::PER_FRAME_UBO_BINDING_INDEX, perFrameUBOHandle);

	// Used for per-drawcall shader data 
	auto perDrawUBOHandle = renderingSystem.CreateBuffer();
	renderingSystem.UpdateBuffer(perDrawUBOHandle, NULL, sizeof(DrawUBO), Graphics::BufferType::DYNAMIC);
	renderingSystem.BindUniformBuffer(Constants::PER_DRAW_UBO_BINDING_INDEX, perDrawUBOHandle);

	// Animates the lights and updates uniform buffer with lightdata
	LightManager<10> lightManager;
	lightManager.Init(renderingSystem);

	// To avoid having to load all textures at startup
	TextureLoader textureLoader;

	// Load the scene.
	// This can take a while for big scenes, so it'll poll the window to keep it responsive.
	std::vector<Renderable> renderables;
	if (!GetRenderables(dataFolder, textureLoader, renderingSystem, renderables /*out*/))
	{
		return 0;
	}

	// Used for culling
	std::vector<bool> isCulled;
	FrustumCuller<Renderable> frustumCuller;

	glm::vec3 cameraPosition(0, 2, 0);
	glm::quat cameraOrientation;

	uint8_t ssaoState = 1;
	const std::array<const char*, 3> ssaoText = {{ "Off", "On", "Occlusion only" }};

	bool parallaxMappingEnabled = true;
	bool normalMappingEnabled = true;

	int frames = 0;
	double timeAccum = 0.0;
	double lastTime = 0.0;

	while (!renderingSystem.CloseRequested())
	{
		double time = renderingSystem.GetTime();
		double dt = time - lastTime;
		lastTime = time;
		timeAccum += dt;

		// Sort renderables by material (could only be done once since it's not dynamic)
		std::sort(renderables.begin(), renderables.end(), [](const Renderable& a, const Renderable& b)
		{
			return a.GetMaterial() < b.GetMaterial();
		});

		// Update movement
		glm::vec3 movement(0, 0, 0);
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::W)) movement.z -= 1.0f;
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::S)) movement.z += 1.0f;
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::A)) movement.x -= 1.0f;
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::D)) movement.x += 1.0f;
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::Q)) movement.y -= 1.0f;
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::E)) movement.y += 1.0f;

		float movementScale = 3.0f;
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::SHIFT))
			movementScale *= 4.0f;

		if (glm::length(movement) > 0)
			movement = glm::normalize(movement) * movementScale * float(dt);

		cameraPosition += movement * cameraOrientation;

		// Mouse look
		static glm::vec2 lastCursor = renderingSystem.GetCursorPosition();
		auto cursor = renderingSystem.GetCursorPosition();
		glm::vec2 diff = lastCursor - cursor;
		lastCursor = cursor;

		if (renderingSystem.IsMouseButtonDown(Graphics::RenderingSystem::MouseButton::Right))
		{
			renderingSystem.SetCursorEnabled(false);
			diff *= 0.1f;
			cameraOrientation = cameraOrientation * glm::rotate(glm::quat(), -diff.x, glm::vec3(0, 1, 0)); // Yaw
			cameraOrientation = glm::rotate(glm::quat(), -diff.y, glm::vec3(1, 0, 0)) * cameraOrientation; // Pitch
		}
		else renderingSystem.SetCursorEnabled(true);

		// Update per-frame UBO
		perFrameUBO.view = glm::toMat4(cameraOrientation) * glm::translate(glm::mat4(1.0f), -cameraPosition);
		perFrameUBO.cameraPosition = glm::vec4(cameraPosition, 1.0);
		perFrameUBO.time = time;
		perFrameUBO.flags = 0;

		if (parallaxMappingEnabled)
			perFrameUBO.flags |= PerFrameUBO::Flags::ParallaxMapping;

		if(normalMappingEnabled)
			perFrameUBO.flags |= PerFrameUBO::Flags::NormalMapping;

		if (ssaoState == 2)
			perFrameUBO.flags |= PerFrameUBO::Flags::SSAOState;

		renderingSystem.UpdateBuffer(perFrameUBOHandle, &perFrameUBO, sizeof(perFrameUBO), Graphics::BufferType::DYNAMIC);

		// Update lights
		lightManager.Update(time, cameraPosition);

		// Do frustum-culling
		frustumCuller.Cull(renderables, isCulled, perFrameUBO.proj * perFrameUBO.view);
#if 1
		// Draw to G-buffer
		{
			// Bind G-buffer
			renderingSystem.BindRenderTarget(gBufferRT);

			// Clear it
			renderingSystem.ClearScreen(Graphics::ClearState::AllBuffers());

			// Prepare to fill it
			renderingSystem.UseShaderProgram(deferredShader);
			renderingSystem.BindUniformBuffer(Constants::PER_FRAME_UBO_BINDING_INDEX, perFrameUBOHandle);
			renderingSystem.BindUniformBuffer(Constants::PER_DRAW_UBO_BINDING_INDEX, perDrawUBOHandle);

			// Draw objects
			DrawRenderables(renderingSystem, renderables, isCulled, perDrawUBOHandle);
		}

		// Do lighting to temporary rendertarget (all lights in one pass -- extremly wasteful; 
		// would really want to cull and then draw individual bounding spheres/quads or similar).
		{
			// Prepare G-buffer textures
			renderingSystem.BindRenderTargetTexture(0, gBufferRT, Graphics::RenderTargetTexture::Color);
			renderingSystem.BindRenderTargetTexture(1, gBufferRT, Graphics::RenderTargetTexture::Depth);
			renderingSystem.BindRenderTargetTexture(2, gBufferRT, Graphics::RenderTargetTexture::Aux);

			// Prepare target RT
			renderingSystem.BindRenderTarget(tempRT);
			renderingSystem.ClearScreen(Graphics::ClearState::AllBuffers());

			// Draw fullscreen quad
			renderingSystem.UseShaderProgram(deferredLightShader);
			renderingSystem.Draw(quadVertexBuffer, Graphics::BufferHandle::Invalid(), 6);

			// Bind tempRT's color texture
			renderingSystem.BindRenderTargetTexture(0, tempRT, Graphics::RenderTargetTexture::Color);
		}

		// Bind default framebuffer
		renderingSystem.BindRenderTarget(Graphics::DefaultRenderTarget());
		renderingSystem.ClearScreen(Graphics::ClearState::AllBuffers());

		// Bind depth- and normal-textures for postprocessing (color is from lighting pass)
		renderingSystem.BindRenderTargetTexture(1, gBufferRT, Graphics::RenderTargetTexture::Depth);
		renderingSystem.BindRenderTargetTexture(2, gBufferRT, Graphics::RenderTargetTexture::Aux); // Normals

		if (ssaoState > 0)
			ssaoPP.Run(Graphics::DefaultRenderTarget());
		else
		{
			renderingSystem.UseShaderProgram(copyShader);
			renderingSystem.Draw(quadVertexBuffer, Graphics::BufferHandle::Invalid(), 6);
		}
#endif
		renderingSystem.SubmitFrame();
		++frames;

		// Print FPS
		if (timeAccum > 1.0)
		{
			printf("FPS: %f\n", frames / timeAccum);
			frames = 0;
			timeAccum = 0.0;
		}

		textureLoader.LoadOne(renderingSystem, dataFolder);

		// Poll window-events
		renderingSystem.PollEvents();

		// Enable/Disable features
		if (renderingSystem.WasPressed(Graphics::RenderingSystem::Key::F1))
		{
			ssaoState = (ssaoState + 1) % 3;
			printf("SSAO: %s\n", ssaoText[ssaoState]);
		}

		if (renderingSystem.WasPressed(Graphics::RenderingSystem::Key::F2))
		{
			normalMappingEnabled = !normalMappingEnabled;
			printf("Normal-mapping: %s\n", normalMappingEnabled ? "ON" : "OFF");
		}

		if (renderingSystem.WasPressed(Graphics::RenderingSystem::Key::F3))
		{
			parallaxMappingEnabled = !parallaxMappingEnabled;
			printf("Parallax-mapping: %s\n", parallaxMappingEnabled ? "ON" : "OFF");
		}

		// Hot reload of shaders
		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::SPACE))
			renderingSystem.ReloadShaders();

		if (renderingSystem.IsKeyDown(Graphics::RenderingSystem::Key::ESCAPE))
			break;
	}

	renderingSystem.Shutdown();

	return 0;
}
Exemplo n.º 21
0
////////////////////////////////////////////////////////////
/// Entry point of the application
////////////////////////////////////////////////////////////
int main()
{
	sf::RenderWindow app(sf::VideoMode(800, 600, 32), "Zoom example 3");
	app.setVerticalSyncEnabled(true);
	
	sf::Mouse::setPosition({400, 0});
	sf::Clock clock;

	Geom geom = Geom::segment({100, 100}, {125, 125})
			  + Geom::segment({300, 200}, {450, 325})
			  + Geom::segment({250, 245}, {400, 365})
			  + Geom::segment({500, 200}, {600, 300})
			  + Geom::segment({125, 430}, {125, 475})
			  + Geom::segment({500, 300}, {600, 200})
			  + Geom::segment({125, 475}, {175, 475});
	
	Shape shape(geom);
	shape.setLiaisonsWidth(3);
	shape.setLiaisonsColor(Color::White);

	LightManager lightManager;

	Light light(150, Color::Green);
	light.setPosition({400, 0});

	Spot spot(400, toRads(45), Color(190, 150, 150));
	spot.setPosition({700, 400});

	lightManager.attach(light);
	lightManager.attach(spot);
	lightManager.attach(geom);

	Variation<double> angle(toRads(180), toRads(225), toRads(20), 0, true, true);

	while( app.isOpen() )
	{
		sf::Event event;
	
		while( app.pollEvent(event) )
		{		
			if( event.type == sf::Event::Closed )
				app.close();
		
			else if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape )
				app.close();
		
			else if( event.type == sf::Event::MouseButtonPressed )
				lightManager.setDebugMode(!lightManager.getDebugMode());

			else if( event.type == sf::Event::MouseMoved )
				light.setPosition(event.mouseMove.x, event.mouseMove.y);
		}

		sf::Time timeStep = clock.restart();

		lightManager.update();
		spot.setRotation(angle.update(timeStep));
	
		app.clear();
		app.draw(shape);
		app.draw(lightManager);

		app.display();
	}
	
	return EXIT_SUCCESS;
}