renamed meshrender to the standard naming scheme render_gdp

This commit is contained in:
Paolo Cignoni cignoni 2008-12-10 23:09:46 +00:00
parent 26fd213e54
commit dc62dcff09
9 changed files with 0 additions and 1353 deletions

View File

@ -1,528 +0,0 @@
/****************************************************************************
* MeshLab o o *
* A versatile mesh processing toolbox o o *
* _ O _ *
* Copyright(C) 2005 \/)\/ *
* 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. *
* *
****************************************************************************/
/****************************************************************************
History
$Log$
Revision 1.25 2008/04/04 14:16:05 cignoni
Solved namespace ambiguities caused by the removal of a silly 'using namespace' in meshmodel.h
Revision 1.24 2007/09/09 17:56:13 ldpmatic
Minor changes to avoid memory leak.
Added two glGetError() to avoid MeshLab to crash when the plugin encounters some error on its way
Revision 1.23 2007/03/12 15:24:00 cignoni
Safer dir search for plugins for mac
Revision 1.22 2007/02/28 00:02:57 cignoni
Added casts for mac compiling
Revision 1.21 2007/02/20 13:05:50 corsini
*** empty log message ***
Revision 1.20 2007/02/20 13:05:23 corsini
add log file for shader compilation and linking error
Revision 1.19 2006/12/24 22:46:34 cignoni
Corrected bug about a wrong glUniform1fARB (thanks Clement Menier!)
Revision 1.18 2006/05/26 04:09:52 cignoni
Still debugging 0.7
Revision 1.17 2006/05/25 04:57:45 cignoni
Major 0.7 release. A lot of things changed. Colorize interface gone away, Editing and selection start to work.
Optional data really working. Clustering decimation totally rewrote. History start to work. Filters organized in classes.
Revision 1.16 2006/03/08 17:26:13 ggangemi
added texture tab
Revision 1.15 2006/02/27 05:02:01 ggangemi
Added texture support
Revision 1.14 2006/02/25 13:44:45 ggangemi
Action "None" is now exported from MeshRenderPlugin
Revision 1.13 2006/02/21 17:26:38 ggangemi
RenderMode is now passed to MeshRender::Init()
Revision 1.11 2006/02/19 02:57:49 ggangemi
Now each shader can change the opengl status
Revision 1.10 2006/02/09 00:42:40 ggangemi
now GLArea is passed to the shaderDialog
Revision 1.9 2006/02/03 12:27:08 ggangemi
improved shaderDialog support
Revision 1.8 2006/01/25 16:58:05 ggangemi
shaderdialog closed every time the user changes the current shader
Revision 1.7 2006/01/25 02:59:38 ggangemi
added shadersDialog initial support
Revision 1.6 2005/12/24 04:18:46 ggangemi
Added generic .gdp shaders support
Revision 1.5 2005/12/05 18:11:28 ggangemi
Added toon shader example
Revision 1.4 2005/12/05 16:52:57 ggangemi
new interfaces
Revision 1.3 2005/12/03 22:50:06 cignoni
Added copyright info
****************************************************************************/
#include <QtGui>
#include <math.h>
#include <stdlib.h>
#include "meshrender.h"
#include <QGLWidget>
#include <QTextStream>
using namespace std;
using namespace vcg;
void MeshShaderRenderPlugin::initActionList() {
QAction * qaNone = new QAction("None", this);
qaNone->setCheckable(false);
actionList << qaNone;
QDir shadersDir = QDir(qApp->applicationDirPath());
#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){
if(shadersDir.exists("shaders")) break;
shadersDir.cdUp();
}
}
#endif
bool ret=shadersDir.cd("shaders");
if(!ret)
{
QMessageBox::information(0, "MeshLab",
"Unable to find the shaders directory.\n"
"No shaders will be loaded.");
}
qDebug("Shader directory found '%s', and it contains %i gdp files",qPrintable(shadersDir.path()),shadersDir.entryList(QStringList("*.gdp")).size());
QDomDocument doc;
foreach (QString fileName, shadersDir.entryList(QDir::Files)) {
if (fileName.endsWith(".gdp")) {
QFile file(shadersDir.absoluteFilePath(fileName));
if (file.open(QIODevice::ReadOnly)) {
if (doc.setContent(&file)) {
file.close();
QDomElement root = doc.documentElement();
if (root.nodeName() == tr("GLSLang")) {
ShaderInfo si;
QDomElement elem;
//Vertex program filename
elem = root.firstChildElement("VPCount");
if (!elem.isNull()) {
//first child of VPCount is "Filenames"
QDomNode child = elem.firstChild();
if (!child.isNull()) {
//first child of "Filenames" is "Filename0"
child = child.firstChild();
si.vpFile = shadersDir.absoluteFilePath((child.toElement()).attribute("VertexProgram", ""));
}
}
//Fragment program filename
elem = root.firstChildElement("FPCount");
if (!elem.isNull()) {
//first child of FPCount is "Filenames"
QDomNode child = elem.firstChild();
if (!child.isNull()) {
//first child of "Filenames" is "Filename0"
child = child.firstChild();
si.fpFile = shadersDir.absoluteFilePath((child.toElement()).attribute("FragmentProgram", ""));
}
}
//Uniform Variables
elem = root.firstChildElement("UniformVariables");
if (!elem.isNull()) {
QDomNode unif = elem.firstChild();
while( !unif.isNull() ) {
UniformVariable uv;
QDomElement unifElem = unif.toElement();
QString unifVarName = unifElem.attribute("Name", "");
uv.type = (unifElem.attribute("Type", "")).toInt();
uv.widget = (unifElem.attribute("Widget", "")).toInt();
uv.min = (unifElem.attribute("Min", "")).toFloat();
uv.max = (unifElem.attribute("Max", "")).toFloat();
uv.step = (unifElem.attribute("Step", "")).toFloat();
QDomNode unifElemValue = unifElem.firstChild();
if (!unifElemValue.isNull()) {
switch (uv.type)
{
case SINGLE_INT:
{
uv.ival[0] = unifElemValue.toElement().attribute("Value0", 0).toInt();
} break;
case SINGLE_FLOAT:
{
uv.fval[0] = unifElemValue.toElement().attribute("Value0", 0).toFloat();
} break;
case ARRAY_2_FLOAT:
{
uv.fval[0] = unifElemValue.toElement().attribute("Value0", 0).toFloat();
uv.fval[1] = unifElemValue.toElement().attribute("Value1", 0).toFloat();
} break;
case ARRAY_3_FLOAT:
{
uv.fval[0] = unifElemValue.toElement().attribute("Value0", 0).toFloat();
uv.fval[1] = unifElemValue.toElement().attribute("Value1", 0).toFloat();
uv.fval[2] = unifElemValue.toElement().attribute("Value2", 0).toFloat();
} break;
case ARRAY_4_FLOAT:
{
uv.fval[0] = unifElemValue.toElement().attribute("Value0", 0).toFloat();
uv.fval[1] = unifElemValue.toElement().attribute("Value1", 0).toFloat();
uv.fval[2] = unifElemValue.toElement().attribute("Value2", 0).toFloat();
uv.fval[3] = unifElemValue.toElement().attribute("Value3", 0).toFloat();
} break;
default:
{
} break;
}
si.uniformVars[unifVarName] = uv;
}
unif = unif.nextSibling();
}
}
//OpenGL Status
elem = root.firstChildElement("FragmentProcessor");
if (!elem.isNull()) {
if (elem.hasAttribute("Shade")) si.glStatus[SHADE] = elem.attribute("Shade", "0");
if (elem.hasAttribute("AlphaTest")) si.glStatus[ALPHA_TEST] = elem.attribute("AlphaTest", "False");
if (elem.hasAttribute("AlphaFunc")) si.glStatus[ALPHA_FUNC] = elem.attribute("AlphaFunc", "0");
if (elem.hasAttribute("AlphaClamp")) si.glStatus[ALPHA_CLAMP] = elem.attribute("AlphaClamp", "0");
if (elem.hasAttribute("Blending")) si.glStatus[BLENDING] = elem.attribute("Blending", "False");
if (elem.hasAttribute("BlendFuncSRC")) si.glStatus[BLEND_FUNC_SRC] = elem.attribute("BlendFuncSRC", "0");
if (elem.hasAttribute("BlendFuncDST")) si.glStatus[BLEND_FUNC_DST] = elem.attribute("BlendFuncDST", "0");
if (elem.hasAttribute("BlendEquation")) si.glStatus[BLEND_EQUATION] = elem.attribute("BlendEquation", "0");
if (elem.hasAttribute("DepthTest")) si.glStatus[DEPTH_TEST] = elem.attribute("DepthTest", "False");
if (elem.hasAttribute("DepthFunc")) si.glStatus[DEPTH_FUNC] = elem.attribute("DepthFunc", "0");
if (elem.hasAttribute("ClampNear")) si.glStatus[CLAMP_NEAR] = elem.attribute("ClampNear", "0");
if (elem.hasAttribute("ClampFar")) si.glStatus[CLAMP_FAR] = elem.attribute("ClampFar", "0");
if (elem.hasAttribute("ClearColorR")) si.glStatus[CLEAR_COLOR_R] = elem.attribute("ClearColorR", "0");
if (elem.hasAttribute("ClearColorG")) si.glStatus[CLEAR_COLOR_G] = elem.attribute("ClearColorG", "0");
if (elem.hasAttribute("ClearColorB")) si.glStatus[CLEAR_COLOR_B] = elem.attribute("ClearColorB", "0");
if (elem.hasAttribute("ClearColorA")) si.glStatus[CLEAR_COLOR_A] = elem.attribute("ClearColorA", "0");
}
//Textures
shadersDir.cdUp();
shadersDir.cd("textures");
elem = root.firstChildElement("TexturedUsed");
if (!elem.isNull()) {
QDomNode unif = elem.firstChild();
while( !unif.isNull() ) {
QDomElement unifElem = unif.toElement();
TextureInfo tInfo;
tInfo.path = shadersDir.absoluteFilePath((unifElem.attribute("Filename", "")));
tInfo.MinFilter = (unifElem.attribute("MinFilter", 0)).toInt();
tInfo.MagFilter = (unifElem.attribute("MagFilter", 0)).toInt();
tInfo.Target = (unifElem.attribute("Target", 0)).toInt();
tInfo.WrapS = (unifElem.attribute("WrapS", 0)).toInt();
tInfo.WrapT = (unifElem.attribute("WrapT", 0)).toInt();
tInfo.WrapR = (unifElem.attribute("WrapR", 0)).toInt();
si.textureInfo.push_back(tInfo);
unif = unif.nextSibling();
}
}
shadersDir.cdUp();
shadersDir.cd("shaders");
//End Textures
shaders[fileName] = si;
QAction * qa = new QAction(fileName, this);
qa->setCheckable(false);
actionList << qa;
}
} else {
file.close();
}
}
}
}
}
void MeshShaderRenderPlugin::Init(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget *gla)
{
if (sDialog) {
sDialog->close();
delete sDialog;
sDialog=0;
}
gla->makeCurrent();
GLenum err = glewInit();
if (GLEW_OK == err) {
if (GLEW_ARB_vertex_program && GLEW_ARB_fragment_program) {
supported = true;
if (shaders.find(a->text()) != shaders.end()) {
v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
char *fs = textFileRead((shaders[a->text()].fpFile).toLocal8Bit().data());
char *vs = textFileRead((shaders[a->text()].vpFile).toLocal8Bit().data());
const char * vv = vs;
const char * ff = fs;
glShaderSourceARB(v, 1, &vv, NULL);
glShaderSourceARB(f, 1, &ff, NULL);
free(fs);
free(vs);
glCompileShaderARB(v);
glCompileShaderARB(f);
GLint statusV;
GLint statusF;
glGetObjectParameterivARB(v, GL_OBJECT_COMPILE_STATUS_ARB, &statusV);
glGetObjectParameterivARB(f, GL_OBJECT_COMPILE_STATUS_ARB, &statusF);
if (statusF && statusV) { //successful compile
shaders[a->text()].shaderProg = glCreateProgramObjectARB();
glAttachObjectARB(shaders[a->text()].shaderProg,v);
glAttachObjectARB(shaders[a->text()].shaderProg,f);
glLinkProgramARB(shaders[a->text()].shaderProg);
GLint linkStatus;
glGetObjectParameterivARB(shaders[a->text()].shaderProg, GL_OBJECT_LINK_STATUS_ARB, &linkStatus);
if (linkStatus) {
map<QString, UniformVariable>::iterator i = shaders[a->text()].uniformVars.begin();
while (i != shaders[a->text()].uniformVars.end()) {
(shaders[a->text()].uniformVars[i->first]).location = glGetUniformLocationARB(shaders[a->text()].shaderProg, (i->first).toLocal8Bit().data());
++i;
}
}
else
{
QFile file("shaders.log");
if (file.open(QFile::Append))
{
char proglog[2048];
GLsizei length;
QTextStream out(&file);
glGetProgramiv(v, GL_LINK_STATUS, &statusV);
glGetProgramInfoLog(v, 2048, &length, proglog);
out << "VERTEX SHADER LINK INFO:" << endl;
out << proglog << endl << endl;
glGetProgramiv(f, GL_LINK_STATUS, &statusF);
glGetProgramInfoLog(f, 2048, &length, proglog);
out << "FRAGMENT SHADER LINK INFO:" << endl << endl;
out << proglog << endl << endl;
file.close();
}
QMessageBox::critical(0, "Meshlab",
QString("An error occurred during shader's linking.\n") +
"See shaders.log for further details about this error.\n");
}
//Textures
std::vector<TextureInfo>::iterator tIter = shaders[a->text()].textureInfo.begin();
while (tIter != shaders[a->text()].textureInfo.end()) {
glEnable(tIter->Target);
QImage img, imgScaled, imgGL;
img.load(tIter->path);
// image has to be scaled to a 2^n size. We choose the first 2^N <= picture size.
int bestW=pow(2.0,floor(::log(double(img.width() ))/::log(2.0)));
int bestH=pow(2.0,floor(::log(double(img.height()))/::log(2.0)));
imgScaled=img.scaled(bestW,bestH,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
imgGL=QGLWidget::convertToGLFormat(imgScaled);
glGenTextures( 1, &(tIter->tId) );
glBindTexture( tIter->Target, tIter->tId );
glTexImage2D( tIter->Target, 0, 3, imgGL.width(), imgGL.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imgGL.bits() );
glTexParameteri( tIter->Target, GL_TEXTURE_MIN_FILTER, tIter->MinFilter );
glTexParameteri( tIter->Target, GL_TEXTURE_MAG_FILTER, tIter->MagFilter );
glTexParameteri( tIter->Target, GL_TEXTURE_WRAP_S, tIter->WrapS );
glTexParameteri( tIter->Target, GL_TEXTURE_WRAP_T, tIter->WrapT );
glTexParameteri( tIter->Target, GL_TEXTURE_WRAP_R, tIter->WrapR );
++tIter;
}
sDialog = new ShaderDialog(&shaders[a->text()], gla, rm);
sDialog->move(10,100);
sDialog->show();
}
else
{
QFile file("shaders.log");
if (file.open(QFile::WriteOnly))
{
char shlog[2048];
GLsizei length;
QTextStream out(&file);
glGetShaderiv(v, GL_COMPILE_STATUS, &statusV);
glGetShaderInfoLog(v, 2048, &length, shlog);
out << "VERTEX SHADER COMPILE INFO:" << endl << endl;
out << shlog << endl << endl;
glGetShaderiv(f, GL_COMPILE_STATUS, &statusF);
glGetShaderInfoLog(f, 2048, &length, shlog);
out << "FRAGMENT SHADER COMPILE INFO:" << endl << endl;
out << shlog << endl << endl;
file.close();
}
QMessageBox::critical(0, "Meshlab",
QString("An error occurred during shader's compiling.\n"
"See shaders.log for further details about this error."));
}
}
}
}
// * clear the errors, if any
glGetError();
}
void MeshShaderRenderPlugin::Render(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget * /* gla */)
{
if (shaders.find(a->text()) != shaders.end()) {
ShaderInfo si = shaders[a->text()];
glUseProgramObjectARB(si.shaderProg);
map<QString, UniformVariable>::iterator i = si.uniformVars.begin();
while (i != si.uniformVars.end()) {
switch(i->second.type) {
case SINGLE_INT: {
glUniform1iARB(i->second.location, i->second.ival[0]);
} break;
case SINGLE_FLOAT: {
glUniform1fARB(i->second.location, i->second.fval[0]);
} break;
case ARRAY_2_FLOAT: {
glUniform2fARB(i->second.location, i->second.fval[0], i->second.fval[1]);
} break;
case ARRAY_3_FLOAT: {
glUniform3fARB(i->second.location, i->second.fval[0], i->second.fval[1], i->second.fval[2]);
} break;
case ARRAY_4_FLOAT: {
glUniform4fARB(i->second.location, i->second.fval[0], i->second.fval[1], i->second.fval[2], i->second.fval[3]);
} break;
default: {} break;
}
++i;
}
std::map<int, QString>::iterator j = si.glStatus.begin();
while (j != si.glStatus.end()) {
switch (j->first) {
case SHADE: glShadeModel(j->second.toInt()); break;
case ALPHA_TEST: if (j->second == "True") glEnable(GL_ALPHA_TEST); else glDisable(GL_ALPHA_TEST); break;
case ALPHA_FUNC: glAlphaFunc(j->second.toInt(), (si.glStatus[ALPHA_CLAMP]).toFloat()); break;
//case ALPHA_CLAMP: used in ALPHA_FUNC
case BLENDING: if (j->second == "True") glEnable(GL_BLEND); else glDisable(GL_BLEND); break;
case BLEND_FUNC_SRC: glBlendFunc(j->second.toInt(), (si.glStatus[BLEND_FUNC_DST]).toInt()); break;
//case BLEND_FUNC_DST: used in BLEND_FUNC_SRC
case BLEND_EQUATION: glBlendEquation(j->second.toInt()); break;
case DEPTH_TEST: if (j->second == "True") glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); break;
case DEPTH_FUNC: glDepthFunc(j->second.toInt()); break;
//case CLAMP_NEAR:
//case CLAMP_FAR:
case CLEAR_COLOR_R: glClearColor(j->second.toFloat(),
(si.glStatus[CLEAR_COLOR_G]).toFloat(),
(si.glStatus[CLEAR_COLOR_B]).toFloat(),
(si.glStatus[CLEAR_COLOR_A]).toFloat()); break;
//case CLEAR_COLOR_G: used in CLEAR_COLOR_R
//case CLEAR_COLOR_B: used in CLEAR_COLOR_R
//case CLEAR_COLOR_A: used in CLEAR_COLOR_R
}
++j;
}
int n = GL_TEXTURE0_ARB;
std::vector<TextureInfo>::iterator tIter = shaders[a->text()].textureInfo.begin();
while (tIter != shaders[a->text()].textureInfo.end()) {
glActiveTexture(n);
glEnable(tIter->Target);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture( tIter->Target, tIter->tId );
rm.textureMode = GLW::TMPerVert;
++tIter;
++n;
}
}
// * clear the errors, if any
glGetError();
}
Q_EXPORT_PLUGIN(MeshShaderRenderPlugin)

