/* main function in embree namespace */ int main(int argc, char** argv) { /* for best performance set FTZ and DAZ flags in MXCSR control and status register */ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); /* create stream for parsing */ Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv)); /* parse command line */ parseCommandLine(stream, FileName()); /* load default scene if none specified */ if (filename.ext() == "") { FileName file = FileName::executableFolder() + FileName("models/cornell_box.ecs"); parseCommandLine(new ParseStream(new LineCommentFilter(file, "#")), file.path()); } /* configure number of threads */ if (g_numThreads) g_rtcore += ",threads=" + std::to_string((long long)g_numThreads); if (g_numBenchmarkFrames) g_rtcore += ",benchmark=1"; g_rtcore += g_subdiv_mode; /* load scene */ if (strlwr(filename.ext()) == std::string("obj")) { g_scene->add(loadOBJ(filename,g_subdiv_mode != "")); } else if (strlwr(filename.ext()) == std::string("xml")) { g_scene->add(loadXML(filename,one)); } else if (filename.ext() != "") THROW_RUNTIME_ERROR("invalid scene type: "+strlwr(filename.ext())); /* initialize ray tracing core */ init(g_rtcore.c_str()); /* send model */ g_obj_scene.add(g_scene.dynamicCast<SceneGraph::Node>(),g_instancing_mode); g_scene = nullptr; set_scene(&g_obj_scene); /* benchmark mode */ if (g_numBenchmarkFrames) renderBenchmark(outFilename); /* render to disk */ if (outFilename.str() != "") renderToFile(outFilename); /* interactive mode */ if (g_interactive) { initWindowState(argc,argv,tutorialName, g_width, g_height, g_fullscreen); enterWindowRunLoop(g_anim_mode); } return 0; }
/* main function in embree namespace */ int main(int argc, char** argv) { /* create stream for parsing */ Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv)); /* parse command line */ parseCommandLine(stream, FileName()); if (g_numThreads) g_rtcore += ",threads=" + std::stringOf(g_numThreads); if (g_numBenchmarkFrames) g_rtcore += ",benchmark=1"; g_rtcore += g_subdiv_mode; /* load scene */ if (strlwr(filename.ext()) == std::string("obj")) { if (g_subdiv_mode != "") { std::cout << "enabling subdiv mode" << std::endl; loadOBJ(filename,one,g_obj_scene,true); } else loadOBJ(filename,one,g_obj_scene); } else if (strlwr(filename.ext()) == std::string("xml")) loadXML(filename,one,g_obj_scene); else if (filename.ext() != "") THROW_RUNTIME_ERROR("invalid scene type: "+strlwr(filename.ext())); /* initialize ray tracing core */ init(g_rtcore.c_str()); /* convert triangle meshes to subdiv meshes */ if (g_only_subdivs) g_obj_scene.convert_to_subdiv(); /* send model */ set_scene(&g_obj_scene); /* benchmark mode */ if (g_numBenchmarkFrames) renderBenchmark(outFilename); /* render to disk */ if (outFilename.str() != "") renderToFile(outFilename); /* interactive mode */ if (g_interactive) { initWindowState(argc,argv,tutorialName, g_width, g_height, g_fullscreen); enterWindowRunLoop(g_anim_mode); } return 0; }
/*! loads an image from a file with auto-detection of format */ Ref<Image> loadImageFromDisk(const FileName& fileName) try { std::string ext = std::strlwr(fileName.ext()); #ifdef USE_OPENEXR if (ext == "exr" ) return loadExr(fileName); #endif #ifdef USE_IMAGEMAGICK if (ext == "bmp" ) return loadMagick(fileName); if (ext == "gif" ) return loadMagick(fileName); if (ext == "png" ) return loadMagick(fileName); if (ext == "tga" ) return loadMagick(fileName); if (ext == "tif" ) return loadMagick(fileName); if (ext == "tiff") return loadMagick(fileName); #endif #ifdef USE_LIBJPEG if (ext == "jpg" ) return loadJPEG(fileName); #endif if (ext == "pfm" ) return loadPFM(fileName); if (ext == "ppm" ) return loadPPM(fileName); throw std::runtime_error("image format " + ext + " not supported"); } catch (const std::exception& e) { std::cout << "cannot read file " << fileName << ": " << e.what() << std::endl; return null; }
void loadFile(const FileName &fileName) { std::string extension = fileName.ext(); if (extension == "vtp") loadVTKFile<vtkXMLPolyDataReader>(fileName.c_str()); }
void loadHair(const FileName& fileName, OBJScene& scene, Vec3fa& offset) { /* add new hair set to scene */ OBJScene::HairSet* hairset = new OBJScene::HairSet; #if CONVERT_TO_BINARY offset = Vec3fa(zero); #endif int numHairs = 0; if (fileName.ext() == "txt") numHairs = loadHairASCII(fileName,hairset,offset); else numHairs = loadHairBin(fileName,hairset,offset); /* reduce number of hairs */ if (g_reduce_hair_segment_error != 0.0f) { std::ios_base :: fmtflags flag = std::cout.flags(); std :: streamsize prec = std::cout.precision(); std::cout << "reducing number of hair segments ... " << std::flush; std::cout.precision(3); std::cout << 1E-6*float(hairset->hairs.size()) << "M" << std::flush; for (size_t i=0; i<10; i++) { hairset = reduce_hairs(hairset,g_reduce_hair_segment_error); std::cout << " " << 1E-6*float(hairset->hairs.size()) << "M" << std::flush; } std::cout << " [DONE]" << std::endl; std::cout.flags (flag); std::cout.precision(prec); } /* add hairset to scene */ scene.hairsets.push_back(hairset); int numPoints = hairset->v.size(); int numSegments = hairset->hairs.size(); #if CONVERT_TO_BINARY FILE* fout = fopen(fileName.setExt(".bin").c_str(),"wb"); if (!fout) THROW_RUNTIME_ERROR("could not open " + fileName.str()); fwrite(&hair_bin_magick,sizeof(int),1,fout); fwrite(&numHairs,sizeof(int),1,fout); fwrite(&numPoints,sizeof(int),1,fout); fwrite(&numSegments,sizeof(int),1,fout); if (numPoints) fwrite(&hairset->v[0],sizeof(Vec3fa),numPoints,fout); if (numSegments) fwrite(&hairset->hairs[0],sizeof(OBJScene::Hair),numSegments,fout); fclose(fout); #endif }
void loadHair(const FileName& fileName, OBJScene& scene, Vec3fa& offset) { /* add new hair set to scene */ OBJScene::HairSet* hairset = new OBJScene::HairSet; #if CONVERT_TO_BINARY offset = Vec3fa(zero); #endif int numHairs = 0; if (fileName.ext() == "txt") numHairs = loadHairASCII(fileName,hairset,offset); else numHairs = loadHairBin(fileName,hairset,offset); /* reduce number of hairs */ #if 0 PRINT(hairset->hairs.size()); hairset = reduce_hairs(hairset); PRINT(hairset->hairs.size()); hairset = reduce_hairs(hairset); PRINT(hairset->hairs.size()); hairset = reduce_hairs(hairset); PRINT(hairset->hairs.size()); hairset = reduce_hairs(hairset); PRINT(hairset->hairs.size()); #endif /* add hairset to scene */ scene.hairsets.push_back(hairset); int numPoints = hairset->v.size(); int numSegments = hairset->hairs.size(); PRINT(numHairs); PRINT(numSegments); PRINT(numPoints); #if CONVERT_TO_BINARY FILE* fout = fopen(fileName.setExt(".bin").c_str(),"wb"); if (!fout) throw std::runtime_error("could not open " + fileName.str()); fwrite(&hair_bin_magick,sizeof(int),1,fout); fwrite(&numHairs,sizeof(int),1,fout); fwrite(&numPoints,sizeof(int),1,fout); fwrite(&numSegments,sizeof(int),1,fout); if (numPoints) fwrite(&hairset->v[0],sizeof(Vec3fa),numPoints,fout); if (numSegments) fwrite(&hairset->hairs[0],sizeof(OBJScene::Hair),numSegments,fout); fclose(fout); #endif }
/*! stores an image to file with auto-detection of format */ void storeImage(const Ref<Image>& img, const FileName& fileName) try { std::string ext = strlwr(fileName.ext()); #ifdef USE_OPENEXR if (ext == "exr" ) { storeExr(img, fileName); return; } #endif #ifdef USE_IMAGEMAGICK if (ext == "bmp" ) { storeMagick(img, fileName); return; } if (ext == "gif" ) { storeMagick(img, fileName); return; } if (ext == "png" ) { storeMagick(img, fileName); return; } if (ext == "tif" ) { storeMagick(img, fileName); return; } if (ext == "tiff") { storeMagick(img, fileName); return; } #endif #ifdef USE_LIBJPEG if (ext == "jpg" ) { storeJPEG(img, fileName); return; } #endif if (ext == "pfm" ) { storePFM(img, fileName); return; } if (ext == "ppm" ) { storePPM(img, fileName); return; } if (ext == "tga" ) { storeTga(img, fileName); return; } throw std::runtime_error("image format " + ext + " not supported"); } catch (const std::exception& e) { std::cout << "cannot write file " << fileName << ": " << e.what() << std::endl; }
Texture2D *loadTexture(const std::string &path, const std::string &fileNameBase, const bool prefereLinear) { const FileName fileName = path+"/"+fileNameBase; static std::map<std::string,Texture2D*> textureCache; if (textureCache.find(fileName.str()) != textureCache.end()) return textureCache[fileName.str()]; Texture2D *tex = NULL; const std::string ext = fileName.ext(); if (ext == "ppm") { try { int rc, peekchar; // open file FILE *file = fopen(fileName.str().c_str(),"rb"); const int LINESZ=10000; char lineBuf[LINESZ+1]; if (!file) throw std::runtime_error("#osp:miniSG: could not open texture file '"+fileName.str()+"'."); // read format specifier: int format=0; fscanf(file,"P%i\n",&format); if (format != 6) throw std::runtime_error("#osp:miniSG: can currently load only binary P6 subformats for PPM texture files. " "Please report this bug at ospray.github.io."); // skip all comment lines peekchar = getc(file); while (peekchar == '#') { fgets(lineBuf,LINESZ,file); peekchar = getc(file); } ungetc(peekchar,file); // read width and height from first non-comment line int width=-1,height=-1; rc = fscanf(file,"%i %i\n",&width,&height); if (rc != 2) throw std::runtime_error("#osp:miniSG: could not parse width and height in P6 PPM file '"+fileName.str()+"'. " "Please report this bug at ospray.github.io, and include named file to reproduce the error."); // skip all comment lines peekchar = getc(file); while (peekchar == '#') { fgets(lineBuf,LINESZ,file); peekchar = getc(file); } ungetc(peekchar,file); // read maxval int maxVal=-1; rc = fscanf(file,"%i",&maxVal); peekchar = getc(file); if (rc != 1) throw std::runtime_error("#osp:miniSG: could not parse maxval in P6 PPM file '"+fileName.str()+"'. " "Please report this bug at ospray.github.io, and include named file to reproduce the error."); if (maxVal != 255) throw std::runtime_error("#osp:miniSG: could not parse P6 PPM file '"+fileName.str()+"': currently supporting only maxVal=255 formats." "Please report this bug at ospray.github.io, and include named file to reproduce the error."); tex = new Texture2D; tex->width = width; tex->height = height; tex->channels = 3; tex->depth = 1; tex->prefereLinear = prefereLinear; tex->data = new unsigned char[width*height*3]; fread(tex->data,width*height*3,1,file); // flip in y, because OSPRay's textures have the origin at the lower left corner unsigned char *texels = (unsigned char *)tex->data; for (size_t y=0; y < height/2; y++) for (size_t x=0; x < width*3; x++) std::swap(texels[y*width*3+x], texels[(height-1-y)*width*3+x]); } catch(std::runtime_error e) { std::cerr << e.what() << std::endl; } } else { #ifdef USE_IMAGEMAGICK Magick::Image image(fileName.str().c_str()); tex = new Texture2D; tex->width = image.columns(); tex->height = image.rows(); tex->channels = image.matte() ? 4 : 3; tex->depth = 4; tex->prefereLinear = prefereLinear; float rcpMaxRGB = 1.0f/float(MaxRGB); const Magick::PixelPacket* pixels = image.getConstPixels(0,0,tex->width,tex->height); if (!pixels) { std::cerr << "#osp:minisg: failed to load texture '"+fileName.str()+"'" << std::endl; delete tex; tex = NULL; } else { tex->data = new float[tex->width*tex->height*tex->channels]; // convert pixels and flip image (because OSPRay's textures have the origin at the lower left corner) for (size_t y=0; y<tex->height; y++) { for (size_t x=0; x<tex->width; x++) { const Magick::PixelPacket &pixel = pixels[y*tex->width+x]; float *dst = &((float*)tex->data)[(x+(tex->height-1-y)*tex->width)*tex->channels]; *dst++ = pixel.red * rcpMaxRGB; *dst++ = pixel.green * rcpMaxRGB; *dst++ = pixel.blue * rcpMaxRGB; if (tex->channels == 4) *dst++ = pixel.opacity * rcpMaxRGB; } } } #endif } textureCache[fileName.str()] = tex; return tex; }
OSPVolume RawVolumeFile::importVolume(OSPVolume volume) { // Look for the volume data file at the given path. FILE *file = NULL; FileName fn = filename; bool gzipped = fn.ext() == "gz"; if (gzipped) { std::string cmd = "/usr/bin/gunzip -c "+filename; file = popen(cmd.c_str(),"r"); } else { file = fopen(filename.c_str(),"rb"); } //FILE *file = fopen(filename.c_str(), "rb"); exitOnCondition(!file, "unable to open file '" + filename + "'"); // Offset into the volume data file if any. int offset = 0; ospGeti(volume, "filename offset", &offset); fseek(file, offset, SEEK_SET); // Volume dimensions. ospcommon::vec3i volumeDimensions; exitOnCondition(!ospGetVec3i(volume, "dimensions", &(osp::vec3i&)volumeDimensions), "no volume dimensions specified"); // Voxel type string. char *voxelType; exitOnCondition(!ospGetString(volume, "voxelType", &voxelType), "no voxel type specified"); // Voxel size in bytes. size_t voxelSize; if (strcmp(voxelType, "uchar") == 0) voxelSize = sizeof(unsigned char); else if (strcmp(voxelType, "float") == 0) voxelSize = sizeof(float); else if (strcmp(voxelType, "double") == 0) voxelSize = sizeof(double); else exitOnCondition(true, "unsupported voxel type"); // Check if a subvolume of the volume has been specified. // Subvolume params: subvolumeOffsets, subvolumeDimensions, subvolumeSteps. // The subvolume defaults to full dimensions (allowing for just subsampling, // for example). ospcommon::vec3i subvolumeOffsets = ospcommon::vec3i(0); ospGetVec3i(volume, "subvolumeOffsets", (osp::vec3i*)&subvolumeOffsets); exitOnCondition(reduce_min(subvolumeOffsets) < 0 || reduce_max(subvolumeOffsets - volumeDimensions) >= 0, "invalid subvolume offsets"); ospcommon::vec3i subvolumeDimensions = volumeDimensions - subvolumeOffsets; ospGetVec3i(volume, "subvolumeDimensions", (osp::vec3i*)&subvolumeDimensions); exitOnCondition(reduce_min(subvolumeDimensions) < 1 || reduce_max(subvolumeDimensions - (volumeDimensions - subvolumeOffsets)) > 0, "invalid subvolume dimension(s) specified"); ospcommon::vec3i subvolumeSteps = ospcommon::vec3i(1); ospGetVec3i(volume, "subvolumeSteps", (osp::vec3i*)&subvolumeSteps); exitOnCondition(reduce_min(subvolumeSteps) < 1 || reduce_max(subvolumeSteps - (volumeDimensions - subvolumeOffsets)) >= 0, "invalid subvolume steps"); bool useSubvolume = false; // The dimensions of the volume to be imported; this will be changed if a // subvolume is specified. ospcommon::vec3i importVolumeDimensions = volumeDimensions; if (reduce_max(subvolumeOffsets) > 0 || subvolumeDimensions != volumeDimensions || reduce_max(subvolumeSteps) > 1) { useSubvolume = true; // The dimensions of the volume to be imported, considering the subvolume // specified. int xdim = subvolumeDimensions.x / subvolumeSteps.x + (subvolumeDimensions.x % subvolumeSteps.x != 0); int ydim = subvolumeDimensions.y / subvolumeSteps.y + (subvolumeDimensions.y % subvolumeSteps.y != 0); int zdim = subvolumeDimensions.z / subvolumeSteps.z + (subvolumeDimensions.z % subvolumeSteps.z != 0); importVolumeDimensions = ospcommon::vec3i(xdim, ydim, zdim); // Range check. exitOnCondition(reduce_min(importVolumeDimensions) <= 0, "invalid import volume dimensions"); // Update the provided dimensions of the volume for the subvolume specified. ospSetVec3i(volume, "dimensions", (osp::vec3i&)importVolumeDimensions); } ospcommon::vec2f voxelRange(+std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity()); if (!useSubvolume) { size_t numSlicesPerSetRegion = 4; // Voxel count. size_t voxelCount = volumeDimensions.x * volumeDimensions.y; // Allocate memory for a single slice through the volume. unsigned char *voxelData = new unsigned char[numSlicesPerSetRegion * voxelCount * voxelSize]; // We copy data into the volume by the slice in case memory is limited. for (size_t z = 0 ; z < volumeDimensions.z ; z += numSlicesPerSetRegion) { // Copy voxel data into the buffer. size_t slicesToRead = std::min(numSlicesPerSetRegion, volumeDimensions.z - z); size_t voxelsRead = fread(voxelData, voxelSize, slicesToRead * voxelCount, file); // The end of the file may have been reached unexpectedly. exitOnCondition(voxelsRead != slicesToRead*voxelCount, "end of volume file reached before read completed"); if (strcmp(voxelType, "uchar") == 0) { extendVoxelRange(voxelRange, (unsigned char *)voxelData, volumeDimensions.x*volumeDimensions.y); } else if (strcmp(voxelType, "float") == 0) { extendVoxelRange(voxelRange, (float *)voxelData, volumeDimensions.x*volumeDimensions.y); } else if (strcmp(voxelType, "double") == 0) { extendVoxelRange(voxelRange, (double *)voxelData, volumeDimensions.x*volumeDimensions.y); } else { exitOnCondition(true, "unsupported voxel type"); } ospcommon::vec3i region_lo(0, 0, z); ospcommon::vec3i region_sz(volumeDimensions.x, volumeDimensions.y, slicesToRead); // Copy the voxels into the volume. ospSetRegion(volume, voxelData, (osp::vec3i&)region_lo, (osp::vec3i&)region_sz); // std::cerr << "volume load: " // << float(z) / float(volumeDimensions.z) * 100. << " %" // << std::endl; } // Clean up. delete [] voxelData; } else { throw std::runtime_error("computation of voxel range not yet " "implemented for subvolumes"); // Allocate memory for a single row of voxel data. unsigned char *rowData = new unsigned char[volumeDimensions.x * voxelSize]; // Allocate memory for a single row of voxel data for the subvolume. unsigned char *subvolumeRowData = new unsigned char[importVolumeDimensions.x * voxelSize]; // Read the subvolume data from the full volume. for(long i3 = subvolumeOffsets.z; i3 < subvolumeOffsets.z + subvolumeDimensions.z; i3 += subvolumeSteps.z) { for(long i2 = subvolumeOffsets.y; i2 < subvolumeOffsets.y + subvolumeDimensions.y; i2+=subvolumeSteps.y) { // Seek to appropriate location in file. fseek(file, offset + (i3 * volumeDimensions.y * volumeDimensions.x * voxelSize) + (i2 * volumeDimensions.x * voxelSize), SEEK_SET); // Read row from volume. size_t voxelsRead = fread(rowData, voxelSize, volumeDimensions.x, file); // The end of the file may have been reached unexpectedly. exitOnCondition(voxelsRead != volumeDimensions.x, "end of volume file reached before read completed"); // Resample row for the subvolume. for(long i1 = subvolumeOffsets.x; i1 < subvolumeOffsets.x+subvolumeDimensions.x; i1 += subvolumeSteps.x) { memcpy(&subvolumeRowData[(i1 - subvolumeOffsets.x) / subvolumeSteps.x * voxelSize], &rowData[i1 * voxelSize], voxelSize); } // Copy subvolume row into the volume. ospcommon::vec3i region_lo(0, (i2 - subvolumeOffsets.y) / subvolumeSteps.y, (i3 - subvolumeOffsets.z) / subvolumeSteps.z); ospcommon::vec3i region_sz(importVolumeDimensions.x, 1, 1); ospSetRegion(volume, &subvolumeRowData[0], (osp::vec3i&)region_lo, (osp::vec3i&)region_sz); } } // Clean up. delete [] rowData; delete [] subvolumeRowData; } if (gzipped) pclose(file); else fclose(file); // Return the volume. VolumeFile::voxelRangeOf[volume] = voxelRange; return(volume); }
void main(int argc, const char *argv[]) { // init ospray ospInit(&argc,argv); // init qt QApplication *app = new QApplication(argc, (char **)argv); Ref<sg::World> world = new sg::World; Ref<sg::Renderer> renderer = new sg::Renderer; bool fullscreen = false; for (int argID=1;argID<argc;argID++) { const std::string arg = argv[argID]; if (arg[0] == '-') { if (arg == "-o" || arg == "--render-to-file") { outFileName = argv[++argID]; } else if (arg == "--size") { frameResolution.x = atoi(argv[++argID]); frameResolution.y = atoi(argv[++argID]); } else if (arg == "-spp" || arg == "--spp" || arg == "--samples-per-pixel") { spp = atoi(argv[++argID]); } else if (arg == "--data-distributed" || arg == "--data-parallel") { sg::Volume::useDataDistributedVolume = true; } else if (arg == "--1k" || arg == "-1k") { frameResolution.x = 1024; frameResolution.y = 1024; } else if (arg == "--test-sphere") { world = sg::createTestSphere(); } else if (arg == "--show-fps" || arg == "-fps" || arg == "--fps") { showFPS = true; } else if (arg == "--module") { sg::loadModule(argv[++argID]); } else if (arg == "--renderer") { integratorFromCommandLine = argv[++argID]; } else if (arg == "-vi") { if (!cameraFromCommandLine) cameraFromCommandLine = new sg::PerspectiveCamera; assert(argID+3<argc); float x = atof(argv[++argID]); float y = atof(argv[++argID]); float z = atof(argv[++argID]); cameraFromCommandLine->setAt(vec3f(x,y,z)); } else if (arg == "-vp") { if (!cameraFromCommandLine) cameraFromCommandLine = new sg::PerspectiveCamera; assert(argID+3<argc); float x = atof(argv[++argID]); float y = atof(argv[++argID]); float z = atof(argv[++argID]); cameraFromCommandLine->setFrom(vec3f(x,y,z)); } else if (arg == "-vu") { assert(argID+3<argc); float x = atof(argv[++argID]); float y = atof(argv[++argID]); float z = atof(argv[++argID]); upFromCommandLine = vec3f(x,y,z); if (cameraFromCommandLine) cameraFromCommandLine->setUp(vec3f(x,y,z)); } else if (arg == "--fullscreen" || arg == "-fs"){ fullscreen = true; } else { throw std::runtime_error("#osp:qtv: unknown cmdline param '"+arg+"'"); } } else { FileName fn = arg; if (fn.ext() == "osp" || fn.ext() == "pkd") { world = sg::loadOSP(fn.str()); // } else if (fn.ext() == "atom") { // world = sg::AlphaSpheres::importOspAtomFile(fn.str()); } else if ((fn.ext() == "ply") || ((fn.ext() == "gz") && (fn.dropExt().ext() == "ply"))) { sg::importPLY(world,fn); } else if (fn.ext() == "obj") { sg::importOBJ(world,fn); // } else if (fn.ext() == "x3d") { // sg::importX3D(world,fn); } else if (fn.ext() == "xml") { std::cout << "#osp:qtv: reading RIVL file " << arg << std::endl; world = sg::importRIVL(arg); } else sg::importFile(world,fn); // throw std::runtime_error("unsupported file format in '"+fn.str()+"'"); // std::cout << "#osp:qtv: reading RIVL file " << arg << std::endl; //world = sg::importRIVL(arg); } } if (!world) { std::cout << "#osp:qtv: no world defined. exiting." << std::endl; exit(1); } // set the current world ... std::cout << "#osp:qtv: setting world ..." << std::endl; renderer->setWorld(world); // ------------------------------------------------------- // initialize renderer's integrator // ------------------------------------------------------- { // first, check if one is specified in the scene file. Ref<sg::Integrator> integrator = renderer->getLastDefinedIntegrator(); if (!integrator) { std::string integratorName = integratorFromCommandLine; if (integratorName == "") integratorName = DEFAULT_INTEGRATOR_NAME; integrator = new sg::Integrator(integratorName); } renderer->setIntegrator(integrator); integrator->setSPP(spp); integrator->commit(); } // ------------------------------------------------------- // initialize renderer's camera // ------------------------------------------------------- { // activate the last camera defined in the scene graph (if set) if (cameraFromCommandLine) { renderer->setCamera(cameraFromCommandLine.cast<sg::Camera>()); } else { renderer->setCamera(renderer->getLastDefinedCamera()); } if (!renderer->camera) { renderer->setCamera(renderer->createDefaultCamera(upFromCommandLine)); } } // ------------------------------------------------------- // determine output method: offline to file, or interactive viewer // ------------------------------------------------------- if (outFileName == "") { // create new modelviewer cout << "#osp:qtv: setting up to open QT viewer window" << endl; ModelViewer *modelViewer = new ModelViewer(renderer, fullscreen); // modelViewer->setFixedSize(frameResolution.x,frameResolution.y); modelViewer->showFrameRate(showFPS); std::cout << "#osp:qtv: Press 'f' to toggle fullscreen rendering mode" << endl; if (fullscreen){ std::cout << "#osp:qtv: opening fullscreen viewer, press 'ESC' to quit" << endl; modelViewer->showFullScreen(); } else { modelViewer->show(); } if (frameResolution.x > 0) { cout << "#osp:qtv: trying to set render size to " << frameResolution.x << "x" << frameResolution.y << " pixels" << endl; float frame_width = modelViewer->width() - modelViewer->renderWidget->width(); float frame_height = modelViewer->height() - modelViewer->renderWidget->height(); modelViewer->resize(frameResolution.x+frame_width, frameResolution.y+frame_height); cout << "#osp:qtv: now rendering at " << modelViewer->renderWidget->width() << "x" << modelViewer->renderWidget->height() << " pixels." << endl; } // let qt run... app->exec(); // done, closing down. delete modelViewer; delete app; } else { cout << "#osp:qtv: setting up in render-to-file mode" << endl; if (frameResolution == vec2i(-1, -1)) { cout << "#osp:qtv: Warning! no resolution specified, defaulting to 1280x720" << endl; frameResolution = vec2i(1280, 720); } if (!renderer->frameBuffer) { cout << "#osp:qtv: creating default framebuffer (" << frameResolution.x << "x" << frameResolution.y << ")" << endl; renderer->frameBuffer = new sg::FrameBuffer(frameResolution); } renderer->frameBuffer->commit(); renderer->frameBuffer->clear(); // output file specified - render to file cout << "#osp:qtv: rendering frame" << endl; renderer->renderFrame(); unsigned char *fbMem = renderer->frameBuffer->map(); cout << "#osp:qtv: saving image" << endl; // PRINT((int*)fbMem); // PRINT(*(int**)fbMem); QImage image = QImage(fbMem, renderer->frameBuffer->getSize().x, renderer->frameBuffer->getSize().y, QImage::Format_ARGB32).rgbSwapped().mirrored(); // QImage fb = QImage(fbMem,size.x,size.y,QImage::Format_RGB32).rgbSwapped().mirrored(); image.save(outFileName.c_str()); renderer->frameBuffer->unmap(fbMem); cout << "#osp:qtv: rendered image saved to " << outFileName << endl; cout << "#osp:qtv: done... exiting." << endl; exit(0); } }
Ref<Image> loadFreeImage(const FileName& fileName) { FIBITMAP* dib = NULL; FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(fileName.c_str()); //------------------------------------------------- // Sonderfall - unser Schutzformat "vrh" laden // ZLib-compressed HDR-Image! //------------------------------------------------- std::string ext = std::strlwr(fileName.ext()); if( ext == "vrh" ) { fif = FIF_HDR; dib = loadVRH(fileName); } else { if(FreeImage_FIFSupportsReading(fif)) dib = FreeImage_Load(fif, fileName.c_str()); } if(!dib) return NULL; FREE_IMAGE_COLOR_TYPE fic = FreeImage_GetColorType(dib); if(fic != FIC_RGB && fic != FIC_RGBALPHA) return NULL; BYTE* pixels = FreeImage_GetBits(dib); unsigned int width = FreeImage_GetWidth(dib); unsigned int height = FreeImage_GetHeight(dib); if((pixels == 0) || (width == 0) || (height == 0)) return NULL; FREE_IMAGE_TYPE fit = FreeImage_GetImageType(dib); // special image handling for float-images (e.g. *.HDR) if(fit == FIT_RGBF) { Image* out = new Image3f(width, height, fileName); for(unsigned int y = 0; y < out->height; y++) { FIRGBF* bits = (FIRGBF*)FreeImage_GetScanLine(dib, y); unsigned int y_pos = y; // Mirror HDR-images! if(fif == FIF_HDR) y_pos = (height - 1) - y; for(unsigned int x = 0; x < out->width; x++) { unsigned int x_pos = x; Color4 c; c.r = bits[x].red; c.g = bits[x].green; c.b = bits[x].blue; out->set(x_pos, y_pos, c); } } return out; } //--------------------------------- // normal bitmap images // --> Texturen // --> Backplates //--------------------------------- if(fit == FIT_BITMAP) { //Image* out = new Image3c(width, height, fileName); Ref<Image> out = new Image4c(width, height, fileName); unsigned int bpp = FreeImage_GetBPP(dib); BOOL bHasAlpha = FreeImage_IsTransparent(dib); float rcpMaxRGB = 1.0f / 255.0f; float rcpGamma = 1.0f; // 1.4f; // TEST - nach HDRI Handbuch ( Texturen um Gamma Wert dunker machen ) for(unsigned int y = 0; y < out->height; y++) { BYTE* bits = (BYTE*)FreeImage_GetScanLine(dib, y); for(unsigned int x = 0; x < out->width; x++) { Color4 c(0, 0, 0, 1 ); if(bpp == 8) { c.r = bits[x]; c.g = bits[x]; c.b = bits[x]; } if(bpp == 24) { RGBTRIPLE& Value = ((RGBTRIPLE*)bits)[x]; c.r = ( ((float)Value.rgbtRed ) * rcpMaxRGB )* rcpGamma ; c.g = ( ((float)Value.rgbtGreen) * rcpMaxRGB )* rcpGamma ; c.b = ( ((float)Value.rgbtBlue ) * rcpMaxRGB )* rcpGamma ; } if(bpp == 32) { RGBQUAD& Value = ((RGBQUAD*)bits)[x]; if(bHasAlpha && Value.rgbReserved < 255) // Alpha-channel { // Color = Magenta c.r = (255.0f) * rcpMaxRGB; c.g = ( 0.0f) * rcpMaxRGB; c.b = (255.0f) * rcpMaxRGB; } else { c.r = ( ((float)Value.rgbRed ) * rcpMaxRGB)* rcpGamma ; c.g = ( ((float)Value.rgbGreen) * rcpMaxRGB)* rcpGamma ; c.b = ( ((float)Value.rgbBlue ) * rcpMaxRGB)* rcpGamma ; } } out->set(x, y, c); } } return out; } return NULL; }
/* main function in embree namespace */ int main(int argc, char** argv) { /* for best performance set FTZ and DAZ flags in MXCSR control and status register */ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); /* create stream for parsing */ Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv)); /* parse command line */ parseCommandLine(stream, FileName()); /* load default scene if none specified */ if (filename.ext() == "") { FileName file = FileName::executableFolder() + FileName("models/cornell_box.ecs"); parseCommandLine(new ParseStream(new LineCommentFilter(file, "#")), file.path()); } /* configure number of threads */ if (g_numThreads) g_rtcore += ",threads=" + std::to_string((long long)g_numThreads); if (g_numBenchmarkFrames) g_rtcore += ",benchmark=1"; g_rtcore += g_subdiv_mode; /* load scene */ if (strlwr(filename.ext()) == std::string("obj")) { if (g_subdiv_mode != "") { std::cout << "enabling subdiv mode" << std::endl; loadOBJ(filename,one,g_obj_scene,true); } else loadOBJ(filename,one,g_obj_scene); } else if (strlwr(filename.ext()) == std::string("xml")) loadXML(filename,one,g_obj_scene); else if (filename.ext() != "") THROW_RUNTIME_ERROR("invalid scene type: "+strlwr(filename.ext())); /* load keyframes */ if (keyframeList.str() != "") loadKeyFrameAnimation(keyframeList); /* initialize ray tracing core */ init(g_rtcore.c_str()); /* set shader mode */ switch (g_shader) { case SHADER_EYELIGHT: key_pressed(GLUT_KEY_F2); break; case SHADER_UV : key_pressed(GLUT_KEY_F4); break; case SHADER_NG : key_pressed(GLUT_KEY_F5); break; case SHADER_GEOMID : key_pressed(GLUT_KEY_F6); break; case SHADER_GEOMID_PRIMID: key_pressed(GLUT_KEY_F7); break; }; /* convert triangle meshes to subdiv meshes */ if (g_only_subdivs) g_obj_scene.convert_to_subdiv(); /* send model */ set_scene(&g_obj_scene); /* send keyframes */ if (g_keyframes.size()) set_scene_keyframes(&*g_keyframes.begin(),g_keyframes.size()); /* benchmark mode */ if (g_numBenchmarkFrames) renderBenchmark(outFilename); /* render to disk */ if (outFilename.str() != "") renderToFile(outFilename); /* interactive mode */ if (g_interactive) { initWindowState(argc,argv,tutorialName, g_width, g_height, g_fullscreen); enterWindowRunLoop(g_anim_mode); } return 0; }