Beispiel #1
0
///////////////////////////////////////////////////////////////////////////////
///  private constant  ObtenirCouleurSurIntersection \n
///  Description : Obtient la couleur à un point d'intersection en particulier
///                Calcule les contributions colorées de toutes les lumières, avec
///                les modèles de Phong et de Gouraud. Aussi, dépendemment des
///                propriétés de la surface en intersection, on réfléchi ou in 
///                réfracte le rayon courant.
///                current ray.
///
///  @param [in]       Rayon const CRayon &    Le rayon à tester
///  @param [in]       Intersection const Scene::CIntersection &    L'ntersection spécifiée
///
///  @return const CCouleur La couleur à l'intersection donnée
///
///  @author Olivier Dionne 
///  @date   13/08/2008
///
///////////////////////////////////////////////////////////////////////////////
const CCouleur CScene::ObtenirCouleurSurIntersection( const CRayon& Rayon, const CIntersection& Intersection ) const
{
    CCouleur  Result = Intersection.ObtenirSurface()->ObtenirCouleur() * Intersection.ObtenirSurface()->ObtenirCoeffAmbiant();
    CVecteur3 IntersectionPoint = Rayon.ObtenirOrigine()+ Intersection.ObtenirDistance() * Rayon.ObtenirDirection();
    
    // Calculer les contribution colorées des toutes les lumières dans la scène
    CCouleur LumiereContributions = CCouleur::NOIR;
    CRayon   LumiereRayon;
    for( LumiereIterator uneLumiere = m_Lumieres.begin(); uneLumiere != m_Lumieres.end(); uneLumiere++ )
    {
        // Initialise le rayon de lumière (ou rayon d'ombre)
        LumiereRayon.AjusterOrigine( IntersectionPoint );
        LumiereRayon.AjusterDirection( ( *uneLumiere )->GetPosition() - IntersectionPoint );
        LumiereRayon.AjusterEnergie( 1 );
        LumiereRayon.AjusterIndiceRefraction( 1 );

        if( CVecteur3::ProdScal( LumiereRayon.ObtenirDirection(), Intersection.ObtenirNormale() ) > 0 )
        {
            // Obtenir la couleur à partir de la lumière
            CCouleur Filter         = ObtenirFiltreDeSurface( LumiereRayon );
            CCouleur LumiereCouleur = ( *uneLumiere )->ObtenirCouleur() * Filter;

            // Ajouter la contribution de Gouraud
            REAL GouraudFactor = ( *uneLumiere )->GetIntensity() * Intersection.ObtenirSurface()->ObtenirCoeffDiffus() *
                CVecteur3::ProdScal( Intersection.ObtenirNormale(), LumiereRayon.ObtenirDirection() );
            Result += Intersection.ObtenirSurface()->ObtenirCouleur() * GouraudFactor * LumiereCouleur;

            // ...
        }
    }

    return Result;
}
Beispiel #2
0
///////////////////////////////////////////////////////////////////////////////
///  private constant  ObtenirFiltreDeSurface \n
///  Description : Obtenir le filtre du matériau de la surface. Le coefficient de
///                réfraction nous indique du même coup s'il y a transparence de la
///                surface.
///
///  @param [in, out]  LumiereRayon CRayon &     Le rayon de lumière (ou d'ombre) à tester
///
///  @return const CCouleur Le filtre de couleur
///
///  @author Olivier Dionne
///  @date   13/08/2008
///
///////////////////////////////////////////////////////////////////////////////
const CCouleur CScene::ObtenirFiltreDeSurface( CRayon& LumiereRayon ) const
{
    CCouleur Filter = CCouleur::BLANC;
    CIntersection LumiereIntersection;

    REAL Distance = CVecteur3::Norme( LumiereRayon.ObtenirDirection() );
    LumiereRayon.AjusterDirection( LumiereRayon.ObtenirDirection() / Distance );

    // TODO : À COMPLÉTER LORS DU VOLET 2...


    // Tester le rayon de lumière avec chaque surface de la scène
    // pour vérifier s'il y a intersection
    CIntersection Result;
    CIntersection Tmp;

    for (SurfaceIterator aSurface = m_Surfaces.begin(); aSurface != m_Surfaces.end(); aSurface++)
    {
        Tmp = (*aSurface)->Intersection(LumiereRayon);
        if (Tmp.ObtenirDistance() > EPSILON)
        {
            Filter *= Tmp.ObtenirSurface()->ObtenirCoeffRefraction() * Tmp.ObtenirSurface()->ObtenirCouleur();
        }
    }

    // S'il y a une intersection appliquer la translucidité de la surface
    // intersectée sur le filtre

    return Filter;
}
Beispiel #3
0
///////////////////////////////////////////////////////////////////////////////
///  public  LancerRayons \n
///  Description : Lancement des rayons (raytrace) dans la scène courante
///
///  @return None
///
///  @author Olivier Dionne 
///  @date   13/08/2008
///
///////////////////////////////////////////////////////////////////////////////
void CScene::LancerRayons( void )
{
	Initialiser();

	// Distance entre la camera et la scene
	const float distanceCameraScene = CVecteur3::Distance(m_Camera.PointVise, m_Camera.Position);

	// Simple trigonometrie entre la distance entre la camera et la scene et l'angle de la camera
	const float hauteur = 2 * (tan(Deg2Rad(m_Camera.Angle)) * distanceCameraScene);
	// Regle de trois pour trouver la largeur a partir de la hauteur
	const float largeur = hauteur * m_ResLargeur / (float)m_ResHauteur;

	// On ne prend pas compte d'une rotation/orientation speciale de la camera ici, elle est prise en compte plus loin
	// La position Hauteur Min de la scene est la somme des vecteurs de distance en -Z et la moitie de la hauteur en -Y
	CVecteur3 positionHauteurMin = CVecteur3(0, -hauteur / 2, -distanceCameraScene);
	// Logique semblable pour la Largeur Min
	CVecteur3 positionLargeurMin = CVecteur3(-largeur / 2, 0, -distanceCameraScene);

	for (int y = 0; y < m_ResHauteur; ++y)
	{
		//Calculer la position pixelY dans la scene
		CVecteur3 pixelY = positionHauteurMin + CVecteur3(0, (y / (float)m_ResHauteur) * hauteur, 0);

		for (int x = 0; x < m_ResLargeur; ++x)
		{
			//Calculer la position pixelX dans la scene
			CVecteur3 pixelX = positionLargeurMin + CVecteur3((x / (float)m_ResLargeur) * largeur, 0, 0);

			CRayon rayon;

			//Ajuster l'origine du rayon
			rayon.AjusterOrigine(m_Camera.Position);

			//Ajuster la direction du rayon
			CVecteur3 direction = CVecteur3::Normaliser(pixelX + pixelY);
			//Ajuster la direction selon la matrice d'orientation de la camera
			rayon.AjusterDirection(direction * m_Camera.Orientation);
			
			//Initialiser les autres caracteristiques du rayon
			rayon.AjusterEnergie(Math3D::REAL(1));
			rayon.AjusterNbRebonds(0);
			rayon.AjusterIndiceRefraction(Math3D::REAL(1));

			//Lancer le rayon et obtenir la couleur
			CCouleur couleur = CScene::ObtenirCouleur(rayon);

			//Enregistrer les couleurs
			m_InfoPixel[(x + y * m_ResLargeur) * 3]     = couleur.r;
			m_InfoPixel[(x + y * m_ResLargeur) * 3 + 1] = couleur.g;
			m_InfoPixel[(x + y * m_ResLargeur) * 3 + 2] = couleur.b;
		}
	}

    // Créer une texture openGL
    glGenTextures  ( 1, &m_TextureScene );
    glBindTexture  ( GL_TEXTURE_2D, m_TextureScene );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexImage2D   ( GL_TEXTURE_2D, 0, GL_RGBA8, m_ResLargeur, m_ResHauteur, 0, GL_RGB, GL_FLOAT, m_InfoPixel );
}
Beispiel #4
0
///////////////////////////////////////////////////////////////////////////////
///  public  LancerRayons \n
///  Description : Lancement des rayons (raytrace) dans la scène courante
///
///  @return None
///
///  @author Olivier Dionne
///  @date   13/08/2008
///
///////////////////////////////////////////////////////////////////////////////
void CScene::LancerRayons( void )
{
    Initialiser();

    REAL HalfH        = tan( Deg2Rad<REAL>( m_Camera.Angle * RENDRE_REEL( 0.5 ) ) );
    REAL HalfW        = ( RENDRE_REEL( m_ResLargeur ) / m_ResHauteur ) * HalfH;
    REAL InvResWidth  = RENDRE_REEL( 1.0 ) / m_ResLargeur;
    REAL InvResHeight = RENDRE_REEL( 1.0 ) / m_ResHauteur;

    CRayon   Rayon;
    CCouleur PixelColor;
    int      PixelIdx = 0;

    #pragma omp parallel for private(Rayon, PixelColor, PixelIdx)
    for( int PixY = 0; PixY < m_ResHauteur; PixY++ )
    {
        for( int PixX = 0; PixX < m_ResLargeur; PixX++ )
        {

            // Prépare le rayon
            Rayon.AjusterOrigine( m_Camera.Position );

            Rayon.AjusterDirection( CVecteur3( ( 2 * PixX * InvResWidth  - 1 ) * HalfW,
                                               ( 2 * PixY * InvResHeight - 1 ) * HalfH,
                                               -1 ) );

            Rayon.AjusterDirection( CVecteur3::Normaliser( Rayon.ObtenirDirection() * m_Camera.Orientation ) );
            Rayon.AjusterEnergie( 1 );
            Rayon.AjusterNbRebonds( 0 );
            Rayon.AjusterIndiceRefraction( 1 );

            PixelColor = ObtenirCouleur( Rayon );

            PixelIdx = ( PixX + ( PixY * m_ResLargeur ) ) * 3;
            m_InfoPixel[ PixelIdx + 0 ] = PixelColor.r;
            m_InfoPixel[ PixelIdx + 1 ] = PixelColor.g;
            m_InfoPixel[ PixelIdx + 2 ] = PixelColor.b;
        }
    }

    // Créer une texture openGL
    glGenTextures  ( 1, &m_TextureScene );
    glBindTexture  ( GL_TEXTURE_2D, m_TextureScene );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexImage2D   ( GL_TEXTURE_2D, 0, GL_RGBA8, m_ResLargeur, m_ResHauteur, 0, GL_RGB, GL_FLOAT, m_InfoPixel );
}
Beispiel #5
0
///////////////////////////////////////////////////////////////////////////////
///  private constant  ObtenirFiltreDeSurface \n
///  Description : Obtenir le filtre du matériau de la surface. Le coefficient de
///                réfraction nous indique du même coup s'il y a transparence de la 
///                surface.
///
///  @param [in, out]  LumiereRayon CRayon &     Le rayon de lumière (ou d'ombre) à tester
///
///  @return const CCouleur Le filtre de couleur
///
///  @author Olivier Dionne 
///  @date   13/08/2008
///
///////////////////////////////////////////////////////////////////////////////
const CCouleur CScene::ObtenirFiltreDeSurface( CRayon& LumiereRayon ) const
{
    CCouleur Filter = CCouleur::BLANC;
    CIntersection LumiereIntersection;
   
    REAL Distance = CVecteur3::Norme( LumiereRayon.ObtenirDirection() );
    LumiereRayon.AjusterDirection( LumiereRayon.ObtenirDirection() / Distance );

    // ...
    // ...

    return Filter;
}