1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
   |  
void on_apercu(GtkWidget* widget, gpointer data)
{
    int ombrage = (int)gtk_adjustment_get_value(adj_ombrage);
    float angle_rayons = (int)gtk_adjustment_get_value(adj_angle_rayons);
    float hauteur_max_rayons = (int)gtk_adjustment_get_value(adj_hauteur_max_rayons);
    float hauteur_max_heightmap = (float)gtk_adjustment_get_value(adj_hauteur_max_heightmap);
 
    int n_channels;
    int rowstride_lightmap, rowstride_heightmap;
    guchar *pixels_lightmap=NULL, *p_lightmap=NULL;
    guchar *pixels_heightmap=NULL, *p_heightmap=NULL;
    int x, y, width, height = 0;
    float step_z=0.0f;
    float z_origine=0.0f;
    int x_rayon=0;
    float z_rayon=0.0f;
 
    n_channels = gdk_pixbuf_get_n_channels(pixbuf_lightmap);
 
    g_assert(gdk_pixbuf_get_colorspace (pixbuf_lightmap) == GDK_COLORSPACE_RGB);
    g_assert(gdk_pixbuf_get_bits_per_sample (pixbuf_lightmap) == 8);
    g_assert(gdk_pixbuf_get_has_alpha (pixbuf_lightmap) == FALSE);
    g_assert(n_channels == 3);
 
    width = gdk_pixbuf_get_width(pixbuf_lightmap);
    height = gdk_pixbuf_get_height(pixbuf_lightmap);
 
    rowstride_lightmap = gdk_pixbuf_get_rowstride(pixbuf_lightmap);
    pixels_lightmap = gdk_pixbuf_get_pixels(pixbuf_lightmap);
 
    rowstride_heightmap = gdk_pixbuf_get_rowstride(pixbuf_heightmap);
    pixels_heightmap = gdk_pixbuf_get_pixels(pixbuf_heightmap);
 
    // Au départ, tout est dans l'ombre...
    for(y=0 ; y<height ; y++)
        for(x=0 ; x<width ; x++)
        {
            p_lightmap = pixels_lightmap + y * rowstride_lightmap + x * n_channels;
            p_lightmap[0] = ombrage;
            p_lightmap[1] = ombrage;
            p_lightmap[2] = ombrage;
        }
 
    // Puis vint la lumière !!
 
    // On calcule de combien on doit incrémenter en z à chaque nouveau rayon
    step_z = fabs(1/tan(angle_rayons));
 
    // On lance les rayons dans le sens horizontal (en voyant de haut), de la gauche vers la droite.
    // On fait donc ça pour toutes les lignes (d'où la boucle en y).
    for(y=0 ; y<height ; y++)
    {
        // On parcourt en montant (i.e. suivant l'axe des Z) pour lancer des rayons à chacune
        // de ces hauteurs
        for(z_origine=0.0f ; z_origine<hauteur_max_rayons ; z_origine+=step_z)
        {
            // Lancer du rayon !
            for(z_rayon=z_origine, x_rayon=0 ;
                x_rayon < width;
                z_rayon-=step_z, x_rayon++)
            {
                // Si la hauteur du pixel en cours est supérieure ou égale à z_rayon,
                // c'est qu'on a touché
                // qqch, alors on le colorie en blanc et on passe au rayon d'après
 
                // On pointe sur le point (x_rayon, y)
                p_heightmap = pixels_heightmap + y * rowstride_heightmap + x_rayon * n_channels;
                p_lightmap = pixels_lightmap + y * rowstride_lightmap + x_rayon * n_channels;
 
                if((float)(p_heightmap[0]/255.0f)*hauteur_max_heightmap >= z_rayon)
                {
                    p_lightmap[0] = p_lightmap[1] = p_lightmap[2] = 255;
                    break;
                }
            }
        }
    }
 
    gtk_image_set_from_pixbuf(GTK_IMAGE(image_lightmap), pixbuf_lightmap);
    redimensionner_image(image_lightmap);
} | 
Partager