void writetgaregion(void * voidofp, int iwidth, int iheight, int startx, int starty, int stopx, int stopy, char * buffer) { int y, totalx, totaly; char * bufpos; int filepos, numbytes; FILE * ofp = (FILE *) voidofp; totalx = stopx - startx + 1; totaly = stopy - starty + 1; for (y=0; y<totaly; y++) { bufpos=buffer + (totalx*3)*(totaly-y-1); filepos=18 + iwidth*3*(iheight - starty - totaly + y + 1) + (startx - 1)*3; if (filepos >= 18) { fseek(ofp, filepos, 0); numbytes = fwrite(bufpos, 3, totalx, ofp); if (numbytes != totalx) { char msgtxt[256]; sprintf(msgtxt, "File write problem, %d bytes written.", numbytes); rt_ui_message(MSG_ERR, msgtxt); } } else { rt_ui_message(MSG_ERR, "writetgaregion: file ptr out of range!!!\n"); return; /* don't try to continue */ } } }
void rtbomb(const char * msg) { rt_ui_message(MSG_ERR, msg); rt_ui_message(MSG_ABORT, "Rendering Aborted."); rt_finalize(); exit(1); }
/* * Save the rendered image to disk. */ static void renderio(scenedef * scene) { flt iotime; char msgtxt[256]; rt_timerhandle ioth; /* I/O timer handle */ ioth=rt_timer_create(); rt_timer_start(ioth); if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB96F) { if (scene->imgprocess & RT_IMAGE_NORMALIZE) { normalize_rgb96f(scene->hres, scene->vres, (float *) scene->img); rt_ui_message(MSG_0, "Post-processing: normalizing pixel values."); } if (scene->imgprocess & RT_IMAGE_GAMMA) { gamma_rgb96f(scene->hres, scene->vres, (float *) scene->img, scene->imggamma); rt_ui_message(MSG_0, "Post-processing: gamma correcting pixel values."); } } else if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) { if (scene->imgprocess & (RT_IMAGE_NORMALIZE | RT_IMAGE_GAMMA)) rt_ui_message(MSG_0, "Can't post-process 24-bit integer image data"); } /* support cropping of output images for SPECMPI benchmarks */ if (scene->imgcrop.cropmode == RT_CROP_DISABLED) { writeimage(scene->outfilename, scene->hres, scene->vres, scene->img, scene->imgbufformat, scene->imgfileformat); } else { /* crop image before writing if necessary */ if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB96F) { float *imgcrop; imgcrop = image_crop_rgb96f(scene->hres, scene->vres, scene->img, scene->imgcrop.xres, scene->imgcrop.yres, scene->imgcrop.xstart, scene->imgcrop.ystart); writeimage(scene->outfilename, scene->imgcrop.xres, scene->imgcrop.yres, imgcrop, scene->imgbufformat, scene->imgfileformat); free(imgcrop); } else if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) { unsigned char *imgcrop; imgcrop = image_crop_rgb24(scene->hres, scene->vres, scene->img, scene->imgcrop.xres, scene->imgcrop.yres, scene->imgcrop.xstart, scene->imgcrop.ystart); writeimage(scene->outfilename, scene->imgcrop.xres, scene->imgcrop.yres, imgcrop, scene->imgbufformat, scene->imgfileformat); free(imgcrop); } } rt_timer_stop(ioth); iotime = rt_timer_time(ioth); rt_timer_destroy(ioth); sprintf(msgtxt, " Image I/O Time: %10.4f seconds", iotime); rt_ui_message(MSG_0, msgtxt); }
void * opentgafile(char * filename) { FILE * ofp; ofp=fopen(filename, "r+b"); if (ofp == NULL) { char msgtxt[2048]; sprintf(msgtxt, "Cannot open %s for output!", filename); rt_ui_message(MSG_ERR, msgtxt); rt_ui_message(MSG_ABORT, "Rendering Aborted."); exit(1); } return ofp; }
void rt_boundthresh(SceneHandle voidscene, int threshold) { scenedef * scene = (scenedef *) voidscene; if (threshold > 1) { scene->boundthresh = threshold; } else { if (rt_mynode() == 0) { rt_ui_message(MSG_0, "Out-of-range automatic bounding threshold.\n"); rt_ui_message(MSG_0, "Automatic bounding threshold reset to default.\n"); } scene->boundthresh = BOUNDTHRESH; } scene->scenecheck = 1; }
void trace_region(scenedef scene, void * tga, int startx, int starty, int stopx, int stopy) { if (scene.verbosemode) { char msgtxt[2048]; sprintf(msgtxt, "Node %3d tracing region %4d, %4d ---> %4d, %4d \n", 0, startx,starty,stopx,stopy); rt_ui_message(MSG_0, msgtxt); } trace_shm(scene, /*buffer,*/ startx, stopx, starty, stopy); /* not used now writetgaregion(tga, scene.hres, scene.vres, startx, starty, stopx, stopy, global_buffer); if (scene.rawimage != NULL) { int x, y; int totalx = stopx - startx + 1; for (y=starty; y<=stopy; y++) { for (x=0; x<scene.hres; x++) { scene.rawimage[(scene.vres-y)*scene.hres*3 + x*3] = global_buffer[(y-starty)*totalx*3 + x*3 + 2]; scene.rawimage[(scene.vres-y)*scene.hres*3 + x*3 +1] = global_buffer[(y-starty)*totalx*3 + x*3 + 1]; scene.rawimage[(scene.vres-y)*scene.hres*3 + x*3 +2] = global_buffer[(y-starty)*totalx*3 + x*3]; } } } */ }
void tachyon_video::on_process() { char buf[8192]; flt runtime; scenedef *scene = (scenedef *) global_scene; updating_mode = scene->displaymode == RT_DISPLAY_ENABLED; recycling = false; pausing = false; do { updating = updating_mode; timer start_timer = gettimer(); rt_renderscene(global_scene); timer end_timer = gettimer(); runtime = timertime(start_timer, end_timer); sprintf(buf, "%s: %.3f seconds", global_window_title, runtime); rt_ui_message(MSG_0, buf); title = buf; show_title(); // show time spent for rendering if(!updating) { updating = true; drawing_memory dm = get_drawing_memory(); drawing_area drawing(0, 0, dm.sizex, dm.sizey);// invalidate whole screen } rt_finalize(); title = global_window_title; show_title(); // reset title to default } while(recycling && running); }
void createtgafile(char *name, unsigned short width, unsigned short height) { int filesize; FILE * ofp; filesize = 3*width*height + 18 - 10; if (name==NULL) exit(1); else { ofp=fopen(name, "w+b"); if (ofp == NULL) { char msgtxt[2048]; sprintf(msgtxt, "Cannot create %s for output!", name); rt_ui_message(MSG_ERR, msgtxt); rt_ui_message(MSG_ABORT, "Rendering Aborted."); exit(1); } fputc(0, ofp); /* IdLength */ fputc(0, ofp); /* ColorMapType */ fputc(2, ofp); /* ImageTypeCode */ fputc(0, ofp); /* ColorMapOrigin, low byte */ fputc(0, ofp); /* ColorMapOrigin, high byte */ fputc(0, ofp); /* ColorMapLength, low byte */ fputc(0, ofp); /* ColorMapLength, high byte */ fputc(0, ofp); /* ColorMapEntrySize */ fputc(0, ofp); /* XOrigin, low byte */ fputc(0, ofp); /* XOrigin, high byte */ fputc(0, ofp); /* YOrigin, low byte */ fputc(0, ofp); /* YOrigin, high byte */ fputc((width & 0xff), ofp); /* Width, low byte */ fputc(((width >> 8) & 0xff), ofp); /* Width, high byte */ fputc((height & 0xff), ofp); /* Height, low byte */ fputc(((height >> 8) & 0xff), ofp); /* Height, high byte */ fputc(24, ofp); /* ImagePixelSize */ fputc(0x20, ofp); /* ImageDescriptorByte 0x20 == flip vertically */ fseek(ofp, filesize, 0); fprintf(ofp, "9876543210"); fclose(ofp); } }
void LoadVol(scalarvol * vol) { FILE * dfile; int status; char msgtxt[2048]; dfile=fopen(vol->name, "r"); if (dfile==NULL) { char msgtxt[2048]; sprintf(msgtxt, "Vol: can't open %s for input!!! Aborting\n",vol->name); rt_ui_message(MSG_ERR, msgtxt); rt_ui_message(MSG_ABORT, "Rendering Aborted."); exit(1); } sprintf(msgtxt, "loading %dx%dx%d volume set from %s", vol->xres, vol->yres, vol->zres, vol->name); rt_ui_message(MSG_0, msgtxt); vol->data = (unsigned char *)rt_getmem(vol->xres * vol->yres * vol->zres); status=fread(vol->data, 1, (vol->xres * vol->yres * vol->zres), dfile); }
void on_process() { char buf[128]; flt runtime; timerstart(); rt_renderscene(global_scene); timerstop(); runtime=timertime(); sprintf(buf, "\nCPU Time: %.3f seconds.", runtime); rt_ui_message(MSG_0, buf); buf[0] = ' '; strcat(global_window_title, buf); title = global_window_title; updating = true; show_title(); rt_finalize(); }
static int fakeimage(char * name, int * xres, int * yres, unsigned char ** imgdata) { int i, imgsize; char msgtxt[2048]; sprintf(msgtxt, "Error loading image %s. Faking it using solid gray.", name); rt_ui_message(MSG_0, msgtxt); *xres = 4; *yres = 4; imgsize = 3 * (*xres) * (*yres); *imgdata = malloc(imgsize); for (i=0; i<imgsize; i++) { (*imgdata)[i] = 255; } return IMAGENOERR; }
void rtmesg(const char * msg) { rt_ui_message(MSG_0, msg); }
/* * Render the scene */ void renderscene(scenedef * scene) { flt runtime; rt_timerhandle rtth; /* render time timer handle */ /* if certain key aspects of the scene parameters have been changed */ /* since the last frame rendered, or when rendering the scene the */ /* first time, various setup, initialization and memory allocation */ /* routines need to be run in order to prepare for rendering. */ if (scene->scenecheck) rendercheck(scene); if (scene->mynode == 0) rt_ui_progress(0); /* print 0% progress at start of rendering */ /* * Core Ray Tracing Code * * Ideally, as little as possible other than this code should be * executed for rendering a frame. Most if not all memory allocations * should be done outside of the core code, and all setup should be * done outside of here. This will give the best speed when rendering * walk-throughs and similar things. */ rtth=rt_timer_create(); /* create/init rendering timer */ rt_timer_start(rtth); /* start ray tracing timer */ camera_init(scene); /* Initialize all aspects of camera system */ #if defined(MPI) && defined(THR) /* reset the rows counter for this frame */ rt_atomic_int_set(((thr_parms *) scene->threadparms)[0].rowsdone, 0); #endif #ifdef THR /* if using threads, wake up the child threads... */ rt_thread_barrier(((thr_parms *) scene->threadparms)[0].runbar, 1); #endif #ifdef MPI /* if using message passing, start persistent receives */ rt_start_scanlinereceives(scene->parbuf); /* start scanline receives */ #endif /* Actually Ray Trace The Image */ thread_trace(&((thr_parms *) scene->threadparms)[0]); #ifdef MPI rt_waitscanlines(scene->parbuf); /* wait for all scanlines to recv/send */ #endif rt_timer_stop(rtth); /* stop timer for ray tracing runtime */ runtime=rt_timer_time(rtth); rt_timer_destroy(rtth); /* * End of Core Ray Tracing Code * * Anything after here should be UI, tear-down, or reset code * */ if (scene->mynode == 0) { char msgtxt[256]; rt_ui_progress(100); /* print 100% progress when finished rendering */ sprintf(msgtxt, "\n Ray Tracing Time: %10.4f seconds", runtime); rt_ui_message(MSG_0, msgtxt); if (scene->writeimagefile) renderio(scene); } } /* end of renderscene() */
/* * Check the scene to determine whether or not any parameters that affect * the thread pool, the persistent message passing primitives, or other * infrastructure needs to be reconfigured before rendering commences. */ void rendercheck(scenedef * scene) { flt runtime; rt_timerhandle stth; /* setup time timer handle */ if (scene->verbosemode && scene->mynode == 0) { char msgtxt[1024]; int i, totalcpus; flt totalspeed; rt_ui_message(MSG_0, "CPU Information:"); totalspeed = 0.0; totalcpus = 0; for (i=0; i<scene->nodes; i++) { sprintf(msgtxt, " Node %4d: %2d CPUs, CPU Speed %4.2f, Node Speed %6.2f Name: %s", i, scene->cpuinfo[i].numcpus, scene->cpuinfo[i].cpuspeed, scene->cpuinfo[i].nodespeed, scene->cpuinfo[i].machname); rt_ui_message(MSG_0, msgtxt); totalcpus += scene->cpuinfo[i].numcpus; totalspeed += scene->cpuinfo[i].nodespeed; } sprintf(msgtxt, " Total CPUs: %d", totalcpus); rt_ui_message(MSG_0, msgtxt); sprintf(msgtxt, " Total Speed: %f\n", totalspeed); rt_ui_message(MSG_0, msgtxt); } rt_barrier_sync(); /* synchronize all nodes at this point */ stth=rt_timer_create(); rt_timer_start(stth); /* Time the preprocessing of the scene database */ rt_autoshader(scene); /* Adapt to the shading features needed at runtime */ /* Hierarchical grid ray tracing acceleration scheme */ if (scene->boundmode == RT_BOUNDING_ENABLED) engrid_scene(scene, scene->boundthresh); /* if any clipping groups exist, we have to use appropriate */ /* intersection testing logic */ if (scene->cliplist != NULL) { scene->flags |= RT_SHADE_CLIPPING; } /* if there was a preexisting image, free it before continuing */ if (scene->imginternal && (scene->img != NULL)) { free(scene->img); scene->img = NULL; } /* Allocate a new image buffer if necessary */ if (scene->img == NULL) { scene->imginternal = 1; if (scene->verbosemode && scene->mynode == 0) { rt_ui_message(MSG_0, "Allocating Image Buffer."); } /* allocate the image buffer accordinate to pixel format */ if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) { scene->img = malloc(scene->hres * scene->vres * 3); } else if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB96F) { scene->img = malloc(sizeof(float) * scene->hres * scene->vres * 3); } else { rt_ui_message(MSG_0, "Illegal image buffer format specifier!"); } if (scene->img == NULL) { scene->imginternal = 0; rt_ui_message(MSG_0, "Warning: Failed To Allocate Image Buffer!"); } } /* if any threads are leftover from a previous scene, and the */ /* scene has changed significantly, we have to collect, and */ /* respawn the worker threads, since lots of things may have */ /* changed which would affect them. */ destroy_render_threads(scene); create_render_threads(scene); /* allocate and initialize persistent scanline receive buffers */ /* which are used by the parallel message passing code. */ scene->parbuf = rt_init_scanlinereceives(scene); /* the scene has been successfully prepared for rendering */ /* unless it gets modified in certain ways, we don't need to */ /* pre-process it ever again. */ scene->scenecheck = 0; rt_timer_stop(stth); /* Preprocessing is finished, stop timing */ runtime=rt_timer_time(stth); rt_timer_destroy(stth); /* Print out relevent timing info */ if (scene->mynode == 0) { char msgtxt[256]; sprintf(msgtxt, "Preprocessing Time: %10.4f seconds",runtime); rt_ui_message(MSG_0, msgtxt); } }
int readimage(rawimage * img) { int rc; int xres, yres; unsigned char * imgdata; char * name = img->name; char msgtxt[2048]; if (strstr(name, ".ppm")) { rc = readppm(name, &xres, &yres, &imgdata); } else if (strstr(name, ".tga")) { rc = readtga(name, &xres, &yres, &imgdata); } else if (strstr(name, ".jpg")) { rc = readjpeg(name, &xres, &yres, &imgdata); } else if (strstr(name, ".png")) { rc = readpng(name, &xres, &yres, &imgdata); } else if (strstr(name, ".gif")) { rc = IMAGEUNSUP; } else if (strstr(name, ".tiff")) { rc = IMAGEUNSUP; } else if (strstr(name, ".rgb")) { rc = IMAGEUNSUP; } else if (strstr(name, ".xpm")) { rc = IMAGEUNSUP; } else { rc = readppm(name, &xres, &yres, &imgdata); } switch (rc) { case IMAGEREADERR: sprintf(msgtxt, "Short read encountered while loading image %s", name); rt_ui_message(MSG_0, msgtxt); rc = IMAGENOERR; /* remap to non-fatal error */ break; case IMAGEUNSUP: sprintf(msgtxt, "Cannot read unsupported format for image %s", name); rt_ui_message(MSG_0, msgtxt); break; } /* If the image load failed, create a tiny white colored image to fake it */ /* this allows a scene to render even when a file can't be loaded */ if (rc != IMAGENOERR) { rc = fakeimage(name, &xres, &yres, &imgdata); } /* If we succeeded in loading the image, return it. */ if (rc == IMAGENOERR) { img->xres = xres; img->yres = yres; img->bpp = 3; img->data = imgdata; } return rc; }