From 6a897869e1edec0d38ec631c7ece7597e89ecccc Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Tue, 11 Dec 2007 12:01:12 +0000 Subject: [PATCH] Added a glwidget class and moved the rendering inside a paintGL call as usually requested by qt --- src/meshlabplugins/filter_ao/AOGLWidget.cpp | 38 ++++++ src/meshlabplugins/filter_ao/AOGLWidget.h | 38 ++++++ src/meshlabplugins/filter_ao/filter_ao.cpp | 125 ++++++++++---------- src/meshlabplugins/filter_ao/filter_ao.h | 9 +- src/meshlabplugins/filter_ao/filter_ao.pro | 4 +- 5 files changed, 142 insertions(+), 72 deletions(-) create mode 100644 src/meshlabplugins/filter_ao/AOGLWidget.cpp create mode 100644 src/meshlabplugins/filter_ao/AOGLWidget.h diff --git a/src/meshlabplugins/filter_ao/AOGLWidget.cpp b/src/meshlabplugins/filter_ao/AOGLWidget.cpp new file mode 100644 index 000000000..60607177d --- /dev/null +++ b/src/meshlabplugins/filter_ao/AOGLWidget.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include "AOGLWidget.h" +#include "filter_ao.h" + +AOGLWidget::AOGLWidget (QWidget * parent, AmbientOcclusionPlugin *_plugin) :QGLWidget (parent) +{ + plugin=_plugin; + cb=0; + m=0; + QGLFormat qFormat = QGLFormat::defaultFormat(); + qFormat.setAlpha(true); + qFormat.setDepth(true); + setFormat(qFormat); + setFixedSize(plugin->texSize,plugin->texSize); + if(!isValid()) + { + qDebug("Error: Unable to create a new QGLWidget"); + return; + } + +} + + +void AOGLWidget::initializeGL () +{ + plugin->initContext(this,cb); +} + +void AOGLWidget::paintGL () +{ + qDebug("Start Painting window size %i %i", width(), height()); + plugin->processGL(this,*m,cb); + hide(); + qDebug("End Painting"); +} + diff --git a/src/meshlabplugins/filter_ao/AOGLWidget.h b/src/meshlabplugins/filter_ao/AOGLWidget.h new file mode 100644 index 000000000..f9bd7878f --- /dev/null +++ b/src/meshlabplugins/filter_ao/AOGLWidget.h @@ -0,0 +1,38 @@ +/* + * editAlignPair.h + * editalign_debug + * + * Created by Paolo Cignoni on 11/6/07. + * Copyright 2007 __MyCompanyName__. All rights reserved. + * + */ +#ifndef __VCG_AOGLWIDGET +#define __VCG_AOGLWIDGET + +#include +#include +#include +#include + +#include +#include + +class AmbientOcclusionPlugin; + +class AOGLWidget: public QGLWidget +{ + Q_OBJECT +public: + AOGLWidget (QWidget * parent, AmbientOcclusionPlugin *_plugin); + AmbientOcclusionPlugin * plugin; + vcg::CallBackPos *cb; + MeshModel *m; + public slots: +protected: + /// opengl initialization and drawing calls + void initializeGL (); + void paintGL (); + +}; + +#endif diff --git a/src/meshlabplugins/filter_ao/filter_ao.cpp b/src/meshlabplugins/filter_ao/filter_ao.cpp index 0c9f3e14e..74a0eabbb 100644 --- a/src/meshlabplugins/filter_ao/filter_ao.cpp +++ b/src/meshlabplugins/filter_ao/filter_ao.cpp @@ -48,15 +48,16 @@ #include #include #include +#include #include "filter_ao.h" - +#include "AOGLWidget.h" #include #define AMBOCC_DEFAULT_TEXTURE_SIZE 1024 -#define AMBOCC_DEFAULT_NUM_VIEWS 250 -#define AMBOCC_USEGPU_BY_DEFAULT true -#define AMBOCC_USEVBO_BY_DEFAULT true +#define AMBOCC_DEFAULT_NUM_VIEWS 32 +#define AMBOCC_USEGPU_BY_DEFAULT false +#define AMBOCC_USEVBO_BY_DEFAULT false static GLuint vs, fs, shdrID; @@ -129,10 +130,6 @@ void AmbientOcclusionPlugin::initParameterSet(QAction *action, MeshModel &m, Fil } bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshModel &m, FilterParameterSet & par, vcg::CallBackPos *cb) { - int tInitElapsed = 0; - QTime tInit, tAll; - tInit.start(); - tAll.start(); assert(filter->text() == filterName(FP_AMBIENT_OCCLUSION)); useGPU = par.getBool("useGPU"); @@ -143,31 +140,43 @@ bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshModel &m, FilterPa if ( useGPU && ((unsigned int)m.cm.vn > texArea) ) { - Log(0, "Too many vertices: up to %d are allowed", texArea); + //Log(0, "Too many vertices: up to %d are allowed", texArea); return false; } - GLfloat *occlusion = new GLfloat[m.cm.vn]; + AOGLWidget *qWidget = new AOGLWidget(0,this); + qWidget->cb = cb; + qWidget->m = &m; + //qWidget->create(); + qWidget->show(); + + + ////Creates a new RC, initializes everything (glew, textures, FBO..) + //if (!initContext(qWidget, cb)) + return false; +} + + bool AmbientOcclusionPlugin::processGL(AOGLWidget *aogl, MeshModel &m, vcg::CallBackPos *cb) + { + checkGLError::qDebug("start"); + int tInitElapsed = 0; + QTime tInit, tAll; + tInit.start(); + tAll.start(); + + GLfloat *occlusion = new GLfloat[m.cm.vn]; typedef std::vector vectP3f; vectP3f::iterator vi; static vectP3f posVect; - QGLWidget qWidget; - - //Creates a new RC, initializes everything (glew, textures, FBO..) - if (!initContext(qWidget, cb)) - return false; - - if (!GLEW_ARB_vertex_buffer_object) - useVBO = false; - + vcg::tri::Allocator::CompactVertexVector(m.cm); //Prepare mesh to be rendered vcg::tri::UpdateNormals::PerVertexNormalized(m.cm); if (useVBO) { m.glw.SetHint(vcg::GLW::HNUseVBO); - cb(0, "Generating vertex data for VBO..."); + //cb(0, "Generating vertex data for VBO..."); m.glw.Update(); - cb(100, "Generating vertex data for VBO... Done."); + //cb(100, "Generating vertex data for VBO... Done."); } if(useGPU) @@ -231,7 +240,6 @@ bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshModel &m, FilterPa } else { - qWidget.makeCurrent(); glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); @@ -246,7 +254,8 @@ bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshModel &m, FilterPa generateOcclusionSW(m, occlusion); } - cb( 100*c/posVect.size() , "Calculating Ambient Occlusion..."); + //cb( 100*c/posVect.size() , "Calculating Ambient Occlusion..."); + //aogl->makeCurrent(); c++; } @@ -259,7 +268,7 @@ bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshModel &m, FilterPa else applyOcclusionSW(m,occlusion); - Log(0,"Successfully calculated A.O. after %3.2f sec, %3.2f of which is due to initialization", ((float)tAll.elapsed()/1000.0f), ((float)tInitElapsed/1000.0f) ); + //Log(0,"Successfully calculated A.O. after %3.2f sec, %3.2f of which is due to initialization", ((float)tAll.elapsed()/1000.0f), ((float)tInitElapsed/1000.0f) ); /********** Clean up the mess ************/ @@ -282,10 +291,11 @@ bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshModel &m, FilterPa delete [] occlusion; - qWidget.doneCurrent(); - return true; -} +} // end processGL + + + void AmbientOcclusionPlugin::renderMesh(MeshModel &m) { m.glw.DrawFill(); @@ -355,46 +365,32 @@ void AmbientOcclusionPlugin::initTextures(GLenum colorFormat, GLenum depthFormat glBindTexture(GL_TEXTURE_2D, 0); } - -bool AmbientOcclusionPlugin::initContext(QGLWidget &qWidget, vcg::CallBackPos *cb) +// Called by the initgl of the aoglwidget +bool AmbientOcclusionPlugin::initContext(QGLWidget *qWidget, vcg::CallBackPos *cb) { - cb(0, "Initializing: Context"); + //cb(0, "Initializing: Context"); - QGLFormat qFormat = QGLFormat::defaultFormat(); - qFormat.setAlpha(true); - qFormat.setDepth(true); - qWidget.setFormat(qFormat); - if(!qWidget.isValid()) - { - Log(0,"Error: Unable to create a new QGLWidget"); - return false; - } - - qWidget.setFixedSize(texSize,texSize); - qWidget.makeCurrent(); - - cb(15, "Initializing: Glew"); - qWidget.makeCurrent(); + //cb(15, "Initializing: Glew"); //*******INIT GLEW********/ GLint glewError = glewInit(); if (glewError) { - Log(0,(const char*)glewGetErrorString(glewError)); + //Log(0,(const char*)glewGetErrorString(glewError)); return false; } //*******CHECK TEX SIZE********/ if (texSize < 15) { - Log(0, "Texture size is too small, 16x16 used instead"); + //Log(0, "Texture size is too small, 16x16 used instead"); texSize = 16; texArea = texSize*texSize; } if (texSize > 1024) { - Log(0, "Texture size is too large, 1024x1024 used instead"); + //Log(0, "Texture size is too large, 1024x1024 used instead"); texSize = 1024; texArea = texSize*texSize; } @@ -407,31 +403,31 @@ bool AmbientOcclusionPlugin::initContext(QGLWidget &qWidget, vcg::CallBackPos *c { if ( !GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader ) { - Log(0, "Your hardware doesn't support Shaders, which are required for hw occlusion"); + //Log(0, "Your hardware doesn't support Shaders, which are required for hw occlusion"); return false; } if ( !GLEW_EXT_framebuffer_object ) { - Log(0, "Your hardware doesn't support FBOs, which are required for hw occlusion"); + //Log(0, "Your hardware doesn't support FBOs, which are required for hw occlusion"); return false; } if ( !GLEW_ARB_texture_float ) { - Log(0,"Your hardware doesn't support FP16/32 textures, which are required for hw occlusion"); + //Log(0,"Your hardware doesn't support FP16/32 textures, which are required for hw occlusion"); return false; } - cb(30, "Initializing: Textures"); + //cb(30, "Initializing: Textures"); //GL_RGBA32/16F_ARB works on nv40+(GeForce6 or newer) and ATI hardware initTextures(GL_RGBA32F_ARB, GL_DEPTH_COMPONENT); //*******LOAD SHADER*******/ - cb(45, "Initializing: Shaders"); + //cb(45, "Initializing: Shaders"); set_shaders("ambient_occlusion",vs,fs,shdrID); //*******INIT FBO*********/ - cb(65, "Initializing: FBOs"); + //cb(65, "Initializing: FBOs"); fboDepth = 0; glGenFramebuffersEXT(1, &fboDepth); // FBO for first pass (1 depth attachment) @@ -462,9 +458,7 @@ bool AmbientOcclusionPlugin::initContext(QGLWidget &qWidget, vcg::CallBackPos *c glViewport(0.0, 0.0, texSize, texSize); - cb(100, "Initializing: Done."); - - qWidget.makeCurrent(); + //cb(100, "Initializing: Done."); return true; } @@ -478,25 +472,26 @@ bool AmbientOcclusionPlugin::checkFramebuffer() switch (fboStatus) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - Log(0, "FBO Incomplete: Attachment"); + //Log(0, "FBO Incomplete: Attachment"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - Log(0, "FBO Incomplete: Missing Attachment"); + //Log(0, "FBO Incomplete: Missing Attachment"); break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - Log(0, "FBO Incomplete: Dimensions"); + //Log(0, "FBO Incomplete: Dimensions"); break; case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - Log(0, "FBO Incomplete: Formats"); + //Log(0, "FBO Incomplete: Formats"); break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - Log(0, "FBO Incomplete: Draw Buffer"); + //Log(0, "FBO Incomplete: Draw Buffer"); break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - Log(0, "FBO Incomplete: Read Buffer"); + //Log(0, "FBO Incomplete: Read Buffer"); break; default: - Log(0, "Undefined FBO error"); + //Log(0, "Undefined FBO error"); + assert(0); } return false; @@ -637,7 +632,7 @@ void AmbientOcclusionPlugin::generateOcclusionSW(MeshModel &m, GLfloat *occlusio glReadPixels(0, 0, texSize, texSize, GL_DEPTH_COMPONENT, GL_FLOAT, dFloat); //size(dFloat) == texSize*texSize (a.k.a. texArea !!) - qDebug("min and max of depth buffer %f %f",std::min_element(dFloat,dFloat+texArea),std::max_element(dFloat,dFloat+texArea)); + //qDebug("min and max of depth buffer %f %f",*std::min_element(dFloat,dFloat+texArea),*std::max_element(dFloat,dFloat+texArea)); cameraDir.Normalize(); Point3 vp; diff --git a/src/meshlabplugins/filter_ao/filter_ao.h b/src/meshlabplugins/filter_ao/filter_ao.h index 2f2e9eca1..cec31fdc1 100644 --- a/src/meshlabplugins/filter_ao/filter_ao.h +++ b/src/meshlabplugins/filter_ao/filter_ao.h @@ -31,14 +31,14 @@ #include #include #include - +class AOGLWidget; class AmbientOcclusionPlugin : public QObject, public MeshFilterInterface { Q_OBJECT Q_INTERFACES(MeshFilterInterface) // Attributes -private: +public: Point3f cameraDir; GLuint fboDepth, fboResult, @@ -74,12 +74,11 @@ public: MeshModel &m, FilterParameterSet & /*parent*/, vcg::CallBackPos * cb) ; -private: void initTextures (GLenum colorFormat, GLenum depthFormat); - bool initContext (QGLWidget &qWidget, + bool initContext (QGLWidget *qWidget, vcg::CallBackPos *cb); - + bool processGL(AOGLWidget *glw, MeshModel &m, vcg::CallBackPos *cb); bool checkFramebuffer(); void vertexCoordsToTexture (MeshModel &m); diff --git a/src/meshlabplugins/filter_ao/filter_ao.pro b/src/meshlabplugins/filter_ao/filter_ao.pro index 45b7e9e39..94eafd001 100644 --- a/src/meshlabplugins/filter_ao/filter_ao.pro +++ b/src/meshlabplugins/filter_ao/filter_ao.pro @@ -19,8 +19,8 @@ win32{ OBJECTS_DIR += debug -HEADERS += ./filter_ao.h -SOURCES += ./filter_ao.cpp \ +HEADERS += ./filter_ao.h AOGLWidget.h +SOURCES += ./filter_ao.cpp AOGLWidget.cpp \ ../../meshlab/filterparameter.cpp \ ../../../../code/lib/glew/src/glew.c