mirror of
https://github.com/overte-org/overte.git
synced 2025-08-17 00:56:16 +02:00
Rather than copying to a QImage, just send the pointer. Also, put the render
code in Webcam itself.
This commit is contained in:
parent
341cde61f5
commit
9e92ea03da
3 changed files with 93 additions and 79 deletions
|
@ -2151,28 +2151,7 @@ void Application::displayOverlay() {
|
|||
}
|
||||
|
||||
// render the webcam input frame
|
||||
if (_webcam.getFrameTextureID() != 0) {
|
||||
glBindTexture(GL_TEXTURE_2D, _webcam.getFrameTextureID());
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
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);
|
||||
}
|
||||
_webcam.renderPreview(_glWidget->width(), _glWidget->height());
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
|
|
@ -14,20 +14,81 @@
|
|||
#include "Application.h"
|
||||
#include "Webcam.h"
|
||||
|
||||
class FrameGrabber : public QObject {
|
||||
public:
|
||||
|
||||
FrameGrabber() : _capture(0) { }
|
||||
virtual ~FrameGrabber();
|
||||
Webcam::Webcam() : _frameTextureID(0) {
|
||||
// the grabber simply runs as fast as possible
|
||||
_grabber = new FrameGrabber();
|
||||
_grabber->moveToThread(&_grabberThread);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Webcam::init() {
|
||||
// start the grabber thread
|
||||
_grabberThread.start();
|
||||
|
||||
virtual void timerEvent(QTimerEvent* event);
|
||||
// let the grabber know we're ready for the first frame
|
||||
QMetaObject::invokeMethod(_grabber, "grabFrame");
|
||||
}
|
||||
|
||||
void Webcam::renderPreview(int screenWidth, int screenHeight) {
|
||||
if (_frameTextureID != 0) {
|
||||
glBindTexture(GL_TEXTURE_2D, _frameTextureID);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glBegin(GL_QUADS);
|
||||
const int PREVIEW_HEIGHT = 200;
|
||||
int previewWidth = _frameWidth * PREVIEW_HEIGHT / _frameHeight;
|
||||
int bottom = screenHeight - 400;
|
||||
int left = screenWidth - previewWidth - 400;
|
||||
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(left, bottom);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(left + previewWidth, bottom);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(left + previewWidth, bottom + PREVIEW_HEIGHT);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f(left, bottom + PREVIEW_HEIGHT);
|
||||
glEnd();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
Webcam::~Webcam() {
|
||||
// stop the grabber thread
|
||||
_grabberThread.quit();
|
||||
_grabberThread.wait();
|
||||
|
||||
private:
|
||||
delete _grabber;
|
||||
}
|
||||
|
||||
void Webcam::setFrame(void* image) {
|
||||
IplImage* img = static_cast<IplImage*>(image);
|
||||
GLint internalFormat;
|
||||
GLenum format;
|
||||
if (img->nChannels == 3) {
|
||||
internalFormat = GL_RGB;
|
||||
format = GL_BGR;
|
||||
|
||||
} else {
|
||||
internalFormat = GL_RGBA;
|
||||
format = GL_BGRA;
|
||||
}
|
||||
if (_frameTextureID == 0) {
|
||||
glGenTextures(1, &_frameTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, _frameTextureID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, _frameWidth = img->width, _frameHeight = img->height, 0, format,
|
||||
GL_UNSIGNED_BYTE, img->imageData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
CvCapture* _capture;
|
||||
};
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, _frameTextureID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _frameWidth, _frameHeight, format, GL_UNSIGNED_BYTE, img->imageData);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// let the grabber know we're ready for the next frame
|
||||
QMetaObject::invokeMethod(_grabber, "grabFrame");
|
||||
}
|
||||
|
||||
FrameGrabber::~FrameGrabber() {
|
||||
if (_capture != 0) {
|
||||
|
@ -35,7 +96,7 @@ FrameGrabber::~FrameGrabber() {
|
|||
}
|
||||
}
|
||||
|
||||
void FrameGrabber::timerEvent(QTimerEvent* event) {
|
||||
void FrameGrabber::grabFrame() {
|
||||
if (_capture == 0) {
|
||||
if ((_capture = cvCaptureFromCAM(-1)) == 0) {
|
||||
printLog("Failed to open webcam.\n");
|
||||
|
@ -52,44 +113,5 @@ void FrameGrabber::timerEvent(QTimerEvent* event) {
|
|||
printLog("Invalid webcam image format.\n");
|
||||
return;
|
||||
}
|
||||
QMetaObject::invokeMethod(Application::getInstance()->getWebcam(), "setFrame",
|
||||
Q_ARG(QImage, QImage((uchar*)image->imageData, image->width, image->height, image->widthStep,
|
||||
image->nChannels == 3 ? QImage::Format_RGB888 : QImage::Format_ARGB32).copy(0, 0, image->width, image->height)));
|
||||
QMetaObject::invokeMethod(Application::getInstance()->getWebcam(), "setFrame", Q_ARG(void*, image));
|
||||
}
|
||||
|
||||
Webcam::Webcam() : _frameTextureID(0) {
|
||||
// the grabber simply runs as fast as possible
|
||||
_grabber = new FrameGrabber();
|
||||
_grabber->startTimer(0);
|
||||
_grabber->moveToThread(&_grabberThread);
|
||||
}
|
||||
|
||||
void Webcam::init() {
|
||||
// start the grabber thread
|
||||
_grabberThread.start();
|
||||
}
|
||||
|
||||
Webcam::~Webcam() {
|
||||
// stop the grabber thread
|
||||
_grabberThread.quit();
|
||||
_grabberThread.wait();
|
||||
|
||||
delete _grabber;
|
||||
}
|
||||
|
||||
void Webcam::setFrame(const QImage& image) {
|
||||
GLenum format = (image.format() == QImage::Format_RGB888) ? GL_BGR : GL_BGRA;
|
||||
if (_frameTextureID == 0) {
|
||||
glGenTextures(1, &_frameTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, _frameTextureID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _frameWidth = image.width(), _frameHeight = image.height(), 0, format,
|
||||
GL_UNSIGNED_BYTE, image.constBits());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, _frameTextureID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _frameWidth, _frameHeight, format, GL_UNSIGNED_BYTE, image.constBits());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,15 +29,11 @@ public:
|
|||
~Webcam();
|
||||
|
||||
void init();
|
||||
|
||||
int getFrameWidth() const { return _frameWidth; }
|
||||
int getFrameHeight() const { return _frameHeight; }
|
||||
float getFrameAspectRatio() const { return _frameWidth / (float)_frameHeight; }
|
||||
GLuint getFrameTextureID() const { return _frameTextureID; }
|
||||
void renderPreview(int screenWidth, int screenHeight);
|
||||
|
||||
public slots:
|
||||
|
||||
void setFrame(const QImage& image);
|
||||
void setFrame(void* image);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -49,4 +45,21 @@ private:
|
|||
GLuint _frameTextureID;
|
||||
};
|
||||
|
||||
class FrameGrabber : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
FrameGrabber() : _capture(0) { }
|
||||
virtual ~FrameGrabber();
|
||||
|
||||
public slots:
|
||||
|
||||
void grabFrame();
|
||||
|
||||
private:
|
||||
|
||||
CvCapture* _capture;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__Webcam__) */
|
||||
|
|
Loading…
Reference in a new issue