예제 #1
0
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);
}
예제 #2
0
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 );
}
예제 #3
0
	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() );
}
예제 #5
0
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();
}
예제 #6
0
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
예제 #7
0
/**
 * 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
예제 #8
0
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 ;
	};
예제 #11
0
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);
	}
}
예제 #12
0
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 );
	}