/**************************************************************************** * 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 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 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&/*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&rm, QGLWidget *parent) { if(!activeShader) return; for(QMap::iterator it = rm.begin(); it != rm.end();++it) it.value().textureMode = vcg::GLW::TMPerWedge; for(shaderPass=0;shaderPassStart(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::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)