diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1acad36d3b..a089149a0a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1567,6 +1567,9 @@ void Application::update(float deltaTime) { // Update transmitter + // Get the webcam frame + _webcam.grabFrame(); + // Sample hardware, update view frustum if needed, and send avatar data to mixer/agents updateAvatar(deltaTime); @@ -2148,6 +2151,27 @@ void Application::displayOverlay() { drawtext(_glWidget->width() - 350, 50, 0.10, 0, 1.0, 0, paintMessage, 1, 1, 0); } + // render the webcam input frame + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, _webcam.getFrameTextureID()); + glBegin(GL_QUADS); + const int FRAME_PREVIEW_HEIGHT = 200; + int framePreviewWidth = _webcam.getFrameAspectRatio() * FRAME_PREVIEW_HEIGHT; + int bottom = _glWidget->height() - 400; + int left = _glWidget->width() - framePreviewWidth - 400; + + glTexCoord2f(0, 0); + glVertex2f(left, bottom); + glTexCoord2f(1, 0); + glVertex2f(left + framePreviewWidth, bottom); + glTexCoord2f(1, 1); + glVertex2f(left + framePreviewWidth, bottom + FRAME_PREVIEW_HEIGHT); + glTexCoord2f(0, 1); + glVertex2f(left, bottom + FRAME_PREVIEW_HEIGHT); + glEnd(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + glPopMatrix(); } diff --git a/interface/src/Webcam.cpp b/interface/src/Webcam.cpp index 2c148f98bd..e8f746d599 100644 --- a/interface/src/Webcam.cpp +++ b/interface/src/Webcam.cpp @@ -14,7 +14,22 @@ Webcam::Webcam() { if ((_capture = cvCaptureFromCAM(-1)) == 0) { printLog("Failed to open webcam.\n"); + return; } + + // bump up the capture property + cvSetCaptureProperty(_capture, CV_CAP_PROP_FPS, 60); + + // get the dimensions of the frames + _frameWidth = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH); + _frameHeight = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT); + + // initialize the texture that will contain the grabbed frames + glGenTextures(1, &_frameTextureID); + glBindTexture(GL_TEXTURE_2D, _frameTextureID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _frameWidth, _frameHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); } Webcam::~Webcam() { @@ -22,3 +37,13 @@ Webcam::~Webcam() { cvReleaseCapture(&_capture); } } + +void Webcam::grabFrame() { + IplImage* image = cvQueryFrame(_capture); + if (image == 0) { + return; + } + glBindTexture(GL_TEXTURE_2D, _frameTextureID); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _frameWidth, _frameHeight, GL_RGB, GL_UNSIGNED_BYTE, image->imageData); + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/interface/src/Webcam.h b/interface/src/Webcam.h index 8dfba100e1..c18fd0fb2a 100644 --- a/interface/src/Webcam.h +++ b/interface/src/Webcam.h @@ -9,7 +9,9 @@ #ifndef __interface__Webcam__ #define __interface__Webcam__ -class CvCapture; +#include "InterfaceConfig.h" + +struct CvCapture; class Webcam { public: @@ -17,9 +19,20 @@ public: Webcam(); ~Webcam(); + int getFrameWidth() const { return _frameWidth; } + int getFrameHeight() const { return _frameHeight; } + float getFrameAspectRatio() const { return _frameWidth / (float)_frameHeight; } + GLuint getFrameTextureID() const { return _frameTextureID; } + + void grabFrame(); + private: CvCapture* _capture; + + int _frameWidth; + int _frameHeight; + GLuint _frameTextureID; }; #endif /* defined(__interface__Webcam__) */