void VideoViewer::videoFrameCallback(const Video::FrameBuffer* frameBuffer) { double timeStamp=saveVideoTimer.peekTime(); /* Start a new value in the input triple buffer: */ Images::RGBImage& image=videoFrames.startNewValue(); /* Extract an RGB image from the provided frame buffer into the new value: */ videoExtractor->extractRGB(frameBuffer,image.modifyPixels()); /* Finish the new value in the triple buffer and wake up the main loop: */ videoFrames.postNewValue(); Vrui::requestUpdate(); if(saveVideoFrames) { /* Create a filename for the new video frame: */ char videoFrameFileName[1024]; snprintf(videoFrameFileName,sizeof(videoFrameFileName),saveVideoFrameNameTemplate.c_str(),saveVideoNextFrameIndex); /* Save the new video frame: */ Images::writeImageFile(image,videoFrameFileName); std::cout<<"Saving frame "<<videoFrameFileName<<" at "<<timeStamp*1000.0<<" ms"<<std::endl; /* Increment the frame counter: */ ++saveVideoNextFrameIndex; } }
void VideoViewer::videoFrameCallback(const Video::FrameBuffer* frameBuffer) { /* Start a new value in the input triple buffer: */ Images::RGBImage& image=videoFrames.startNewValue(); /* Extract an RGB image from the provided frame buffer into the new value: */ videoExtractor->extractRGB(frameBuffer,image.modifyPixels()); /* Finish the new value in the triple buffer and wake up the main loop: */ videoFrames.postNewValue(); Vrui::requestUpdate(); }
void VideoViewer::frame(void) { /* Lock the most recent video frame in the input triple buffer: */ if(videoFrames.lockNewValue()) { /* Bump up the video frame's version number to invalidate the cached texture: */ ++videoFrameVersion; } }
void VideoViewer::initContext(GLContextData& contextData) const { DataItem* dataItem=new DataItem; contextData.addDataItem(this,dataItem); /* Check whether non-power-of-two-dimension textures are supported: */ dataItem->haveNpotdt=GLARBTextureNonPowerOfTwo::isSupported(); if(dataItem->haveNpotdt) GLARBTextureNonPowerOfTwo::initExtension(); /* Calculate the texture coordinate rectangle: */ unsigned int texSize[2]; if(dataItem->haveNpotdt) { for(int i=0; i<2; ++i) texSize[i]=videoFormat.size[i]; } else { /* Find the next larger power-of-two texture size: */ for(int i=0; i<2; ++i) for(texSize[i]=1U; texSize[i]<videoFormat.size[i]; texSize[i]<<=1) ; } /* Calculate texture coordinates to map the (padded) texture onto the geometry: */ for(int i=0; i<2; ++i) { dataItem->texMin[i]=0.0f; dataItem->texMax[i]=GLfloat(videoFormat.size[i])/GLfloat(texSize[i]); } /* Bind the texture object: */ glBindTexture(GL_TEXTURE_2D,dataItem->videoTextureId); /* Initialize basic texture settings: */ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); /* Upload the initial texture image: */ videoFrames.getLockedValue().glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,!dataItem->haveNpotdt); dataItem->videoTextureVersion=videoFrameVersion; /* Protect the texture object: */ glBindTexture(GL_TEXTURE_2D,0); }
void VideoViewer::display(GLContextData& contextData) const { /* Get the context data item: */ DataItem* dataItem=contextData.retrieveDataItem<DataItem>(this); /* Set up OpenGL state: */ glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); /* Bind the texture object: */ glBindTexture(GL_TEXTURE_2D,dataItem->videoTextureId); /* Check if the cached texture is outdated: */ if(dataItem->videoTextureVersion!=videoFrameVersion) { /* Upload the most recent texture image: */ videoFrames.getLockedValue().glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,!dataItem->haveNpotdt); dataItem->videoTextureVersion=videoFrameVersion; } glBegin(GL_QUADS); glTexCoord2f(dataItem->texMin[0],dataItem->texMin[1]); glVertex2i(0,0); glTexCoord2f(dataItem->texMax[0],dataItem->texMin[1]); glVertex2i(videoFormat.size[0],0); glTexCoord2f(dataItem->texMax[0],dataItem->texMax[1]); glVertex2i(videoFormat.size[0],videoFormat.size[1]); glTexCoord2f(dataItem->texMin[0],dataItem->texMax[1]); glVertex2i(0,videoFormat.size[1]); glEnd(); /* Protect the texture object: */ glBindTexture(GL_TEXTURE_2D,0); /* Draw the video's backside: */ glDisable(GL_TEXTURE_2D); glMaterial(GLMaterialEnums::FRONT,GLMaterial(GLMaterial::Color(0.7f,0.7f,0.7f))); glBegin(GL_QUADS); glNormal3f(0.0f,0.0f,-1.0f); glVertex2i(0,0); glVertex2i(0,videoFormat.size[1]); glVertex2i(videoFormat.size[0],videoFormat.size[1]); glVertex2i(videoFormat.size[0],0); glEnd(); /* Restore OpenGL state: */ glPopAttrib(); }
void IMUTest::sampleCallback(const IMU::CalibratedSample& sample) { /* Store the calibrated sample: */ samples.postNewValue(sample); /* Forward the calibrated sample to the 6-DOF tracker: */ tracker->integrateSample(sample); #if 0 static IMU::Vector accel(0.0,0.0,0.0); static IMU::Vector mag(0.0,0.0,0.0); const double w=1.0/1024.0; accel=accel*(1.0-w)+sample.accelerometer*w; mag=mag*(1.0-w)+sample.magnetometer*w; std::cout<<std::fixed; std::cout.precision(4); std::cout<<'\r'; std::cout<<std::setw(10)<<accel.mag()<<", "; std::cout<<std::setw(10)<<mag.mag(); std::cout<<std::flush; #endif #if 0 std::cout<<std::fixed; std::cout.precision(4); std::cout<<'\r'; for(int i=0;i<3;++i) std::cout<<std::setw(10)<<sample.magnetometer[i]; std::cout<<std::flush; #endif Vrui::requestUpdate(); }
void IMUTest::display(GLContextData& contextData) const { glPushAttrib(GL_ENABLE_BIT); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); glMaterialSpecular(GLMaterialEnums::FRONT,GLColor<GLfloat,4>(1.0f,1.0f,1.0f)); glMaterialShininess(GLMaterialEnums::FRONT,25.0f); /* Draw a global coordinate frame: */ glPushMatrix(); glColor3f(1.0f,0.5f,0.5f); glRotated(90.0,0.0,1.0,0.0); glTranslated(0.0,0.0,5.0); glDrawArrow(0.5f,1.0f,1.5f,10.0f,16); glPopMatrix(); glPushMatrix(); glColor3f(0.5f,1.0f,0.5f); glRotated(-90.0,1.0,0.0,0.0); glTranslated(0.0,0.0,5.0); glDrawArrow(0.5f,1.0f,1.5f,10.0f,16); glPopMatrix(); glPushMatrix(); glColor3f(0.5f,0.5f,1.0f); glTranslated(0.0,0.0,5.0); glDrawArrow(0.5f,1.0f,1.5f,10.0f,16); glPopMatrix(); /* Draw a local coordinate frame: */ glPushMatrix(); const IMUTracker::State& state=tracker->getLockedState(); // if(lockPosition) // glTranslated(5.0,5.0,5.0); // else // glTranslate(state.translation*IMUTracker::Scalar(10)); glRotate(state.rotation); glPushMatrix(); glColor3f(1.0f,0.5f,0.5f); glRotated(90.0,0.0,1.0,0.0); glTranslated(0.0,0.0,2.5); glDrawArrow(0.5f,1.0f,1.5f,5.0f,16); glPopMatrix(); glPushMatrix(); glColor3f(0.5f,1.0f,0.5f); glRotated(-90.0,1.0,0.0,0.0); glTranslated(0.0,0.0,2.5); glDrawArrow(0.5f,1.0f,1.5f,5.0f,16); glPopMatrix(); glPushMatrix(); glColor3f(0.5f,0.5f,1.0f); glTranslated(0.0,0.0,2.5); glDrawArrow(0.5f,1.0f,1.5f,5.0f,16); glPopMatrix(); const IMU::CalibratedSample& sample=samples.getLockedValue(); /* Draw the current linear acceleration vector: */ glPushMatrix(); glColor3f(1.0f,1.0f,0.0f); GLfloat len=GLfloat(Geometry::mag(sample.accelerometer)); glRotate(IMUTracker::Rotation::rotateFromTo(IMUTracker::Vector(0,0,1),sample.accelerometer)); glTranslatef(0.0f,0.0f,len*0.5f); glDrawArrow(0.5f,1.0f,1.5f,len,16); glPopMatrix(); /* Draw the current magnetic flux density vector: */ glPushMatrix(); glColor3f(1.0f,0.0f,1.0f); len=GLfloat(Geometry::mag(sample.magnetometer))*0.2f; glRotate(IMUTracker::Rotation::rotateFromTo(IMUTracker::Vector(0,0,1),sample.magnetometer)); // glTranslatef(0.0f,0.0f,len*0.5f); glDrawArrow(0.5f,1.0f,1.5f,len*2.0f,16); glPopMatrix(); glPopMatrix(); glPopAttrib(); }
void IMUTest::frame(void) { /* Lock the most recent sample and tracker state: */ tracker->lockNewState(); samples.lockNewValue(); }