draft plugin to use kinect in meshlab (this version only for linux32)

This commit is contained in:
Fabio Ganovelli ganovelli 2011-01-04 14:43:41 +00:00
parent 3acd1b0abd
commit ab2e0276ec
13 changed files with 1595 additions and 0 deletions

View 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(){
}

View 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

View 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

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>icons/kinect.png</file>
</qresource>
</RCC>

View 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)

View 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

View 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

View 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

View 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 ();
}

View 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_ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View 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>

View 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