#include #include #include "src/giram.h" #include "src/object.h" #include "src/camera.h" gchar *module_icon_xpm[] = { "20 20 32 1", " c None", ". c #F88484", "+ c #F68181", "@ c #EF7878", "# c #D15151", "$ c #B12828", "% c #970606", "& c #F78282", "* c #E76D6D", "= c #C74545", "- c #A71B1B", "; c #960404", "> c #EC7575", ", c #D65858", "' c #B42D2D", ") c #9E1010", "! c #930202", "~ c #FB4242", "{ c #FA5252", "] c #FA5858", "^ c #EE5858", "/ c #D74A4A", "( c #FE1212", "_ c #FD2121", ": c #FC2C2C", "< c #E42C2C", "[ c #C11E1E", "} c #FF0000", "| c #DB0000", "1 c #B70101", "2 c #BB0101", "3 c #C10101", " .........+@#$%", " ..........&*=-;", " ...........>,')!", " ...........>,')!!", " ...........>,')!!!", " ~{]]]]]]]]]^/')!!!!", "(_::::::::::<[)!!!!!", "}}}}}}}}}}}}|1!!!!!!", "}}}}}}}}}}}}|1!!!!!!", "}}}}}}}}}}}}|1!!!!!!", "}}}}}}}}}}}}|1!!!!!!", "}}}}}}}}}}}}|1!!!!!!", "}}}}}}}}}}}}|1!!!!!!", "}}}}}}}}}}}}|1!!!!!!", "}}}}}}}}}}}}|1!!!!! ", "}}}}}}}}}}}}|1!!!! ", "}}}}}}}}}}}}|1!!! ", "}}}}}}}}}}}}|1!! ", "}}}}}}}}}}}}|2! ", "}}}}}}}}}}}}|3 " }; gchar *module_name = "The raytracing renderer module"; gint module_type = 1; /************************************************************************* * rendering_func **************************************************************************/ GdkPixmap *rendering_func(GtkWidget *area, gint width, gint height) { GdkPixmap *pixmap; FrameStruct *frame; GSList *tmp_list, *tmp_ls; ObjectStruct *Tmp, *nearest_object; CameraStruct *camera; gdouble color[5]; gdouble color_result[5]; gdouble Norme, alpha; Vector dx, dy; LightSourceStruct *Light; Vector origin, dir, NormalLight, intersect, normal, I, N, dist; gint i, j; guchar *rgb_buf; gdouble nearest; gboolean render; pixmap = gdk_pixmap_new(area->window, width, height, -1); frame = g_object_get_data(G_OBJECT(area), "frame"); camera = frame->all_cameras->data; /* Origin of the ray ( case of 1 camera) */ V3Dcopy(origin, camera->Location); dx[0]=camera->Right[0]/width; dx[1]=camera->Right[1]/width; dx[2]=camera->Right[2]/width; dy[0]=camera->Up[0]/height; dy[1]=camera->Up[1]/height; dy[2]=camera->Up[2]/height; rgb_buf = g_malloc0(3*width*height); for (i=0 ; iDirection[0]+0.5*camera->Up[0]-0.5*camera->Right[0]+dx[0]*i-dy[0]*j; dir[1]=camera->Direction[1]+0.5*camera->Up[1]-0.5*camera->Right[1]+dx[1]*i-dy[1]*j; dir[2]=camera->Direction[2]+0.5*camera->Up[2]-0.5*camera->Right[2]+dx[2]*i-dy[2]*j; nearest_object = NULL; nearest = 0.0; /* cast the primary rays */ for (tmp_list = frame->all_objects ; tmp_list ; tmp_list = g_slist_next(tmp_list)) { Tmp = tmp_list->data; if ((Tmp->visible) && (giram_object_find_intersection(Tmp, origin, dir, I, N))) { dist[0] = I[0]-origin[0]; dist[1] = I[1]-origin[1]; dist[2] = I[2]-origin[2]; if (V3DLength(dist) < nearest || !nearest_object) { nearest = V3DLength(dist); V3Dcopy(intersect, I); V3Dcopy(normal, N); nearest_object = Tmp; } } } if (nearest_object) { /* we found an object */ if (nearest_object->Texture && nearest_object->Texture->Pigment) giram_pigment_evaluate(color, nearest_object->Texture->Pigment, intersect); else color[0] = color[1] = color[2] = 1.0; /* ambient part of the light */ color_result[0] = color[0] * nearest_object->Texture->finish->ambient[0]; color_result[1] = color[1] * nearest_object->Texture->finish->ambient[1]; color_result[2] = color[2] * nearest_object->Texture->finish->ambient[2]; for (tmp_ls = frame->all_light_sources ; tmp_ls ; tmp_ls = g_slist_next(tmp_ls)) { /* add diffuse for all lights */ Light = tmp_ls->data; NormalLight[0] = Light->Location[0]-intersect[0]; NormalLight[1] = Light->Location[1]-intersect[1]; NormalLight[2] = Light->Location[2]-intersect[2]; Norme = V3DLength(NormalLight); NormalLight[0] /= Norme; NormalLight[1] /= Norme; NormalLight[2] /= Norme; alpha = V3DDot(normal, NormalLight) * nearest_object->Texture->finish->diffuse; if (alpha>0.) { render = TRUE; for (tmp_list = frame->all_objects ; tmp_list ; tmp_list = g_slist_next(tmp_list)) { /* now cast the shadow rays */ Tmp = tmp_list->data; if (giram_object_is_intersection(Tmp,intersect,NormalLight)) { render = FALSE; break; } } if (render) { color_result[0] += alpha*color[0]*Light->Color[0]; color_result[1] += alpha*color[1]*Light->Color[1]; color_result[2] += alpha*color[2]*Light->Color[2]; } } } rgb_buf[j*3*width+i*3+0]=255.*CLAMP(color_result[0], 0.0, 1.0); rgb_buf[j*3*width+i*3+1]=255.*CLAMP(color_result[1], 0.0, 1.0); rgb_buf[j*3*width+i*3+2]=255.*CLAMP(color_result[2], 0.0, 1.0); } else { rgb_buf[j*3*width+i*3+0] = 255.*frame->background_color[0]; rgb_buf[j*3*width+i*3+1] = 255.*frame->background_color[1]; rgb_buf[j*3*width+i*3+2] = 255.*frame->background_color[2]; } } gdk_draw_rgb_image(pixmap, area->style->white_gc, 0,0, width, height, GDK_RGB_DITHER_MAX, rgb_buf, 3*width); /* Freeing ... */ g_free(rgb_buf); return pixmap; }