2020-10-21 17:24:01 +02:00

220 lines
6.2 KiB
C++
Executable File

/****************************************************************************
* 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 "render_rfx.h"
#include <common/pluginmanager.h>
RenderRFX::RenderRFX()
{
shadersSupported = false;
shaderPass = -1;
totPass = -1;
dialog = NULL;
activeShader = NULL;
}
RenderRFX::~RenderRFX()
{
if (dialog) {
dialog->close();
delete dialog;
}
foreach (QAction *a, actionList)
delete a;
actionList.clear();
}
QList<QAction*> RenderRFX::actions()
{
if (actionList.isEmpty())
initActionList();
return actionList;
}
void RenderRFX::initActionList()
{
QDir shadersDir = PluginManager::getBaseDirPath();
#if defined(Q_OS_WIN)
if (shadersDir.dirName() == "debug" ||
shadersDir.dirName() == "release" ||
shadersDir.dirName() == "plugins")
shadersDir.cdUp();
#elif defined(Q_OS_MAC)
if (shadersDir.dirName() == "MacOS") {
for (int i = 0; i < 6; ++i) {
shadersDir.cdUp();
if (shadersDir.exists("shadersrm"))
break;
}
}
#endif
if (!shadersDir.cd("shaders/shadersrm")) {
QMessageBox::information(0, "MeshLab",
"Unable to find the render monkey "
"shaders directory.\n"
"No shaders will be loaded.");
return;
}
shaderDir = shadersDir.path();
qDebug("Shader directory found '%s', and it contains %i rfx files",
qPrintable(shadersDir.path()),
shadersDir.entryList(QStringList("*.rfx")).size());
// validate each .rfx file found and add to actionList
// (this is actually just a sanity check, shaders created are deleted immediately)
foreach (QString fileName, shadersDir.entryList(QDir::Files)) {
if (fileName.endsWith(".rfx")) {
RfxParser theParser(shadersDir.absoluteFilePath(fileName));
if (theParser.isValidDoc()) {
QAction *action = new QAction(fileName, this);
action->setCheckable(false);
actionList.append(action);
delete theParser.GetShader();
}
}
}
}
void RenderRFX::Init(QAction *action, MeshDocument &md, QMap<int,RenderMode>&/*rmode*/, QGLWidget *parent)
{
if (!actionList.contains(action))
{
shadersSupported = false;
return;
}
if (activeShader) {
delete activeShader;
activeShader = NULL;
}
// parse shader file we're going to use
RfxParser theParser(QDir(shaderDir).absoluteFilePath(action->text()));
// Small hack that allow to use the current mesh textures for the shaders.
foreach(MeshModel * mp, md.meshList)
{
if(mp->cm.textures.size()>0)
{
QFileInfo meshBaseDir(mp->fullName());
theParser.setMeshTexture(meshBaseDir.absolutePath()+"/"+QString(mp->cm.textures[0].c_str()));
}
}
theParser.Parse(md);
RfxShader *tmp = theParser.GetShader();
//activeShader = theParser.GetShader();
//assert(activeShader);
if (dialog) {
dialog->close();
delete dialog;
}
//verifies if there's some special attributes in the shader.
if(!tmp->checkSpecialAttributeDataMask(&md))
{
if (activeShader) {
delete activeShader;
activeShader = NULL;
}
shadersSupported = false;
return;
}
activeShader = tmp;
parent->makeCurrent();
GLenum err = glewInit();
if (GLEW_OK == err) {
if (GLEW_ARB_vertex_program && GLEW_ARB_fragment_program) {
shadersSupported = true;
activeShader->CompileAndLink();
totPass = activeShader->GetTotalPasses();
shaderPass = 0;
dialog = new RfxDialog(activeShader, action, parent);
dialog->move(0, 100);
dialog->show();
}
}
glGetError();
}
void RenderRFX::Render(QAction *action, MeshDocument &md, QMap<int,RenderMode>&rm, QGLWidget *parent)
{
if(!activeShader) return;
for(QMap<int,RenderMode>::iterator it = rm.begin(); it != rm.end();++it)
it.value().textureMode = vcg::GLW::TMPerWedge;
for(shaderPass=0;shaderPass<totPass;shaderPass++)
{
activeShader->Start(shaderPass);
glGetError();
foreach(MeshModel * mp, md.meshList)
{
if(mp->visible && activeShader->GetPass(shaderPass)->hasSpecialAttribute()){
GLuint *program = activeShader->GetPass(shaderPass)->getProgram();
Draw(&md, program, activeShader->GetPass(shaderPass)->AttributesList());
}
else{
QMap<int,RenderMode>::const_iterator it = rm.find(mp->id());
if ((mp->visible) && (it != rm.end()))
mp->render(it.value().drawMode,it.value().colorMode,it.value().textureMode);
}
}
}
glUseProgramObjectARB(0);
}
void RenderRFX::Finalize(QAction * /*act*/, MeshDocument */*md*/, GLArea */*gla*/)
{
// close any open dialog
if (dialog) {
dialog->close();
delete dialog;
dialog = NULL;
}
// ... and delete any active shader
if (activeShader) {
delete activeShader;
activeShader = NULL;
}
}
MESHLAB_PLUGIN_NAME_EXPORTER(RenderRFX)