View File

@ -1,153 +0,0 @@
/****************************************************************************
* MeshLab o o *
* A versatile mesh processing toolbox o o *
* _ O _ *
* Copyright(C) 2005 \/)\/ *
* 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. *
* *
****************************************************************************/
/****************************************************************************
History
$Log$
Revision 1.22 2008/04/04 14:16:02 cignoni
Solved namespace ambiguities caused by the removal of a silly 'using namespace' in meshmodel.h
Revision 1.21 2007/10/09 13:02:08 fuscof
Initial implementation of multipass rendering.
Please note that MeshRenderInterface has been modified to get the number of rendering passes.
Revision 1.20 2006/07/08 06:37:48 cignoni
Many small bugs correction (esc crash, info in about, obj loading progress,fullscreen es)
Revision 1.19 2006/06/08 08:54:43 zifnab1974
Do not use classname in class definition
Revision 1.18 2006/05/25 04:57:45 cignoni
Major 0.7 release. A lot of things changed. Colorize interface gone away, Editing and selection start to work.
Optional data really working. Clustering decimation totally rewrote. History start to work. Filters organized in classes.
Revision 1.17 2006/02/27 05:02:01 ggangemi
Added texture support
Revision 1.16 2006/02/21 17:26:38 ggangemi
RenderMode is now passed to MeshRender::Init()
Revision 1.14 2006/02/19 02:57:49 ggangemi
Now each shader can change the opengl status
Revision 1.13 2006/02/03 12:27:08 ggangemi
improved shaderDialog support
Revision 1.12 2006/01/25 16:58:05 ggangemi
shaderdialog closed every time the user changes the current shader
Revision 1.11 2006/01/25 02:59:38 ggangemi
added shadersDialog initial support
Revision 1.10 2006/01/19 11:41:42 ggangemi
Reduced memory occupation of "UniformVariable" struct
Revision 1.9 2006/01/17 11:04:14 cignoni
Removed bug due to multiple creation of list of action
Revision 1.8 2005/12/29 13:52:31 mariolatronico
gl/glew.h -> GL/glew.h
Revision 1.7 2005/12/24 04:18:46 ggangemi
Added generic .gdp shaders support
Revision 1.6 2005/12/19 16:22:30 davide_portelli
Now "Toon Shader" plugin is checkable
Revision 1.5 2005/12/05 18:11:28 ggangemi
Added toon shader example
Revision 1.4 2005/12/05 16:52:57 ggangemi
new interfaces
Revision 1.3 2005/12/03 22:50:06 cignoni
Added copyright info
****************************************************************************/
#ifndef SHADERRENDERPLUGIN_H
#define SHADERRENDERPLUGIN_H
#include <QDir>
#include <QObject>
#include <QAction>
#include <QList>
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
#include <QtXml/QDomNode>
#include <QtXml/QDomNamedNodeMap>
#include <QFile>
#include <QString>
#include <QApplication>
#include <QMap>
#include <map>
#include <vector>
#include <QImage>
#include <GL/glew.h>
#include <meshlab/meshmodel.h>
#include <meshlab/interfaces.h>
#include "textfile.h"
#include "shaderStructs.h"
#include "shaderDialog.h"
class MeshShaderRenderPlugin : public QObject, public MeshRenderInterface
{
Q_OBJECT
Q_INTERFACES(MeshRenderInterface)
GLhandleARB v;
GLhandleARB f;
std::map<QString, ShaderInfo> shaders;
bool supported;
QList <QAction *> actionList;
ShaderDialog *sDialog;
public:
MeshShaderRenderPlugin()
{
supported = false;
sDialog = 0;
}
QList<QAction *> actions () {
if(actionList.isEmpty()) initActionList();
return actionList;
}
void initActionList();
virtual bool isSupported() {return supported;}
virtual void Init(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget *gla);
virtual void Render(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget *gla);
virtual int passNum() { return 1; } /* single pass rendering */
};
#endif

