void Listener::initialize(const Misc::ConfigurationFileSection& configFileSection) { /* Read the listener's name: */ std::string name=configFileSection.retrieveString("./name"); listenerName=new char[name.size()+1]; strcpy(listenerName,name.c_str()); /* Determine whether the listener is head-tracked: */ headTracked=configFileSection.retrieveValue<bool>("./headTracked",false); if(headTracked) { /* Retrieve head tracking device pointer: */ headDevice=findInputDevice(configFileSection.retrieveString("./headDevice").c_str()); if(headDevice==0) Misc::throwStdErr("Listener: Head device \"%s\" not found",configFileSection.retrieveString("./headDevice").c_str()); } else { /* Retrieve fixed head position/orientation: */ headDeviceTransformation=configFileSection.retrieveValue<TrackerState>("./headDeviceTransformation"); } /* Get head position and listening and up directions in head device coordinates: */ deviceHeadPosition=configFileSection.retrieveValue<Point>("./headPosition",Point::origin); deviceListenDirection=configFileSection.retrieveValue<Vector>("./listenDirection",Vector(0,1,0)); deviceUpDirection=configFileSection.retrieveValue<Vector>("./upDirection",Vector(0,0,1)); }
ToolKillZoneFrustum::ToolKillZoneFrustum(const Misc::ConfigurationFileSection& configFileSection) :ToolKillZone(configFileSection), viewer(0),screen(0) { /* Get the viewer: */ std::string viewerName=configFileSection.retrieveString("./killZoneViewerName"); viewer=findViewer(viewerName.c_str()); if(viewer==0) Misc::throwStdErr("ToolKillZoneFrustum::ToolKillZoneFrustum: Viewer %s not found",viewerName.c_str()); /* Get the screen: */ std::string screenName=configFileSection.retrieveString("./killZoneScreenName"); screen=findScreen(screenName.c_str()); if(screen==0) Misc::throwStdErr("ToolKillZoneFrustum::ToolKillZoneFrustum: Screen %s not found",screenName.c_str()); /* Read box' center and size: */ Point boxCenter=configFileSection.retrieveValue<Point>("./killZoneCenter"); Vector boxSize=configFileSection.retrieveValue<Vector>("./killZoneSize"); /* Transform box center and size to screen coordinates: */ ONTransform screenT=screen->getScreenTransformation(); boxCenter=screenT.inverseTransform(boxCenter); boxCenter[2]=Scalar(0); boxSize=screenT.inverseTransform(boxSize); boxSize[2]=Scalar(0); box=Box(boxCenter-boxSize*Scalar(0.5),boxCenter+boxSize*Scalar(0.5)); }
void Viewer::initialize(const Misc::ConfigurationFileSection& configFileSection) { /* Read the viewer's name: */ std::string name=configFileSection.retrieveString("./name"); viewerName=new char[name.size()+1]; strcpy(viewerName,name.c_str()); /* Determine whether the viewer is head-tracked: */ headTracked=configFileSection.retrieveValue<bool>("./headTracked",false); if(headTracked) { /* Retrieve head tracking device pointer: */ headDevice=findInputDevice(configFileSection.retrieveString("./headDevice").c_str()); if(headDevice==0) Misc::throwStdErr("Viewer: Head device \"%s\" not found",configFileSection.retrieveString("./headDevice").c_str()); } else { /* Retrieve fixed head position/orientation: */ headDeviceTransformation=configFileSection.retrieveValue<TrackerState>("./headDeviceTransformation"); } /* Get view direction and eye positions in head device coordinates: */ deviceViewDirection=configFileSection.retrieveValue<Vector>("./viewDirection",Vector(0,1,0)); deviceMonoEyePosition=configFileSection.retrieveValue<Point>("./monoEyePosition",Point::origin); deviceLeftEyePosition=configFileSection.retrieveValue<Point>("./leftEyePosition",Point::origin); deviceRightEyePosition=configFileSection.retrieveValue<Point>("./rightEyePosition",Point::origin); /* Create the viewer's light source: */ lightsource=getLightsourceManager()->createLightsource(true); /* Get head light enable flag: */ if(!configFileSection.retrieveValue<bool>("./headLightEnabled",true)) lightsource->disable(); /* Get head light position and direction in head device coordinates: */ headLightDevicePosition=configFileSection.retrieveValue<Point>("./headLightPosition",Point::origin); headLightDeviceDirection=configFileSection.retrieveValue<Vector>("./headLightDirection",Vector(0,1,0)); /* Retrieve head light settings: */ GLLight::Color headLightColor=configFileSection.retrieveValue<GLLight::Color>("./headLightColor",GLLight::Color(1.0f,1.0f,1.0f)); lightsource->getLight().diffuse=headLightColor; lightsource->getLight().specular=headLightColor; lightsource->getLight().spotCutoff=configFileSection.retrieveValue<GLfloat>("./headLightSpotCutoff",180.0f); lightsource->getLight().spotExponent=configFileSection.retrieveValue<GLfloat>("./headLightSpotExponent",0.0f); /* Initialize transient state if head tracking is disabled: */ if(!headTracked) { /* Initialize transient state: */ Point hlp=headDeviceTransformation.transform(headLightDevicePosition); lightsource->getLight().position=GLLight::Position(GLfloat(hlp[0]),GLfloat(hlp[1]),GLfloat(hlp[2]),1.0f); Vector hld=headDeviceTransformation.transform(headLightDeviceDirection); hld.normalize(); lightsource->getLight().spotDirection=GLLight::SpotDirection(GLfloat(hld[0]),GLfloat(hld[1]),GLfloat(hld[2])); } }
void ViewpointFileNavigationTool::configure(Misc::ConfigurationFileSection& configFileSection) { /* Override per-class configuration settings: */ viewpointFileName=configFileSection.retrieveString("./viewpointFileName",viewpointFileName); showGui=configFileSection.retrieveValue<bool>("./showGui",showGui); showKeyframes=configFileSection.retrieveValue<bool>("./showKeyframes",showKeyframes); pauseFileName=configFileSection.retrieveString("./pauseFileName",pauseFileName); autostart=configFileSection.retrieveValue<bool>("./autostart",autostart); }
TheoraMovieSaver::TheoraMovieSaver(const Misc::ConfigurationFileSection& configFileSection) :MovieSaver(configFileSection), movieFile(IO::openFile(configFileSection.retrieveString("./movieFileName").c_str(),IO::File::WriteOnly)), oggStream(1), theoraBitrate(0),theoraQuality(32),theoraGopSize(32), imageExtractor(0) { movieFile->setEndianness(Misc::LittleEndian); /* Read the encoder parameters: */ theoraBitrate=configFileSection.retrieveValue<int>("./movieBitrate",theoraBitrate); if(theoraBitrate<0) theoraBitrate=0; theoraQuality=configFileSection.retrieveValue<int>("./movieQuality",theoraQuality); if(theoraQuality<0) theoraQuality=0; if(theoraQuality>63) theoraQuality=63; theoraGopSize=configFileSection.retrieveValue<int>("./movieGopSize",theoraGopSize); if(theoraGopSize<1) theoraGopSize=1; /* Set the Theora frame rate and adjust the initially configured frame rate: */ theoraFrameRate=int(frameRate+0.5); frameRate=theoraFrameRate; frameInterval=Misc::Time(1.0/frameRate); }
ImageSequenceMovieSaver::ImageSequenceMovieSaver(const Misc::ConfigurationFileSection& configFileSection) :MovieSaver(configFileSection), frameNameTemplate(configFileSection.retrieveString("./movieFrameNameTemplate")), done(false) { /* Check if the frame name template has the correct format: */ int numConversions=0; bool hasIntConversion=false; for(std::string::const_iterator fntIt=frameNameTemplate.begin();fntIt!=frameNameTemplate.end();++fntIt) { if(*fntIt=='%') { ++fntIt; if(*fntIt!='%') { ++numConversions; /* Skip width modifiers: */ while(isdigit(*fntIt)) ++fntIt; /* Check for unsigned integer conversion: */ if(*fntIt=='u') hasIntConversion=true; } } else if(*fntIt=='/') // Only accept conversions in the file name part hasIntConversion=false; } if(numConversions!=1||!hasIntConversion) Misc::throwStdErr("MovieSaver::MovieSaver: movie frame name template \"%s\" does not have exactly one %%u conversion",frameNameTemplate.c_str()); /* Start the image writing thread: */ frameSavingThread.start(this,&ImageSequenceMovieSaver::frameSavingThreadMethod); }
VRDeviceClient::VRDeviceClient(const Misc::ConfigurationFileSection& configFileSection) :pipe(Comm::TCPSocket(configFileSection.retrieveString("./serverName"),configFileSection.retrieveValue<int>("./serverPort"))), active(false),streaming(false), packetNotificationCB(0),packetNotificationCBData(0) { initClient(); }
InputDeviceAdapterVisBox::InputDeviceAdapterVisBox(InputDeviceManager* sInputDeviceManager,const Misc::ConfigurationFileSection& configFileSection) :InputDeviceAdapter(sInputDeviceManager), xyzhpr((const float*)-1) { /* Retrieve the shared memory key from the configuration file: */ key_t sharedMemoryKey=key_t(configFileSection.retrieveValue<int>("./sharedMemoryKey",0xDEAD)); /* Try attaching to the shared memory segment: */ int sharedMemoryID=shmget(sharedMemoryKey,6*sizeof(float),0777); if(sharedMemoryID<0) Misc::throwStdErr("InputDeviceAdapterVisBox::InputDeviceAdapterVisBox: Could not attach to shared memory segment using key %x",int(sharedMemoryKey)); /* Get the pointer to the tracker state variables: */ xyzhpr=reinterpret_cast<const float*>(shmat(sharedMemoryID,0,SHM_RDONLY)); if(xyzhpr==(const float*)-1) Misc::throwStdErr("InputDeviceAdapterVisBox::InputDeviceAdapterVisBox: Could not map shared memory segment using key %x",int(sharedMemoryKey)); /* Allocate new adapter state arrays: */ numInputDevices=1; inputDevices=new InputDevice*[numInputDevices]; /* Create new input device: */ std::string deviceName=configFileSection.retrieveString("./name"); inputDevices[0]=inputDeviceManager->createInputDevice(deviceName.c_str(),InputDevice::TRACK_POS|InputDevice::TRACK_DIR|InputDevice::TRACK_ORIENT,0,0,true); inputDevices[0]->setDeviceRayDirection(configFileSection.retrieveValue<Vector>("./deviceRayDirection",Vector(0,1,0))); /* Initialize the new device's glyph from the current configuration file section: */ Glyph& deviceGlyph=inputDeviceManager->getInputGraphManager()->getInputDeviceGlyph(inputDevices[0]); deviceGlyph.configure(configFileSection,"./deviceGlyphType","./deviceGlyphMaterial"); /* Set device's linear and angular velocities to zero, because we don't know any better: */ inputDevices[0]->setLinearVelocity(Vector::zero); inputDevices[0]->setAngularVelocity(Vector::zero); }
void Glyph::configure(const Misc::ConfigurationFileSection& configFileSection,const char* glyphTypeTagName,const char* glyphMaterialTagName) { /* Retrieve glyph type as string: */ std::string glyphTypeName=configFileSection.retrieveString(glyphTypeTagName,"None"); if(glyphTypeName!="None") { if(glyphTypeName=="Cone") glyphType=CONE; else if(glyphTypeName=="Cube") glyphType=CUBE; else if(glyphTypeName=="Sphere") glyphType=SPHERE; else if(glyphTypeName=="Crossball") glyphType=CROSSBALL; else if(glyphTypeName=="Box") glyphType=BOX; else if(glyphTypeName=="Cursor") glyphType=CURSOR; else Misc::throwStdErr("GlyphRenderer::Glyph: Invalid glyph type %s",glyphTypeName.c_str()); enabled=true; glyphMaterial=configFileSection.retrieveValue<GLMaterial>(glyphMaterialTagName,glyphMaterial); } else enabled=false; }
SoundContext::SoundContext(const Misc::ConfigurationFileSection& configFileSection,VruiState* sVruiState) :vruiState(sVruiState), #ifdef VRUI_USE_OPENAL alDevice(0),alContext(0), #endif contextData(0), listener(findListener(configFileSection.retrieveString("./listenerName").c_str())) { #ifdef VRUI_USE_OPENAL /* Open the OpenAL device: */ std::string alDeviceName=configFileSection.retrieveValue<std::string>("./deviceName","Default"); alDevice=alcOpenDevice(alDeviceName!="Default"?alDeviceName.c_str():0); if(alDevice==0) Misc::throwStdErr("SoundContext::SoundContext: Could not open OpenAL sound device %s",alDeviceName.c_str()); /* Create an OpenAL context: */ alContext=alcCreateContext(alDevice,0); if(alContext==0) { alcCloseDevice(alDevice); Misc::throwStdErr("SoundContext::SoundContext: Could not create OpenAL context for sound device %s",alDeviceName.c_str()); } #endif /* Create an AL context data object: */ contextData=new ALContextData(101); /* Initialize the sound context's OpenAL context: */ makeCurrent(); /* Initialize application sound state: */ if(vruiState->perSoundInitFunction!=0) vruiState->perSoundInitFunction(*contextData,vruiState->perSoundInitFunctionData); }
void Glyph::configure(const Misc::ConfigurationFileSection& configFileSection,const char* glyphTypeTagName,const char* glyphMaterialTagName) { /* Retrieve glyph type as string and set it: */ setGlyphType(configFileSection.retrieveString(glyphTypeTagName,"None").c_str()); /* Retrieve the glyph material: */ glyphMaterial=configFileSection.retrieveValue<GLMaterial>(glyphMaterialTagName,glyphMaterial); }
std::string InputDeviceDataSaver::getInputDeviceDataFileName(const Misc::ConfigurationFileSection& configFileSection) { /* Retrieve the base file name: */ std::string inputDeviceDataFileName=configFileSection.retrieveString("./inputDeviceDataFileName"); /* Make the file name unique: */ char numberedFileName[1024]; Misc::createNumberedFileName(inputDeviceDataFileName.c_str(),4,numberedFileName); return numberedFileName; }
InputDeviceDataSaver::InputDeviceDataSaver(const Misc::ConfigurationFileSection& configFileSection,InputDeviceManager& inputDeviceManager) :inputDeviceDataFile(getInputDeviceDataFileName(configFileSection).c_str(),"wb",Misc::File::LittleEndian), numInputDevices(inputDeviceManager.getNumInputDevices()), inputDevices(new InputDevice*[numInputDevices]), soundRecorder(0), firstFrame(true) { /* Save number of input devices: */ inputDeviceDataFile.write<int>(numInputDevices); /* Save layout of all input devices in the input device manager: */ for(int i=0;i<numInputDevices;++i) { /* Get pointer to the input device: */ inputDevices[i]=inputDeviceManager.getInputDevice(i); /* Save input device's layout: */ char name[40]; strncpy(name,inputDevices[i]->getDeviceName(),40); name[39]='\0'; inputDeviceDataFile.write(name,40); inputDeviceDataFile.write<int>(inputDevices[i]->getTrackType()); inputDeviceDataFile.write<int>(inputDevices[i]->getNumButtons()); inputDeviceDataFile.write<int>(inputDevices[i]->getNumValuators()); inputDeviceDataFile.write(inputDevices[i]->getDeviceRayDirection().getComponents(),3); } /* Check if the user wants to record a commentary track: */ std::string soundFileName=configFileSection.retrieveString("./soundFileName",""); if(soundFileName!="") { try { /* Create a sound data format for recording: */ Sound::SoundDataFormat soundFormat; soundFormat.bitsPerSample=configFileSection.retrieveValue<int>("./sampleResolution",soundFormat.bitsPerSample); soundFormat.samplesPerFrame=configFileSection.retrieveValue<int>("./numChannels",soundFormat.samplesPerFrame); soundFormat.framesPerSecond=configFileSection.retrieveValue<int>("./sampleRate",soundFormat.framesPerSecond); /* Create a sound recorder for the given sound file name: */ char numberedFileName[1024]; soundRecorder=new Sound::SoundRecorder(soundFormat,Misc::createNumberedFileName(soundFileName.c_str(),4,numberedFileName)); } catch(std::runtime_error error) { /* Print a message, but carry on: */ std::cerr<<"InputDeviceDataSaver: Disabling sound recording due to exception "<<error.what()<<std::endl; } } }
VisletManager::VisletManager(const Misc::ConfigurationFileSection& sConfigFileSection) :Plugins::FactoryManager<VisletFactory>(sConfigFileSection.retrieveString("./visletDsoNameTemplate",SYSVISLETDSONAMETEMPLATE)), configFileSection(sConfigFileSection) { typedef std::vector<std::string> StringList; /* Get additional search paths from configuration file section and add them to the factory manager: */ StringList visletSearchPaths=configFileSection.retrieveValue<StringList>("./visletSearchPaths",StringList()); for(StringList::const_iterator vspIt=visletSearchPaths.begin();vspIt!=visletSearchPaths.end();++vspIt) { /* Add the path: */ getDsoLocator().addPath(*vspIt); } }
void InputDeviceAdapter::createInputDevice(int deviceIndex,const Misc::ConfigurationFileSection& configFileSection) { /* Read input device name: */ std::string name=configFileSection.retrieveString("./name"); /* Determine input device type: */ int trackType=InputDevice::TRACK_NONE; std::string trackTypeString=configFileSection.retrieveString("./trackType","None"); if(trackTypeString=="None") trackType=InputDevice::TRACK_NONE; else if(trackTypeString=="3D") trackType=InputDevice::TRACK_POS; else if(trackTypeString=="Ray") trackType=InputDevice::TRACK_POS|InputDevice::TRACK_DIR; else if(trackTypeString=="6D") trackType=InputDevice::TRACK_POS|InputDevice::TRACK_DIR|InputDevice::TRACK_ORIENT; else Misc::throwStdErr("InputDeviceAdapter: Unknown tracking type \"%s\"",trackTypeString.c_str()); /* Determine numbers of buttons and valuators: */ int numButtons=configFileSection.retrieveValue<int>("./numButtons",0); int numValuators=configFileSection.retrieveValue<int>("./numValuators",0); /* Create new input device as a physical device: */ InputDevice* newDevice=inputDeviceManager->createInputDevice(name.c_str(),trackType,numButtons,numValuators,true); Vector deviceRayDirection=configFileSection.retrieveValue<Vector>("./deviceRayDirection",Vector(0,1,0)); Scalar deviceRayStart=configFileSection.retrieveValue<Scalar>("./deviceRayStart",-getInchFactor()); newDevice->setDeviceRay(deviceRayDirection,deviceRayStart); /* Initialize the new device's glyph from the current configuration file section: */ Glyph& deviceGlyph=inputDeviceManager->getInputGraphManager()->getInputDeviceGlyph(newDevice); deviceGlyph.configure(configFileSection,"./deviceGlyphType","./deviceGlyphMaterial"); /* Save the new input device: */ inputDevices[deviceIndex]=newDevice; }
ToolKillZone::ToolKillZone(const Misc::ConfigurationFileSection& configFileSection) :baseDevice(0), render(true), material(getWidgetMaterial()), modelVersion(1) { /* Retrieve the name of the base device (if any) from the configuration file: */ std::string baseDeviceName=configFileSection.retrieveString("./killZoneBaseDevice",""); if(baseDeviceName!="") { /* Attach the kill zone to the base device: */ baseDevice=getInputDeviceManager()->findInputDevice(baseDeviceName.c_str()); if(baseDevice==0) Misc::throwStdErr("ToolKillZone: Unknown base input device \"%s\"",baseDeviceName.c_str()); } /* Retrieve the render flag: */ render=configFileSection.retrieveValue<bool>("./killZoneRender",render); /* Retrieve the model material: */ material=configFileSection.retrieveValue<GLMaterial>("./killZoneMaterial",material); }
InputDeviceAdapterPlayback::InputDeviceAdapterPlayback(InputDeviceManager* sInputDeviceManager,const Misc::ConfigurationFileSection& configFileSection) :InputDeviceAdapter(sInputDeviceManager), inputDeviceDataFile(configFileSection.retrieveString("./inputDeviceDataFileName").c_str(),"rb",Misc::File::LittleEndian), mouseCursorFaker(0), synchronizePlayback(configFileSection.retrieveValue<bool>("./synchronizePlayback",false)), quitWhenDone(configFileSection.retrieveValue<bool>("./quitWhenDone",false)), soundPlayer(0), saveMovie(configFileSection.retrieveValue<bool>("./saveMovie",false)), movieWindowIndex(0),movieWindow(0), firstFrame(true),timeStamp(0.0), done(false) { /* Read file header: */ static const char* fileHeader="Vrui Input Device Data File v2.0\n"; char header[34]; inputDeviceDataFile.read<char>(header,34); bool haveFeatureNames=strncmp(header,fileHeader,34)==0; if(!haveFeatureNames) { /* Old file format doesn't have the header text: */ inputDeviceDataFile.rewind(); } /* Read random seed value: */ unsigned int randomSeed=inputDeviceDataFile.read<unsigned int>(); setRandomSeed(randomSeed); /* Read number of saved input devices: */ numInputDevices=inputDeviceDataFile.read<int>(); inputDevices=new InputDevice*[numInputDevices]; deviceFeatureBaseIndices=new int[numInputDevices]; /* Initialize devices: */ for(int i=0;i<numInputDevices;++i) { /* Read device's name and layout from file: */ std::string name=Misc::readCppString(inputDeviceDataFile); int trackType=inputDeviceDataFile.read<int>(); int numButtons=inputDeviceDataFile.read<int>(); int numValuators=inputDeviceDataFile.read<int>(); Vector deviceRayDirection; inputDeviceDataFile.read<Scalar>(deviceRayDirection.getComponents(),3); /* Create new input device: */ InputDevice* newDevice=inputDeviceManager->createInputDevice(name.c_str(),trackType,numButtons,numValuators,true); newDevice->setDeviceRayDirection(deviceRayDirection); /* Initialize the new device's glyph from the current configuration file section: */ Glyph& deviceGlyph=inputDeviceManager->getInputGraphManager()->getInputDeviceGlyph(newDevice); char deviceGlyphTypeTag[20]; snprintf(deviceGlyphTypeTag,sizeof(deviceGlyphTypeTag),"./device%dGlyphType",i); char deviceGlyphMaterialTag[20]; snprintf(deviceGlyphMaterialTag,sizeof(deviceGlyphMaterialTag),"./device%dGlyphMaterial",i); deviceGlyph.configure(configFileSection,deviceGlyphTypeTag,deviceGlyphMaterialTag); /* Store the input device: */ inputDevices[i]=newDevice; /* Read or create the device's feature names: */ deviceFeatureBaseIndices[i]=int(deviceFeatureNames.size()); if(haveFeatureNames) { /* Read feature names from file: */ for(int j=0;j<newDevice->getNumFeatures();++j) deviceFeatureNames.push_back(Misc::readCppString(inputDeviceDataFile)); } else { /* Create default feature names: */ for(int j=0;j<newDevice->getNumFeatures();++j) deviceFeatureNames.push_back(getDefaultFeatureName(InputDeviceFeature(newDevice,j))); } } /* Check if the user wants to use a fake mouse cursor: */ int fakeMouseCursorDevice=configFileSection.retrieveValue<int>("./fakeMouseCursorDevice",-1); if(fakeMouseCursorDevice>=0) { /* Read the cursor file name and nominal size: */ std::string mouseCursorImageFileName=configFileSection.retrieveString("./mouseCursorImageFileName",DEFAULTMOUSECURSORIMAGEFILENAME); unsigned int mouseCursorNominalSize=configFileSection.retrieveValue<unsigned int>("./mouseCursorNominalSize",24); /* Create the mouse cursor faker: */ mouseCursorFaker=new MouseCursorFaker(inputDevices[fakeMouseCursorDevice],mouseCursorImageFileName.c_str(),mouseCursorNominalSize); mouseCursorFaker->setCursorSize(configFileSection.retrieveValue<Size>("./mouseCursorSize",mouseCursorFaker->getCursorSize())); mouseCursorFaker->setCursorHotspot(configFileSection.retrieveValue<Vector>("./mouseCursorHotspot",mouseCursorFaker->getCursorHotspot())); } /* Read time stamp of first data frame: */ try { nextTimeStamp=inputDeviceDataFile.read<double>(); /* Request an update for the next frame: */ requestUpdate(); } catch(Misc::File::ReadError) { done=true; nextTimeStamp=Math::Constants<double>::max; if(quitWhenDone) { /* Request exiting the program: */ shutdown(); } } /* Check if the user wants to play back a commentary sound track: */ std::string soundFileName=configFileSection.retrieveString("./soundFileName",""); if(soundFileName!="") { try { /* Create a sound player for the given sound file name: */ soundPlayer=new Sound::SoundPlayer(soundFileName.c_str()); } catch(std::runtime_error error) { /* Print a message, but carry on: */ std::cerr<<"InputDeviceAdapterPlayback: Disabling sound playback due to exception "<<error.what()<<std::endl; } } /* Check if the user wants to save a movie: */ if(saveMovie) { /* Read the movie image file name template: */ movieFileNameTemplate=configFileSection.retrieveString("./movieFileNameTemplate"); /* Check if the name template has the correct format: */ int numConversions=0; bool hasIntConversion=false; for(std::string::const_iterator mfntIt=movieFileNameTemplate.begin();mfntIt!=movieFileNameTemplate.end();++mfntIt) { if(*mfntIt=='%') { ++mfntIt; if(*mfntIt!='%') { ++numConversions; /* Skip width modifiers: */ while(isdigit(*mfntIt)) ++mfntIt; /* Check for integer conversion: */ if(*mfntIt=='d') hasIntConversion=true; } } else if(*mfntIt=='/') // Only accept conversions in the file name part hasIntConversion=false; } if(numConversions!=1||!hasIntConversion) Misc::throwStdErr("InputDeviceAdapterPlayback::InputDeviceAdapterPlayback: movie file name template \"%s\" does not have exactly one %%d conversion",movieFileNameTemplate.c_str()); /* Get the index of the window from which to save the frames: */ movieWindowIndex=configFileSection.retrieveValue<int>("./movieWindowIndex",movieWindowIndex); /* Get the intended frame rate for the movie: */ double frameRate=configFileSection.retrieveValue<double>("./movieFrameRate",30.0); movieFrameTimeInterval=1.0/frameRate; /* Calculate the first time at which to save a frame: */ nextMovieFrameTime=nextTimeStamp+movieFrameTimeInterval*0.5; nextMovieFrameCounter=0; } }
void InputDeviceAdapterHID::createInputDevice(int deviceIndex,const Misc::ConfigurationFileSection& configFileSection) { /* Read input device name: */ std::string name=configFileSection.retrieveString("./name"); /* Read HID's vendor / product IDs: */ std::string deviceVendorProductId=configFileSection.retrieveString("./deviceVendorProductId"); /* Split ID string into vendor ID / product ID: */ char* colonPtr; unsigned int vendorId=strtoul(deviceVendorProductId.c_str(),&colonPtr,16); char* endPtr; unsigned int productId=strtoul(colonPtr+1,&endPtr,16); if(*colonPtr!=':'||*endPtr!='\0') Misc::throwStdErr("InputDeviceAdapterHID::InputDeviceAdapterHID: Malformed vendorId:productId string \"%s\" for device %s",deviceVendorProductId.c_str(),name.c_str()); /* Get the device index: */ int matchingDeviceIndex=configFileSection.retrieveValue<int>("./deviceIndex",0); /* Create list of all available /dev/input/eventX devices, in numerical order: */ struct dirent** eventFiles=0; int numEventFiles=scandir("/dev/input",&eventFiles,isEventFile,versionsort); /* Check all event files for the wanted device: */ int deviceFd=-1; for(int eventFileIndex=0;eventFileIndex<numEventFiles;++eventFileIndex) { /* Open the event file: */ char eventFileName[256]; snprintf(eventFileName,sizeof(eventFileName),"/dev/input/%s",eventFiles[eventFileIndex]->d_name); int eventFd=open(eventFileName,O_RDONLY); if(eventFd>=0) { /* Get device information: */ input_id deviceInformation; if(ioctl(eventFd,EVIOCGID,&deviceInformation)>=0) { if(deviceInformation.vendor==vendorId&&deviceInformation.product==productId) { /* We have a match: */ if(matchingDeviceIndex==0) { /* We have a winner! */ deviceFd=eventFd; break; } /* Try again on the next matching device: */ --matchingDeviceIndex; } } /* This is not the device you are looking for, go to the next: */ close(eventFd); } } /* Destroy list of event files: */ for(int i=0;i<numEventFiles;++i) free(eventFiles[i]); free(eventFiles); /* Check if a matching device was found: */ if(deviceFd<0) Misc::throwStdErr("InputDeviceAdapterHID::InputDeviceAdapterHID: No match for vendorId:productId \"%s\" for device %s",deviceVendorProductId.c_str(),name.c_str()); /* Create a new device structure: */ Device newDevice; newDevice.deviceFd=deviceFd; /* Query all feature types of the device: */ unsigned char featureTypeBits[EV_MAX/8+1]; memset(featureTypeBits,0,EV_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(0,sizeof(featureTypeBits)),featureTypeBits)<0) Misc::throwStdErr("InputDeviceAdapterHID::InputDeviceAdapterHID: Unable to query device feature types for device %s",name.c_str()); /* Count the number of keys: */ newDevice.numButtons=0; /* Query the number of keys/buttons on the device: */ if(featureTypeBits[EV_KEY/8]&(1<<(EV_KEY%8))) { /* Query key features: */ unsigned char keyBits[KEY_MAX/8+1]; memset(keyBits,0,KEY_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(EV_KEY,sizeof(keyBits)),keyBits)<0) Misc::throwStdErr("InputDeviceAdapterHID::InputDeviceAdapterHID: Unable to query keys for device %s",name.c_str()); /* Initialize the key translation array: */ newDevice.keyMap.reserve(KEY_MAX+1); for(int i=0;i<=KEY_MAX;++i) { if(keyBits[i/8]&(1<<(i%8))) { newDevice.keyMap.push_back(newDevice.numButtons); ++newDevice.numButtons; } else newDevice.keyMap.push_back(-1); } } /* Count the number of absolute and relative axes: */ newDevice.numValuators=0; /* Query the number of absolute axes on the device: */ if(featureTypeBits[EV_ABS/8]&(1<<(EV_ABS%8))) { /* Query absolute axis features: */ unsigned char absAxisBits[ABS_MAX/8+1]; memset(absAxisBits,0,ABS_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(EV_ABS,sizeof(absAxisBits)),absAxisBits)<0) Misc::throwStdErr("InputDeviceAdapterHID::InputDeviceAdapterHID: Unable to query absolute axes for device %s",name.c_str()); /* Initialize the axis translation array: */ newDevice.absAxisMap.reserve(ABS_MAX+1); for(int i=0;i<=ABS_MAX;++i) { if(absAxisBits[i/8]&(1<<(i%8))) { /* Enter the next valuator index into the axis map: */ newDevice.absAxisMap.push_back(newDevice.numValuators); /* Query the configuration of this axis: */ input_absinfo absAxisConf; if(ioctl(deviceFd,EVIOCGABS(i),&absAxisConf)<0) Misc::throwStdErr("InputDeviceAdapterHID::InputDeviceAdapterHID: Unable to query absolute axis configuration for device %s",name.c_str()); /* Create an absolute axis value mapper: */ Device::AxisValueMapper avm; avm.min=double(absAxisConf.minimum); double mid=Math::mid(double(absAxisConf.minimum),double(absAxisConf.maximum)); avm.deadMin=mid-double(absAxisConf.flat); avm.deadMax=mid+double(absAxisConf.flat); avm.max=double(absAxisConf.maximum); /* Override axis value mapper from configuration file: */ char axisSettingsTag[20]; snprintf(axisSettingsTag,sizeof(axisSettingsTag),"axis%dSettings",newDevice.numValuators); avm=configFileSection.retrieveValue<Device::AxisValueMapper>(axisSettingsTag,avm); /* Store the axis value mapper: */ newDevice.axisValueMappers.push_back(avm); ++newDevice.numValuators; } else newDevice.absAxisMap.push_back(-1); } } /* Query the number of relative axes on the device: */ if(featureTypeBits[EV_REL/8]&(1<<(EV_REL%8))) { /* Query relative axis features: */ unsigned char relAxisBits[REL_MAX/8+1]; memset(relAxisBits,0,REL_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(EV_REL,sizeof(relAxisBits)),relAxisBits)<0) Misc::throwStdErr("InputDeviceAdapterHID::InputDeviceAdapterHID: Unable to query relative axes for device %s",name.c_str()); /* Initialize the axis translation array: */ newDevice.relAxisMap.reserve(REL_MAX+1); for(int i=0;i<=REL_MAX;++i) { if(relAxisBits[i/8]&(1<<(i%8))) { /* Enter the next valuator index into the axis map: */ newDevice.relAxisMap.push_back(newDevice.numValuators); /* Create a relative axis value mapper: */ Device::AxisValueMapper avm; avm.min=-1.0; avm.deadMin=0.0; avm.deadMax=0.0; avm.max=1.0; /* Override axis value mapper from configuration file: */ char axisSettingsTag[20]; snprintf(axisSettingsTag,sizeof(axisSettingsTag),"axis%dSettings",newDevice.numValuators); avm=configFileSection.retrieveValue<Device::AxisValueMapper>(axisSettingsTag,avm); /* Store the axis value mapper: */ newDevice.axisValueMappers.push_back(avm); ++newDevice.numValuators; } else newDevice.relAxisMap.push_back(-1); } } /* Create new input device as a physical device: */ newDevice.device=inputDeviceManager->createInputDevice(name.c_str(),InputDevice::TRACK_NONE,newDevice.numButtons,newDevice.numValuators,true); /* Store the new device structure: */ devices.push_back(newDevice); }
SoundContext::SoundContext(const Misc::ConfigurationFileSection& configFileSection,VruiState* sVruiState) :vruiState(sVruiState), #if ALSUPPORT_CONFIG_HAVE_OPENAL alDevice(0),alContext(0), #endif contextData(0), listener(findListener(configFileSection.retrieveString("./listenerName").c_str())), speedOfSound(float(getMeterFactor())*343.0f), dopplerFactor(1.0f), distanceAttenuationModel(CONSTANT) { /* Set sound context parameters from configuration file: */ speedOfSound=configFileSection.retrieveValue<float>("./speedOfSound",speedOfSound); dopplerFactor=configFileSection.retrieveValue<float>("./dopplerFactor",dopplerFactor); distanceAttenuationModel=configFileSection.retrieveValue<DistanceAttenuationModel>("./distanceAttenuationModel",distanceAttenuationModel); #if ALSUPPORT_CONFIG_HAVE_OPENAL /* Open the OpenAL device: */ std::string alDeviceName=configFileSection.retrieveValue<std::string>("./deviceName","Default"); alDevice=alcOpenDevice(alDeviceName!="Default"?alDeviceName.c_str():0); if(alDevice==0) Misc::throwStdErr("SoundContext::SoundContext: Could not open OpenAL sound device \"%s\"",alDeviceName.c_str()); /* Create a list of context attributes: */ ALCint alContextAttributes[9]; ALCint* attPtr=alContextAttributes; if(configFileSection.hasTag("./mixerFrequency")) { *(attPtr++)=ALC_FREQUENCY; *(attPtr++)=configFileSection.retrieveValue<ALCint>("./mixerFrequency"); } if(configFileSection.hasTag("./refreshFrequency")) { *(attPtr++)=ALC_REFRESH; *(attPtr++)=configFileSection.retrieveValue<ALCint>("./refreshFrequency"); } if(configFileSection.hasTag("./numMonoSources")) { *(attPtr++)=ALC_MONO_SOURCES; *(attPtr++)=configFileSection.retrieveValue<ALCint>("./numMonoSources"); } if(configFileSection.hasTag("./numStereoSources")) { *(attPtr++)=ALC_STEREO_SOURCES; *(attPtr++)=configFileSection.retrieveValue<ALCint>("./numStereoSources"); } *(attPtr++)=ALC_INVALID; /* Create an OpenAL context: */ alContext=alcCreateContext(alDevice,alContextAttributes); if(alContext==0) { alcCloseDevice(alDevice); Misc::throwStdErr("SoundContext::SoundContext: Could not create OpenAL context for sound device %s",alDeviceName.c_str()); } #endif /* Create an AL context data object: */ contextData=new ALContextData(101); /* Initialize the sound context's OpenAL context: */ makeCurrent(); #if ALSUPPORT_CONFIG_HAVE_OPENAL /* Set global OpenAL parameters: */ alSpeedOfSound(speedOfSound); alDopplerFactor(dopplerFactor); switch(distanceAttenuationModel) { case CONSTANT: alDistanceModel(AL_NONE); break; case INVERSE: alDistanceModel(AL_INVERSE_DISTANCE); break; case INVERSE_CLAMPED: alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); break; case LINEAR: alDistanceModel(AL_LINEAR_DISTANCE); break; case LINEAR_CLAMPED: alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); break; case EXPONENTIAL: alDistanceModel(AL_EXPONENT_DISTANCE); break; case EXPONENTIAL_CLAMPED: alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED); break; } #endif }
void VRScreen::initialize(const Misc::ConfigurationFileSection& configFileSection) { /* Read the screen's name: */ std::string name=configFileSection.retrieveString("./name"); screenName=new char[name.size()+1]; strcpy(screenName,name.c_str()); /* Determine whether screen is device-mounted: */ deviceMounted=configFileSection.retrieveValue<bool>("./deviceMounted",false); if(deviceMounted) { /* Retrieve the input device this screen is attached to: */ std::string deviceName=configFileSection.retrieveString("./deviceName"); device=findInputDevice(deviceName.c_str()); if(device==0) Misc::throwStdErr("VRScreen: Mounting device \"%s\" not found",deviceName.c_str()); } /* Retrieve screen position/orientation in physical or device coordinates: */ try { /* Try reading the screen transformation directly: */ transform=configFileSection.retrieveValue<ONTransform>("./transform"); } catch(std::runtime_error) { /* Fall back to reading the screen's origin and axis directions: */ Point origin=configFileSection.retrieveValue<Point>("./origin"); Vector horizontalAxis=configFileSection.retrieveValue<Vector>("./horizontalAxis"); Vector verticalAxis=configFileSection.retrieveValue<Vector>("./verticalAxis"); ONTransform::Rotation rot=ONTransform::Rotation::fromBaseVectors(horizontalAxis,verticalAxis); transform=ONTransform(origin-Point::origin,rot); } /* Read the screen's size: */ screenSize[0]=configFileSection.retrieveValue<Scalar>("./width"); screenSize[1]=configFileSection.retrieveValue<Scalar>("./height"); /* Apply a rotation around a single axis: */ Point rotateCenter=configFileSection.retrieveValue<Point>("./rotateCenter",Point::origin); Vector rotateAxis=configFileSection.retrieveValue<Vector>("./rotateAxis",Vector(1,0,0)); Scalar rotateAngle=configFileSection.retrieveValue<Scalar>("./rotateAngle",Scalar(0)); if(rotateAngle!=Scalar(0)) { ONTransform screenRotation=ONTransform::translateFromOriginTo(rotateCenter); screenRotation*=ONTransform::rotate(ONTransform::Rotation::rotateAxis(rotateAxis,Math::rad(rotateAngle))); screenRotation*=ONTransform::translateToOriginFrom(rotateCenter); transform.leftMultiply(screenRotation); } /* Apply an arbitrary pre-transformation: */ ONTransform preTransform=configFileSection.retrieveValue<ONTransform>("./preTransform",ONTransform::identity); transform.leftMultiply(preTransform); /* Finalize the screen transformation: */ transform.renormalize(); inverseTransform=Geometry::invert(transform); /* Check if the screen is projected off-axis: */ offAxis=configFileSection.retrieveValue<bool>("./offAxis",offAxis); if(offAxis) { /* Create the inverse of the 2D homography from clip space to rectified screen space in screen coordinates: */ PTransform2 sHomInv=PTransform2::identity; sHomInv.getMatrix()(0,0)=Scalar(2)/screenSize[0]; sHomInv.getMatrix()(0,2)=Scalar(-1); sHomInv.getMatrix()(1,1)=Scalar(2)/screenSize[1]; sHomInv.getMatrix()(1,2)=Scalar(-1); sHomInv.getMatrix()(2,2)=Scalar(1); /* Retrieve the 2D homography from clip space to projected screen space in screen coordinates: */ PTransform2 pHom=configFileSection.retrieveValue<PTransform2>("./homography"); /* Calculate the screen space homography: */ screenHomography=pHom*sHomInv; /* Calculate the clip space homography: */ PTransform2 hom=sHomInv*pHom; for(int i=0;i<3;++i) for(int j=0;j<3;++j) inverseClipHomography.getMatrix()(i<2?i:3,j<2?j:3)=hom.getMatrix()(i,j); /* Put in correction factors to keep the frustum's far plane in the same position: */ inverseClipHomography.getMatrix()(2,0)=inverseClipHomography.getMatrix()(3,0); inverseClipHomography.getMatrix()(2,1)=inverseClipHomography.getMatrix()(3,1); inverseClipHomography.doInvert(); } }
void InputDeviceAdapterDeviceDaemon::createInputDevice(int deviceIndex,const Misc::ConfigurationFileSection& configFileSection) { /* Check if the device client has a virtual device of the same name as this configuration file section: */ for(int vdIndex=0;vdIndex<deviceClient.getNumVirtualDevices();++vdIndex) { const VRDeviceDescriptor& vd=deviceClient.getVirtualDevice(vdIndex); if(vd.name==configFileSection.getName()) { /* Ensure that the index mapping tables exist: */ createIndexMappings(); /* Create an input device from the virtual input device descriptor: */ int trackType=InputDevice::TRACK_NONE; if(vd.trackType&VRDeviceDescriptor::TRACK_POS) trackType|=InputDevice::TRACK_POS; if(vd.trackType&VRDeviceDescriptor::TRACK_DIR) trackType|=InputDevice::TRACK_DIR; if(vd.trackType&VRDeviceDescriptor::TRACK_ORIENT) trackType|=InputDevice::TRACK_ORIENT; /* Create new input device as a physical device: */ std::string deviceName=configFileSection.retrieveString("./name",vd.name); InputDevice* newDevice=inputDeviceManager->createInputDevice(deviceName.c_str(),trackType,vd.numButtons,vd.numValuators,true); newDevice->setDeviceRay(vd.rayDirection,vd.rayStart); /* Initialize the new device's glyph from the current configuration file section: */ Glyph& deviceGlyph=inputDeviceManager->getInputGraphManager()->getInputDeviceGlyph(newDevice); deviceGlyph.configure(configFileSection,"./deviceGlyphType","./deviceGlyphMaterial"); /* Save the new input device: */ inputDevices[deviceIndex]=newDevice; /* Assign the new device's tracker index: */ trackerIndexMapping[deviceIndex]=vd.trackerIndex; /* Assign the new device's button indices: */ if(vd.numButtons>0) { buttonIndexMapping[deviceIndex]=new int[vd.numButtons]; for(int i=0;i<vd.numButtons;++i) buttonIndexMapping[deviceIndex][i]=vd.buttonIndices[i]; } else buttonIndexMapping[deviceIndex]=0; /* Store the virtual input device's button names: */ for(int i=0;i<vd.numButtons;++i) buttonNames.push_back(vd.buttonNames[i]); /* Assign the new device's valuator indices: */ if(vd.numValuators>0) { valuatorIndexMapping[deviceIndex]=new int[vd.numValuators]; for(int i=0;i<vd.numValuators;++i) valuatorIndexMapping[deviceIndex][i]=vd.valuatorIndices[i]; } else valuatorIndexMapping[deviceIndex]=0; /* Store the virtual input device's valuator names: */ for(int i=0;i<vd.numValuators;++i) valuatorNames.push_back(vd.valuatorNames[i]); /* Skip the usual device creation procedure: */ return; } } /* Call base class method to initialize the input device: */ InputDeviceAdapterIndexMap::createInputDevice(deviceIndex,configFileSection); /* Read the list of button names for this device: */ /* Read the names of all button features: */ typedef std::vector<std::string> StringList; StringList tempButtonNames=configFileSection.retrieveValue<StringList>("./buttonNames",StringList()); int buttonIndex=0; for(StringList::iterator bnIt=tempButtonNames.begin();bnIt!=tempButtonNames.end()&&buttonIndex<inputDevices[deviceIndex]->getNumButtons();++bnIt,++buttonIndex) { /* Store the button name: */ buttonNames.push_back(*bnIt); } for(;buttonIndex<inputDevices[deviceIndex]->getNumButtons();++buttonIndex) { char buttonName[40]; snprintf(buttonName,sizeof(buttonName),"Button%d",buttonIndex); buttonNames.push_back(buttonName); } /* Read the names of all valuator features: */ StringList tempValuatorNames=configFileSection.retrieveValue<StringList>("./valuatorNames",StringList()); int valuatorIndex=0; for(StringList::iterator vnIt=tempValuatorNames.begin();vnIt!=tempValuatorNames.end()&&valuatorIndex<inputDevices[deviceIndex]->getNumValuators();++vnIt,++valuatorIndex) { /* Store the valuator name: */ valuatorNames.push_back(*vnIt); } for(;valuatorIndex<inputDevices[deviceIndex]->getNumValuators();++valuatorIndex) { char valuatorName[40]; snprintf(valuatorName,sizeof(valuatorName),"Valuator%d",valuatorIndex); valuatorNames.push_back(valuatorName); } }
void VideoDevice::configure(const Misc::ConfigurationFileSection& cfg) { /* Check which components of the video format are stored in the configuration file section: */ unsigned int frameSize[2]={0,0}; bool haveFrameSize=false; if(cfg.hasTag("./width")&&cfg.hasTag("./height")) { /* Read the requested frame size as width and height: */ frameSize[0]=cfg.retrieveValue<unsigned int>("./width"); frameSize[1]=cfg.retrieveValue<unsigned int>("./height"); haveFrameSize=true; } if(cfg.hasTag("./frameSize")) { /* Read the requested frame size as a two-element array: */ Misc::CFixedArrayValueCoder<unsigned int,2> valueCoder(frameSize); cfg.retrieveValueWC<unsigned int*>("./frameSize",valueCoder); haveFrameSize=true; } double frameRate=0.0; bool haveFrameRate=false; if(cfg.hasTag("./frameRate")) { /* Read the requested frame rate as a double: */ frameRate=cfg.retrieveValue<double>("./frameRate"); haveFrameRate=true; } unsigned int pixelFormat=0; bool havePixelFormat=false; if(cfg.hasTag("./pixelFormat")) { /* Read a pixel format as a FourCC code: */ std::string fourCC=cfg.retrieveValue<std::string>("./pixelFormat"); if(fourCC.size()!=4) Misc::throwStdErr("Video::VideoDevice::configure: Invalid pixel format code \"%s\"",fourCC.c_str()); /* Convert the FourCC code to a pixel format: */ VideoDataFormat temp; temp.setPixelFormat(fourCC.c_str()); pixelFormat=temp.pixelFormat; havePixelFormat=true; } if(cfg.hasTag("./pixelFormatHex")) { /* Read a pixel format as a hexadecimal number: */ std::string hex=cfg.retrieveString("./pixelFormatHex"); if(hex.size()!=8) Misc::throwStdErr("Video::VideoDevice::configure: Invalid hexadecimal pixel format code \"%s\"",hex.c_str()); for(int i=0;i<8;++i) { if(hex[i]>='0'&&hex[i]<='9') pixelFormat=(pixelFormat<<4)|(hex[i]-'0'); else if(hex[i]>='A'&&hex[i]<='F') pixelFormat=(pixelFormat<<4)|(hex[i]-'A'+10); else if(hex[i]>='a'&&hex[i]<='f') pixelFormat=(pixelFormat<<4)|(hex[i]-'a'+10); else Misc::throwStdErr("Video::VideoDevice::configure: Invalid hexadecimal pixel format code \"%s\"",hex.c_str()); } havePixelFormat=true; } /* Get the list of the device's supported video formats: */ std::vector<VideoDataFormat> deviceFormats=getVideoFormatList(); /* Find the best-matching video format among the device's advertised formats: */ std::vector<VideoDataFormat>::iterator bestFormat=deviceFormats.end(); double bestMatch=0.0; for(std::vector<VideoDataFormat>::iterator dfIt=deviceFormats.begin();dfIt!=deviceFormats.end();++dfIt) { double match=1.0; if(haveFrameSize) for(int i=0;i<2;++i) match*=dfIt->size[i]>=frameSize[i]?double(frameSize[i])/double(dfIt->size[i]):double(dfIt->size[i])/double(frameSize[i]); if(haveFrameRate) { double dfRate=double(dfIt->frameIntervalDenominator)/double(dfIt->frameIntervalCounter); match*=dfRate>=frameRate?frameRate/dfRate:dfRate/frameRate; } if(havePixelFormat&&dfIt->pixelFormat!=pixelFormat) match*=0.75; if(bestMatch<match) { bestFormat=dfIt; bestMatch=match; } } if(bestFormat==deviceFormats.end()) // Can only happen if there are no device formats throw std::runtime_error("Video::VideoDevice::configure: No matching video formats found"); /* Set the selected video format: */ setVideoFormat(*bestFormat); }