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