View File

@ -1,14 +0,0 @@
include (../../shared.pri)
HEADERS = meshrender.h textfile.h shaderStructs.h shaderDialog.h ../../meshlab/meshmodel.h
SOURCES = meshrender.cpp \
textfile.cpp \
shaderDialog.cpp \
$$GLEWCODE \
../../meshlab/meshmodel.cpp
TARGET = meshrender
FORMS = shaderDialog.ui
QT += opengl xml

View File

@ -1,352 +0,0 @@
#include "shaderDialog.h"
#include <QTextStream>
#include <QFileDialog>
#include <QMessageBox>
#define DECFACTOR 100000.0f
using namespace vcg;
ShaderDialog::ShaderDialog(ShaderInfo *sInfo, QGLWidget* gla, RenderMode &rm, QWidget *parent)
: QDockWidget(parent)
{
ui.setupUi(this);
this->setWidget(ui.frame);
this->setFeatures(QDockWidget::AllDockWidgetFeatures);
this->setAllowedAreas(Qt::LeftDockWidgetArea);
this->setFloating(true);
shaderInfo = sInfo;
glarea = gla;
rendMode = &rm;
colorSignalMapper = new QSignalMapper(this);
valueSignalMapper = new QSignalMapper(this);
QGridLayout * qgrid = new QGridLayout(ui.uvTab);
qgrid->setColumnMinimumWidth(0, 45);
qgrid->setColumnMinimumWidth(1, 40);
qgrid->setColumnMinimumWidth(2, 40);
qgrid->setColumnMinimumWidth(3, 40);
QLabel *perVertexColorLabel = new QLabel(this);
perVertexColorLabel->setText("Use PerVertex Color");
QCheckBox *perVertexColorCBox = new QCheckBox(this);
rendMode->colorMode = GLW::CMNone;
connect(perVertexColorCBox, SIGNAL(stateChanged(int)), this, SLOT(setColorMode(int)));
qgrid->addWidget(perVertexColorLabel, 0, 0);
qgrid->addWidget(perVertexColorCBox, 0, 1);
int row=1;
std::map<QString, UniformVariable>::iterator i;
for (i = shaderInfo->uniformVars.begin(); i != shaderInfo->uniformVars.end(); ++i) {
QLabel *varNameLabel = new QLabel(this);
varNameLabel->setObjectName(i->first+"_name");
varNameLabel->setText(i->first);
qgrid->addWidget(varNameLabel, row, 0);
int varNum = getVarsNumber(i->second.type);
switch (i->second.widget) {
case WIDGET_NONE: {
for (int j=0;j<varNum;++j) {
QLineEdit *qline = new QLineEdit(this);
qline->setAlignment(Qt::AlignRight);
qline->setObjectName(tr("%1%2").arg(i->first).arg(j));
if (i->second.type == SINGLE_INT) {
qline->setText(tr("%1").arg(i->second.ival[j]));
} else {
qline->setText(tr("%1").arg(i->second.fval[j]));
}
connect(qline, SIGNAL(textChanged(QString)), valueSignalMapper, SLOT(map()));
valueSignalMapper->setMapping(qline,tr("%1%2").arg(i->first).arg(j));
lineEdits[tr("%1%2").arg(i->first).arg(j)]=qline;
qgrid->addWidget(qline, row, j+1);
}
} break;
case WIDGET_COLOR : {
QPushButton * colorButton = new QPushButton(this);
colorButton->setText("Change");
connect(colorButton, SIGNAL(clicked()), colorSignalMapper, SLOT(map()));
colorSignalMapper->setMapping(colorButton,i->first);
qgrid->addWidget(colorButton, row, 1);
} break;
case WIDGET_SLIDER : {
for (int j=0;j<varNum;++j) {
QSlider *qslider = new QSlider(this);
qslider->setTickPosition(QSlider::NoTicks);
qslider->setOrientation(Qt::Horizontal);
qslider->setObjectName(tr("%1%2").arg(i->first).arg(j));
if (i->second.type == SINGLE_INT) {
qslider->setTickInterval(i->second.step);
qslider->setRange(i->second.min, i->second.max);
qslider->setValue(i->second.ival[j]);
} else {
qslider->setTickInterval(i->second.step*DECFACTOR);
qslider->setRange(i->second.min*DECFACTOR, i->second.max*DECFACTOR);
qslider->setValue(i->second.fval[j]*DECFACTOR);
}
connect(qslider, SIGNAL(valueChanged(int)), valueSignalMapper, SLOT(map()));
valueSignalMapper->setMapping(qslider,tr("%1%2").arg(i->first).arg(j));
sliders[tr("%1%2").arg(i->first).arg(j)]=qslider;
qgrid->addWidget(qslider, row, j+1);
}
} break;
}
++row;
}
connect(colorSignalMapper, SIGNAL(mapped(const QString &)), this, SLOT(setColorValue(const QString &)));
connect(valueSignalMapper, SIGNAL(mapped(const QString &)), this, SLOT(valuesChanged(const QString &)));
//Texture Tab Section
if (shaderInfo->textureInfo.size() > 0) {
textLineSignalMapper = new QSignalMapper(this);
textButtonSignalMapper = new QSignalMapper(this);
QGridLayout * qgridTexTab = new QGridLayout(ui.textureTab);
qgridTexTab->setColumnMinimumWidth(0, 45);
qgridTexTab->setColumnMinimumWidth(1, 40);
row = 0;
std::vector<TextureInfo>::iterator textIter;
for (textIter = shaderInfo->textureInfo.begin(); textIter != shaderInfo->textureInfo.end(); ++textIter) {
QLabel *textNameLabel = new QLabel(this);
QLineEdit *textValueEdit = new QLineEdit(this);
QPushButton * textButton = new QPushButton(this);
textButton->setText("Browse");
textNameLabel->setText(tr("Texture Unit %1:").arg(row));
textValueEdit->setText(textIter->path);
qgridTexTab->addWidget(textNameLabel, row, 0);
qgridTexTab->addWidget(textValueEdit, row, 1);
qgridTexTab->addWidget(textButton, row, 2);
connect(textValueEdit, SIGNAL(editingFinished()), textLineSignalMapper, SLOT(map()));
textLineSignalMapper->setMapping(textValueEdit,row);
connect(textButton, SIGNAL(clicked()), textButtonSignalMapper, SLOT(map()));
textButtonSignalMapper->setMapping(textButton,row);
textLineEdits.push_back(textValueEdit);
++row;
}
connect(textLineSignalMapper, SIGNAL(mapped(int)), this, SLOT(changeTexturePath(int)));
connect(textButtonSignalMapper, SIGNAL(mapped(int)), this, SLOT(browseTexturePath(int)));
}
//OpenGL Status Tab Section
QGridLayout * qgridGlStatus = new QGridLayout(ui.glTab);
qgridGlStatus->setColumnMinimumWidth(0, 45);
qgridGlStatus->setColumnMinimumWidth(1, 40);
row = 0;
std::map<int, QString>::iterator glIterator;
for (glIterator = shaderInfo->glStatus.begin(); glIterator != shaderInfo->glStatus.end(); ++glIterator) {
QLabel *glVarLabel = new QLabel(this);
QLabel *glValueLabel = new QLabel(this);
switch (glIterator->first) {
case SHADE: glVarLabel->setText("glShadeModel"); glValueLabel->setText(glIterator->second); ++row; break;
case ALPHA_TEST: glVarLabel->setText("GL_ALPHA_TEST"); glValueLabel->setText(glIterator->second); ++row; break;
case ALPHA_FUNC: glVarLabel->setText("glAlphaFunc"); glValueLabel->setText(glIterator->second + ", " + shaderInfo->glStatus[ALPHA_CLAMP]); ++row; break;
//case ALPHA_CLAMP: used in ALPHA_FUNC
case BLENDING: glVarLabel->setText("GL_BLEND"); glValueLabel->setText(glIterator->second); ++row; break;
case BLEND_FUNC_SRC: glVarLabel->setText("glBlendFunc"); glValueLabel->setText(glIterator->second + ", " + shaderInfo->glStatus[BLEND_FUNC_SRC]); ++row; break;
//case BLEND_FUNC_DST: used in BLEND_FUNC_SRC
case BLEND_EQUATION: glVarLabel->setText("glBlendEquation"); glValueLabel->setText(glIterator->second); ++row; break;
case DEPTH_TEST: glVarLabel->setText("GL_DEPTH_TEST"); glValueLabel->setText(glIterator->second); ++row; break;
case DEPTH_FUNC: glVarLabel->setText("glDepthFunc"); glValueLabel->setText(glIterator->second); ++row; break;
//case CLAMP_NEAR:
//case CLAMP_FAR:
case CLEAR_COLOR_R: glVarLabel->setText("glClearColor"); glValueLabel->setText(glIterator->second + ", " +
shaderInfo->glStatus[CLEAR_COLOR_G] + ", " +
shaderInfo->glStatus[CLEAR_COLOR_B] + ", " +
shaderInfo->glStatus[CLEAR_COLOR_A]); ++row; break;
//case CLEAR_COLOR_G: used in CLEAR_COLOR_R
//case CLEAR_COLOR_B: used in CLEAR_COLOR_R
//case CLEAR_COLOR_A: used in CLEAR_COLOR_R
}
qgridGlStatus->addWidget(glVarLabel, row, 0);
qgridGlStatus->addWidget(glValueLabel, row, 1);
}
//Vertex and Fragment Program Tabs Section
QFile qf;
QTextStream ts(&qf);
qf.setFileName(shaderInfo->vpFile);
if (!qf.open(QIODevice::ReadOnly | QIODevice::Text) )
QMessageBox::critical(this,"Opengl Shader" ,"unable to open file");
ui.vpTextBrowser->insertPlainText(ts.readAll());
qf.close();
qf.setFileName(shaderInfo->fpFile);
if (!qf.open(QIODevice::ReadOnly | QIODevice::Text) )
QMessageBox::critical(this,"Opengl Shader" ,"unable to open file");
ui.fpTextBrowser->insertPlainText(ts.readAll());
qf.close();
//End of Vertex and Fragment Program Tabs Section
// this->setWindowFlags(Qt::WindowStaysOnTopHint);
connect(ui.okButton, SIGNAL(clicked()), this, SLOT(accept()));
}
ShaderDialog::~ShaderDialog()
{
}
void ShaderDialog::setColorValue(const QString &varName)
{
QColor old;
if ( shaderInfo->uniformVars[varName].type == ARRAY_3_FLOAT) {
old.setRgbF(shaderInfo->uniformVars[varName].fval[0], shaderInfo->uniformVars[varName].fval[1], shaderInfo->uniformVars[varName].fval[2]);
} else if (shaderInfo->uniformVars[varName].type == ARRAY_4_FLOAT) {
old.setRgbF(shaderInfo->uniformVars[varName].fval[0], shaderInfo->uniformVars[varName].fval[1], shaderInfo->uniformVars[varName].fval[2], shaderInfo->uniformVars[varName].fval[3]);
}
QColor newColor = QColorDialog::getColor(old, this);
if (newColor.isValid()) {
shaderInfo->uniformVars[varName].fval[0] = newColor.redF();
shaderInfo->uniformVars[varName].fval[1] = newColor.greenF();
shaderInfo->uniformVars[varName].fval[2] = newColor.blueF();
if (shaderInfo->uniformVars[varName].type == ARRAY_4_FLOAT) {
shaderInfo->uniformVars[varName].fval[3] = newColor.alphaF();
}
}
glarea->updateGL();
}
void ShaderDialog::valuesChanged(const QString &varNameAndIndex) {
int varIndex = varNameAndIndex[varNameAndIndex.length()-1].digitValue();
QString varName = varNameAndIndex;
varName.chop(1);
int varWidget = shaderInfo->uniformVars[varName].widget;
int varType = shaderInfo->uniformVars[varName].type;
switch (varWidget) {
case WIDGET_NONE: {
QLineEdit * qline = lineEdits[varNameAndIndex];
if (varType == SINGLE_INT) {
shaderInfo->uniformVars[varName].ival[varIndex] = qline->text().toInt();
} else {
shaderInfo->uniformVars[varName].fval[varIndex] = qline->text().toFloat();
}
} break;
case WIDGET_SLIDER: {
QSlider * qslider = sliders[varNameAndIndex];
if (varType == SINGLE_INT) {
shaderInfo->uniformVars[varName].ival[varIndex] = qslider->value();
} else {
shaderInfo->uniformVars[varName].fval[varIndex] = qslider->value()/DECFACTOR;
}
} break;
}
glarea->updateGL();
}
void ShaderDialog::setColorMode(int state) {
if (state == Qt::Checked) {
rendMode->colorMode = GLW::CMPerVert;
} else {
rendMode->colorMode = GLW::CMNone;
}
glarea->updateGL();
}
void ShaderDialog::changeTexturePath(int i) {
shaderInfo->textureInfo[i].path = textLineEdits[i]->text();
reloadTexture(i);
}
void ShaderDialog::browseTexturePath(int i) {
QFileDialog fd(0,"Choose new texture");
QDir shadersDir = QDir(qApp->applicationDirPath());
#if defined(Q_OS_WIN)
if (shadersDir.dirName() == "debug" || shadersDir.dirName() == "release")
shadersDir.cdUp();
#elif defined(Q_OS_MAC)
if (shadersDir.dirName() == "MacOS") {
shadersDir.cdUp();
shadersDir.cdUp();
shadersDir.cdUp();
}
#endif
shadersDir.cd("textures");
fd.setDirectory(shadersDir);
fd.move(500, 100);
QStringList newPath;
if (fd.exec())
{
newPath = fd.selectedFiles();
textLineEdits[i]->setText(newPath.at(0));
shaderInfo->textureInfo[i].path = newPath.at(0);
reloadTexture(i);
}
}
void ShaderDialog::reloadTexture(int i) {
glDeleteTextures( 1, &shaderInfo->textureInfo[i].tId);
glEnable(shaderInfo->textureInfo[i].Target);
QImage img, imgScaled, imgGL;
img.load(shaderInfo->textureInfo[i].path);
// image has to be scaled to a 2^n size. We choose the first 2^N <= picture size.
int bestW=pow(2.0,floor(::log(double(img.width() ))/::log(2.0)));
int bestH=pow(2.0,floor(::log(double(img.height()))/::log(2.0)));
imgScaled=img.scaled(bestW,bestH,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
imgGL=QGLWidget::convertToGLFormat(imgScaled);
glGenTextures( 1, &(shaderInfo->textureInfo[i].tId) );
glBindTexture( shaderInfo->textureInfo[i].Target, shaderInfo->textureInfo[i].tId );
glTexImage2D( shaderInfo->textureInfo[i].Target, 0, 3, imgGL.width(), imgGL.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imgGL.bits() );
glTexParameteri( shaderInfo->textureInfo[i].Target, GL_TEXTURE_MIN_FILTER, shaderInfo->textureInfo[i].MinFilter );
glTexParameteri( shaderInfo->textureInfo[i].Target, GL_TEXTURE_MAG_FILTER, shaderInfo->textureInfo[i].MagFilter );
glTexParameteri( shaderInfo->textureInfo[i].Target, GL_TEXTURE_WRAP_S, shaderInfo->textureInfo[i].WrapS );
glTexParameteri( shaderInfo->textureInfo[i].Target, GL_TEXTURE_WRAP_T, shaderInfo->textureInfo[i].WrapT );
glTexParameteri( shaderInfo->textureInfo[i].Target, GL_TEXTURE_WRAP_R, shaderInfo->textureInfo[i].WrapR );
glarea->updateGL();
}

View File

@ -1,44 +0,0 @@
#ifndef SHADERDIALOG_H
#define SHADERDIALOG_H
#include <map>
#include <GL/glew.h>
#include <meshlab/meshmodel.h>
#include <QtGui>
#include <QGLWidget>
#include "shaderStructs.h"
#include "ui_shaderDialog.h"
class ShaderDialog : public QDockWidget
{
Q_OBJECT
public:
ShaderDialog(ShaderInfo *sInfo, QGLWidget* gla, RenderMode &rm, QWidget *parent = 0);
~ShaderDialog();
private:
QGLWidget* glarea;
RenderMode * rendMode;
ShaderInfo * shaderInfo;
QSignalMapper *colorSignalMapper;
QSignalMapper *valueSignalMapper;
QSignalMapper *textLineSignalMapper;
QSignalMapper *textButtonSignalMapper;
std::map<QString, QLabel*> labels;
std::map<QString, QSlider*> sliders;
std::vector<QLineEdit*> textLineEdits;
std::map<QString, QLineEdit*> lineEdits;
Ui::ShaderDialogClass ui;
private slots:
void valuesChanged(const QString &);
void setColorValue(const QString &);
void setColorMode(int);
void changeTexturePath(int);
void browseTexturePath(int);
void reloadTexture(int i);
};
#endif // SHADERDIALOG_H

View File

@ -1,103 +0,0 @@
<ui version="4.0" >
<class>ShaderDialogClass</class>
<widget class="QWidget" name="ShaderDialogClass" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>601</width>
<height>541</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="QFrame" name="frame" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QTabWidget" name="tabWidget" >
<property name="currentIndex" >
<number>3</number>
</property>
<widget class="QWidget" name="uvTab" >
<attribute name="title" >
<string>Uniform Variables</string>
</attribute>
<widget class="QWidget" name="varListLayer" >
<property name="geometry" >
<rect>
<x>10</x>
<y>20</y>
<width>171</width>
<height>20</height>
</rect>
</property>
<layout class="QHBoxLayout" />
</widget>
</widget>
<widget class="QWidget" name="textureTab" >
<attribute name="title" >
<string>Textures</string>
</attribute>
</widget>
<widget class="QWidget" name="glTab" >
<attribute name="title" >
<string>OpenGL Status</string>
</attribute>
</widget>
<widget class="QWidget" name="vpTab" >
<attribute name="title" >
<string>Vertex Program</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2" >
<item>
<widget class="QTextBrowser" name="vpTextBrowser" />
</item>
</layout>
</widget>
<widget class="QWidget" name="fpTab" >
<attribute name="title" >
<string>Fragment Program</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<widget class="QTextBrowser" name="fpTextBrowser" />
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="bottomRowLayout" >
<item>
<spacer name="spacer" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="okButton" >
<property name="text" >
<string>Close Shader</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,87 +0,0 @@
#ifndef SHDRSTRUCTS
#define SHDRSTRUCTS
#include <map>
#include <QString>
#include <vector>
struct UniformVariable {
short type;
short widget;
float min;
float max;
float step;
int location;
union {
int ival[4];
float fval[4];
};
};
struct TextureInfo {
QString path;
GLuint tId;
short MinFilter;
short MagFilter;
short Target;
short WrapS;
short WrapT;
short WrapR;
};
struct ShaderInfo {
QString vpFile;
QString fpFile;
std::map<QString, UniformVariable> uniformVars;
std::map<int, QString> glStatus;
std::vector<TextureInfo> textureInfo;
int shaderProg;
};
enum {
SINGLE_INT = 1,
SINGLE_FLOAT = 5,
ARRAY_2_FLOAT = 6,
ARRAY_3_FLOAT = 7,
ARRAY_4_FLOAT = 8
};
static int getVarsNumber(int i) {
switch (i) {
case SINGLE_INT: return 1; break;
case SINGLE_FLOAT: return 1; break;
case ARRAY_2_FLOAT: return 2; break;
case ARRAY_3_FLOAT: return 3; break;
case ARRAY_4_FLOAT: return 4; break;
default: return 0; break;
}
}
enum {
WIDGET_NONE = 0,
WIDGET_COLOR = 1,
WIDGET_SLIDER = 2
};
enum {
SHADE = 0,
ALPHA_TEST,
ALPHA_FUNC,
ALPHA_CLAMP,
BLENDING,
BLEND_FUNC_SRC,
BLEND_FUNC_DST,
BLEND_EQUATION,
DEPTH_TEST,
DEPTH_FUNC,
CLAMP_NEAR,
CLAMP_FAR,
CLEAR_COLOR_R,
CLEAR_COLOR_G,
CLEAR_COLOR_B,
CLEAR_COLOR_A
};
#endif

View File

@ -1,62 +0,0 @@
// textfile.cpp
//
// simple reading and writing for text files
//
// www.lighthouse3d.com
//
// You may use these functions freely.
// they are provided as is, and no warranties, either implicit,
// or explicit are given
//////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *textFileRead(char *fn) {
FILE *fp;
char *content = NULL;
int count=0;
if (fn != NULL) {
fp = fopen(fn,"rt");
if (fp != NULL) {
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
return content;
}
int textFileWrite(char *fn, char *s) {
FILE *fp;
int status = 0;
if (fn != NULL) {
fp = fopen(fn,"w");
if (fp != NULL) {
if (fwrite(s,sizeof(char),strlen(s),fp) == strlen(s))
status = 1;
fclose(fp);
}
}
return(status);
}

View File

@ -1,10 +0,0 @@
// textfile.h: interface for reading and writing text files
// www.lighthouse3d.com
//
// You may use these functions freely.
// they are provided as is, and no warranties, either implicit,
// or explicit are given
//////////////////////////////////////////////////////////////////////
char *textFileRead(char *fn);
int textFileWrite(char *fn, char *s);