mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-19 19:14:42 +00:00
renamed meshrender to the standard naming scheme render_gdp
This commit is contained in:
parent
26fd213e54
commit
dc62dcff09
@ -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)
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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();
|
||||
}
|
||||
@ -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
|
||||
@ -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>
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
Loading…
x
Reference in New Issue
Block a user