/* 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(); } }
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; }
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)); }
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)); }
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); }
//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); }
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(); }
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); }
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; } } } } }
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 ¤tBatch = 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(); }
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; }
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; }
//////////////////////////////////////////////////////////// /// 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; }