void RenderingEngine::DrawParticles(simlist<Particle>* particles, long particlesLength, PointArrays* arrays){
    if(_currentTexture->Name != Factory::Instance->TextureParticle->Name){
        glBindTexture(GL_TEXTURE_2D, Factory::Instance->TextureParticle->Name);
        glEnableVertexAttribArray(_attributes.Position);
        glDisableVertexAttribArray(_attributes.TextureCoord);
        glUniform1i(_uniforms.IsParticle, GL_TRUE);
        glUniform1i(_uniforms.HasColorChange, GL_TRUE);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
        //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
        _currentTexture = Factory::Instance->TextureParticle;
    }
    int v = 0;
    int c = 0;
    simnode<Particle>* node = particles->head;
    while (node != NULL) {
        Particle* p = node->data;
        
        vec2 pos = p->Pos();
        vec4 color = p->Color();
        arrays->vertices[v++] = pos.x;
        arrays->vertices[v++] = pos.y;
        
        arrays->colors[c++] = color.x;
        arrays->colors[c++] = color.y;
        arrays->colors[c++] = color.z;
        arrays->colors[c++] = color.w;
        
        node = node->next;
    }
    glVertexAttribPointer(_attributes.Position, 2, GL_FLOAT, GL_FALSE, 0, arrays->vertices);
    glVertexAttribPointer(_attributes.Color, 4, GL_FLOAT, GL_FALSE, 0, arrays->colors);
    
    glDrawArrays(GL_POINTS, 0, particlesLength);
    
}
// Scene 04
void Scene04(float time, float dt)
{
	static const float cameraBobbleSpeed = 0.5f;
	static const float cameraBobble = 0.1f;
	static float wobbleParameter = 0.0f;

	// Get world
	World* world = WorldSingleton::Get();


	// Move tanks
	redTank1->SetTargetPosition(Vector3f(160.0f, 0.0f, -16.0f));
	redTank2->SetTargetPosition(Vector3f(60.0f, 0.0f, -16.0f));
	blueTank1->SetTargetPosition(Vector3f(-128.0f, 0.0f, -64.0f));
	blueTank2->SetTargetPosition(Vector3f(432.0f, 0.0f, -80.0f));
	
	redTank1->SetTargetVelocity(30.0f);
	redTank2->SetTargetVelocity(30.0f);
	blueTank1->SetTargetVelocity(30.0f);
	blueTank2->SetTargetVelocity(30.0f);

	redTank1->Update(dt, terrain);
	redTank2->Update(dt, terrain);
	blueTank1->Update(dt, terrain);
	blueTank2->Update(dt, terrain);

	redTank1->OrientToTerrain(terrain, dt);
	redTank2->OrientToTerrain(terrain, dt);
	blueTank1->OrientToTerrain(terrain, dt);
	blueTank2->OrientToTerrain(terrain, dt);

	blueTank1->OrientTurret(-5.0f, Approach(blueTank1->GetTurretOrientation().y, -80.0f, 1.0f, dt));
	blueTank2->OrientTurret(-10.0f, Approach(blueTank2->GetTurretOrientation().y, 90.0f, 1.0f, dt));


	// Spit particles
	static Trigger* particleSpawnTimer = new Trigger(0.25f);
	static Lerp2f* sizeLerp = new Lerp2f(Vector2f(4.0f, 4.0f), Vector2f(8.0f, 8.0f));

	particleSpawnTimer->SetPlayState(Loop);
	particleSpawnTimer->Update(dt);

	if( particleSpawnTimer->DoTrigger() )
	{
		cout << "Trigger..." << endl;
		PointManager* pointManager = PointManagerSingleton::Get();
		Particle* particle;

		particle = pointManager->EmitParticle();
		if( particle )
		{
			particle->MaxLife() = Rnd(0.25f, 1.5f);
			particle->Life() = particle->MaxLife();
			particle->Rotation() = Rnd(0.0f, 360.0f);
			particle->Position() = redTank1->GetPosition()+Vector3f(Rnd(-4.0f, 4.0f), Rnd(0.0f, 4.0f), Rnd(-4.0f, 4.0f));
			particle->Velocity().Set(Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f));
			particle->Size() = sizeLerp;
			particle->SetTexture(smokeTexture);
			particle->Color().Set(140.0f/255.0f, 128.0f/255.0f, 112.0f/255.0f, 0.75f);
		}

		particle = pointManager->EmitParticle();
		if( particle )
		{
			particle->MaxLife() = Rnd(0.25f, 1.5f);
			particle->Life() = particle->MaxLife();
			particle->Rotation() = Rnd(0.0f, 360.0f);
			particle->Position() = redTank2->GetPosition()+Vector3f(Rnd(-4.0f, 4.0f), Rnd(0.0f, 4.0f), Rnd(-4.0f, 4.0f));
			particle->Velocity().Set(Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f));
			particle->Size() = sizeLerp;
			particle->SetTexture(smokeTexture);
			particle->Color().Set(140.0f/255.0f, 128.0f/255.0f, 112.0f/255.0f, 0.75f);
		}
	}


	// Orbit camera
	wobbleParameter += 30.0f*(1.0f+sin(wobbleParameter*0.4f)*0.05f)*dt;

	mainCamera->SetFieldOfView(90.0f);
	mainCamera->SetPosition(500.0f, 700.0f, -300.0f);
	mainCamera->SetEulerRotation(
		-60.0f+sin(wobbleParameter*0.2f*cameraBobbleSpeed)*3.0f*cameraBobble-5,
		120.0f+sin(wobbleParameter*0.1f*cameraBobbleSpeed)*6.0f*cameraBobble,
		sin(wobbleParameter*0.05f*cameraBobbleSpeed)*30.0f*cameraBobble);


	// Update blur effect
	blurEffect->SetBlurFactor(0.6f);
}
// Scene 03
void Scene03(float time, float dt)
{
	// Get world
	World* world = WorldSingleton::Get();


	// Move tanks
	redTank1->SetTargetPosition(Vector3f(160.0f, 0.0f, -16.0f));
	redTank2->SetTargetPosition(Vector3f(60.0f, 0.0f, -16.0f));
	
	redTank1->SetTargetVelocity(30.0f);
	redTank2->SetTargetVelocity(30.0f);

	redTank1->Update(dt, terrain);
	redTank2->Update(dt, terrain);

	redTank1->OrientToTerrain(terrain, dt);
	redTank2->OrientToTerrain(terrain, dt);
	blueTank1->OrientToTerrain(terrain, dt);
	blueTank2->OrientToTerrain(terrain, dt);

	redTank1->OrientTurret(10.0f, 45.0f+Sin(time*60.0f)*30.0f);
	redTank2->OrientTurret(15.0f, -30.0f+Sin(time*80.0f)*45.0f);


	// Spit particles
	static Trigger* particleSpawnTimer = new Trigger(0.25f);
	static Lerp2f* sizeLerp = new Lerp2f(Vector2f(4.0f, 4.0f), Vector2f(8.0f, 8.0f));

	particleSpawnTimer->SetPlayState(Loop);
	particleSpawnTimer->Update(dt);

	if( particleSpawnTimer->DoTrigger() )
	{
		cout << "Trigger..." << endl;
		PointManager* pointManager = PointManagerSingleton::Get();
		Particle* particle;

		particle = pointManager->EmitParticle();
		if( particle )
		{
			particle->MaxLife() = Rnd(0.25f, 1.5f);
			particle->Life() = particle->MaxLife();
			particle->Rotation() = Rnd(0.0f, 360.0f);
			particle->Position() = redTank1->GetPosition()+Vector3f(Rnd(-4.0f, 4.0f), Rnd(0.0f, 4.0f), Rnd(-4.0f, 4.0f));
			particle->Velocity().Set(Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f));
			particle->Size() = sizeLerp;
			particle->SetTexture(smokeTexture);
			particle->Color().Set(140.0f/255.0f, 128.0f/255.0f, 112.0f/255.0f, 0.75f);
		}

		particle = pointManager->EmitParticle();
		if( particle )
		{
			particle->MaxLife() = Rnd(0.25f, 1.5f);
			particle->Life() = particle->MaxLife();
			particle->Rotation() = Rnd(0.0f, 360.0f);
			particle->Position() = redTank2->GetPosition()+Vector3f(Rnd(-4.0f, 4.0f), Rnd(0.0f, 4.0f), Rnd(-4.0f, 4.0f));
			particle->Velocity().Set(Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f), Rnd(-1.5f, 1.5f));
			particle->Size() = sizeLerp;
			particle->SetTexture(smokeTexture);
			particle->Color().Set(140.0f/255.0f, 128.0f/255.0f, 112.0f/255.0f, 0.75f);
		}
	}


	// Orbit camera
	mainCamera->SetFieldOfView(90.0f);

	mainCamera->SetEulerRotation(-6.0f, 100.0f, 0.0f);

	float yaw = mainCamera->GetEulerRotation().y;

	mainCamera->SetPosition(
		redTank1->GetPosition().x+Sin(yaw)*64.0f,
		redTank1->GetPosition().y+18.0f,
		redTank1->GetPosition().z+24.0f+Cos(yaw)*64.0f);


	// Update blur effect
	blurEffect->SetBlurFactor(0.7);
}