- Introducing rendering to multiple render targets. In order to allow more vertices to be processed by the hardware, MRTs became a necessity. In this way we can multiply by 4 or even by 8 (GF 8xxx +) the maximum number of vertices processed.

- Texture size for vertices and normals are choosen automatically, picking the smallest one possible in order to greatly speeding up the calculations.
- Max textures size is now 2048 for a couple of reasons..
- Small bugs fixed
This commit is contained in:
Paolo Cignoni cignoni 2008-02-09 17:55:19 +00:00
parent a56d55418b
commit 41df01263f
3 changed files with 202 additions and 107 deletions

View File

@ -24,7 +24,8 @@ AOGLWidget::AOGLWidget (QWidget * parent, AmbientOcclusionPlugin *_plugin) :QGLW
void AOGLWidget::initializeGL ()
{
plugin->initGL(cb);
plugin->initGL(cb,m->cm.vn);
setFixedSize(plugin->maxTexSize,plugin->maxTexSize);
}

View File

@ -20,6 +20,18 @@
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log$
Revision 1.27 2008/02/09 17:55:19 mischitelli
- Introducing rendering to multiple render targets. In order to allow more vertices to be processed by the hardware, MRTs became a necessity. In this way we can multiply by 4 or even by 8 (GF 8xxx +) the maximum number of vertices processed.
- Texture size for vertices and normals are choosen automatically, picking the smallest one possible in order to greatly speeding up the calculations.
- Max textures size is now 2048 for a couple of reasons..
- Small bugs fixed
****************************************************************************/
@ -54,7 +66,7 @@
#include "AOGLWidget.h"
#include <iostream>
#define AMBOCC_MAX_TEXTURE_SIZE 4096
#define AMBOCC_MAX_TEXTURE_SIZE 2048
#define AMBOCC_DEFAULT_TEXTURE_SIZE 512
#define AMBOCC_DEFAULT_NUM_VIEWS 128
#define AMBOCC_USEGPU_BY_DEFAULT false
@ -73,6 +85,7 @@ AmbientOcclusionPlugin::AmbientOcclusionPlugin()
numViews = AMBOCC_DEFAULT_NUM_VIEWS;
depthTexSize = AMBOCC_DEFAULT_TEXTURE_SIZE;
depthTexArea = depthTexSize*depthTexSize;
maxTexSize = 16;
}
AmbientOcclusionPlugin::~AmbientOcclusionPlugin()
@ -131,24 +144,27 @@ void AmbientOcclusionPlugin::initParameterSet(QAction *action, MeshModel &m, Fil
}
bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshModel &m, FilterParameterSet & par, vcg::CallBackPos *cb)
{
assert(filter->text() == filterName(FP_AMBIENT_OCCLUSION));
useGPU = par.getBool("useGPU");
useVBO = par.getBool("useVBO");
depthTexSize = par.getInt("depthTexSize");
depthTexArea = depthTexSize*depthTexSize;
numViews = par.getInt("reqViews");
errInit = false;
AOGLWidget *qWidget = new AOGLWidget(0,this);
qWidget->cb = cb;
qWidget->m = &m;
qWidget->show(); //Ugly, but HAVE to be shown in order for it to work!
return true;
return !errInit;
}
bool AmbientOcclusionPlugin::processGL(AOGLWidget *aogl, MeshModel &m, vcg::CallBackPos *cb)
{
if (errInit)
return false;
checkGLError::qDebug("start");
int tInitElapsed = 0;
QTime tInit, tAll;
@ -212,16 +228,15 @@ bool AmbientOcclusionPlugin::processGL(AOGLWidget *aogl, MeshModel &m, vcg::Call
// FIRST PASS - fill depth buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboDepth);
glBindTexture(GL_TEXTURE_2D, depthBufferTex);
//glBindTexture(GL_TEXTURE_2D, depthBufferTex); ///// non dovrebbe servire a na mazza
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(0, 0, 0, 0);
renderMesh(m);
glColorMask(1, 1, 1, 1);
glViewport(0,0,maxTexSize,maxTexSize);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboResult);
glViewport(0,0,maxTexSize,maxTexSize);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE); //final.rgba = min(2^31, src.rgba*1 + dest.rgba*1);
@ -267,18 +282,21 @@ bool AmbientOcclusionPlugin::processGL(AOGLWidget *aogl, MeshModel &m, vcg::Call
{
glDisable(GL_BLEND);
glDetachObjectARB(fboDepth, depthBufferTex);
glDetachObjectARB(fboResult, resultBufferTex);
glUseProgram(0);
glDeleteFramebuffersEXT(1, &fboDepth);
glDeleteFramebuffersEXT(1, &fboResult);
glDeleteTextures(1, &vertexCoordTex);
glDeleteTextures(1, &vertexNormalsTex);
glDeleteTextures(1, &resultBufferTex);
glDeleteTextures(numTexPages, resultBufferTex);
glDetachShader(shdrID, vs);
glDetachShader(shdrID, fs);
glDeleteShader(shdrID);
glDeleteShader(shdrID); //executes but gives INVALID_OPERATION ( ?!?!? )
delete [] resultBufferTex;
delete [] resultBufferMRT;
}
glDeleteTextures(1, &depthBufferTex);
@ -289,10 +307,7 @@ bool AmbientOcclusionPlugin::processGL(AOGLWidget *aogl, MeshModel &m, vcg::Call
delete [] occlusion;
return true;
} // end processGL
}
void AmbientOcclusionPlugin::renderMesh(MeshModel &m)
{
m.glw.DrawFill<vcg::GLW::NMNone, vcg::GLW::CMNone, vcg::GLW::TMNone>();
@ -300,49 +315,61 @@ void AmbientOcclusionPlugin::renderMesh(MeshModel &m)
void AmbientOcclusionPlugin::initTextures(GLenum colorFormat, GLenum depthFormat)
{
vertexCoordTex = 0;
unsigned int potTexSize = 0;
vertexCoordTex = 0;
vertexNormalsTex = 0;
resultBufferTex= 0;
glEnable( GL_TEXTURE_2D );
resultBufferTex = new GLuint[numTexPages];
//**** find nearest POT size for numTexPages in order to use it as depth size in 3D Textures ****/
for (potTexSize=1; potTexSize<numTexPages; potTexSize*=2);
//*******INIT VERTEX COORDINATES TEXTURE*********/
glGenTextures (1, &vertexCoordTex);
glBindTexture(GL_TEXTURE_2D, vertexCoordTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, colorFormat,
maxTexSize, maxTexSize, 0, GL_RGBA, GL_FLOAT, 0);
//*******INIT NORMAL VECTORS TEXTURE*********/
glGenTextures (1, &vertexNormalsTex);
glBindTexture(GL_TEXTURE_2D, vertexNormalsTex);
glGenTextures (numTexPages, resultBufferTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//*******INIT VERTEX COORDINATES TEXTURE - 3D *********/
glBindTexture(GL_TEXTURE_3D, vertexCoordTex);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, colorFormat,
maxTexSize, maxTexSize, 0, GL_RGBA, GL_FLOAT, 0);
glTexImage3D(GL_TEXTURE_3D, 0, colorFormat,
maxTexSize, maxTexSize, potTexSize, 0, GL_RGBA, GL_FLOAT, 0);
//*******INIT RESULT TEXTURE*********/
glGenTextures (1, &resultBufferTex);
glBindTexture(GL_TEXTURE_2D, resultBufferTex);
//*******INIT NORMAL VECTORS TEXTURE - 3D *********/
glBindTexture(GL_TEXTURE_3D, vertexNormalsTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, colorFormat,
maxTexSize, maxTexSize, 0, GL_RGBA, GL_FLOAT, 0);
glTexImage3D(GL_TEXTURE_3D, 0, colorFormat,
maxTexSize, maxTexSize, potTexSize, 0, GL_RGBA, GL_FLOAT, 0);
//*******INIT RESULT TEXTURE - 2D Array *********/
for (unsigned int i=0; i<numTexPages; ++i)
{
glBindTexture(GL_TEXTURE_2D, resultBufferTex[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, colorFormat,
maxTexSize, maxTexSize, 0, GL_RGBA, GL_FLOAT, 0);
}
//*******INIT DEPTH TEXTURE*********/
glGenTextures(1, &depthBufferTex);
@ -363,25 +390,26 @@ void AmbientOcclusionPlugin::initTextures(GLenum colorFormat, GLenum depthFormat
glBindTexture(GL_TEXTURE_2D, 0);
}
// Called by the initgl of the aoglwidget
bool AmbientOcclusionPlugin::initGL(vcg::CallBackPos *cb)
void AmbientOcclusionPlugin::initGL(vcg::CallBackPos *cb, unsigned int numVertices)
{
glGetIntegerv(GL_MAX_TEXTURE_SIZE, reinterpret_cast<GLint*>(&maxTexSize) );
qDebug("max tex size: %d\n",maxTexSize);
maxTexSize = std::min(maxTexSize, (unsigned int)AMBOCC_MAX_TEXTURE_SIZE);
//cb(0, "Initializing: Glew");
//*******INIT GLEW********/
//cb(0, "Initializing: Glew");
GLint glewError = glewInit();
if (glewError)
{
Log(0,(const char*)glewGetErrorString(glewError));
return false;
errInit = true;
return;
}
//*******QUERY HARDWARE FOR: MAX TEX SIZE********/
glGetIntegerv(GL_MAX_TEXTURE_SIZE, reinterpret_cast<GLint*>(&maxTexSize) );
maxTexSize = std::min(maxTexSize, (unsigned int)AMBOCC_MAX_TEXTURE_SIZE);
//*******QUERY HARDWARE FOR: MAX NUMBER OF MRTs *********/
unsigned int maxTexPages=1;
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, reinterpret_cast<GLint*>(&maxTexPages) );
//*******CHECK TEX SIZE********/
if (depthTexSize < 16)
{
Log(0, "Texture size is too small, 16x16 used instead");
@ -394,9 +422,17 @@ bool AmbientOcclusionPlugin::initGL(vcg::CallBackPos *cb)
depthTexSize = maxTexSize;
depthTexArea = depthTexSize*depthTexSize;
}
if ((maxTexSize*maxTexSize*maxTexPages) < numVertices && useGPU)
{
Log(0, "That's a really huge model, I can't handle it in hardware, sorry..");
errInit = true;
return;
}
//*******SET DEFAULT OPENGL STUFF**********/
glEnable( GL_DEPTH_TEST );
glEnable( GL_TEXTURE_2D );
glEnable( GL_TEXTURE_3D_EXT );
//*******CHECK THAT EVERYTHING IS SUPPORTED**********/
@ -405,28 +441,49 @@ bool AmbientOcclusionPlugin::initGL(vcg::CallBackPos *cb)
if ( !GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader )
{
Log(0, "Your hardware doesn't support Shaders, which are required for hw occlusion");
return false;
errInit = true;
return;
}
if ( !GLEW_EXT_framebuffer_object )
{
Log(0, "Your hardware doesn't support FBOs, which are required for hw occlusion");
return false;
errInit = true;
return;
}
if ( !GLEW_ARB_texture_float )
{
Log(0,"Your hardware doesn't support FP16/32 textures, which are required for hw occlusion");
return false;
errInit = true;
return;
}
//cb(10, "Initializing: Textures");
//GL_RGBA32/16F_ARB works on nv40+(GeForce6 or newer) and ATI hardware
initTextures(GL_RGBA32F_ARB, GL_DEPTH_COMPONENT);
//*******FIND BEST COMPROMISE BETWEEN TEX SIZE AND MRTs********/
unsigned int smartTexSize;
for (smartTexSize=64; (smartTexSize*smartTexSize) < (numVertices/maxTexPages); smartTexSize*=2 );
if (smartTexSize > maxTexSize)
{
//should ever enter this point, just exit with error
Log(0,"There was an error while determining best texture size, unable to continue");
errInit = true;
return;
}
maxTexSize = smartTexSize;
numTexPages = std::min( (numVertices / (smartTexSize*smartTexSize))+1, maxTexPages);
resultBufferTex = new GLuint[numTexPages];
resultBufferMRT = new GLenum[numTexPages];
//*******LOAD SHADER*******/
//cb(30, "Initializing: Shaders");
set_shaders("ambient_occlusion",vs,fs,shdrID);
//*******INIT TEXTURES **********/
//GL_RGBA32/16F_ARB works on nv40+(GeForce6 or newer) and ATI hardware
initTextures(GL_RGBA32F_ARB, GL_DEPTH_COMPONENT);
//*******INIT FBO*********/
//cb(60, "Initializing: FBOs");
@ -440,7 +497,10 @@ bool AmbientOcclusionPlugin::initGL(vcg::CallBackPos *cb)
glReadBuffer(GL_NONE);
if (!checkFramebuffer())
return false;
{
errInit = true;
return;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
@ -448,11 +508,19 @@ bool AmbientOcclusionPlugin::initGL(vcg::CallBackPos *cb)
fboResult = 0;
glGenFramebuffersEXT(1, &fboResult); // FBO for second pass (1 color attachment)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboResult);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, resultBufferTex, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
for (unsigned int i=0; i<numTexPages; ++i)
{
resultBufferMRT[i] = GL_COLOR_ATTACHMENT0_EXT+i;
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_2D, resultBufferTex[i], 0);
}
glDrawBuffers(numTexPages, resultBufferMRT);
if (!checkFramebuffer())
return false;
{
errInit = true;
return;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
@ -460,8 +528,6 @@ bool AmbientOcclusionPlugin::initGL(vcg::CallBackPos *cb)
glViewport(0.0, 0.0, depthTexSize, depthTexSize);
//cb(100, "Initializing: Done.");
return true;
}
bool AmbientOcclusionPlugin::checkFramebuffer()
@ -503,8 +569,11 @@ bool AmbientOcclusionPlugin::checkFramebuffer()
void AmbientOcclusionPlugin::vertexCoordsToTexture(MeshModel &m)
{
GLfloat *vertexPosition= new GLfloat[maxTexSize*maxTexSize*4];
GLfloat *vertexNormals = new GLfloat[maxTexSize*maxTexSize*4];
unsigned int texSize = maxTexSize*maxTexSize*numTexPages*4;
GLfloat *vertexPosition= new GLfloat[texSize];
GLfloat *vertexNormals = new GLfloat[texSize];
vcg::Point3<CMeshO::ScalarType> vn;
//Copies each vertex's position and normal in new vectors
for (int i=0; i < m.cm.vn; ++i)
@ -516,25 +585,23 @@ void AmbientOcclusionPlugin::vertexCoordsToTexture(MeshModel &m)
vertexPosition[i*4+3] = 1.0;
//Normal vector for each vertex
vcg::Point3<CMeshO::ScalarType> n = m.cm.vert[i].N();
vertexNormals[i*4+0] = n.X();
vertexNormals[i*4+1] = n.Y();
vertexNormals[i*4+2] = n.Z();
vn = m.cm.vert[i].N();
vertexNormals[i*4+0] = vn.X();
vertexNormals[i*4+1] = vn.Y();
vertexNormals[i*4+2] = vn.Z();
vertexNormals[i*4+3] = 1.0;
}
//The aforementioned vectors are used to encode a texture that stores each vertex's position & normal
//Those texture are then used to perform a GPU occlusion test with each view's depth buffer
//Write vertex coordinates
glBindTexture(GL_TEXTURE_2D, vertexCoordTex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, maxTexSize, maxTexSize, GL_RGBA, GL_FLOAT, vertexPosition);
delete [] vertexPosition;
glBindTexture(GL_TEXTURE_3D_EXT, vertexCoordTex);
glTexSubImage3D(GL_TEXTURE_3D_EXT, 0, 0, 0, 0, maxTexSize, maxTexSize, numTexPages, GL_RGBA, GL_FLOAT, vertexPosition);
//Write normal directions
glBindTexture(GL_TEXTURE_2D, vertexNormalsTex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, maxTexSize, maxTexSize, GL_RGBA, GL_FLOAT, vertexNormals);
glBindTexture(GL_TEXTURE_3D_EXT, vertexNormalsTex);
glTexSubImage3D(GL_TEXTURE_3D_EXT, 0, 0, 0, 0, maxTexSize, maxTexSize, numTexPages, GL_RGBA, GL_FLOAT, vertexNormals);
delete [] vertexNormals;
delete [] vertexPosition;
}
void AmbientOcclusionPlugin::setCamera(Point3f camDir, Box3f &meshBBox)
@ -590,12 +657,12 @@ void AmbientOcclusionPlugin::generateOcclusionHW()
// Set vertex position texture
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, vertexCoordTex);
glBindTexture(GL_TEXTURE_3D_EXT, vertexCoordTex);
glUniform1i(glGetUniformLocation(shdrID, "vTexture"), 1);
// Set vertex normal texture
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, vertexNormalsTex);
glBindTexture(GL_TEXTURE_3D_EXT, vertexNormalsTex);
glUniform1i(glGetUniformLocation(shdrID, "nTexture"), 2);
// Set view direction
@ -604,6 +671,9 @@ void AmbientOcclusionPlugin::generateOcclusionHW()
// Set ModelView-Projection Matrix
glUniformMatrix4fv(glGetUniformLocation(shdrID, "mvprMatrix"), 1, GL_FALSE, (const GLfloat*)mv_pr_Matrix_f);
// Set total number of texture pages
glUniform1i(glGetUniformLocation(shdrID, "numTexPages"), numTexPages);
// Set texture Size
glUniform1i(glGetUniformLocation(shdrID, "texSize"), depthTexSize);
@ -650,10 +720,12 @@ void AmbientOcclusionPlugin::generateOcclusionSW(MeshModel &m, GLfloat *occlusio
int x = floor(resCoords[0]);
int y = floor(resCoords[1]);
vn = m.cm.vert[i].N();
if (resCoords[2] <= (GLdouble)dFloat[depthTexSize*y+x])
{
vn = m.cm.vert[i].N();
//vn = m.cm.vert[i].N();
occlusion[i] += max(vn*cameraDir, 0.0f);
}
}
@ -662,30 +734,45 @@ void AmbientOcclusionPlugin::generateOcclusionSW(MeshModel &m, GLfloat *occlusio
}
void AmbientOcclusionPlugin::applyOcclusionHW(MeshModel &m)
{
GLfloat *result = new GLfloat[maxTexSize*maxTexSize*4];
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, maxTexSize, maxTexSize, GL_RGBA, GL_FLOAT, result);
const unsigned int maxmax = maxTexSize*maxTexSize;
GLfloat *result = new GLfloat[maxmax*4];
unsigned int nVert=0;
float maxvalue = 0.0f, minvalue = 100000.0f;
for (int i=0; i < m.cm.vn; i++)
{
if (result[i*4] < minvalue)
minvalue = result[i*4];
if (result[i*4] > maxvalue)
maxvalue = result[i*4];
for (unsigned int n=0; n<numTexPages; ++n)
{
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT+n);
glReadPixels(0, 0, maxTexSize, maxTexSize, GL_RGBA, GL_FLOAT, result); //usare GL_RED
nVert = ( n+1 == numTexPages) ? (m.cm.vn % maxmax) : maxmax;
for (unsigned int i = 0; i < nVert; i++)
{
if (result[i*4] < minvalue)
minvalue = result[i*4];
if (result[i*4] > maxvalue)
maxvalue = result[i*4];
m.cm.vert[maxmax*n+i].Q() = result[i*4];
}
}
float scale = 255.0f / (maxvalue - minvalue);
char scaledValue = 0;
for (int i = 0; i < m.cm.vn; i++)
{
m.cm.vert[i].Q() = result[i*4+0];
m.cm.vert[i].C()[0] = (m.cm.vert[i].Q() - minvalue) * scale;
m.cm.vert[i].C()[1] = (m.cm.vert[i].Q() - minvalue) * scale;
m.cm.vert[i].C()[2] = (m.cm.vert[i].Q() - minvalue) * scale;
}
scaledValue = (char)((m.cm.vert[i].Q() - minvalue) * scale);
m.cm.vert[i].C()[0] = scaledValue;
m.cm.vert[i].C()[1] = scaledValue;
m.cm.vert[i].C()[2] = scaledValue;
}
delete [] result;
}
@ -790,7 +877,8 @@ void AmbientOcclusionPlugin::dumpFloatTexture(QString filename, float *texdata,
for (int i=0; i<elems; ++i)
cdata[i] = (unsigned char)(texdata[i]*255.0);
FILE *f=fopen(reinterpret_cast<char*>(filename.data()) ,"wb+");
FILE *f;
fopen_s(&f, reinterpret_cast<char*>(filename.data()) ,"wb+");
fwrite(cdata,sizeof(unsigned char),elems,f);
fclose(f);

View File

@ -38,22 +38,27 @@ class AmbientOcclusionPlugin : public QObject, public MeshFilterInterface
Q_INTERFACES(MeshFilterInterface)
// Attributes
public:
protected:
Point3f cameraDir;
GLuint fboDepth,
fboResult,
depthBufferTex,
vertexCoordTex,
vertexNormalsTex,
resultBufferTex;
*resultBufferTex;
GLenum *resultBufferMRT;
unsigned int numViews,
depthTexSize,
depthTexArea,
maxTexSize;
numTexPages;
bool useGPU,
useVBO;
useVBO,
errInit;
public:
unsigned int maxTexSize;
// Methods
public:
@ -77,7 +82,8 @@ public:
vcg::CallBackPos * cb) ;
void initTextures (GLenum colorFormat,
GLenum depthFormat);
bool initGL (vcg::CallBackPos *cb);
void initGL (vcg::CallBackPos *cb,
unsigned int numVertices);
bool processGL (AOGLWidget *glw,
MeshModel &m,
vcg::CallBackPos *cb);