mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 11:26:11 +00:00
draft plugin to use kinect in meshlab (this version only for linux32)
This commit is contained in:
parent
3acd1b0abd
commit
ab2e0276ec
434
src/meshlabplugins/edit_kinect/edit_kinect.cpp
Executable file
434
src/meshlabplugins/edit_kinect/edit_kinect.cpp
Executable file
@ -0,0 +1,434 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mm->cm processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
History
|
||||
$Log: meshedit.cpp,v $
|
||||
****************************************************************************/
|
||||
#include <QtGui>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <meshlab/glarea.h>
|
||||
#include "edit_kinect.h"
|
||||
#include "ui_kinect.h"
|
||||
#include <wrap/gl/picking.h>
|
||||
#include<vcg/complex/trimesh/append.h>
|
||||
#include "freenect.h"
|
||||
#include "shader_basic.h"
|
||||
|
||||
#define GL_TEST_ERR\
|
||||
{\
|
||||
GLenum eCode;\
|
||||
if((eCode=glGetError())!=GL_NO_ERROR)\
|
||||
std::cerr << "OpenGL error : " << gluErrorString(eCode) << " in " << __FILE__ << " : " << __LINE__ << std::endl;\
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using namespace vcg;
|
||||
|
||||
|
||||
|
||||
KinectEditPlugin::KinectEditPlugin() {
|
||||
cumulate_frames = false;
|
||||
// n_frame = 1;
|
||||
ViewMode = VIEW_REAL_TIME;
|
||||
qFont.setFamily("Helvetica");
|
||||
qFont.setPixelSize(12);
|
||||
toinitialize = true;
|
||||
tilt = 0.0;
|
||||
mm = NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
const QString KinectEditPlugin::Info()
|
||||
{
|
||||
return tr("Kinect.");
|
||||
}
|
||||
|
||||
void KinectEditPlugin::mousePressEvent(QMouseEvent */*e*/, MeshModel &, GLArea * ) {
|
||||
// pickx = e->pos().x();
|
||||
// picky = e->pos().y();
|
||||
// pick = true;
|
||||
// start=e->pos();
|
||||
// cur=start;
|
||||
};
|
||||
void KinectEditPlugin::mouseMoveEvent(QMouseEvent */*e*/, MeshModel &, GLArea * ) {
|
||||
// isDragging = true;
|
||||
// prev=cur;
|
||||
// cur=e->pos();
|
||||
// a->update();
|
||||
};
|
||||
|
||||
|
||||
|
||||
void KinectEditPlugin::mouseReleaseEvent(QMouseEvent * , MeshModel & , GLArea * )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool KinectEditPlugin::ScanningConverged(){
|
||||
unsigned short n_avg[640*480];
|
||||
memset(&frames_avg[0],0,640*480*sizeof(float));
|
||||
memset(&frames_var[0],0,640*480*sizeof(float));
|
||||
memset(&n_avg[0],0,640*480*sizeof(unsigned short));
|
||||
|
||||
for(unsigned int fi = 0; fi < frames.size(); ++fi)
|
||||
for(unsigned int i = 0; i < 640*480; ++i)
|
||||
if(frames[fi].data[i] < 2000){
|
||||
frames_avg[i] += frames[fi].data[i];
|
||||
n_avg[i]++;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < 640*480; ++i)
|
||||
frames_avg[i] /= n_avg[i];
|
||||
|
||||
for(unsigned int fi = 0; fi < frames.size(); ++fi)
|
||||
for(unsigned int i = 0; i < 640*480; ++i)
|
||||
if(frames[fi].data[i] < 2000)
|
||||
frames_var[i] += (frames[fi].data[i]-frames_avg[i])*(frames[fi].data[i]-frames_avg[i]);
|
||||
for(unsigned int i = 0; i < 640*480; ++i)
|
||||
frames_var[i] /= n_avg[i];
|
||||
|
||||
|
||||
unsigned short ttt[640*480];
|
||||
for(unsigned int i = 0; i < 640*480; ++i)
|
||||
ttt[i] = frames_avg[i];
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D,gl_depth_tex_avg);
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,640,480,GL_RED,GL_UNSIGNED_SHORT,&ttt[0]);
|
||||
|
||||
// just one scan
|
||||
return (frames.size()==1);
|
||||
}
|
||||
|
||||
void KinectEditPlugin::CleanupGL(){
|
||||
glDeleteTextures(1, &gl_depth_tex);
|
||||
glDeleteTextures(1, &gl_depth_tex_avg);
|
||||
glDeleteTextures(1, &gl_color_tex);
|
||||
glDeleteBuffers(1, &point_cloud);
|
||||
glDeleteProgram(pr);
|
||||
}
|
||||
void KinectEditPlugin::InitializeGL(){
|
||||
|
||||
|
||||
/* generate texture to store kinect map*/
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &gl_depth_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,GL_R32F, 1024, 512, 0, GL_RED, GL_UNSIGNED_SHORT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||
|
||||
glGenTextures(1, &gl_depth_tex_avg);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_depth_tex_avg);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,GL_R32F, 1024, 512, 0, GL_RED, GL_UNSIGNED_SHORT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
|
||||
glGenTextures(1, &gl_color_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_color_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, 1024, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
||||
/* create the VBO for the vertices */
|
||||
glGenBuffersARB(1,&point_cloud);
|
||||
float points[640*480][3];
|
||||
for(unsigned int i = 0 ; i < 640;++i)
|
||||
for(unsigned int j = 0 ; j < 480;++j){
|
||||
points[j*640+i][0] = i/float(1024);
|
||||
points[j*640+i][1] = j/float(512);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, point_cloud );
|
||||
glBufferData(GL_ARRAY_BUFFER, 3*sizeof(float)*640*480,&points[0][0], GL_STATIC_DRAW);
|
||||
|
||||
|
||||
|
||||
GLuint fs, vs;
|
||||
|
||||
std::string str_vs =
|
||||
std::string("varying bool kill;")+
|
||||
std::string("uniform sampler2D col;")+
|
||||
std::string("uniform sampler2D dv;")+
|
||||
std::string("uniform float focal;")+
|
||||
std::string("uniform float shiftx;")+
|
||||
|
||||
std::string("vec4 point(float X, float Y){")+
|
||||
std::string(" vec4 pp;")+
|
||||
std::string(" vec4 p = texture2D(dv,vec2(X,Y));")+
|
||||
std::string(" pp.z = 0.1236 *tan(p.x*65536.0 / 2842.5 + 1.1863);")+
|
||||
std::string(" pp.x = (X*1024.0/640.0-0.5)*pp.z * 1.1904;")+
|
||||
std::string(" pp.y = (Y*512.0/480.0-0.5)*pp.z * 0.8832;")+
|
||||
std::string(" if( (pp.z> 5.0) || (pp.z < 0.50)) pp.w= 0.0; else pp.w = 1.0;")+
|
||||
std::string(" return pp;}")+
|
||||
|
||||
std::string("vec2 proj_color(vec4 p){")+
|
||||
std::string(" vec2 pp;")+
|
||||
std::string(" pp.x = ((p.x+shiftx)/p.z)*focal;")+
|
||||
std::string(" pp.y = (p.y/p.z)*focal;")+
|
||||
std::string(" pp.x = (pp.x+1.0)/2;")+
|
||||
std::string(" pp.y = (pp.y+1.0)/2;")+
|
||||
std::string(" pp.x = pp.x*640.0/1024.0;")+
|
||||
std::string(" pp.y = pp.y*480.0/512.0;")+
|
||||
std::string(" return pp;}")+
|
||||
|
||||
std::string("void main() { ")+
|
||||
std::string(" vec4 pp = point(gl_Vertex.x,gl_Vertex.y);")+
|
||||
std::string(" gl_Position = gl_ModelViewProjectionMatrix * pp;")+
|
||||
std::string(" vec4 p_dx = point(gl_Vertex.x+3.0/1024.0,gl_Vertex.y);")+
|
||||
std::string(" vec4 p_dy = point(gl_Vertex.x,gl_Vertex.y+3.0/480.0);")+
|
||||
std::string(" vec3 nn = normalize(cross( p_dx-pp,p_dy-pp));")+
|
||||
std::string(" nn = gl_NormalMatrix * nn;")+
|
||||
std::string(" nn = normalize(nn);")+
|
||||
std::string(" vec3 lightVec = normalize(gl_LightSource[0].position.xyz);")+
|
||||
std::string(" float gray = abs(lightVec*nn);")+
|
||||
std::string(" vec4 color = texture2D(col,vec2(gl_Vertex.x,gl_Vertex.y));")+
|
||||
// std::string(" vec4 color = texture2D(col,proj_color(pp));")+
|
||||
// std::string(" gl_FrontColor = vec4(gray,gray,gray,1.0);")+
|
||||
std::string(" gl_FrontColor = vec4(color.xyz,1.0);")+
|
||||
std::string(" if(pp.w==0) kill = true;else kill=false;")+
|
||||
std::string("}");
|
||||
std::string str_fs =
|
||||
std::string("varying bool kill;")+
|
||||
std::string("void main() { ")+
|
||||
std::string(" gl_FragColor = gl_Color;")+
|
||||
std::string(" if (kill) discard;")+
|
||||
std::string("}");
|
||||
|
||||
if(Shader::SetFromString(str_vs.c_str(),str_fs.c_str(),fs,vs,pr)==0)
|
||||
Shader::Validate(pr);
|
||||
glUseProgram(pr);
|
||||
GLuint depth_loc = glGetUniformLocation(pr,"dv");
|
||||
glUniform1i(depth_loc,0);
|
||||
GLuint col_loc = glGetUniformLocation(pr,"col");
|
||||
glUniform1i(col_loc,2);
|
||||
foc_loc = glGetUniformLocation(pr,"focal");
|
||||
glUniform1f(foc_loc,1.0);
|
||||
shx_loc = glGetUniformLocation(pr,"shiftx");
|
||||
glUniform1f(shx_loc,0.0);
|
||||
glUseProgram(0);
|
||||
|
||||
}
|
||||
|
||||
void KinectEditPlugin::Decorate(MeshModel &, GLArea * )
|
||||
{
|
||||
|
||||
if(toinitialize){
|
||||
InitializeGL();
|
||||
toinitialize = false;
|
||||
}
|
||||
kinect_qt::qbackbuf_mutex.lock();
|
||||
|
||||
while ( kinect_qt::got_frames < 2) {
|
||||
kinect_qt::qwait.wait(& kinect_qt::qbackbuf_mutex);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
if(ViewMode==VIEW_REAL_TIME){
|
||||
glBindTexture(GL_TEXTURE_2D,gl_depth_tex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,640,480,GL_RED,GL_UNSIGNED_SHORT,&kinect_qt::gl_depth_front[0]);
|
||||
}
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D,gl_color_tex);
|
||||
|
||||
if(ViewMode==VIEW_REAL_TIME)
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,640,480,GL_RGB,GL_UNSIGNED_BYTE,&kinect_qt::gl_rgb_back[0]);
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,640,480,GL_RGB,GL_UNSIGNED_BYTE,&rgb_stored[0]);
|
||||
|
||||
if(cumulate_frames){
|
||||
frames.push_back(Frame());
|
||||
memcpy(&frames.back().data[0],&kinect_qt::gl_depth_front[0], sizeof(kinect_qt::gl_depth_front));
|
||||
if( ScanningConverged()){
|
||||
cumulate_frames = false;
|
||||
frames.clear();
|
||||
memcpy(&rgb_stored[0],&kinect_qt::gl_rgb_back[0],640*480*4);
|
||||
}
|
||||
}
|
||||
|
||||
kinect_qt::qbackbuf_mutex.unlock();
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if(ViewMode==VIEW_REAL_TIME)
|
||||
glBindTexture(GL_TEXTURE_2D,gl_depth_tex);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D,gl_depth_tex_avg);
|
||||
|
||||
|
||||
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, point_cloud);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, 0);
|
||||
|
||||
|
||||
glUseProgram(pr);
|
||||
|
||||
glDrawArrays(GL_POINTS,0,640*480);
|
||||
glDisableClientState(GL_VERTEX_ARRAY); // deactivate vertex array
|
||||
glUseProgram(0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KinectEditPlugin::startScan(){
|
||||
cumulate_frames = true;
|
||||
odw->vsmRadioButton->setChecked(true);
|
||||
odw->vrtRadioButton->setChecked(false);
|
||||
ViewMode = VIEW_SCANNED_MODEL;
|
||||
|
||||
|
||||
}
|
||||
void KinectEditPlugin::stopScan(){
|
||||
cumulate_frames = false;
|
||||
frames.clear() ;
|
||||
}
|
||||
|
||||
void KinectEditPlugin::setViewMode(){
|
||||
if(odw->vsmRadioButton->isChecked())
|
||||
ViewMode = VIEW_SCANNED_MODEL;
|
||||
else
|
||||
ViewMode = VIEW_REAL_TIME;
|
||||
}
|
||||
|
||||
void KinectEditPlugin::setTilt(double v){
|
||||
tilt = v;
|
||||
kinect_qt::set_tilt_degs(v);
|
||||
}
|
||||
|
||||
vcg::Point3f Point(float v, float X, float Y){
|
||||
vcg::Point3f pp;
|
||||
pp[2] = 0.1236 *tan(v / 2842.5 + 1.1863);
|
||||
pp[0] = (X - 640 / 2) * pp[2] * 0.00186;
|
||||
pp[1] = (Y - 480 / 2) * pp[2] * 0.00184;
|
||||
return pp;
|
||||
}
|
||||
|
||||
void KinectEditPlugin::saveScan(){
|
||||
mm = (MeshModel*)1;
|
||||
mm = gla->meshDoc->addNewMesh("Kinect Mesh",false);
|
||||
|
||||
CMeshO::VertexIterator vi =
|
||||
vcg::tri::Allocator<CMeshO>::AddVertices(mm->cm,640*480);
|
||||
|
||||
mm->updateDataMask( MeshModel::MM_VERTCOLOR|MeshModel::MM_VERTQUALITY);
|
||||
for(unsigned int i = 0; i < 640; ++i)
|
||||
for(unsigned int j = 0; j < 480; ++j){
|
||||
|
||||
(*vi).P() = Point(frames_avg[j*640+i],i,j);
|
||||
(*vi).Q() = 1.0/(frames_var[j*640+i]+1);
|
||||
(*vi).C() = vcg::Color4b(rgb_stored[3*(j*640+i)], rgb_stored[3*(j*640+i)+1],rgb_stored[3*(j*640+i)+2],255);
|
||||
if((*vi).P()!=(*vi).P())
|
||||
vcg::tri::Allocator<CMeshO>::DeleteVertex(mm->cm,*vi);
|
||||
vi++;
|
||||
}
|
||||
mm->cm.bbox.Add(vcg::Point3f(-3,4,5));
|
||||
mm->cm.bbox.Add(vcg::Point3f(3,-4,0));
|
||||
|
||||
}
|
||||
|
||||
bool KinectEditPlugin::StartEdit(MeshModel &/*m*/, GLArea *_gla )
|
||||
{
|
||||
gla = _gla;
|
||||
|
||||
odw = new Ui::KinectDockWidget ();
|
||||
kinect_panel = new QDockWidget(gla);
|
||||
odw->setupUi(kinect_panel);
|
||||
|
||||
kinect_panel->show();
|
||||
|
||||
kinect_qt::start_kinect();
|
||||
QObject::connect(odw->startScanPushButton,SIGNAL(clicked()),this,SLOT(startScan()));
|
||||
QObject::connect(odw->saveScanPushButton,SIGNAL(clicked()),this,SLOT(saveScan()));
|
||||
|
||||
QObject::connect(odw->vrtRadioButton,SIGNAL(clicked()),this,SLOT(setViewMode()));
|
||||
QObject::connect(odw->vsmRadioButton,SIGNAL(clicked()),this,SLOT(setViewMode()));
|
||||
QObject::connect(odw->tiltSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setTilt(double)));
|
||||
|
||||
odw->vrtRadioButton->setChecked(true);
|
||||
|
||||
|
||||
QTimer *timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), _gla, SLOT(update()));
|
||||
timer->start(50);
|
||||
|
||||
{
|
||||
this->curr_track.track.tra=gla->trackball.track.tra ;
|
||||
this->curr_track.track.sca=gla->trackball.track.sca ;
|
||||
this->curr_track.track.rot=gla->trackball.track.rot ;
|
||||
|
||||
|
||||
vcg::Quaternionf q; q.FromEulerAngles(3.14,0,0);
|
||||
gla->trackball.Reset();
|
||||
float newScale= 3.0f/5.0;
|
||||
gla->trackball.track.sca = newScale;
|
||||
gla->trackball.track.tra = vcg::Point3f(0,0,-2.5);
|
||||
gla->trackball.track.rot = q;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void KinectEditPlugin::EndEdit(MeshModel &/*m*/, GLArea *gla )
|
||||
{
|
||||
//if(mm) return;
|
||||
kinect_panel->hide();
|
||||
kinect_qt::stop_kinect();
|
||||
toinitialize = true;
|
||||
{
|
||||
gla->trackball.track.tra = this->curr_track.track.tra;
|
||||
gla->trackball.track.sca = this->curr_track.track.sca;
|
||||
gla->trackball.track.rot = this->curr_track.track.rot;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void KinectEditPlugin::setTrackBall(){
|
||||
// gla->trackball.Reset();
|
||||
// float newScale= 3.0f/ocme_bbox.Diag();
|
||||
// gla->trackball.track.sca = newScale;
|
||||
// gla->trackball.track.tra = -ocme_bbox.Center();
|
||||
|
||||
}
|
||||
void KinectEditPlugin::resetPlugin(){
|
||||
|
||||
}
|
||||
92
src/meshlabplugins/edit_kinect/edit_kinect.h
Executable file
92
src/meshlabplugins/edit_kinect/edit_kinect.h
Executable file
@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef KinectEditPlugin_H
|
||||
#define KinectEditPlugin_H
|
||||
|
||||
#include <QObject>
|
||||
#include <common/interfaces.h>
|
||||
#include <common/meshmodel.h>
|
||||
#include <vector>
|
||||
#include "ui_kinect.h"
|
||||
|
||||
|
||||
|
||||
/* OCME include */
|
||||
#include <wrap/gui/trackball.h>
|
||||
|
||||
class KinectEditPlugin : public QObject, public MeshEditInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MeshEditInterface)
|
||||
|
||||
public:
|
||||
KinectEditPlugin();
|
||||
virtual ~KinectEditPlugin() {}
|
||||
|
||||
static const QString Info();
|
||||
|
||||
virtual bool StartEdit(MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
virtual void EndEdit(MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
|
||||
virtual void Decorate(MeshModel &/*m*/, GLArea * /*parent*/);
|
||||
virtual void mousePressEvent(QMouseEvent *, MeshModel &, GLArea * ) ;
|
||||
virtual void mouseMoveEvent(QMouseEvent *, MeshModel &, GLArea * ) ;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event, MeshModel &/*m*/, GLArea * );
|
||||
|
||||
void setTrackBall();
|
||||
void resetPlugin();
|
||||
QFont qFont;
|
||||
QDockWidget * kinect_panel;
|
||||
Ui::KinectDockWidget * odw;
|
||||
GLArea * gla;
|
||||
MeshModel * mm; // mesh associated with ocme
|
||||
vcg::Trackball curr_track;
|
||||
bool cumulate_frames;
|
||||
float tilt,toinitialize;
|
||||
GLuint gl_depth_tex, // texture to upload the kinect values
|
||||
gl_depth_tex_avg,
|
||||
gl_color_tex,
|
||||
foc_loc,
|
||||
shx_loc,
|
||||
point_cloud, // VBO of 680*480 vertex
|
||||
pr; // program to displace vertices
|
||||
|
||||
enum {VIEW_SCANNED_MODEL,VIEW_REAL_TIME} ViewMode;
|
||||
struct Frame{ unsigned short data[640*480];};
|
||||
float frames_avg[640*480];
|
||||
float frames_var[640*480];
|
||||
std::vector<Frame> frames;
|
||||
unsigned char rgb_stored[640*480*4];
|
||||
bool ScanningConverged();
|
||||
void InitializeGL();
|
||||
void CleanupGL();
|
||||
public slots:
|
||||
void startScan();
|
||||
void stopScan();
|
||||
void saveScan();
|
||||
void setViewMode();
|
||||
void setTilt(double);
|
||||
};
|
||||
|
||||
#endif
|
||||
28
src/meshlabplugins/edit_kinect/edit_kinect.pro
Executable file
28
src/meshlabplugins/edit_kinect/edit_kinect.pro
Executable file
@ -0,0 +1,28 @@
|
||||
# this is the common include for all the plugins
|
||||
include (../../shared.pri)
|
||||
|
||||
INCLUDEPATH += ../../external/openkinect/include \
|
||||
/usr/include/libusb-1.0/
|
||||
|
||||
LIBS += /media/ACER_/devel/meshlab/src/external/lib/linux/libfreenect.a \
|
||||
/usr/lib/libusb-1.0.a
|
||||
|
||||
HEADERS = edit_kinect_factory.h \
|
||||
ui_kinect.h \
|
||||
edit_kinect.h
|
||||
|
||||
SOURCES = edit_kinect_factory.cpp \
|
||||
edit_kinect.cpp \ # ../../../../meshlab/src/meshlab/glarea.cpp \
|
||||
freenect.cpp \
|
||||
../../../../vcglib/wrap/gui/trackmode.cpp \
|
||||
../../../../vcglib/wrap/gui/trackball.cpp # ../../../../vcglib/wrap/gui/rubberband.cpp \
|
||||
|
||||
TARGET = edit_kinect
|
||||
QT += opengl
|
||||
RESOURCES = edit_kinect.qrc
|
||||
FORMS += kinect.ui
|
||||
|
||||
# OCME src/ocme FILES
|
||||
# Lib headers
|
||||
|
||||
|
||||
5
src/meshlabplugins/edit_kinect/edit_kinect.qrc
Executable file
5
src/meshlabplugins/edit_kinect/edit_kinect.qrc
Executable file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>icons/kinect.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
58
src/meshlabplugins/edit_kinect/edit_kinect_factory.cpp
Executable file
58
src/meshlabplugins/edit_kinect/edit_kinect_factory.cpp
Executable file
@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005-2008 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "edit_kinect_factory.h"
|
||||
#include "edit_kinect.h"
|
||||
|
||||
KinectEditFactory::KinectEditFactory()
|
||||
{
|
||||
editKinect = new QAction(QIcon(":/icons/kinect.png"),"Kinect", this);
|
||||
|
||||
actionList << editKinect;
|
||||
|
||||
foreach(QAction *editAction, actionList)
|
||||
editAction->setCheckable(true);
|
||||
}
|
||||
|
||||
//gets a list of actions available from this plugin
|
||||
QList<QAction *> KinectEditFactory::actions() const
|
||||
{
|
||||
return actionList;
|
||||
}
|
||||
|
||||
//get the edit tool for the given action
|
||||
MeshEditInterface* KinectEditFactory::getMeshEditInterface(QAction *action)
|
||||
{
|
||||
if(action == editKinect)
|
||||
{
|
||||
return new KinectEditPlugin();
|
||||
} else assert(0); //should never be asked for an action that isnt here
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString KinectEditFactory::getEditToolDescription(QAction *)
|
||||
{
|
||||
return KinectEditPlugin::Info();
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(KinectEditFactory)
|
||||
55
src/meshlabplugins/edit_kinect/edit_kinect_factory.h
Executable file
55
src/meshlabplugins/edit_kinect/edit_kinect_factory.h
Executable file
@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
* MeshLab o o *
|
||||
* A versatile mesh processing toolbox o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2005-2008 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef KinectEditFactoryPLUGIN_H
|
||||
#define KinectEditFactoryPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include <common/interfaces.h>
|
||||
|
||||
class KinectEditFactory : public QObject, public MeshEditInterfaceFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MeshEditInterfaceFactory)
|
||||
|
||||
public:
|
||||
KinectEditFactory();
|
||||
virtual ~KinectEditFactory() { delete editKinect; }
|
||||
|
||||
//gets a list of actions available from this plugin
|
||||
virtual QList<QAction *> actions() const;
|
||||
|
||||
//get the edit tool for the given action
|
||||
virtual MeshEditInterface* getMeshEditInterface(QAction *);
|
||||
|
||||
//get the description for the given action
|
||||
virtual QString getEditToolDescription(QAction *);
|
||||
|
||||
private:
|
||||
QList <QAction *> actionList;
|
||||
|
||||
QAction *editKinect;
|
||||
};
|
||||
|
||||
#endif
|
||||
129
src/meshlabplugins/edit_kinect/freenect.cpp
Executable file
129
src/meshlabplugins/edit_kinect/freenect.cpp
Executable file
@ -0,0 +1,129 @@
|
||||
|
||||
#include <libfreenect.h>
|
||||
#include "freenect.h"
|
||||
|
||||
#include <qthread.h>
|
||||
#include <qmutex.h>
|
||||
#include <qwaitcondition.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace kinect_qt{
|
||||
|
||||
|
||||
uint16_t gl_depth_front[640*480];
|
||||
uint16_t gl_depth_back[640*480];
|
||||
uint8_t gl_rgb_front[640*480*4];
|
||||
uint8_t gl_rgb_back[640*480*4];
|
||||
|
||||
freenect_context *f_ctx;
|
||||
freenect_device *f_dev;
|
||||
int freenect_angle;
|
||||
int freenect_led;
|
||||
volatile int die = 0;
|
||||
int got_frames = 0;
|
||||
QMutex qbackbuf_mutex, qstop_mutex;
|
||||
QWaitCondition qwait;
|
||||
|
||||
void KinectThread::run()
|
||||
{
|
||||
printf("'w'-tilt up, 's'-level, 'x'-tilt down, '0'-'6'-select LED mode\n");
|
||||
|
||||
while(!die && freenect_process_events(f_ctx) >= 0 )
|
||||
{
|
||||
// int16_t ax,ay,az;
|
||||
// freenect_get_raw_accel(f_dev, &ax, &ay, &az);
|
||||
// double dx,dy,dz;
|
||||
// freenect_get_mks_accel(f_dev, &dx, &dy, &dz);
|
||||
// printf("\r raw acceleration: %4d %4d %4d mks acceleration: %4f %4f %4f\r", ax, ay, az, dx, dy, dz);
|
||||
// fflush(stdout);
|
||||
}
|
||||
|
||||
printf("\nshutting down streams...\n");
|
||||
|
||||
freenect_stop_depth(f_dev);
|
||||
freenect_stop_video(f_dev);
|
||||
|
||||
freenect_close_device(f_dev);
|
||||
freenect_shutdown(f_ctx);
|
||||
die = false;
|
||||
printf("-- done!\n");
|
||||
qstop_mutex.unlock();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void rgb_cb(freenect_device */*dev*/, void *rgb, uint32_t /*timestamp*/)
|
||||
{
|
||||
qbackbuf_mutex.lock();
|
||||
got_frames++;
|
||||
memcpy(gl_rgb_back, rgb, FREENECT_VIDEO_RGB_SIZE);
|
||||
qwait.wakeAll();
|
||||
qbackbuf_mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
static void depth_cb(freenect_device */*dev*/, void *v_depth, uint32_t /*timestamp*/)
|
||||
{
|
||||
qbackbuf_mutex.lock();
|
||||
memcpy(gl_depth_front, v_depth, sizeof(v_depth)*640*480);
|
||||
got_frames++;
|
||||
qbackbuf_mutex.unlock();
|
||||
qwait.wakeAll();
|
||||
}
|
||||
|
||||
KinectThread kinect_thread;
|
||||
|
||||
|
||||
|
||||
void start_kinect ()
|
||||
{
|
||||
// initialize Kinect
|
||||
printf("Kinect camera test\n");
|
||||
|
||||
|
||||
|
||||
if (freenect_init(&f_ctx, NULL) < 0) {
|
||||
printf("freenect_init() failed\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
freenect_set_log_level(f_ctx, FREENECT_LOG_DEBUG);
|
||||
|
||||
int nr_devices = freenect_num_devices (f_ctx);
|
||||
printf ("Number of devices found: %d\n", nr_devices);
|
||||
|
||||
int user_device_number = 0;
|
||||
|
||||
if (freenect_open_device(f_ctx, &f_dev, user_device_number) < 0) {
|
||||
printf("Could not open device\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
freenect_set_tilt_degs(f_dev,0.f/*freenect_angle*/);
|
||||
freenect_set_led(f_dev,LED_RED);
|
||||
freenect_set_depth_callback(f_dev, depth_cb);
|
||||
freenect_set_video_callback(f_dev, rgb_cb);
|
||||
freenect_set_video_format(f_dev, FREENECT_VIDEO_RGB);
|
||||
freenect_set_depth_format(f_dev, FREENECT_DEPTH_11BIT);
|
||||
|
||||
freenect_start_depth(f_dev);
|
||||
freenect_start_video(f_dev);
|
||||
|
||||
kinect_thread.start();
|
||||
|
||||
}
|
||||
|
||||
void stop_kinect(){
|
||||
qstop_mutex.lock();
|
||||
die = true;
|
||||
qstop_mutex.lock();
|
||||
qstop_mutex.unlock();
|
||||
}
|
||||
|
||||
void set_tilt_degs(double angle){freenect_set_tilt_degs(f_dev,angle);}
|
||||
|
||||
} // end namespace kinect_qt
|
||||
32
src/meshlabplugins/edit_kinect/freenect.h
Executable file
32
src/meshlabplugins/edit_kinect/freenect.h
Executable file
@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
#include <qthread.h>
|
||||
#include <qmutex.h>
|
||||
#include <qwaitcondition.h>
|
||||
|
||||
namespace kinect_qt{
|
||||
|
||||
extern uint16_t gl_depth_front[640*480];
|
||||
extern uint16_t gl_depth_back[640*480];
|
||||
extern uint8_t gl_rgb_front[640*480*4];
|
||||
extern uint8_t gl_rgb_back[640*480*4];
|
||||
|
||||
extern int freenect_angle;
|
||||
extern int freenect_led;
|
||||
extern volatile int die ;
|
||||
extern int got_frames;
|
||||
|
||||
struct KinectThread: public QThread{
|
||||
|
||||
void run();
|
||||
};
|
||||
|
||||
extern KinectThread kinect_thread;
|
||||
extern QMutex qbackbuf_mutex;
|
||||
extern QWaitCondition qwait;
|
||||
|
||||
void start_kinect ();
|
||||
void set_tilt_degs(double angle);
|
||||
void stop_kinect();
|
||||
|
||||
} // end namespace kinect_qt
|
||||
426
src/meshlabplugins/edit_kinect/glarea.cpp
Executable file
426
src/meshlabplugins/edit_kinect/glarea.cpp
Executable file
@ -0,0 +1,426 @@
|
||||
/****************************************************************************
|
||||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2007 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.1 2007/10/18 08:52:06 benedetti
|
||||
Initial release.
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui>
|
||||
#include "glarea.h"
|
||||
#include <wrap/qt/trackball.h>
|
||||
|
||||
#include <vcg/math/histogram.h>
|
||||
|
||||
//---------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "libfreenect.h"
|
||||
#include "freenect.h"
|
||||
|
||||
#include <qthread.h>
|
||||
#include <qmutex.h>
|
||||
#include <qwaitcondition.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <GLUT/glut.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glut.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <wrap/io_trimesh/export_ply.h>
|
||||
|
||||
|
||||
using namespace vcg;
|
||||
class CFace;
|
||||
class CVertex;
|
||||
|
||||
GLuint gl_depth_tex,gl_rgb_tex;
|
||||
bool snapshot = false;
|
||||
bool pick_depth = false;
|
||||
int i_pick,j_pick;
|
||||
uint16_t t_gamma[2048];
|
||||
unsigned int n_frames = 0;
|
||||
unsigned int last_time_on[640*480];
|
||||
uint16_t last_value_on[640*480];
|
||||
vcg::Point3f normals[640*480];
|
||||
vcg::Point3f points[640*480];
|
||||
uint16_t gl_depths[100][640*480];
|
||||
uint32_t gl_depths_sum[640*480];
|
||||
unsigned int curs = 0;
|
||||
|
||||
const float ToZ(float v){return 0.1236 * tan(v / 2842.5 + 1.1863);
|
||||
}
|
||||
|
||||
vcg::Point3f P( int i, int j){
|
||||
vcg::Point3f p;
|
||||
p[2] = ToZ(gl_depths_sum[640*j+i]/100.f);
|
||||
if( (p[2]>5.0) ||(p[2]< 0.5))
|
||||
p[2]=6.0;
|
||||
p[0] = (i - 640 / 2) * p[2] * 0.00186;
|
||||
p[1] = (j - 480 / 2) * p[2] * 0.00184;
|
||||
return p;
|
||||
}
|
||||
|
||||
vcg::Point3f N(int i, int j){
|
||||
vcg::Point3f n;
|
||||
vcg::Point3f p = points[j*640+i];
|
||||
vcg::Point3f p0 = (points[j*640+i+1]-p).Normalize();
|
||||
vcg::Point3f p1 = (points[(j+1)*640+i]-p).Normalize();
|
||||
n = (p0^p1).Normalize();
|
||||
return n;
|
||||
// n= vcg::Point3f(ToZ(kinect_qt::gl_depth_front[640*j+i+1]) - ToZ(kinect_qt::gl_depth_front[640*j+i-1]),
|
||||
// ToZ(kinect_qt::gl_depth_front[640*(j+1)+i]) -ToZ(kinect_qt::gl_depth_front[640*(j+1)+i]) ,
|
||||
// 0.002);
|
||||
// n.Normalize();
|
||||
// return n;
|
||||
}
|
||||
|
||||
void GLArea::paintGL()
|
||||
{
|
||||
n_frames++;
|
||||
kinect_qt::qbackbuf_mutex.lock();
|
||||
|
||||
while ( kinect_qt::got_frames < 2) {
|
||||
kinect_qt::qwait.wait(& kinect_qt::qbackbuf_mutex);
|
||||
}
|
||||
|
||||
memcpy( kinect_qt::gl_rgb_front, kinect_qt::gl_rgb_back, sizeof( kinect_qt::gl_rgb_back));
|
||||
|
||||
for(unsigned int i = 0; i < 640*480;++i)
|
||||
gl_depths_sum[i] -= gl_depths[curs][i];
|
||||
|
||||
memcpy( gl_depths[curs], kinect_qt::gl_depth_front, sizeof( kinect_qt::gl_depth_front));
|
||||
|
||||
for(unsigned int i = 0; i < 640*480;++i)
|
||||
gl_depths_sum[i] += gl_depths[curs][i];
|
||||
|
||||
curs=(curs+1)%100;
|
||||
|
||||
if(pick_depth){
|
||||
printf("depth %d \n",kinect_qt::gl_depth_front[640*j_pick+i_pick]);
|
||||
vcg::Point3f p = P(i_pick,480-j_pick);
|
||||
printf("p3: %f %f %f \n",p[0],p[1],p[2]);
|
||||
|
||||
pick_depth = false;
|
||||
}
|
||||
if(1) {
|
||||
for(unsigned int i = 0; i < 640;++i)
|
||||
for(unsigned int j = 0; j < 480;++j){
|
||||
if(kinect_qt::gl_depth_front[640*j +i ]>=2047)
|
||||
{
|
||||
if(n_frames - last_time_on[j*640+i]< 15)
|
||||
kinect_qt::gl_depth_front[640*j +i ] = last_value_on[j*640+i];
|
||||
}else{
|
||||
last_value_on[j*640+i] = kinect_qt::gl_depth_front[640*j +i ];
|
||||
last_time_on[j*640+i] = n_frames;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
vcg::Color4b im[640*480];
|
||||
for (unsigned int i=0; i<FREENECT_FRAME_PIX; i++) {
|
||||
int pval = t_gamma[kinect_qt::gl_depth_front[i]];
|
||||
int lb = pval & 0xff;
|
||||
switch (pval>>8) {
|
||||
case 0:
|
||||
im[i][0] = 255;
|
||||
im[i][1] = 255-lb;
|
||||
im[i][2] = 255-lb;
|
||||
break;
|
||||
case 1:
|
||||
im[i][0] = 255;
|
||||
im[i][1] = lb;
|
||||
im[i][2] = 0;
|
||||
break;
|
||||
case 2:
|
||||
im[i][0] = 255-lb;
|
||||
im[i][1] = 255;
|
||||
im[i][2] = 0;
|
||||
break;
|
||||
case 3:
|
||||
im[i][0] = 0;
|
||||
im[i][1] = 255;
|
||||
im[i][2] = lb;
|
||||
break;
|
||||
case 4:
|
||||
im[i][0] = 0;
|
||||
im[i][1] = 255-lb;
|
||||
im[i][2] = 255;
|
||||
break;
|
||||
case 5:
|
||||
im[i][0] = 0;
|
||||
im[i][1] = 0;
|
||||
im[i][2] = 255-lb;
|
||||
break;
|
||||
default:
|
||||
im[i][0] = 0;
|
||||
im[i][1] = 0;
|
||||
im[i][2] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(unsigned int i = 0; i < 640;++i)
|
||||
for(unsigned int j = 0; j< 480;++j){
|
||||
points[640*j+i] = P(i,480-j);
|
||||
}
|
||||
for(unsigned int i = 0; i < 640;++i)
|
||||
for(unsigned int j = 0; j< 480;++j){
|
||||
normals[640*j+i] = N(i,j);
|
||||
}
|
||||
|
||||
kinect_qt::qbackbuf_mutex.unlock();
|
||||
kinect_qt:: got_frames = 0;
|
||||
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
if(0)
|
||||
{
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
|
||||
vcg::Color4b c;
|
||||
|
||||
// glPixelTransferf(GL_RED_SCALE,32.0);
|
||||
// glTexImage2D(GL_TEXTURE_2D, 0, 1, 640, 480, 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, kinect_qt::gl_depth_front);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGBA, GL_UNSIGNED_BYTE, im);
|
||||
glPixelTransferf(GL_RED_SCALE,1.0);
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glColor4f(255.0f, 255.0f, 255.0f, 255.0f);
|
||||
glTexCoord2f(0, 0); glVertex3f(-1,1,0);
|
||||
glTexCoord2f(1, 0); glVertex3f(0,1,0);
|
||||
glTexCoord2f(1, 1); glVertex3f(0,-1,0);
|
||||
glTexCoord2f(0, 1);glVertex3f(-1,-1,0);
|
||||
glEnd();
|
||||
|
||||
}// colored
|
||||
else
|
||||
{
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_LIGHTING);
|
||||
glColor3f(1,1,1);
|
||||
glViewport(0,0,640,480);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float w = 0.3;
|
||||
glFrustum( w,-w, w/1.5, -w/1.5,0.5,6.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(0,0,0,0,0,1,0,1,0);
|
||||
// glPointSize(2.0);
|
||||
glBegin(GL_POINTS);
|
||||
|
||||
for(unsigned int i = 0; i < 640*480;++i){
|
||||
glNormal(normals[i]);
|
||||
glVertex(points[i]);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
}
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glViewport(0,0,1280,480);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, kinect_qt::gl_rgb_front);
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glColor4f(255.0f, 255.0f, 255.0f, 255.0f);
|
||||
glTexCoord2f(0, 0); glVertex3f(0,1,0);
|
||||
glTexCoord2f(1, 0); glVertex3f(1,1,0);
|
||||
glTexCoord2f(1, 1); glVertex3f(1,-1,0);
|
||||
glTexCoord2f(0, 1);glVertex3f(0,-1,0);
|
||||
glEnd();
|
||||
}
|
||||
if(snapshot){
|
||||
snapshot = false;
|
||||
CMesh m;
|
||||
CMesh::VertexIterator vi = vcg::tri::Allocator<CMesh>::AddVertices(m,640*480);
|
||||
for(unsigned int i = 0; vi != m.vert.end(); ++vi,++i){
|
||||
|
||||
(*vi).N() = normals[i];
|
||||
(*vi).P() = points[i];
|
||||
//if((*vi).P()[2] <0)
|
||||
// if(n_frames - last_time_on[i]>3)
|
||||
// vcg::tri::Allocator<CMesh>::DeleteVertex(m,*vi);
|
||||
}
|
||||
|
||||
// discard high rms
|
||||
// float rms = 0;
|
||||
|
||||
for(unsigned int i = 0; i < 640*480;++i){
|
||||
// vcg::Distribution<float> d;
|
||||
float vmin = 2047,vmax=0;
|
||||
for(unsigned int c = 0; c < 100;++c) {
|
||||
vmin=std::min<float>(vmin,gl_depths[c][i]);
|
||||
vmax=std::max<float>(vmax,gl_depths[c][i]);
|
||||
}
|
||||
// d.Add(gl_depths[c][i]);
|
||||
// rms = d.RMS();
|
||||
// if(rms>500)
|
||||
if((vmax-vmin)>20)
|
||||
vcg::tri::Allocator<CMesh>::DeleteVertex(m,m.vert[i]);
|
||||
}
|
||||
|
||||
vcg::tri::UpdateBounding<CMesh>::Box(m);
|
||||
vcg::tri::io::ExporterPLY<CMesh>::Save(m,"out.ply",vcg::tri::io::Mask::IOM_VERTNORMAL |vcg::tri::io::Mask::IOM_VERTCOORD);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
GLArea::~GLArea(){
|
||||
kinect_qt::kinect_thread.terminate();
|
||||
}
|
||||
GLArea::GLArea (QWidget * parent)
|
||||
:QGLWidget (parent)
|
||||
{
|
||||
drawmode= SMOOTH;
|
||||
QTimer *timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
timer->start(50);
|
||||
}
|
||||
|
||||
|
||||
void GLArea::initializeGL ()
|
||||
{
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glGenTextures(1, &gl_depth_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_depth_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glGenTextures(1, &gl_rgb_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_rgb_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
static bool first = true;
|
||||
if(first){
|
||||
first = false;
|
||||
kinect_qt::start_kinect();
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i=0; i<2048; i++) {
|
||||
float v = i/2048.0;
|
||||
v = powf(v, 3)* 6;
|
||||
t_gamma[i] = v*6*256;
|
||||
}
|
||||
for (i=0; i<640*480; i++) {
|
||||
last_time_on[i]=0;
|
||||
last_value_on[i]=2049;
|
||||
}
|
||||
}
|
||||
|
||||
void GLArea::resizeGL (int w, int h)
|
||||
{
|
||||
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
|
||||
initializeGL();
|
||||
}
|
||||
|
||||
void GLArea::keyReleaseEvent (QKeyEvent * e)
|
||||
{
|
||||
e->ignore ();
|
||||
if (e->key () == Qt::Key_Control)
|
||||
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier));
|
||||
if (e->key () == Qt::Key_Shift)
|
||||
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
|
||||
if (e->key () == Qt::Key_Alt)
|
||||
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier));
|
||||
updateGL ();
|
||||
}
|
||||
|
||||
void GLArea::keyPressEvent (QKeyEvent * e)
|
||||
{
|
||||
e->ignore ();
|
||||
if (e->key () == Qt::Key_Control)
|
||||
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier));
|
||||
if (e->key () == Qt::Key_Shift)
|
||||
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
|
||||
if (e->key () == Qt::Key_Alt)
|
||||
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier));
|
||||
|
||||
updateGL ();
|
||||
}
|
||||
|
||||
void GLArea::mousePressEvent (QMouseEvent * e)
|
||||
{
|
||||
e->accept();
|
||||
pick_depth = true;
|
||||
i_pick = e->x();
|
||||
j_pick = e->y();
|
||||
snapshot = true;
|
||||
// e->accept ();
|
||||
// setFocus ();
|
||||
// track.MouseDown (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ()));
|
||||
// updateGL ();
|
||||
}
|
||||
|
||||
void GLArea::mouseMoveEvent (QMouseEvent * e)
|
||||
{
|
||||
// if (e->buttons ()) {
|
||||
// track.MouseMove (e->x (), height () - e->y ());
|
||||
// updateGL ();
|
||||
// }
|
||||
}
|
||||
|
||||
void GLArea::mouseReleaseEvent (QMouseEvent * e)
|
||||
{
|
||||
// track.MouseUp (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ()));
|
||||
// updateGL ();
|
||||
}
|
||||
|
||||
void GLArea::wheelEvent (QWheelEvent * e)
|
||||
{
|
||||
// const int WHEEL_STEP = 120;
|
||||
// track.MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ()));
|
||||
// updateGL ();
|
||||
}
|
||||
105
src/meshlabplugins/edit_kinect/glarea.h
Executable file
105
src/meshlabplugins/edit_kinect/glarea.h
Executable file
@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2007 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.1 2007/10/18 08:52:06 benedetti
|
||||
Initial release.
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef GLAREA_H_
|
||||
#define GLAREA_H_
|
||||
|
||||
/// Opengl related imports
|
||||
#include <GL/glew.h>
|
||||
#include <QtOpenGL/QGLWidget>
|
||||
|
||||
/// vcg imports
|
||||
#include <vcg/simplex/vertex/base.h>
|
||||
#include <vcg/simplex/face/base.h>
|
||||
#include <vcg/complex/trimesh/base.h>
|
||||
#include <vcg/complex/trimesh/update/bounding.h>
|
||||
#include <vcg/complex/trimesh/update/normal.h>
|
||||
#include <vcg/complex/trimesh/create/platonic.h>
|
||||
|
||||
/// wrapper imports
|
||||
#include <wrap/io_trimesh/import.h>
|
||||
#include <wrap/gl/trimesh.h>
|
||||
#include <wrap/gui/trackball.h>
|
||||
|
||||
/// declaring edge and face type
|
||||
|
||||
using namespace vcg;
|
||||
class CFace;
|
||||
class CVertex;
|
||||
|
||||
struct MyUsedTypes : public UsedTypes< Use<CVertex> ::AsVertexType,
|
||||
Use<CFace> ::AsFaceType>{};
|
||||
|
||||
/// compositing wanted proprieties
|
||||
class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{};
|
||||
class CFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {};
|
||||
class CMesh : public vcg::tri::TriMesh< std::vector<CVertex>, std::vector<CFace> > {};
|
||||
|
||||
class GLArea:public QGLWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~GLArea();
|
||||
GLArea (QWidget * parent = 0);
|
||||
/// we choosed a subset of the avaible drawing modes
|
||||
enum DrawMode{SMOOTH=0,POINTS,WIRE,FLATWIRE,HIDDEN,FLAT};
|
||||
public slots:
|
||||
|
||||
signals:
|
||||
/// signal for setting the statusbar message
|
||||
void setStatusBar(QString message);
|
||||
protected:
|
||||
/// opengl initialization and drawing calls
|
||||
void initializeGL ();
|
||||
void resizeGL (int w, int h);
|
||||
void paintGL ();
|
||||
/// keyboard and mouse event callbacks
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
void mousePressEvent(QMouseEvent*e);
|
||||
void mouseMoveEvent(QMouseEvent*e);
|
||||
void mouseReleaseEvent(QMouseEvent*e);
|
||||
void wheelEvent(QWheelEvent*e);
|
||||
private:
|
||||
/// the active mesh instance
|
||||
CMesh mesh;
|
||||
/// the active mesh opengl wrapper
|
||||
vcg::GlTrimesh<CMesh> glWrap;
|
||||
/// the active manipulator
|
||||
vcg::Trackball track;
|
||||
/// the current drawmode
|
||||
DrawMode drawmode;
|
||||
/// mesh data structure initializer
|
||||
void initMesh(QString message);
|
||||
};
|
||||
|
||||
#endif /*GLAREA_H_ */
|
||||
BIN
src/meshlabplugins/edit_kinect/icons/kinect.png
Executable file
BIN
src/meshlabplugins/edit_kinect/icons/kinect.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
135
src/meshlabplugins/edit_kinect/kinect.ui
Executable file
135
src/meshlabplugins/edit_kinect/kinect.ui
Executable file
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KinectDockWidget</class>
|
||||
<widget class="QDockWidget" name="KinectDockWidget">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::NonModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>205</width>
|
||||
<height>175</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>800</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="floating">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Kinect</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<widget class="QPushButton" name="startScanPushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>40</y>
|
||||
<width>91</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start Scan</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="vrtRadioButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>70</y>
|
||||
<width>158</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>watch real time</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string>buttonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="vsmRadioButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>90</y>
|
||||
<width>158</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>view scanned model</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string>buttonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="saveScanPushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>120</y>
|
||||
<width>91</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save Scan</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDoubleSpinBox" name="tiltSpinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>10</y>
|
||||
<width>62</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-30.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>30.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>10</y>
|
||||
<width>56</width>
|
||||
<height>15</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tilt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="buttonGroup"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
96
src/meshlabplugins/edit_kinect/shader_basic.h
Executable file
96
src/meshlabplugins/edit_kinect/shader_basic.h
Executable file
@ -0,0 +1,96 @@
|
||||
#ifndef _SHADER_BASIC_
|
||||
#define _SHADER_BASIC_
|
||||
|
||||
|
||||
|
||||
struct Shader{
|
||||
|
||||
static int SetFromString( const GLchar *stringV, const GLchar *stringF, GLuint &fs, GLuint & vs, GLuint &pr){
|
||||
fs= glCreateShader(GL_FRAGMENT_SHADER);
|
||||
vs= glCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
|
||||
if(stringV!=NULL){
|
||||
glShaderSource(vs, 1, &stringV,NULL);
|
||||
glCompileShader(vs);
|
||||
int errV;
|
||||
glGetShaderiv(vs,GL_COMPILE_STATUS,&errV);
|
||||
if(errV!=GL_TRUE) return -2;
|
||||
}else return -1;
|
||||
if(stringF!=NULL){
|
||||
glShaderSource(fs, 1, &stringF,NULL);
|
||||
glCompileShader(fs);
|
||||
int errF;
|
||||
glGetShaderiv(fs,GL_COMPILE_STATUS,&errF);
|
||||
if(errF!=GL_TRUE) return -4;
|
||||
}else return -3;
|
||||
pr = glCreateProgram();
|
||||
glAttachShader(pr,vs);
|
||||
glAttachShader(pr,fs);
|
||||
glLinkProgram(pr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void Validate( const int & s ){
|
||||
int res;
|
||||
glValidateProgram(s);
|
||||
glGetProgramiv(s,GL_VALIDATE_STATUS,&res);
|
||||
qDebug("validation of program %d:%d \n",s,res);
|
||||
|
||||
glGetProgramiv(s,GL_LINK_STATUS,&res);
|
||||
qDebug("linking of program %d:%d \n",s,res);
|
||||
|
||||
glGetProgramiv(s,GL_ACTIVE_ATTRIBUTES,&res);
|
||||
qDebug("active attribute of program %d:%d \n",s,res);
|
||||
|
||||
glGetProgramiv(s,GL_ACTIVE_UNIFORMS,&res);
|
||||
qDebug("active uniform of program %d:%d \n",s,res);
|
||||
|
||||
glGetProgramiv(s,GL_ACTIVE_UNIFORM_MAX_LENGTH,&res);
|
||||
qDebug("active uniform Max Length of program %d:%d \n",s,res);
|
||||
}
|
||||
};
|
||||
|
||||
struct FBO{
|
||||
static void Check(int fboStatus)
|
||||
{
|
||||
if ( fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
if (fboStatus == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT)
|
||||
{
|
||||
qDebug("FBO Incomplete: Attachment");
|
||||
}
|
||||
else if (fboStatus == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT)
|
||||
{
|
||||
qDebug("FBO Incomplete: Missing Attachment");
|
||||
}
|
||||
else if (fboStatus == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT)
|
||||
{
|
||||
qDebug("FBO Incomplete: Dimensions");
|
||||
}
|
||||
else if (fboStatus == GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT)
|
||||
{
|
||||
qDebug("FBO Incomplete: Formats");
|
||||
}
|
||||
else if (fboStatus == GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT)
|
||||
{
|
||||
qDebug("FBO Incomplete: Draw Buffer");
|
||||
}
|
||||
else if (fboStatus == GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT)
|
||||
{
|
||||
qDebug("FBO Incomplete: Read Buffer");
|
||||
}
|
||||
else if (fboStatus == GL_FRAMEBUFFER_UNSUPPORTED_EXT)
|
||||
{
|
||||
qDebug("FBO Unsupported");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Undefined FBO error");
|
||||
exit(-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user