mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-19 19:14:42 +00:00
315 lines
9.4 KiB
C++
315 lines
9.4 KiB
C++
/****************************************************************************
|
|
* Render Radiance Scaling *
|
|
* Meshlab's plugin *
|
|
* *
|
|
* Copyright(C) 2010 *
|
|
* Vergne Romain, Dumas Olivier *
|
|
* INRIA - Institut Nationnal de Recherche en Informatique et Automatique *
|
|
* *
|
|
* 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 "radianceScalingRenderer.h"
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <iostream>
|
|
#include <common/GLExtensionsManager.h>
|
|
#include <QGLWidget>
|
|
#include <QTextStream>
|
|
#include <QResource>
|
|
#include "meshlab/glarea.h"
|
|
|
|
using namespace std;
|
|
|
|
#define GL_TEST_ERR \
|
|
{ \
|
|
GLenum eCode; \
|
|
if((eCode=glGetError())!=GL_NO_ERROR) \
|
|
std::cerr << "OpenGL error : " << gluErrorString(eCode) << " in " << __FILE__ << " : " << __LINE__ << std::endl; \
|
|
}
|
|
|
|
RadianceScalingRendererPlugin::RadianceScalingRendererPlugin()
|
|
: _supported(false),
|
|
_sDialog(0),
|
|
_fbo(NULL),
|
|
_buffPass(NULL),
|
|
_rsPass(NULL),
|
|
_depthTex(NULL),
|
|
_gradTex(NULL),
|
|
_normTex(NULL),
|
|
_colorTex(NULL),
|
|
_convexLS(NULL),
|
|
_concavLS(NULL) {
|
|
|
|
}
|
|
|
|
QString RadianceScalingRendererPlugin::pluginName() const
|
|
{
|
|
return "RenderRadianceScaling";
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::init(QAction *, MeshDocument &, MLSceneGLSharedDataContext::PerMeshRenderingDataMap& /*mp*/, GLArea *gla) {
|
|
if (_sDialog) {
|
|
_sDialog->close();
|
|
delete _sDialog;
|
|
_sDialog = 0;
|
|
}
|
|
|
|
gla->makeCurrent();
|
|
GLExtensionsManager::initializeGLextensions();
|
|
|
|
GL_TEST_ERR
|
|
|
|
if (!GLEW_ARB_vertex_program ||
|
|
!GLEW_ARB_fragment_program ||
|
|
!GLEW_ARB_texture_float ||
|
|
!GLEW_ARB_draw_buffers ||
|
|
!GLEW_EXT_framebuffer_object) {
|
|
|
|
_supported = false;
|
|
return;
|
|
}
|
|
|
|
_supported = true;
|
|
_sDialog = new ShaderDialog(this, gla, gla);
|
|
_sDialog->move(10, 100);
|
|
_sDialog->show();
|
|
|
|
_sDialog->changeIcon(":/RadianceScalingRenderer/litSpheres/ls02.png", ShaderDialog::convex_icon);
|
|
_sDialog->changeIcon(":/RadianceScalingRenderer/litSpheres/ls01.png", ShaderDialog::concav_icon);
|
|
|
|
createLit(":/RadianceScalingRenderer/litSpheres/ls02.png", 0);
|
|
createLit(":/RadianceScalingRenderer/litSpheres/ls01.png", 1);
|
|
|
|
initFBOs();
|
|
GL_TEST_ERR
|
|
|
|
initShaders();
|
|
GL_TEST_ERR
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::render(QAction *, MeshDocument &md, MLSceneGLSharedDataContext::PerMeshRenderingDataMap& /*mp*/, GLArea *gla)
|
|
{
|
|
if (gla == NULL)
|
|
return;
|
|
|
|
MultiViewer_Container* mvcont = gla->mvc();
|
|
if (mvcont == NULL)
|
|
return;
|
|
|
|
MLSceneGLSharedDataContext* shared = mvcont->sharedDataContext();
|
|
if (shared == NULL)
|
|
return;
|
|
|
|
checkViewport();
|
|
|
|
// first pass: buffers
|
|
_fbo->bind();
|
|
glDrawBuffers(3, FramebufferObject::buffers(0));
|
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
vcg::glColor(vcg::Color4b(vcg::Color4b::LightGray));
|
|
_buffPass->enable();
|
|
|
|
for(MeshModel *mp: md.meshIterator())
|
|
{
|
|
if ((mp != NULL) && (gla->meshVisibilityMap[mp->id()]))
|
|
{
|
|
shared->setMeshTransformationMatrix(mp->id(), mp->cm.Tr);
|
|
shared->draw(mp->id(), gla->context());
|
|
}
|
|
}
|
|
_buffPass->disable();
|
|
|
|
// second pass: descriptor, radiance scaling, lighting
|
|
FramebufferObject::unbind();
|
|
swapToScreenMode();
|
|
_rsPass->enable();
|
|
drawQuad();
|
|
_rsPass->disable();
|
|
swapToWorldMode();
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::finalize(QAction *, MeshDocument *, GLArea *) {
|
|
cleanShaders();
|
|
cleanFBOs();
|
|
|
|
if (_sDialog) {
|
|
_sDialog->close();
|
|
delete _sDialog;
|
|
_sDialog = 0;
|
|
}
|
|
|
|
if (_convexLS != NULL) {
|
|
delete _convexLS;
|
|
_convexLS = NULL;
|
|
}
|
|
|
|
if (_concavLS != NULL) {
|
|
delete _concavLS;
|
|
_concavLS = NULL;
|
|
}
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::initActionList() {
|
|
_actionList << new QAction("Radiance Scaling", this);
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::createLit(const QString &filename, int type) {
|
|
QImage t;
|
|
QImage b;
|
|
|
|
if (!b.load(filename)) {
|
|
return;
|
|
}
|
|
|
|
t = QGLWidget::convertToGLFormat(b);
|
|
|
|
if (type == 0) {
|
|
if (_convexLS != NULL) {
|
|
delete _convexLS;
|
|
_convexLS = NULL;
|
|
}
|
|
|
|
_convexLS = new UbyteTexture2D(TextureFormat(GL_TEXTURE_2D, t.width(), t.height(), 3, GL_RGBA, GL_UNSIGNED_BYTE), TextureParams(GL_LINEAR, GL_LINEAR), t.bits());
|
|
}
|
|
else {
|
|
|
|
if (_concavLS != NULL) {
|
|
delete _concavLS;
|
|
_concavLS = NULL;
|
|
}
|
|
|
|
_concavLS = new UbyteTexture2D(TextureFormat(GL_TEXTURE_2D, t.width(), t.height(), 3, GL_RGBA, GL_UNSIGNED_BYTE), TextureParams(GL_LINEAR, GL_LINEAR), t.bits());
|
|
}
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::initShaders(bool reload)
|
|
{
|
|
if (!reload) {
|
|
string path = ":/RadianceScalingRenderer/shaders/";
|
|
delete _buffPass;
|
|
delete _rsPass;
|
|
_buffPass = new GPUProgram(path + "01_buffer.vs", path + "01_buffer.fs");
|
|
_rsPass = new GPUProgram(path + "02_rs.vs", path + "02_rs.fs");
|
|
GL_TEST_ERR
|
|
|
|
_rsPass->enable();
|
|
_rsPass->addUniform("sw");
|
|
_rsPass->addUniform("sh");
|
|
_rsPass->addUniform("enhancement");
|
|
_rsPass->addUniform("transition");
|
|
_rsPass->addUniform("enabled");
|
|
_rsPass->addUniform("invert");
|
|
_rsPass->addUniform("doubleSide");
|
|
_rsPass->addUniform("twoLS");
|
|
_rsPass->addUniform("display");
|
|
_rsPass->addUniform("grad");
|
|
_rsPass->addUniform("norm");
|
|
_rsPass->addUniform("convexLS");
|
|
_rsPass->addUniform("concavLS");
|
|
_rsPass->addUniform("colormap");
|
|
_rsPass->disable();
|
|
|
|
GL_TEST_ERR
|
|
}
|
|
else {
|
|
_buffPass->reload();
|
|
_rsPass->reload();
|
|
GL_TEST_ERR
|
|
}
|
|
|
|
float sw = 1.0f / (float)_w;
|
|
float sh = 1.0f / (float)_h;
|
|
|
|
_rsPass->enable();
|
|
_rsPass->setUniform1f("sw", sw);
|
|
_rsPass->setUniform1f("sh", sh);
|
|
_rsPass->setUniform1f("enhancement", _sDialog->getEnhancement());
|
|
_rsPass->setUniform1f("transition", _sDialog->getTransition());
|
|
_rsPass->setUniform1i("enabled", _sDialog->getEnable());
|
|
_rsPass->setUniform1i("display", _sDialog->getDisplay());
|
|
_rsPass->setUniform1i("invert", _sDialog->getInvert());
|
|
_rsPass->setUniform1i("doubleSide", _sDialog->getDoubleSide());
|
|
_rsPass->setUniform1i("twoLS", _sDialog->getTwoLS());
|
|
_rsPass->setUniformTexture("grad", 0, _gradTex->format().target(), _gradTex->id());
|
|
_rsPass->setUniformTexture("norm", 1, _normTex->format().target(), _normTex->id());
|
|
_rsPass->setUniformTexture("colormap", 2, _colorTex->format().target(), _colorTex->id());
|
|
_rsPass->setUniformTexture("convexLS", 3, _convexLS->format().target(), _convexLS->id());
|
|
_rsPass->setUniformTexture("concavLS", 4, _concavLS->format().target(), _concavLS->id());
|
|
_rsPass->disable();
|
|
GL_TEST_ERR
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::initFBOs() {
|
|
int v[4];
|
|
glGetIntegerv(GL_VIEWPORT, v);
|
|
_w = v[2];
|
|
_h = v[3];
|
|
|
|
if (_fbo == NULL) {
|
|
GLenum filter = GL_LINEAR;
|
|
GLenum format = GL_RGBA16F_ARB;
|
|
_fbo = new FramebufferObject();
|
|
_depthTex = new FloatTexture2D(TextureFormat(GL_TEXTURE_2D, _w, _h, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT), TextureParams(filter, filter));
|
|
_gradTex = new FloatTexture2D(TextureFormat(GL_TEXTURE_2D, _w, _h, format, GL_RGBA, GL_FLOAT), TextureParams(filter, filter));
|
|
_normTex = new FloatTexture2D(_gradTex->format(), _gradTex->params());
|
|
_colorTex = new UbyteTexture2D(TextureFormat(GL_TEXTURE_2D, _w, _h, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE), TextureParams(GL_LINEAR, GL_LINEAR));//new FloatTexture2D(_gradTex->format(),_gradTex->params());
|
|
}
|
|
|
|
_fbo->bind();
|
|
_fbo->unattachAll();
|
|
_depthTex->bind();
|
|
_fbo->attachTexture(_depthTex->format().target(), _depthTex->id(), GL_DEPTH_ATTACHMENT_EXT);
|
|
_gradTex->bind();
|
|
_fbo->attachTexture(_gradTex->format().target(), _gradTex->id(), GL_COLOR_ATTACHMENT0_EXT);
|
|
_normTex->bind();
|
|
_fbo->attachTexture(_normTex->format().target(), _normTex->id(), GL_COLOR_ATTACHMENT1_EXT);
|
|
_colorTex->bind();
|
|
_fbo->attachTexture(_colorTex->format().target(), _colorTex->id(), GL_COLOR_ATTACHMENT2_EXT);
|
|
_fbo->isValid();
|
|
|
|
FramebufferObject::unbind();
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::cleanShaders() {
|
|
if (_buffPass != NULL) {
|
|
delete _buffPass;
|
|
delete _rsPass;
|
|
|
|
_buffPass = NULL;
|
|
_rsPass = NULL;
|
|
}
|
|
}
|
|
|
|
void RadianceScalingRendererPlugin::cleanFBOs()
|
|
{
|
|
if (_fbo != NULL)
|
|
{
|
|
delete _fbo;
|
|
delete _depthTex;
|
|
delete _gradTex;
|
|
delete _normTex;
|
|
delete _colorTex;
|
|
|
|
_fbo = NULL;
|
|
_depthTex = NULL;
|
|
_gradTex = NULL;
|
|
_normTex = NULL;
|
|
_colorTex = NULL;
|
|
}
|
|
}
|
|
|
|
MESHLAB_PLUGIN_NAME_EXPORTER(RadianceScalingRendererPlugin)
|