mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-15 17:14:39 +00:00
179 lines
5.5 KiB
C++
179 lines
5.5 KiB
C++
/****************************************************************************
|
|
* 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 "rfx_glpass.h"
|
|
|
|
RfxGLPass::~RfxGLPass()
|
|
{
|
|
if (shaderLinked)
|
|
glDeleteObjectARB(shaderProgram);
|
|
|
|
foreach (RfxState *state, rfxStates)
|
|
delete state;
|
|
rfxStates.clear();
|
|
|
|
foreach (RfxUniform *uniform, shaderUniforms)
|
|
delete uniform;
|
|
shaderUniforms.clear();
|
|
|
|
foreach (RfxSpecialAttribute *attribute, shaderSpecialAttributes)
|
|
delete attribute;
|
|
shaderSpecialAttributes.clear();
|
|
}
|
|
|
|
void RfxGLPass::SetShaderSource(const QString &source, bool isFragment)
|
|
{
|
|
if (isFragment)
|
|
frag = source;
|
|
else
|
|
vert = source;
|
|
}
|
|
|
|
void RfxGLPass::CompileAndLink()
|
|
{
|
|
if (frag.isEmpty() || vert.isEmpty()) {
|
|
compileLog = "OK (No sources)";
|
|
return;
|
|
}
|
|
|
|
GLubyte *ShaderSource;
|
|
GLint ShaderLen;
|
|
|
|
// compile vertex shader
|
|
ShaderSource = (GLubyte *)new char[vert.length() + 1];
|
|
memcpy(ShaderSource, vert.toLocal8Bit().data(), vert.length());
|
|
ShaderLen = (GLint) vert.length();
|
|
|
|
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
|
|
glShaderSource(vertShader, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
|
glCompileShader(vertShader);
|
|
|
|
delete[] ShaderSource;
|
|
ShaderSource = (GLubyte *)new char[frag.length() + 1];
|
|
memcpy(ShaderSource, frag.toLocal8Bit().data(), frag.length());
|
|
ShaderLen = (GLint) frag.length();
|
|
|
|
// compile fragment shader
|
|
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
glShaderSource(fragShader, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
|
glCompileShader(fragShader);
|
|
|
|
delete[] ShaderSource;
|
|
|
|
// attach shaders to program and link
|
|
shaderProgram = glCreateProgram();
|
|
glAttachShader(shaderProgram, vertShader);
|
|
glAttachShader(shaderProgram, fragShader);
|
|
glLinkProgram(shaderProgram);
|
|
|
|
GLint res;
|
|
glGetObjectParameterivARB(shaderProgram, GL_OBJECT_LINK_STATUS_ARB, &res);
|
|
if (!res) {
|
|
FillInfoLog(shaderProgram);
|
|
} else {
|
|
compileLog = "OK";
|
|
|
|
// shader link successful. update uniform locations
|
|
// and load textures
|
|
shaderLinked = true;
|
|
foreach (RfxUniform *uni, shaderUniforms) {
|
|
uni->LoadTexture();
|
|
uni->UpdateUniformLocation(shaderProgram);
|
|
}
|
|
}
|
|
}
|
|
|
|
void RfxGLPass::FillInfoLog(GLhandleARB obj)
|
|
{
|
|
GLint infologLength = 0;
|
|
GLsizei charsWritten = 0;
|
|
char *infoLog;
|
|
|
|
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength);
|
|
|
|
if (infologLength > 0) {
|
|
infoLog = new char[infologLength];
|
|
glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
|
|
|
|
compileLog = "FAILED\n";
|
|
compileLog.append(infoLog);
|
|
|
|
delete[] infoLog;
|
|
}
|
|
}
|
|
|
|
void RfxGLPass::Start()
|
|
{
|
|
// set gl states
|
|
foreach (RfxState *state, rfxStates)
|
|
state->SetEnvironment();
|
|
|
|
// if this pass has no glsl sources,
|
|
// keep using glsl program of the previous pass
|
|
if (!frag.isEmpty() && !vert.isEmpty()) {
|
|
|
|
glUseProgram(shaderProgram);
|
|
|
|
// pass uniforms
|
|
foreach (RfxUniform *uni, shaderUniforms) {
|
|
uni->PassToShader();
|
|
}
|
|
}
|
|
}
|
|
|
|
RfxUniform* RfxGLPass::getUniform(const QString& uniIdx)
|
|
{
|
|
foreach (RfxUniform *u, shaderUniforms) {
|
|
if (u->GetName() == uniIdx)
|
|
return u;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
Checks whether the actual mesh document contains the value needed to set up the value of the special attributes.
|
|
If not an alert message is shown and it returns false.
|
|
@param md the mesh document to test.
|
|
@return true if the mesh document contains all the value per vertex needed to set up the special attribute values, false otherwise.
|
|
*/
|
|
bool RfxGLPass::checkSpecialAttributeDataMask(MeshDocument* md){
|
|
QListIterator<RfxSpecialAttribute*> iterator = QListIterator<RfxSpecialAttribute*>(this->shaderSpecialAttributes);
|
|
|
|
RfxSpecialAttribute* spa;
|
|
|
|
while(iterator.hasNext()){
|
|
spa = iterator.next();
|
|
if(!md->mm()->hasDataMask(spa->getDataMask()))
|
|
{
|
|
QMessageBox msgBox;
|
|
msgBox.setIcon(QMessageBox::Warning);
|
|
msgBox.setWindowTitle("Attribute missed");
|
|
msgBox.setText(QString("The requested shader needs the model contains per %1 value").arg(spa->getDescription()));
|
|
int ret = msgBox.exec();
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|