void DeferredShader::drawLighting(Scene & scene, Camera & camera) { glEnable(GL_BLEND); for (unsigned int i = 0; i < scene.getLightVector().size(); ++i) { for(unsigned int j = 0; j < 5; ++j) { } glm::vec4 lightPos(scene.getLightVector()[i]->getPosition(),1.0); glm::vec4 viewPos(camera.getEyePoint(),1.0); lightPos = (lightPos * camera.getModelViewMatrix()) * camera.getProjectionMatrix(); viewPos = (viewPos * camera.getModelViewMatrix()) * camera.getProjectionMatrix(); shaderManager.setCgParam(lightPos,"lightPos",FRAGMENT); shaderManager.setCgParam(viewPos,"viewPos",FRAGMENT); shaderManager.setCgParam(scene.getLightVector()[i]->getColor(),"lightColor",FRAGMENT); shaderManager.setCgParam(scene.getLightVector()[i]->getRadius(),"radius",FRAGMENT); drawRec(camera); } glDisable(GL_BLEND); }
void MapRenderer::drawBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, const std::string& texture, float heading, float size) { glm::vec2 adjustedCoord = coord; if (mi.clipToSize) { float maxDist = mi.worldSize/2.f; float centerDist = glm::distance(coord, mi.worldCenter); if (centerDist > maxDist) { adjustedCoord = mi.worldCenter + ((coord - mi.worldCenter)/centerDist)*maxDist; } } glm::vec3 viewPos(view * glm::vec4(glm::vec2(1.f,-1.f)*adjustedCoord, 0.f, 1.f)); glm::mat4 model; model = glm::translate(model, viewPos); model = glm::scale(model, glm::vec3(size)); model = glm::rotate(model, heading, glm::vec3(0.f, 0.f, 1.f)); renderer->setUniform(rectProg, "model", model); GLuint tex = 0; if ( !texture.empty() ) { auto sprite= data->findTexture(texture); tex = sprite->getName(); renderer->setUniform(rectProg, "colour", glm::vec4(0.f, 0.f, 0.f, 1.f)); } else { renderer->setUniform(rectProg, "colour", glm::vec4(1.0f, 1.0f, 1.0f, 1.f)); } glBindTexture(GL_TEXTURE_2D, tex); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); }
virtual void update() { PROFILE_BEGIN_FRAME() glFinish(); std::vector<cl::Memory> acquireGLMems = {texMem}; commands.enqueueAcquireGLObjects(&acquireGLMems); //run kernel cl::NDRange globalSize = cl::NDRange(size(0), size(1)); cl::NDRange localSize = cl::NDRange(16, 16); cl::NDRange offset = cl::NDRange(0, 0); //update new buffer and display texture setArgs(updateKernel, updateBuffers[!bufferIndex], updateBuffers[bufferIndex], texMem); commands.enqueueNDRangeKernel(updateKernel, offset, globalSize, localSize); bufferIndex = !bufferIndex; commands.enqueueReleaseGLObjects(&acquireGLMems); commands.finish(); //clear screen buffer Super::update(); //transforms glLoadIdentity(); glTranslatef(-viewPos(0), -viewPos(1), 0); glScalef(viewZoom, viewZoom, viewZoom); //display glBindTexture(GL_TEXTURE_2D, texID); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(-.5f, -.5f); glTexCoord2f(1,0); glVertex2f(.5f, -.5f); glTexCoord2f(1,1); glVertex2f(.5f, .5f); glTexCoord2f(0,1); glVertex2f(-.5f, .5f); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); PROFILE_END_FRAME() }
void CharacterModel::SetupFX() { DDCamera* cam = GPlayerManager->GetCamera(); D3DXVECTOR4 viewPos( cam->GetTransform().GetPosition(), 0.0f ); D3DXMATRIXA16 wvp = cam->GetMatProj() * cam->GetMatView() * m_Matrix; D3DXVECTOR3 lightDir = GEnvironmentManager->GetLight( ClientLightTag::DIRECTIONAL_MAIN )->GetViewDirection(); // m_pEffect->SetMatrix( "g_matWVP", &wvp ); // m_pEffect->SetMatrix( "g_matWorld", &m_Matrix ); // m_pEffect->SetVector( "g_camPos", &viewPos ); // m_pEffect->SetValue( "g_vLightDir", &lightDir, sizeof( lightDir ) ); m_pEffect->SetMatrix( "gWorldMatrix", &m_Matrix ); m_pEffect->SetMatrix( "gViewMatrix", &cam->GetMatView() ); m_pEffect->SetMatrix( "gProjectionMatrix", &cam->GetMatProj() ); }
void CameraProperty::changeFocusPoint(Event* event) { if (auto mouseEvent = dynamic_cast<MouseEvent*>(event)) { auto p = mouseEvent->posNormalized(); auto d = mouseEvent->depth(); if (std::abs(d - 1.0) < glm::epsilon<decltype(d)>()) { return; } p.y = 1.0f - p.y; p = p * 2.0f - 1.0f; vec4 viewPos(p.x, p.y, static_cast<float>(d), 1.0f); auto point = (inverseViewMatrix() * inverseProjectionMatrix()) * viewPos; auto newLookTo = point.xyz() / point.w; auto newLookFrom = lookFrom_.get() + (newLookTo - lookTo_.get()); setLookTo(newLookTo); setLookFrom(newLookFrom); } event->markAsUsed(); }
void SDRender::UpdateSky(double currentTime, double accelTime) { // Detect first call (in order to initialize "last times"). static bool bInitialized = false; static double lastTimeHighSpeed = 0; static int lastTimeLowSpeed = 0; // Nothing to do if static sky dome, or race not started. //if (!grDynamicSkyDome) //TODO(kilo): find some meaning for this variable /*if (!SDSkyDomeDistance || SDTrack->skyversion < 1) return;*/ if (currentTime < 0) { bInitialized = false; return; } if (!bInitialized) { if ( SDSkyDomeDistance ) { // Ensure the sun and moon positions are reset const int timeOfDay = (int)SDTrack->local.timeofday; GLfloat sunAscension = SDTrack->local.sunascension; SDSunDeclination = (float)(15 * (double)timeOfDay / 3600 - 90.0); const float moonAscension = SDTrack->local.sunascension; //SDMoonDeclination = grUpdateMoonPos(timeOfDay); thesky->setSD( DEG2RAD(SDSunDeclination)); thesky->setSRA( sunAscension ); thesky->setMD( DEG2RAD(SDMoonDeclination) ); thesky->setMRA( DEG2RAD(moonAscension) ); } lastTimeHighSpeed = currentTime; lastTimeLowSpeed = 60 * (int)floor(accelTime / 60.0); bInitialized = true; return; } // At each call, update possibly high speed objects of the sky dome : the clouds. scenery = (SDScenery *)getScenery(); double r_WrldX = scenery->getWorldX(); double r_WrldY = scenery->getWorldY(); osg::Vec3 viewPos(r_WrldX / 2, r_WrldY/ 2, 0.0 ); thesky->reposition(viewPos, 0, currentTime - lastTimeHighSpeed); // Now, we are done for high speed objects. lastTimeHighSpeed = currentTime; // Check if time to update low speed objects : sun and moon (once every minute). int nextTimeLowSpeed = 60 * (int)floor((accelTime + 60.0) / 60.0); const float deltaTimeLowSpeed = (float)(nextTimeLowSpeed - lastTimeLowSpeed); // Update sun and moon, and thus global lighting / coloring parameters of the scene. if (nextTimeLowSpeed != lastTimeLowSpeed) { // 1) Update sun position const float deltaDecl = deltaTimeLowSpeed * 360.0f / (24.0f * 60.0f * 60.0f); SDSunDeclination += deltaDecl; if (SDSunDeclination >= 360.0f) SDSunDeclination -= 360.0f; thesky->setSD( DEG2RAD(SDSunDeclination) ); // 2) Update moon position SDMoonDeclination += deltaDecl; if (SDMoonDeclination >= 360.0f) SDMoonDeclination -= 360.0f; thesky->setMD( DEG2RAD(SDMoonDeclination) ); lastTimeLowSpeed = nextTimeLowSpeed; } // 3) Update scene color and light UpdateLight(); sunLight->getLight()->setAmbient(SceneAmbiant); sunLight->getLight()->setDiffuse(SceneDiffuse); sunLight->getLight()->setSpecular(SceneSpecular); sunLight->setStateSetModes(*stateSet,osg::StateAttribute::ON); float emis = 0.5f * sky_brightness; float ambian = 0.8f * sky_brightness; Scene_ambiant = osg::Vec4f(ambian, ambian, ambian, 1.0f); osg::ref_ptr<osg::Material> material = new osg::Material; material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(emis, emis, emis, 1.0f)); material->setAmbient(osg::Material::FRONT_AND_BACK, Scene_ambiant); stateSet->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); osg::Vec3f sun_position = thesky->sunposition(); osg::Vec3f sun_direction = -sun_position; osg::Vec4f position(sun_position, 1.0f); sunLight->getLight()->setPosition(position); sunLight->getLight()->setDirection(sun_direction); }//grUpdateSky
/** * SDRender * Initialises a scene (ie a new view). * * @return 0 if OK, -1 if something failed */ void SDRender::Init(tTrack *track) { SDTrack = track; std::string datapath = GetDataDir(); //datapath +="/"; thesky = new SDSky; GfOut("SDSky class\n"); // Sky dome / background. SDSkyDomeDistance = 20000; if (SDSkyDomeDistance > 0 && SDSkyDomeDistance < SDSkyDomeDistThresh) SDSkyDomeDistance = SDSkyDomeDistThresh; // If user enabled it (>0), must be at least the threshold. SDDynamicSkyDome = strcmp(GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_DYNAMICSKYDOME, GR_ATT_DYNAMICSKYDOME_DISABLED), GR_ATT_DYNAMICSKYDOME_ENABLED) == 0; GfLogInfo("Graphic options : Sky dome : distance = %u m, dynamic = %s\n", SDSkyDomeDistance, SDDynamicSkyDome ? "true" : "false"); // Dynamic weather. //grDynamicWeather = GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_grDynamicWeather, (char*)NULL, grDynamicWeather); // Cloud layers. SDNbCloudLayers = (unsigned)(GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_CLOUDLAYER, 0, 0) + 0.5); GfLogInfo("Graphic options : Number of cloud layers : %u\n", SDNbCloudLayers); SDMax_Visibility = (unsigned)(GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_VISIBILITY, 0, 0)); ShadowIndex = 0; // Default value index, in case file value not found in list. const char* pszShadow = GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_SHADOW_TYPE, GR_ATT_SHADOW_NONE); for (int i = 0; i < NbShadowValues; i++) { if (!strcmp(pszShadow, ShadowValues[i])) { ShadowIndex = i; break; } } TexSizeIndex = 0; // Default value index, in case file value not found in list. const char* pszTexSize = GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_SHADOW_SIZE, GR_ATT_SHADOW_1024); for (int i = 0; i < NbTexSizeValues; i++) { if (!strcmp(pszTexSize, TexSizeValues[i])) { TexSizeIndex = i; break; } } switch (TexSizeIndex) { case 0: ShadowTexSize = 512; break; case 1: ShadowTexSize = 1024; break; case 2: ShadowTexSize = 2048; break; case 3: ShadowTexSize = 4096; break; case 4: ShadowTexSize = 8192; break; default: ShadowTexSize = 1024; break; } QualityIndex = 0; // Default value index, in case file value not found in list. const char* pszQuality = GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_AGR_QUALITY, GR_ATT_AGR_LITTLE); for (int i = 0; i < NbQualityValues; i++) { if (!strcmp(pszQuality, QualityValues[i])) { QualityIndex = i; break; } } carsShader = 0; // Default value index, in case file value not found in list. const char* pszShaders = GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_SHADERS, GR_ATT_AGR_NULL); for (int i = 0; i < NbShadersValues; i++) { if (!strcmp(pszShaders, ShadersValues[i])) { carsShader = i; break; } } GfLogInfo("Graphic options : Shadow Type : %u\n", ShadowIndex); GfLogInfo("Graphic options : Shadow Texture Size : %u\n", ShadowTexSize); GfLogInfo("Graphic options : Shadow Quality : %u\n", QualityIndex); NStars = NMaxStars; if (AStarsData) delete [] AStarsData; AStarsData = new osg::Vec3d[NStars]; for(int i= 0; i < NStars; i++) { AStarsData[i][0] = SDRandom() * PI; AStarsData[i][1] = SDRandom() * PI; AStarsData[i][2] = SDRandom() * 7.0; } GfLogInfo(" Stars (random) : %d\n", NStars); NPlanets = 0; APlanetsData = NULL; GfLogInfo(" Planets : %d\n", NPlanets); const int timeOfDay = (int)SDTrack->local.timeofday; const double domeSizeRatio = SDSkyDomeDistance / 80000.0; GfLogInfo(" domeSizeRation : %d\n", domeSizeRatio); thesky->build(datapath, SDSkyDomeDistance, SDSkyDomeDistance, 800, 40000, 800, 30000, NPlanets, APlanetsData, NStars, AStarsData ); GfOut("Build SKY\n"); GLfloat sunAscension = SDTrack->local.sunascension; SDSunDeclination = (float)(15 * (double)timeOfDay / 3600 - 90.0); thesky->setSD( DEG2RAD(SDSunDeclination)); thesky->setSRA( sunAscension ); GfLogInfo(" Sun : time of day = %02d:%02d:%02d (declination = %.1f deg), " "ascension = %.1f deg\n", timeOfDay / 3600, (timeOfDay % 3600) / 60, timeOfDay % 60, SDSunDeclination, RAD2DEG(sunAscension)); if ( SDSunDeclination > 180 ) SDMoonDeclination = 3.0 + (rand() % 40); else SDMoonDeclination = (rand() % 270); //SDMoonDeclination = grUpdateMoonPos(timeOfDay); //SDMoonDeclination = 22.0; /*(rand() % 270);*/ const float moonAscension = SDTrack->local.sunascension; thesky->setMD( DEG2RAD(SDMoonDeclination) ); thesky->setMRA( DEG2RAD(moonAscension) ); GfLogInfo(" Moon : declination = %.1f deg, ascension = %.1f deg\n", SDMoonDeclination, moonAscension); /* SDCloudLayer *layer = new SDCloudLayer(datapath); layer->setCoverage(layer->SD_CLOUD_CIRRUS); layer->setSpeed(30); layer->setDirection(20); layer->setElevation_m(3000); layer->setThickness_m(400 / domeSizeRatio); layer->setTransition_m(400 / domeSizeRatio); layer->setSpan_m(SDSkyDomeDistance / 2); thesky->add_cloud_layer(layer); SDCloudLayer *layer2 = new SDCloudLayer(datapath); layer2->setCoverage(layer2->SD_CLOUD_CIRRUS2); layer2->setSpeed(60); layer2->setDirection(20); layer2->setElevation_m(1500); layer2->setThickness_m(400 / domeSizeRatio); layer2->setTransition_m(400 / domeSizeRatio); layer2->setSpan_m(SDSkyDomeDistance / 2); thesky->add_cloud_layer(layer2);*/ // Initialize the whole sky dome. SDScenery * scenery = (SDScenery *)getScenery(); double r_WrldX = scenery->getWorldX(); double r_WrldY = scenery->getWorldY(); //double r_WrldZ = SDScenery::getWorldZ(); osg::Vec3 viewPos(r_WrldX / 2, r_WrldY/ 2, 0.0 ); weather(); thesky->set_visibility( SDVisibility ); // Visibility in meters thesky->reposition( viewPos, 0, 0); sol_angle = (float)thesky->getSA(); moon_angle = (float)thesky->getMA(); thesky->repaint(SkyColor, FogColor, CloudsColor, sol_angle, moon_angle, NPlanets, APlanetsData, NStars, AStarsData); UpdateLight(); osg::ref_ptr<osg::Group> sceneGroup = new osg::Group; osg::ref_ptr<osg::Group> mRoot = new osg::Group; osg::ref_ptr<osgShadow::ShadowMap> vdsm = new osgShadow::ShadowMap; m_scene = new osg::Group; m_CarRoot = new osg::Group; m_RealRoot = new osg::Group; shadowRoot = new osgShadow::ShadowedScene; osg::ref_ptr<osgParticle::PrecipitationEffect> precipitationEffect = new osgParticle::PrecipitationEffect; if (SDVisibility < 2000) { sceneGroup->addChild(precipitationEffect.get()); } osg::ref_ptr<osg::Group> scene = new osg::Group; osg::ref_ptr<osg::Group> background = new osg::Group; osg::ref_ptr<osg::Group> cargroup = new osg::Group; scene->addChild(scenery->getScene()); cargroup->addChild(m_CarRoot.get()); background->addChild(scenery->getBackground()); if(ShadowIndex > 0) { switch (QualityIndex+1) { case 0: break; case 1: scene->setNodeMask( rcvShadowMask ); background->setNodeMask(~(rcvShadowMask | castShadowMask)); cargroup->setNodeMask(castShadowMask); break; case 2: scene->setNodeMask( rcvShadowMask ); background->setNodeMask(~(rcvShadowMask | castShadowMask)); cargroup->setNodeMask(rcvShadowMask | castShadowMask); break; case 3: scene->setNodeMask( rcvShadowMask | castShadowMask); background->setNodeMask(~(rcvShadowMask | castShadowMask)); cargroup->setNodeMask(rcvShadowMask | castShadowMask); break; default: break; } } m_scene->addChild(scene.get()); m_scene->addChild(cargroup.get()); m_scene->addChild(background.get()); sceneGroup->addChild(m_scene.get()); stateSet = new osg::StateSet; stateSet = m_scene->getOrCreateStateSet(); stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); if (SDVisibility < 2000) stateSet->setAttributeAndModes(precipitationEffect->getFog()); float emis = 0.5f * sky_brightness; float ambian = 0.8f * sky_brightness; osg::ref_ptr<osg::Material> material = new osg::Material; material->setColorMode(osg::Material::OFF); // switch glColor usage off Scene_ambiant = osg::Vec4f( ambian, ambian, ambian, 1.0f); ; material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(emis, emis, emis, 1.0f)); material->setAmbient(osg::Material::FRONT_AND_BACK, Scene_ambiant); stateSet->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); lightSource = new osg::LightSource; lightSource->getLight()->setDataVariance(osg::Object::DYNAMIC); lightSource->getLight()->setLightNum(0); // relative because of CameraView being just a clever transform node lightSource->setReferenceFrame(osg::LightSource::RELATIVE_RF); lightSource->setLocalStateSetModes(osg::StateAttribute::ON); lightSource->getLight()->setAmbient(osg::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); lightSource->getLight()->setDiffuse(osg::Vec4( 0.2f, 0.2f, 0.2f, 1.0f)); lightSource->getLight()->setSpecular(osg::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); sceneGroup->addChild(lightSource); // we need a white diffuse light for the phase of the moon sunLight = new osg::LightSource; sunLight->getLight()->setDataVariance(osg::Object::DYNAMIC); sunLight->getLight()->setLightNum(1); sunLight->setReferenceFrame(osg::LightSource::RELATIVE_RF); sunLight->setLocalStateSetModes(osg::StateAttribute::ON); sunLight->getLight()->setAmbient(SceneAmbiant); sunLight->getLight()->setDiffuse(SceneDiffuse); sunLight->getLight()->setSpecular(SceneSpecular); sunLight->setStateSetModes(*stateSet,osg::StateAttribute::ON); osg::Vec3f sun_position = thesky->sunposition(); osg::Vec3f sun_direction = -sun_position; osg::Vec4f position(sun_position, 1.0f); sunLight->getLight()->setPosition(position); sunLight->getLight()->setDirection(sun_direction); skyGroup = new osg::Group; skyGroup->setName("skyCloudsGroup"); skyGroup->setNodeMask(thesky->BACKGROUND_BIT); skyGroup->addChild(thesky->getPreRoot()); skyGroup->addChild((thesky->getCloudRoot())); skySS = new osg::StateSet; skySS = skyGroup->getOrCreateStateSet(); skySS->setMode(GL_LIGHT0, osg::StateAttribute::OFF); skySS->setAttributeAndModes( new osg::ColorMask( true, true, true, false ), osg::StateAttribute::ON ); skyGroup->setNodeMask(~(rcvShadowMask | castShadowMask)); sunLight->addChild(skyGroup.get()); mRoot->addChild(sceneGroup.get()); mRoot->setStateSet(setFogState().get()); mRoot->addChild(sunLight.get()); // Clouds are added to the scene graph later osg::ref_ptr<osg::StateSet> stateSet2 = new osg::StateSet; stateSet2 = mRoot->getOrCreateStateSet(); stateSet2->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); stateSet2->setMode(GL_LIGHTING, osg::StateAttribute::ON); stateSet2->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); m_RealRoot->addChild(mRoot.get()); GfOut("LE POINTEUR %d\n", mRoot.get()); }//SDRender::Init
void GLLineIlluminator::enableLighting(GLContextData& contextData) const { /* Get a pointer to the context data item: */ DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this); /* Update the material texture if it is outdated: */ if(dataItem->materialVersion!=materialVersion) updateMaterial(dataItem); GLenum previousMatrixMode=glGet<GLint>(GL_MATRIX_MODE); Geometry::Matrix<GLfloat,4,4> modelView; if(autoViewDirection||autoLightDirection) { /* Get the modelview matrix from OpenGL: */ GLfloat matrixArray[16]; glGetFloatv(GL_MODELVIEW_MATRIX,matrixArray); modelView=Geometry::Matrix<GLfloat,4,4>::fromColumnMajor(matrixArray); } /* Determine the view direction: */ Geometry::ComponentArray<GLfloat,3> viewDir(viewDirection.getXyzw()); if(autoViewDirection) { /* Get the projection matrix from OpenGL: */ GLfloat matrixArray[16]; glGetFloatv(GL_PROJECTION_MATRIX,matrixArray); Geometry::Matrix<GLfloat,4,4> projection=Geometry::Matrix<GLfloat,4,4>::fromColumnMajor(matrixArray); /* Calculate the view direction from the OpenGL projection and modelview matrices: */ Geometry::ComponentArray<GLfloat,4> viewPos(0.0f,0.0f,1.0f,0.0f); viewPos=viewPos/projection; viewPos=viewPos/modelView; /* Check if it's an orthogonal or perspective projection: */ if(Math::abs(viewPos[3])<1.0e-8f) { /* Just copy the view direction: */ viewDir=viewPos; } else { /* Calculate the direction from the view point to the scene center: */ for(int i=0;i<3;++i) viewDir[i]=viewPos[i]/viewPos[3]-sceneCenter[i]; } GLfloat viewDirLen=GLfloat(Geometry::mag(viewDir)); for(int i=0;i<3;++i) viewDir[i]/=viewDirLen; } /* Determine the light direction: */ Geometry::ComponentArray<GLfloat,3> lightDir(lightDirection.getXyzw()); if(autoLightDirection) { /* Query the light direction from OpenGL and transform it to model coordinates: */ Geometry::ComponentArray<GLfloat,4> lightPos; glGetLightPosition(autoLightIndex,lightPos.getComponents()); lightPos=lightPos/modelView; /* Check if it's a directional or point light: */ if(Math::abs(lightPos[3])<1.0e-8f) { /* Just copy the light direction: */ lightDir=lightPos; } else { /* Calculate the direction from the light source to the scene center: */ for(int i=0;i<3;++i) lightDir[i]=lightPos[i]/lightPos[3]-sceneCenter[i]; } GLfloat lightDirLen=GLfloat(Geometry::mag(lightDir)); for(int i=0;i<3;++i) lightDir[i]/=lightDirLen; } /* Set up the OpenGL texture matrix: */ glMatrixMode(GL_TEXTURE); glPushMatrix(); GLfloat matrix[4][4]; for(int j=0;j<3;++j) { matrix[j][0]=lightDir[j]; matrix[j][1]=viewDir[j]; matrix[j][2]=0.0f; matrix[j][3]=0.0f; } matrix[3][0]=1.0f; matrix[3][1]=1.0f; matrix[3][2]=0.0f; matrix[3][3]=2.0f; glLoadMatrixf((const GLfloat*)matrix); /* Set the OpenGL rendering mode: */ glPushAttrib(GL_TEXTURE_BIT); glBindTexture(GL_TEXTURE_2D,dataItem->materialTextureId); glEnable(GL_TEXTURE_2D); if(dataItem->materialType==INTENSITY) glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); else glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); /* Clean up: */ glMatrixMode(previousMatrixMode); }
//! Called by the engine when the vertex and/or pixel shader constants for an //! material renderer should be set. void COpenGLParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) { video::IVideoDriver* driver = services->getVideoDriver(); // set transposed world matrix const core::matrix4& tWorld = driver->getTransform(video::ETS_WORLD).getTransposed(); services->setVertexShaderConstant(tWorld.pointer(), 0, 4); // set transposed worldViewProj matrix core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); worldViewProj *= driver->getTransform(video::ETS_VIEW); worldViewProj *= driver->getTransform(video::ETS_WORLD); core::matrix4 tr(worldViewProj.getTransposed()); services->setVertexShaderConstant(tr.pointer(), 8, 4); // here we fetch the fixed function lights from the driver // and set them as constants u32 cnt = driver->getDynamicLightCount(); // Load the inverse world matrix. core::matrix4 invWorldMat; driver->getTransform(video::ETS_WORLD).getInverse(invWorldMat); for (u32 i=0; i<2; ++i) { video::SLight light; if (i<cnt) light = driver->getDynamicLight(i); else { light.DiffuseColor.set(0,0,0); // make light dark light.Radius = 1.0f; } light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation // Transform the light by the inverse world matrix to get it into object space. invWorldMat.transformVect(light.Position); services->setVertexShaderConstant( reinterpret_cast<const f32*>(&light.Position), 12+(i*2), 1); services->setVertexShaderConstant( reinterpret_cast<const f32*>(&light.DiffuseColor), 13+(i*2), 1); } // Obtain the view position by transforming 0,0,0 by the inverse view matrix // and then multiply this by the inverse world matrix. core::vector3df viewPos(0.0f, 0.0f, 0.0f); core::matrix4 inverseView; driver->getTransform(video::ETS_VIEW).getInverse(inverseView); inverseView.transformVect(viewPos); invWorldMat.transformVect(viewPos); services->setVertexShaderConstant(reinterpret_cast<const f32*>(&viewPos.X), 16, 1); // set scale factor f32 factor = 0.02f; // default value if (CurrentScale != 0.0f) factor = CurrentScale; f32 c6[] = {factor, factor, factor, factor}; services->setPixelShaderConstant(c6, 0, 1); }
bool COGLES2FixedPipelineShader::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) { Driver->testGLError(); bool statusOk = true; /* Matrices Upload */ core::matrix4 world = Driver->getTransform(ETS_WORLD); setUniform(WORLD_MATRIX, world.pointer()); core::matrix4 worldViewProj = Driver->getTransform(video::ETS_PROJECTION); worldViewProj *= Driver->getTransform(video::ETS_VIEW); worldViewProj *= Driver->getTransform(ETS_WORLD); setUniform(MVP_MATRIX, worldViewProj.pointer()); /* Textures Upload */ //statusOk &= setVertexShaderConstant("uTextureUnit", (f32*)TextureUnits, MAX_TEXTURE_UNITS); setUniform(TEXTURE_UNIT0, &TextureUnits[0]); setUniform(TEXTURE_UNIT1, &TextureUnits[1]); setUniform(USE_TEXTURE, UseTexture, MATERIAL_MAX_TEXTURES); setUniform(USE_TEXTURE_MATRIX, UseTexMatrix, MATERIAL_MAX_TEXTURES); setUniform(TEXTURE_MATRIX, TextureMatrix, MATERIAL_MAX_TEXTURES); core::matrix4 invWorld; /* Lights (in Object Space) Upload */ if (Lighting) { u32 cnt = Driver->getDynamicLightCount(); Driver->getTransform(ETS_WORLD).getInverse(invWorld); for ( size_t i = 0; i < MAX_LIGHTS; ++i ) { if ( i < cnt ) { UseLight[i] = 1; video::SLight light; light = Driver->getDynamicLight( i ); switch ( light.Type ) { case ELT_DIRECTIONAL: invWorld.rotateVect(( f32* )&LightPosition[i], light.Direction ); LightPosition[i].data[4] = 0.0; break; case ELT_SPOT: invWorld.rotateVect( LightDirection[i], light.Direction ); LightExponent[i] = light.Falloff; LightCutoff[i] = light.OuterCone; //no break on purpose ! case ELT_POINT: invWorld.transformVect(( f32* )&LightPosition[i], light.Position ); LightPosition[i].data[4] = 1.0; LightAttenuation[i] = light.Attenuation; break; default: UseLight[i] = 0; break; } LightAmbient[i] = light.AmbientColor; LightDiffuse[i] = light.DiffuseColor; LightSpecular[i] = light.SpecularColor; LightAttenuation[i] = light.Attenuation; } else { UseLight[i] = 0; } } //statusOk &= setVertexShaderConstant( "uLighting", ( f32* ) & Lighting, 1 ); setUniform( USE_LIGHT, UseLight, MAX_LIGHTS ); setUniform( LIGHT_POSITION, LightPosition, MAX_LIGHTS ); setUniform( LIGHT_DIRECTION, LightDirection, MAX_LIGHTS ); setUniform( LIGHT_AMBIENT, LightAmbient, MAX_LIGHTS ); setUniform( LIGHT_DIFFUSE, LightDiffuse, MAX_LIGHTS ); setUniform( LIGHT_SPECULAR, LightSpecular, MAX_LIGHTS ); setUniform( LIGHT_ATTENUATION, LightAttenuation, MAX_LIGHTS ); setUniform( LIGHT_EXPONENT, LightExponent, MAX_LIGHTS ); setUniform( LIGHT_CUTOFF, LightCutoff, MAX_LIGHTS ); AmbientColor = Driver->getAmbientLight(); setUniform( LIGHT_AMBIENT, &AmbientColor ); } /* Fog */ /* statusOk &= setVertexShaderConstant("uFog", (f32*) &Fog, 1); statusOk &= setVertexShaderConstant("uFogType", (f32*) &FogType, 1); statusOk &= setVertexShaderConstant("uFogColor", FogColor, 4); statusOk &= setVertexShaderConstant("uFogStart", &FogStart, 1); statusOk &= setVertexShaderConstant("uFogEnd", &FogEnd, 1); statusOk &= setVertexShaderConstant("uFogDensity", &FogDensity, 1);*/ /* Clip Plane */ u32 cnt = Driver->getClipPlaneCount(); if (cnt > 0) { Clip = 1; ClipPlane = Driver->getClipPlane(0); } else { Clip = 0; } /* Eye/Camera Position in ObjectSpace */ if (Clip || RenderMode == EMT_SPHERE_MAP || RenderMode == EMT_REFLECTION_2_LAYER) // Need clipping or reflection { if (!Lighting) Driver->getTransform(ETS_WORLD).getInverse(invWorld); core::vector3df viewPos(0.0f, 0.0f, 0.0f); core::matrix4 inverseView; Driver->getTransform(video::ETS_VIEW).getInverse(inverseView); inverseView.transformVect(viewPos); invWorld.transformVect(viewPos); setUniform(EYE_POSITION, &viewPos.X); } setUniform(CLIP, &Clip); setUniform(CLIP_PLANE, &ClipPlane); setUniform(RENDER_MODE, &RenderMode); return statusOk ; };
void CharacterIn2D::UpdateTopDown(CMap *map, double dt) { //Calculate the friction force static float frictionForce = this->m_mass * GRAVITY * FRICTIONCOEFFICENT; Vector2 frictionDirection; if(m_velocity.Length() > 0) { frictionDirection = -m_velocity.Normalized(); } else { frictionDirection.Set(0,0); } Vector2 frictionInOppositeDirection = frictionDirection * frictionForce; if(frictionInOppositeDirection.Length() < 1.f) { frictionInOppositeDirection.Set(0,0); } m_velocity = m_velocity + (frictionInOppositeDirection * dt); if(m_velocity.Length() < 1.f) { m_velocity.Set(0,0); } // New position next frame Vector2 tilePos((map->GetmapOffset().x + (this->GetPosition().x + (this->m_velocity.x * dt))) / map->GetTileSize() , map->GetNumOfTiles_Height() - (int) (ceil((float)((this->GetPosition().y + this->m_velocity.y * dt) + map->GetTileSize()) / map->GetTileSize()))); Vector2 viewPos((map->GetmapOffset().x + (this->m_viewPosition.x + (this->m_velocity.x * dt))) / map->GetTileSize() , map->GetNumOfTiles_Height() - (int) (ceil((float)((this->m_viewPosition.y + this->m_velocity.y * dt) + map->GetTileSize()) / map->GetTileSize()))); if(m_collision) { if(m_facingNormal.x > 0) { if(map->theScreenMap[viewPos.y][viewPos.x+1] > 0 && map->theScreenMap[viewPos.y+1][viewPos.x+1] > 0) { this->m_viewPosition.x = this->m_viewPosition.x + (m_velocity.x * dt); } if(map->theScreenMap[tilePos.y][tilePos.x+1] > 0 && map->theScreenMap[tilePos.y+1][tilePos.x+1] > 0) { this->m_position.x = this->m_position.x + (m_velocity.x * dt); } else { m_velocity.x = 0; } } else if(m_facingNormal.x < 0) { if(map->theScreenMap[viewPos.y][viewPos.x] > 0 && map->theScreenMap[viewPos.y+1][viewPos.x] > 0) { this->m_viewPosition.x = this->m_viewPosition.x + (m_velocity.x * dt); } if(map->theScreenMap[tilePos.y][tilePos.x] > 0 && map->theScreenMap[tilePos.y+1][tilePos.x] > 0) { this->m_position.x = this->m_position.x + (m_velocity.x * dt); } else { m_velocity.x = 0; } } if(m_facingNormal.y > 0) { if(map->theScreenMap[viewPos.y][viewPos.x] > 0 && map->theScreenMap[viewPos.y][viewPos.x+1] > 0) { this->m_viewPosition.y = this->m_viewPosition.y + (m_velocity.y * dt); } if(map->theScreenMap[tilePos.y][tilePos.x] > 0 && map->theScreenMap[tilePos.y][tilePos.x+1] > 0) { this->m_position.y = this->m_position.y + (m_velocity.y * dt); } else { m_velocity.y = 0; } } else if(m_facingNormal.y < 0) { if(map->theScreenMap[viewPos.y+1][viewPos.x] > 0 && map->theScreenMap[viewPos.y+1][viewPos.x+1] > 0) { this->m_viewPosition.y = this->m_viewPosition.y + (m_velocity.y * dt); } if(map->theScreenMap[tilePos.y+1][tilePos.x] > 0 && map->theScreenMap[tilePos.y+1][tilePos.x+1] > 0) { this->m_position.y = this->m_position.y + (m_velocity.y * dt); } else { m_velocity.y = 0; } } } else { this->m_position = this->m_position + (m_velocity * dt); } }
void Light::SetupShadowViews(Camera* mainCamera, Vector<AutoPtr<ShadowView> >& shadowViews, size_t& useIndex) { size_t numViews = NumShadowViews(); if (!numViews) return; if (shadowViews.Size() < useIndex + numViews) shadowViews.Resize(useIndex + numViews); int numVerticalSplits = (lightType == LIGHT_POINT || (lightType == LIGHT_DIRECTIONAL && NumShadowSplits() > 2)) ? 2 : 1; int actualShadowMapSize = shadowRect.Height() / numVerticalSplits; for (size_t i = 0; i < numViews; ++i) { if (!shadowViews[useIndex + i]) shadowViews[useIndex + i] = new ShadowView(); ShadowView* view = shadowViews[useIndex + i].Get(); view->Clear(); view->light = this; Camera& shadowCamera = view->shadowCamera; switch (lightType) { case LIGHT_DIRECTIONAL: { IntVector2 topLeft(shadowRect.left, shadowRect.top); if (i & 1) topLeft.x += actualShadowMapSize; if (i & 2) topLeft.y += actualShadowMapSize; view->viewport = IntRect(topLeft.x, topLeft.y, topLeft.x + actualShadowMapSize, topLeft.y + actualShadowMapSize); float splitStart = Max(mainCamera->NearClip(), (i == 0) ? 0.0f : ShadowSplit(i - 1)); float splitEnd = Min(mainCamera->FarClip(), ShadowSplit(i)); float extrusionDistance = mainCamera->FarClip(); // Calculate initial position & rotation shadowCamera.SetTransform(mainCamera->WorldPosition() - extrusionDistance * WorldDirection(), WorldRotation()); // Calculate main camera shadowed frustum in light's view space Frustum splitFrustum = mainCamera->WorldSplitFrustum(splitStart, splitEnd); const Matrix3x4& lightView = shadowCamera.ViewMatrix(); Frustum lightViewFrustum = splitFrustum.Transformed(lightView); // Fit the frustum inside a bounding box BoundingBox shadowBox; shadowBox.Define(lightViewFrustum); // If shadow camera is far away from the frustum, can bring it closer for better depth precision /// \todo The minimum distance is somewhat arbitrary float minDistance = mainCamera->FarClip() * 0.25f; if (shadowBox.min.z > minDistance) { float move = shadowBox.min.z - minDistance; shadowCamera.Translate(Vector3(0.0f, 0.f, move)); shadowBox.min.z -= move, shadowBox.max.z -= move; } shadowCamera.SetOrthographic(true); shadowCamera.SetFarClip(shadowBox.max.z); Vector3 center = shadowBox.Center(); Vector3 size = shadowBox.Size(); shadowCamera.SetOrthoSize(Vector2(size.x, size.y)); shadowCamera.SetZoom(1.0f); // Center shadow camera to the view space bounding box Vector3 pos(shadowCamera.WorldPosition()); Quaternion rot(shadowCamera.WorldRotation()); Vector3 adjust(center.x, center.y, 0.0f); shadowCamera.Translate(rot * adjust, TS_WORLD); // Snap to whole texels { Vector3 viewPos(rot.Inverse() * shadowCamera.WorldPosition()); float invSize = 1.0f / actualShadowMapSize; Vector2 texelSize(size.x * invSize, size.y * invSize); Vector3 snap(-fmodf(viewPos.x, texelSize.x), -fmodf(viewPos.y, texelSize.y), 0.0f); shadowCamera.Translate(rot * snap, TS_WORLD); } } break; case LIGHT_POINT: { static const Quaternion pointLightFaceRotations[] = { Quaternion(0.0f, 90.0f, 0.0f), Quaternion(0.0f, -90.0f, 0.0f), Quaternion(-90.0f, 0.0f, 0.0f), Quaternion(90.0f, 0.0f, 0.0f), Quaternion(0.0f, 0.0f, 0.0f), Quaternion(0.0f, 180.0f, 0.0f) }; IntVector2 topLeft(shadowRect.left, shadowRect.top); if (i & 1) topLeft.y += actualShadowMapSize; topLeft.x += ((unsigned)i >> 1) * actualShadowMapSize; view->viewport = IntRect(topLeft.x, topLeft.y, topLeft.x + actualShadowMapSize, topLeft.y + actualShadowMapSize); shadowCamera.SetTransform(WorldPosition(), pointLightFaceRotations[i]); shadowCamera.SetFov(90.0f); // Adjust zoom to avoid edge sampling artifacts (there is a matching adjustment in the shadow sampling) shadowCamera.SetZoom(0.99f); shadowCamera.SetFarClip(Range()); shadowCamera.SetNearClip(Range() * 0.01f); shadowCamera.SetOrthographic(false); shadowCamera.SetAspectRatio(1.0f); } break; case LIGHT_SPOT: view->viewport = shadowRect; shadowCamera.SetTransform(WorldPosition(), WorldRotation()); shadowCamera.SetFov(fov); shadowCamera.SetZoom(1.0f); shadowCamera.SetFarClip(Range()); shadowCamera.SetNearClip(Range() * 0.01f); shadowCamera.SetOrthographic(false); shadowCamera.SetAspectRatio(1.0f); break; } } // Setup shadow matrices now as camera positions have been finalized if (lightType != LIGHT_POINT) { shadowMatrices.Resize(numViews); for (size_t i = 0; i < numViews; ++i) { ShadowView* view = shadowViews[useIndex + i].Get(); Camera& shadowCamera = view->shadowCamera; float width = (float)shadowMap->Width(); float height = (float)shadowMap->Height(); Vector3 offset((float)view->viewport.left / width, (float)view->viewport.top / height, 0.0f); Vector3 scale(0.5f * (float)view->viewport.Width() / width, 0.5f * (float)view->viewport.Height() / height, 1.0f); offset.x += scale.x; offset.y += scale.y; scale.y = -scale.y; // OpenGL has different depth range #ifdef TURSO3D_OPENGL offset.z = 0.5f; scale.z = 0.5f; #endif Matrix4 texAdjust(Matrix4::IDENTITY); texAdjust.SetTranslation(offset); texAdjust.SetScale(scale); shadowMatrices[i] = texAdjust * shadowCamera.ProjectionMatrix() * shadowCamera.ViewMatrix(); } } else { // Point lights use an extra constant instead shadowMatrices.Clear(); Vector2 textureSize((float)shadowMap->Width(), (float)shadowMap->Height()); pointShadowParameters = Vector4(actualShadowMapSize / textureSize.x, actualShadowMapSize / textureSize.y, (float)shadowRect.left / textureSize.x, (float)shadowRect.top / textureSize.y); } // Calculate shadow mapping constants Camera& shadowCamera = shadowViews[useIndex]->shadowCamera; float nearClip = shadowCamera.NearClip(); float farClip = shadowCamera.FarClip(); float q = farClip / (farClip - nearClip); float r = -q * nearClip; shadowParameters = Vector4(0.5f / (float)shadowMap->Width(), 0.5f / (float)shadowMap->Height(), q, r); useIndex += numViews; }
//! Called by the engine when the vertex and/or pixel shader constants for an //! material renderer should be set. void COGLES2ParallaxMapRenderer::OnSetConstants( IMaterialRendererServices* services, s32 userData ) { video::IVideoDriver* driver = services->getVideoDriver(); // set transposed worldViewProj matrix core::matrix4 worldViewProj( driver->getTransform( video::ETS_PROJECTION ) ); worldViewProj *= driver->getTransform( video::ETS_VIEW ); worldViewProj *= driver->getTransform( video::ETS_WORLD ); setUniform( MVP_MATRIX, worldViewProj.pointer() ); // here we fetch the fixed function lights from the driver // and set them as constants u32 cnt = driver->getDynamicLightCount(); // Load the inverse world matrix. core::matrix4 invWorldMat; driver->getTransform( video::ETS_WORLD ).getInverse( invWorldMat ); float lightPosition[4*MAX_LIGHTS]; float lightColor[4*MAX_LIGHTS]; for ( u32 i = 0; i < 2; ++i ) { video::SLight light; if ( i < cnt ) light = driver->getDynamicLight( i ); else { light.DiffuseColor.set( 0, 0, 0 ); // make light dark light.Radius = 1.0f; } light.DiffuseColor.a = 1.0f / ( light.Radius * light.Radius ); // set attenuation // Transform the light by the inverse world matrix to get it into object space. invWorldMat.transformVect( light.Position ); memcpy( lightPosition + i*4, &light.Position, sizeof( float )*4 ); memcpy( lightColor + i*4, &light.DiffuseColor, sizeof( float )*4 ); } setUniform( LIGHT_POSITION, lightPosition, MAX_LIGHTS ); setUniform( LIGHT_COLOR, lightColor, MAX_LIGHTS ); // Obtain the view position by transforming 0,0,0 by the inverse view matrix // and then multiply this by the inverse world matrix. core::vector3df viewPos( 0.0f, 0.0f, 0.0f ); core::matrix4 inverseView; driver->getTransform( video::ETS_VIEW ).getInverse( inverseView ); inverseView.transformVect( viewPos ); invWorldMat.transformVect( viewPos ); setUniform( EYE_POSITION, &viewPos.X ); // set scale factor f32 factor = 0.02f; // default value if ( CurrentScale != 0.0f ) factor = CurrentScale; setUniform( HEIGHT_SCALE, &factor ); }