Commit b77fc0d4 authored by Jan Möbius's avatar Jan Möbius

Implemented basic postprocessor interface

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@12287 383ad7c9-94d9-4d36-a494-682f7c89f535
parent ae3527b0
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef POSTPROCESSORINTERFACE_HH
#define POSTPROCESSORINTERFACE_HH
#include <ACG/GL/GLState.hh>
/** \file PostProcessorInterface.hh
*
* Interface for adding global image post processor functions. \ref PostProcessorInterfacePage
*/
/** \brief Interface to add global image post processor functions from within plugins.
*
* \ref PostProcessorInterfacePage "Detailed description"
* \n
* \n
*
* Interface for adding and controlling global image post processor functions from a plugin.\n
*/
class PostProcessorInterface {
public:
/// Destructor
virtual ~PostProcessorInterface() {};
public slots:
/** \brief post processor function
*
*/
virtual void postProcess(ACG::GLState* _glState) {};
/** \brief announce name for the postProcessor function
*
*
* @param _name displayed name of the postProcessor function
*/
virtual QString postProcessorName() = 0;
};
/** \page PostProcessorInterfacePage Post Processor Interface
\image html PostProcessorInterfacePage.png
\n
The PostProcessor Interface can be used to add additional image post processing functions
to OpenFlipper. For example you get the rendered image in the usual buffers. Afterwards you can
add a post processor doing for example edge detection or taking the depth image from the
buffer and render it to the main image.
Example Code for functions:
\code
TODO
\endcode
To use the PostProcessorInterface:
<ul>
<li> include PostProcessorInterface.hh in your plugins header file
<li> derive your plugin from the class PostProcessorInterface
<li> add Q_INTERFACES(PostProcessorInterface) to your plugin class
<li> And add the signals or slots you want to use to your plugin class (You don't need to implement all of them)
</ul>
*/
Q_DECLARE_INTERFACE(PostProcessorInterface,"OpenFlipper.PostProcessorInterface/1.0")
#endif // RPCINTERFACE_HH
......@@ -73,6 +73,7 @@
#include "OpenFlipper/BasePlugin/ToolbarInterface.hh"
#include "OpenFlipper/BasePlugin/TextureInterface.hh"
#include "OpenFlipper/BasePlugin/RenderInterface.hh"
#include "OpenFlipper/BasePlugin/PostProcessorInterface.hh"
#include "OpenFlipper/BasePlugin/MenuInterface.hh"
#include "OpenFlipper/BasePlugin/ContextMenuInterface.hh"
#include "OpenFlipper/BasePlugin/ProcessInterface.hh"
......@@ -1911,12 +1912,46 @@ void Core::loadPlugin(QString filename, bool silent, QString& _licenseErrors, QO
}
} else {
emit log(LOGERR,tr("Error: Renderer Plugin without rendererNameFunction?!"));
emit log(LOGERR,tr("Error: Renderer Plugin without rendererName Function?!"));
}
std::cerr << "Render Plugin .. not yet implemented" << std::endl;
}
//Check if the plugin supports PostProcessorInterface
PostProcessorInterface* postProcessorPlugin = qobject_cast< PostProcessorInterface * >(plugin);
if ( postProcessorPlugin ) {
supported = supported + "PostProcessor ";
if ( checkSlot( plugin , "postProcessorName()" ) ) {
QString postProcessorNameString = "";
// Get the name of the PostProcessor
QMetaObject::invokeMethod(plugin,"postProcessorName", Qt::DirectConnection, Q_RETURN_ARG(QString,postProcessorNameString) ) ;
std::cerr << postProcessorNameString.toStdString() << std::endl;
// Check if it already exists and add it if not.
PostProcessorInfo* postProcessorInfo = 0;
if ( ! postProcessorManager().postProcessorExists(postProcessorNameString) ) {
postProcessorInfo = postProcessorManager().newPostProcessor(postProcessorNameString);
} else {
emit log(LOGERR,tr("Error: PostProcessor Plugin %1 already exists").arg(postProcessorNameString));
}
// Retrieve and store PostProcessor information
if ( postProcessorInfo != 0) {
std::cerr << "PostProcessor ok" << std::endl;
postProcessorInfo->plugin = postProcessorPlugin;
}
} else {
emit log(LOGERR,tr("Error: PostProcessor Plugin without postProcessorName Function?!"));
}
std::cerr << "PostProcessor Plugin .. not yet implemented" << std::endl;
}
//========================================================================================
// === Collect Scripting Information for Plugin ============================
......
......@@ -44,20 +44,39 @@
#include <OpenFlipper/Core/RendererInfo.hh>
#include <iostream>
static RenderManager renderManager_;
static RenderManager renderManager_;
static PostProcessorManager postProcessorManager_;
RenderManager& renderManager() {
return renderManager_;
}
RenderManager::RenderManager() {
PostProcessorManager& postProcessorManager() {
return postProcessorManager_;
}
RendererInfo::RendererInfo():
plugin(0),
name("")
{
}
RendererInfo::RendererInfo(QObject* _plugin,QString _name) :
plugin(_plugin),
name(_name)
{
}
RenderManager::RenderManager():
activeRenderer_(0)
{
availableRenderers_.clear();
availableRenderers_.push_back(RendererInfo(0,"Default internal renderer"));
}
bool RenderManager::rendererExists(QString _name) {
std::cerr << "Render Manager rendererExists ?" << std::endl;
for ( unsigned int i = 0 ; i < availableRenderers_.size() ; ++i)
if ( availableRenderers_[i].name == _name)
......@@ -68,7 +87,6 @@ bool RenderManager::rendererExists(QString _name) {
}
RendererInfo* RenderManager::newRenderer(QString _name) {
std::cerr << "Render Manager newRenderer" << std::endl;
for ( unsigned int i = 0 ; i < availableRenderers_.size() ; ++i)
if ( availableRenderers_[i].name == _name)
......@@ -82,8 +100,6 @@ RendererInfo* RenderManager::newRenderer(QString _name) {
RendererInfo* RenderManager::getRenderer(QString _name) {
std::cerr << "Render Manager getRenderer" << std::endl;
for ( unsigned int i = 0 ; i < availableRenderers_.size() ; ++i)
if ( availableRenderers_[i].name == _name)
return &availableRenderers_[i];
......@@ -100,29 +116,137 @@ int RenderManager::countRenderers(ACG::SceneGraph::DrawModes::DrawMode _mode) {
if ( (availableRenderers_[i].modes & _mode) )
renderers++;
std::cerr << "Found " << renderers << " Renderers" << std::endl;
return renderers;
}
std::vector<int> RenderManager::getRendererIds(ACG::SceneGraph::DrawModes::DrawMode _mode){
std::vector <int> renderers;
RendererInfo* RenderManager::operator[](unsigned int _id) {
// Skip first one as it is the default renderer
for ( unsigned int i = 1 ; i < availableRenderers_.size() ; ++i)
if ( (availableRenderers_[i].modes & _mode) )
renderers.push_back(i);
if ( _id >= availableRenderers_.size())
return 0;
else
return &availableRenderers_[_id];
return renderers;
}
unsigned int RenderManager::available() {
return availableRenderers_.size();
}
RendererInfo* RenderManager::operator[](unsigned int _id) {
if ( _id >= availableRenderers_.size())
void RenderManager::setActive(unsigned int _active) {
if ( _active < availableRenderers_.size() )
activeRenderer_ = _active;
else
std::cerr << "Out of range error when setting active renderer" << std::endl;
}
void RenderManager::setActive(QString _active) {
for ( unsigned int i = 0 ; i < availableRenderers_.size() ; ++i)
if ( availableRenderers_[i].name == _active) {
activeRenderer_ = i;
}
}
RendererInfo* RenderManager::active() {
return &availableRenderers_[activeRenderer_];
}
unsigned int RenderManager::activeId() {
return activeRenderer_;
}
//===================================================================
PostProcessorInfo::PostProcessorInfo(PostProcessorInterface* _plugin, QString _name) :
plugin(_plugin),
name(_name)
{
}
PostProcessorInfo::PostProcessorInfo()
{
plugin = 0;
name = "";
}
PostProcessorManager::PostProcessorManager():
activePostProcessor_(0)
{
availablePostProcessors_.clear();
availablePostProcessors_.push_back(PostProcessorInfo(0,"Default internal post processor"));
}
bool PostProcessorManager::postProcessorExists(QString _name) {
for ( unsigned int i = 0 ; i < availablePostProcessors_.size() ; ++i)
if ( availablePostProcessors_[i].name == _name)
return true;
return false;
}
PostProcessorInfo* PostProcessorManager::newPostProcessor(QString _name) {
for ( unsigned int i = 0 ; i < availablePostProcessors_.size() ; ++i)
if ( availablePostProcessors_[i].name == _name)
return &availablePostProcessors_[i];
availablePostProcessors_.push_back(PostProcessorInfo());
availablePostProcessors_[availablePostProcessors_.size()-1].name = _name;
return &availablePostProcessors_[availablePostProcessors_.size()-1];
}
PostProcessorInfo* PostProcessorManager::getPostProcessor(QString _name) {
for ( unsigned int i = 0 ; i < availablePostProcessors_.size() ; ++i)
if ( availablePostProcessors_[i].name == _name)
return &availablePostProcessors_[i];
return 0;
}
PostProcessorInfo* PostProcessorManager::operator[](unsigned int _id) {
if ( _id >= availablePostProcessors_.size())
return 0;
else
return &availableRenderers_[_id];
return &availablePostProcessors_[_id];
}
unsigned int PostProcessorManager::available() {
return availablePostProcessors_.size();
}
void PostProcessorManager::setActive(unsigned int _active) {
if ( _active < availablePostProcessors_.size() )
activePostProcessor_ = _active;
else
std::cerr << "Out of range error when setting active postprocessor" << std::endl;
}
void PostProcessorManager::setActive(QString _active) {
for ( unsigned int i = 0 ; i < availablePostProcessors_.size() ; ++i)
if ( availablePostProcessors_[i].name == _active) {
activePostProcessor_ = i;
}
}
PostProcessorInfo* PostProcessorManager::active() {
return &availablePostProcessors_[activePostProcessor_];
}
unsigned int PostProcessorManager::activeId() {
return activePostProcessor_;
}
......@@ -47,6 +47,7 @@
#include <QString>
#include <QObject>
#include <ACG/Scenegraph/DrawModes.hh>
#include <OpenFlipper/BasePlugin/PostProcessorInterface.hh>
#include <vector>
......@@ -55,21 +56,21 @@ class RendererInfo{
public :
RendererInfo() {
plugin = 0;
name = "";
}
RendererInfo();
/// Pointer to the loaded plugin (Already casted when loading it)
QObject* plugin;
RendererInfo(QObject* _plugin,QString _name);
/// Name of the plugin ( requested from the plugin on load)
QString name;
/// Pointer to the loaded plugin (Already casted when loading it)
QObject* plugin;
/// Supported DrawModes
ACG::SceneGraph::DrawModes::DrawMode modes;
/// Name of the plugin ( requested from the plugin on load)
QString name;
/// Supported DrawModes
ACG::SceneGraph::DrawModes::DrawMode modes;
};
class RenderManager {
public:
RenderManager();
......@@ -106,15 +107,150 @@ class RenderManager {
*/
int countRenderers(ACG::SceneGraph::DrawModes::DrawMode _mode);
std::vector<int> getRendererIds(ACG::SceneGraph::DrawModes::DrawMode _mode);
/** \brief Get the renderer with the given id
*
* @param _id Id of the renderer
* @return
*/
RendererInfo* operator[](unsigned int _id);
/** \brief number of available renderers
*
* @return number of available renderers
*/
unsigned int available();
/** \brief set the active renderer
*
* @param _active id of the renderer
*/
void setActive(unsigned int _active);
/** \brief set the active renderer
*
* @param _active name of the renderer
*/
void setActive(QString _active);
/** \brief Get the current active renderer
*
* @return Renderer
*/
RendererInfo* active();
/** \brief Get the id of the active renderer
*
* @return renderer id
*/
unsigned int activeId();
private:
/// Vector holding all available renderers
std::vector<RendererInfo> availableRenderers_;
/// The currently active renderer id
unsigned int activeRenderer_;
};
/// Get an instance of the render manager
RenderManager& renderManager();
//===================================================================================
// Post processor Manager
//===================================================================================
/** Type defining a currently loaded Post processor */
class PostProcessorInfo{
public :
PostProcessorInfo();
PostProcessorInfo(PostProcessorInterface* _plugin, QString _name);
/// Pointer to the loaded plugin (Already casted when loading it)
PostProcessorInterface* plugin;
/// Name of the plugin ( requested from the plugin on load)
QString name;
};
class PostProcessorManager {
public:
PostProcessorManager();
/** \brief Check if a post processor with the given name exists
*
* @param _name Name of the post processor
* @return exists or not
*/
bool postProcessorExists(QString _name);
/**\brief Get a new post processor Instance
*
* @param _name Name of the new post processor
*
* @return Pointer to post processor. If it exists, the existing one is returned!
*/
PostProcessorInfo* newPostProcessor(QString _name);
/** \brief get post processor with the given name
*
* @param _name Name of the post processor
* @return pointer or 0 if it does not exist
*/
PostProcessorInfo* getPostProcessor(QString _name);
/** \brief Get the post processor with the given id
*
* @param _id Id of the post processor
* @return
*/
PostProcessorInfo* operator[](unsigned int _id);
/** \brief number of available post processor
*
* @return number of available post processor
*/
unsigned int available();
/** \brief set the active post processor
*
* @param _active id of the post processor
*/
void setActive(unsigned int _active);
/** \brief set the active post processor
*
* @param _active name of the post processor
*/
void setActive(QString _active);
/** \brief Get the current active post processor
*
* @return post processor
*/
PostProcessorInfo* active();
/** \brief Get the id of the active post processor
*
* @return post processor id
*/
unsigned int activeId();
private:
/// Vector holding all available post processors
std::vector<PostProcessorInfo> availablePostProcessors_;
/// The currently active post processor id
int activePostProcessor_;
};
/// Get an instance of the Post Processor manager
PostProcessorManager& postProcessorManager();
#endif //RENDERERINFO_HH
......@@ -57,6 +57,7 @@
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/common/GlobalOptions.hh>
#include "../../common/GlobalOptions.hh"
#include <OpenFlipper/Core/RendererInfo.hh>
//== IMPLEMENTATION ==========================================================
#include <ACG/Scenegraph/CoordsysNode.hh>
......@@ -211,6 +212,42 @@ void CoreWidget::updatePopupMenuCoordsysNode(QMenu* _menu , const int /*_part*/
mipmapping->setChecked( PluginFunctions::viewerProperties().mipmapping() );
connect(mipmapping, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMipmapping(bool) ) );
//============================================================================================================
// Post processor Menu
//============================================================================================================
if ( postProcessorManager().available() > 0 ) {
QMenu* postProcessorMenu = new QMenu(tr("Post processors"),_menu);
_menu->addMenu(postProcessorMenu);
// Recreate actionGroup
QActionGroup* groupPostProcessor = new QActionGroup( this );
groupPostProcessor->setExclusive( true );
for ( unsigned int i = 0 ; i < postProcessorManager().available() ; ++i) {
// Add a new Action with the postprocessors name
QAction * action = new QAction( postProcessorManager()[i]->name, groupPostProcessor );
action->setCheckable( true );
// Check if this processor is currently active
if ( postProcessorManager().activeId() == i )
action->setChecked(true);
// Remember the id for the processor
action->setData(QVariant(i));
}
// Add all new actions from the group to the menu
postProcessorMenu->addActions( groupPostProcessor->actions() );
// Connect signal of group to our managing slot
connect( groupPostProcessor , SIGNAL( triggered( QAction * ) ),
this , SLOT( slotPostProcessorMenu( QAction * ) ) );
}
//============================================================================================================
// Viewing Direction Menu
......@@ -813,4 +850,9 @@ void CoreWidget::slotViewerDrawMenu(QAction * _action) {
}
void CoreWidget::slotPostProcessorMenu( QAction * _action) {
unsigned int mode = _action->data().toUInt();
postProcessorManager().setActive(mode);
}
//=============================================================================
......@@ -845,6 +845,9 @@ public:
/// Called when a coordsys drawMode has been changed
void slotViewerDrawMenu( QAction * _action );
/// Called when a different post processor has been chosen
void slotPostProcessorMenu( QAction * _action);
/// Creates a draw Menu for the currently active Viewer
void slotUpdateViewerDrawMenu();
......
......@@ -120,6 +120,9 @@
#include <QGLFramebufferObject>
#include <OpenFlipper/Core/RendererInfo.hh>
#include <OpenFlipper/BasePlugin/PostProcessorInterface.hh>
//== NAMESPACES ===============================================================
......@@ -584,10 +587,27 @@ void glViewer::drawScene()
// draw mono or stereo
makeCurrent();
/* std::cerr << "Draw Scene" << std::endl;
std::cerr << "Available renderers: " << renderManager().available() << std::endl;
std::cerr << "Active renderer: " << renderManager().active()->name.toStdString() << std::endl;
std::cerr << "Available postprocessors: " << postProcessorManager().available() << std::endl;
std::cerr << "Active postprocessor: " << postProcessorManager().active()->name.toStdString() << std::endl;
*/
if (stereo_) drawScene_stereo();
else drawScene_mono();
if ( postProcessorManager().activeId() != 0 ) {
std::cerr << "Non default postProcessor!" << std::endl;
postProcessorManager().active()->plugin->postProcess(glstate_);
}
// } else {
// std::cerr << "No post processor" << std::endl;
// }
glFinish();
frame_time_ = timer.elapsed();
......@@ -828,6 +848,7 @@ void glViewer::drawScene_mono()
cursorPainter_->paintCursor (glstate_);
glstate_->pop_modelview_matrix ();
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment