00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef SPLATRENDERER_H
00025 #define SPLATRENDERER_H
00026
00027 #include <QObject>
00028 #include <QTextStream>
00029 #include <QFile>
00030 #include <wrap/gl/trimesh.h>
00031 #include <wrap/gl/shaders.h>
00032 #include <wrap/gl/trimesh.h>
00033 #include <QGLFramebufferObject>
00034 #include <vcg/complex/complex.h>
00035 #define GL_TEST_ERR\
00036 {\
00037 GLenum eCode;\
00038 if((eCode=glGetError())!=GL_NO_ERROR)\
00039 std::cerr << "OpenGL error : " << gluErrorString(eCode) << " in " << __FILE__ << " : " << __LINE__ << std::endl;\
00040 }
00041
00042 class QGLFramebufferObject;
00043
00044
00045
00046
00047
00048 template <class MeshType>
00049 class SplatRenderer
00050 {
00051 bool mIsSupported;
00052 bool init_called;
00053
00054 enum {
00055 DEFERRED_SHADING_BIT = 0x000001,
00056 DEPTH_CORRECTION_BIT = 0x000002,
00057 OUTPUT_DEPTH_BIT = 0x000004,
00058 BACKFACE_SHADING_BIT = 0x000008,
00059 FLOAT_BUFFER_BIT = 0x000010
00060 };
00061 int mFlags;
00062 int mCachedFlags;
00063 int mRenderBufferMask;
00064 int mSupportedMask;
00065
00066
00067 int mBindedPass;
00068 GLuint mDummyTexId;
00069 bool mWorkaroundATI;
00070 bool mBuggedAtiBlending;
00071 GLuint mNormalTextureID;
00072 GLuint mDepthTextureID;
00073 ProgramVF mShaders[3];
00074 QString mShaderSrcs[6];
00075 QGLFramebufferObject* mRenderBuffer;
00076 float mCachedMV[16];
00077 float mCachedProj[16];
00078 GLint mCachedVP[4];
00079
00080 struct UniformParameters
00081 {
00082 float radiusScale;
00083 float preComputeRadius;
00084 float depthOffset;
00085 float oneOverEwaRadius;
00086 vcg::Point2f halfVp;
00087 vcg::Point3f rayCastParameter1;
00088 vcg::Point3f rayCastParameter2;
00089 vcg::Point2f depthParameterCast;
00090
00091 void loadTo(Program& prg);
00092 void update(float* mv, float* proj, GLint* vp);
00093 };
00094
00095 UniformParameters mParams;
00096
00097 QString loadSource(const QString& func,const QString& file);
00098 void configureShaders();
00099 void updateRenderBuffer();
00100 void enablePass(int n);
00101 void drawSplats(std::vector<MeshType*> & , vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm);
00102 void drawSplats(
00103 std::vector< std::vector<vcg::Point3f> * > & positions,
00104 std::vector< std::vector<vcg::Point3f> * > & normals,
00105 std::vector< std::vector<vcg::Point3<unsigned char> > * > & colors,
00106 std::vector<float> & radius,
00107 vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm);
00108
00109
00110 public:
00111
00112 void Clear();
00113 void Destroy();
00114 bool isSupported() {return mIsSupported;}
00115 void Init(QGLWidget *gla);
00116 void Render( std::vector<MeshType*> &meshes, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm);
00117
00118 void Render(
00119 std::vector< std::vector<vcg::Point3f> * > & positions,
00120 std::vector< std::vector<vcg::Point3f> * > & normals,
00121 std::vector< std::vector<vcg::Point3<unsigned char> > * > & colors,
00122 std::vector<float> & radius,
00123 vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm);
00124
00125 };
00126
00127 template <class MeshType>
00128 void SplatRenderer<MeshType>:: Destroy(){
00129 delete mRenderBuffer;
00130 mRenderBuffer = 0;
00131 glDeleteTextures(1,&mDepthTextureID);
00132 glDeleteTextures(1,&mNormalTextureID);
00133 for(int i = 0; i < 3; ++i)
00134 this->mShaders[i].prog.Del();
00135
00136 Clear();
00137 }
00138
00139 template <class MeshType>
00140 void SplatRenderer<MeshType>::Clear()
00141 {
00142 mNormalTextureID = 0;
00143 mDepthTextureID = 0;
00144 mIsSupported = false;
00145 mRenderBuffer = 0;
00146 mWorkaroundATI = false;
00147 mBuggedAtiBlending = false;
00148 mDummyTexId = 0;
00149
00150 mFlags = DEFERRED_SHADING_BIT | DEPTH_CORRECTION_BIT | FLOAT_BUFFER_BIT | OUTPUT_DEPTH_BIT;
00151 mCachedFlags = ~mFlags;
00152
00153 mRenderBufferMask = DEFERRED_SHADING_BIT | FLOAT_BUFFER_BIT;
00154
00155 init_called = false;
00156 }
00157
00158
00159 template <class MeshType>
00160 QString SplatRenderer<MeshType>::loadSource(const QString& func,const QString& filename)
00161 {
00162 QString res;
00163 QFile f(":/SplatRenderer/shaders/" + filename);
00164 if (!f.open(QFile::ReadOnly))
00165 {
00166 std::cerr << "failed to load shader file " << filename.toUtf8().data() << "\n";
00167 return res;
00168 }
00169 else qDebug("Succesfully loaded shader func '%s' in file '%s'",qPrintable(func),qPrintable(filename));
00170 QTextStream stream(&f);
00171 res = stream.readAll();
00172 f.close();
00173 res = QString("#define __%1__ 1\n").arg(func)
00174 + QString("#define %1 main\n").arg(func)
00175 + res;
00176 return res;
00177 }
00178 template <class MeshType>
00179 void SplatRenderer<MeshType>::configureShaders()
00180 {
00181 const char* passNames[3] = {"Visibility","Attribute","Finalization"};
00182 QString defines = "";
00183 if (mFlags & DEFERRED_SHADING_BIT)
00184 defines += "#define EXPE_DEFERRED_SHADING\n";
00185 if (mFlags & DEPTH_CORRECTION_BIT)
00186 defines += "#define EXPE_DEPTH_CORRECTION\n";
00187 if (mFlags & OUTPUT_DEPTH_BIT)
00188 defines += "#define EXPE_OUTPUT_DEPTH 1\n";
00189 if (mFlags & BACKFACE_SHADING_BIT)
00190 defines += "#define EXPE_BACKFACE_SHADING\n";
00191 if (mWorkaroundATI)
00192 defines += "#define EXPE_ATI_WORKAROUND\n";
00193
00194 QString shading =
00195 "vec4 meshlabLighting(vec4 color, vec3 eyePos, vec3 normal)"
00196 "{"
00197 " normal = normalize(normal);"
00198 " vec3 lightVec = normalize(gl_LightSource[0].position.xyz);"
00199 " vec3 halfVec = normalize( lightVec - normalize(eyePos) );"
00200 " float aux_dot = dot(normal,lightVec);"
00201 " float diffuseCoeff = clamp(aux_dot, 0.0, 1.0);"
00202 " float specularCoeff = aux_dot>0.0 ? clamp(pow(clamp(dot(halfVec, normal),0.0,1.0),gl_FrontMaterial.shininess), 0.0, 1.0) : 0.0;"
00203 " return vec4(color.rgb * ( gl_FrontLightProduct[0].ambient.rgb + diffuseCoeff * gl_FrontLightProduct[0].diffuse.rgb) + specularCoeff * gl_FrontLightProduct[0].specular.rgb, 1.0);"
00204 "}\n";
00205
00206 for (int k=0;k<3;++k)
00207 {
00208 QString vsrc = shading + defines + mShaderSrcs[k*2+0];
00209 QString fsrc = shading + defines + mShaderSrcs[k*2+1];
00210 mShaders[k].SetSources(mShaderSrcs[k*2+0]!="" ? vsrc.toUtf8().data() : 0,
00211 mShaderSrcs[k*2+1]!="" ? fsrc.toUtf8().data() : 0);
00212 mShaders[k].prog.Link();
00213 if (mShaderSrcs[k*2+0]!="")
00214 {
00215 std::string compileinfo = mShaders[k].vshd.InfoLog();
00216 if (compileinfo.size()>0)
00217 std::cout << "Vertex shader info (" << passNames[k] << ":\n" << compileinfo << "\n";
00218 }
00219 if (mShaderSrcs[k*2+1]!="")
00220 {
00221 std::string compileinfo = mShaders[k].fshd.InfoLog();
00222 if (compileinfo.size()>0)
00223 std::cout << "Fragment shader info (" << passNames[k] << ":\n" << compileinfo << "\n";
00224 }
00225 std::string linkinfo = mShaders[k].prog.InfoLog();
00226 if (linkinfo.size()>0)
00227 std::cout << "Link info (" << passNames[k] << ":\n" << linkinfo << "\n";
00228 }
00229 }
00230
00231 template <class MeshType>
00232 void SplatRenderer<MeshType>::Init(QGLWidget *gla)
00233 {
00234
00235 mIsSupported = true;
00236 gla->makeCurrent();
00237
00238 glewInit();
00239
00240 const char* rs = (const char*)glGetString(GL_RENDERER);
00241 QString rendererString("");
00242 if(rs)
00243 rendererString = QString(rs);
00244 mWorkaroundATI = rendererString.startsWith("ATI") || rendererString.startsWith("AMD");
00245
00246 mBuggedAtiBlending = rendererString.startsWith("ATI") || rendererString.startsWith("AMD");
00247
00248 if (mWorkaroundATI && mDummyTexId==0)
00249 {
00250 glActiveTexture(GL_TEXTURE0);
00251 glGenTextures(1,&mDummyTexId);
00252 glBindTexture(GL_TEXTURE_2D, mDummyTexId);
00253 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
00254 }
00255
00256
00257 mSupportedMask = DEPTH_CORRECTION_BIT | BACKFACE_SHADING_BIT;
00258 if (!QGLFramebufferObject::hasOpenGLFramebufferObjects ())
00259 {
00260 mIsSupported = false;
00261 return;
00262 }
00263 if (GLEW_ARB_texture_float)
00264 mSupportedMask |= FLOAT_BUFFER_BIT;
00265 else
00266 std::cout << "Splatting: warning floating point textures are not supported.\n";
00267
00268 if (GLEW_ARB_draw_buffers && (!mBuggedAtiBlending))
00269 mSupportedMask |= DEFERRED_SHADING_BIT;
00270 else
00271 std::cout << "Splatting: warning deferred shading is not supported.\n";
00272
00273 if (GLEW_ARB_shadow)
00274 mSupportedMask |= OUTPUT_DEPTH_BIT;
00275 else
00276 std::cerr << "Splatting: warning copy of the depth buffer is not supported.\n";
00277
00278 mFlags = mFlags & mSupportedMask;
00279
00280
00281 mShaderSrcs[0] = loadSource("VisibilityVP","Raycasting.glsl");
00282 mShaderSrcs[1] = loadSource("VisibilityFP","Raycasting.glsl");
00283 mShaderSrcs[2] = loadSource("AttributeVP","Raycasting.glsl");
00284 mShaderSrcs[3] = loadSource("AttributeFP","Raycasting.glsl");
00285 mShaderSrcs[4] = "";
00286 mShaderSrcs[5] = loadSource("Finalization","Finalization.glsl");
00287
00288
00289 mBindedPass = -1;
00290 GL_TEST_ERR
00291 }
00292
00293 template <class MeshType>
00294 void SplatRenderer<MeshType>::updateRenderBuffer()
00295 {
00296 if ( (!mRenderBuffer)
00297 || (mRenderBuffer->width()!=mCachedVP[2])
00298 || (mRenderBuffer->height()!=mCachedVP[3])
00299 || ( (mCachedFlags & mRenderBufferMask) != (mFlags & mRenderBufferMask) ))
00300 {
00301 delete mRenderBuffer;
00302 GLenum fmt = (mFlags&FLOAT_BUFFER_BIT) ? GL_RGBA16F_ARB : GL_RGBA;
00303 mRenderBuffer = new QGLFramebufferObject(mCachedVP[2], mCachedVP[3],
00304 (mFlags&OUTPUT_DEPTH_BIT) ? QGLFramebufferObject::NoAttachment : QGLFramebufferObject::Depth,
00305 GL_TEXTURE_RECTANGLE_ARB, fmt);
00306
00307 if (!mRenderBuffer->isValid())
00308 {
00309 std::cout << "SplatRenderer: invalid FBO\n";
00310 }
00311
00312 GL_TEST_ERR
00313 if (mFlags&DEFERRED_SHADING_BIT)
00314 {
00315
00316 if (mNormalTextureID==0)
00317 glGenTextures(1,&mNormalTextureID);
00318 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID);
00319 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0);
00320 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00321 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00322 mRenderBuffer->bind();
00323 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID, 0);
00324 mRenderBuffer->release();
00325 GL_TEST_ERR
00326 }
00327
00328 if (mFlags&OUTPUT_DEPTH_BIT)
00329 {
00330
00331
00332 if (mDepthTextureID==0)
00333 glGenTextures(1,&mDepthTextureID);
00334 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID);
00335 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24_ARB, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
00336 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00337 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00338 mRenderBuffer->bind();
00339 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID, 0);
00340 mRenderBuffer->release();
00341 GL_TEST_ERR
00342 }
00343 }
00344 }
00345
00346
00347 template <class MeshType>
00348 void SplatRenderer<MeshType>::Render(std::vector<MeshType*> & meshes, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm )
00349 {
00350 if(meshes.empty()) return;
00351
00352 GL_TEST_ERR
00353
00354
00355
00356 glGetIntegerv(GL_VIEWPORT, mCachedVP);
00357 glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV);
00358 glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj);
00359
00360 updateRenderBuffer();
00361 if (mCachedFlags != mFlags)
00362 configureShaders();
00363
00364 mCachedFlags = mFlags;
00365
00366 mParams.update(mCachedMV, mCachedProj, mCachedVP);
00367
00368
00369
00370 float s = 1.f;
00371 mParams.radiusScale *= s;
00372
00373
00374 glDisable(GL_COLOR_MATERIAL);
00375 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64);
00376 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, vcg::Point4f(0.3, 0.3, 0.3, 1.).V());
00377 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vcg::Point4f(0.6, 0.6, 0.6, 1.).V());
00378 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, vcg::Point4f(0.5, 0.5, 0.5, 1.).V());
00379
00380 mRenderBuffer->bind();
00381 if (mFlags&DEFERRED_SHADING_BIT)
00382 {
00383 GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT};
00384 glDrawBuffersARB(2, buf);
00385 }
00386 glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]);
00387 glClearColor(0,0,0,0);
00388 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00389
00390
00391 mParams.loadTo(mShaders[0].prog);
00392 enablePass(0);
00393 drawSplats(meshes,cm,tm);
00394
00395
00396 mParams.loadTo(mShaders[1].prog);
00397 enablePass(1);
00398
00399 drawSplats(meshes,cm,tm);
00400
00401
00402
00403
00404 mRenderBuffer->release();
00405 if (mFlags&DEFERRED_SHADING_BIT)
00406 glDrawBuffer(GL_BACK);
00407
00408 enablePass(2);
00409
00410
00411 glMatrixMode(GL_PROJECTION);
00412 glPushMatrix();
00413 glLoadIdentity();
00414 glMatrixMode(GL_MODELVIEW);
00415 glPushMatrix();
00416 glLoadIdentity();
00417
00418 mShaders[2].prog.Uniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3]));
00419 mShaders[2].prog.Uniform("ColorWeight",GLint(0));
00420 glActiveTexture(GL_TEXTURE0);
00421 glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture());
00422
00423 if (mFlags&DEFERRED_SHADING_BIT)
00424 {
00425 mShaders[2].prog.Uniform("unproj", mCachedProj[10], mCachedProj[14]);
00426 mShaders[2].prog.Uniform("NormalWeight",GLint(1));
00427 glActiveTexture(GL_TEXTURE1);
00428 glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID);
00429 GL_TEST_ERR
00430 }
00431
00432 if (mFlags&OUTPUT_DEPTH_BIT)
00433 {
00434 mShaders[2].prog.Uniform("Depth",GLint(2));
00435 glActiveTexture(GL_TEXTURE2);GL_TEST_ERR
00436 glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID);GL_TEST_ERR
00437 GL_TEST_ERR
00438 }
00439 else
00440 {
00441 glDisable(GL_DEPTH_TEST);
00442 glDepthMask(GL_FALSE);
00443 }
00444
00445
00446 vcg::Point3f viewVec(1./mCachedProj[0], 1./mCachedProj[5], -1);
00447
00448 glBegin(GL_QUADS);
00449 glColor3f(1, 0, 0);
00450 glTexCoord3f(viewVec.X(),viewVec.Y(),viewVec.Z());
00451 glMultiTexCoord2f(GL_TEXTURE1,1.,1.);
00452 glVertex3f(1,1,0);
00453
00454 glColor3f(1, 1, 0);
00455 glTexCoord3f(-viewVec.X(),viewVec.Y(),viewVec.Z());
00456 glMultiTexCoord2f(GL_TEXTURE1,0.,1.);
00457 glVertex3f(-1,1,0);
00458
00459 glColor3f(0, 1, 1);
00460 glTexCoord3f(-viewVec.X(),-viewVec.Y(),viewVec.Z());
00461 glMultiTexCoord2f(GL_TEXTURE1,0.,0.);
00462 glVertex3f(-1,-1,0);
00463
00464 glColor3f(1, 0, 1);
00465 glTexCoord3f(viewVec.X(),-viewVec.Y(),viewVec.Z());
00466 glMultiTexCoord2f(GL_TEXTURE1,1.,0.);
00467 glVertex3f(1,-1,0);
00468 glEnd();
00469 if (!(mFlags&OUTPUT_DEPTH_BIT))
00470 {
00471 glEnable(GL_DEPTH_TEST);
00472 glDepthMask(GL_TRUE);
00473 }
00474
00475 glUseProgram(0);
00476
00477
00478 glMatrixMode(GL_PROJECTION);
00479 glPopMatrix();
00480 glMatrixMode(GL_MODELVIEW);
00481 glPopMatrix();
00482
00483 GL_TEST_ERR
00484
00485 }
00486
00487
00488 template <class MeshType>
00489 void SplatRenderer<MeshType>::Render(
00490 std::vector< std::vector<vcg::Point3f> * > & positions,
00491 std::vector< std::vector<vcg::Point3f> * > & normals,
00492 std::vector< std::vector<vcg::Point3<unsigned char> > * > & colors,
00493 std::vector<float> & radius, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm )
00494 {
00495 if(positions.empty()) return;
00496
00497 GL_TEST_ERR
00498
00499
00500
00501 glGetIntegerv(GL_VIEWPORT, mCachedVP);
00502 glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV);
00503 glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj);
00504
00505 updateRenderBuffer();
00506 if (mCachedFlags != mFlags)
00507 configureShaders();
00508
00509 mCachedFlags = mFlags;
00510
00511 mParams.update(mCachedMV, mCachedProj, mCachedVP);
00512
00513
00514
00515 float s = 1.f;
00516 mParams.radiusScale *= s;
00517
00518
00519 glDisable(GL_COLOR_MATERIAL);
00520 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64);
00521 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, vcg::Point4f(0.3, 0.3, 0.3, 1.).V());
00522 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vcg::Point4f(0.6, 0.6, 0.6, 1.).V());
00523 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, vcg::Point4f(0.5, 0.5, 0.5, 1.).V());
00524
00525 mRenderBuffer->bind();
00526 if (mFlags&DEFERRED_SHADING_BIT)
00527 {
00528 GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT};
00529 glDrawBuffersARB(2, buf);
00530 }
00531 glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]);
00532 glClearColor(0,0,0,0);
00533 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00534
00535
00536 mParams.loadTo(mShaders[0].prog);
00537 enablePass(0);
00538 drawSplats(positions,normals,colors,radius,cm,tm);
00539
00540
00541 mParams.loadTo(mShaders[1].prog);
00542 enablePass(1);
00543
00544 drawSplats(positions,normals,colors,radius,cm,tm);
00545
00546
00547
00548
00549 mRenderBuffer->release();
00550 if (mFlags&DEFERRED_SHADING_BIT)
00551 glDrawBuffer(GL_BACK);
00552
00553 enablePass(2);
00554
00555
00556 glMatrixMode(GL_PROJECTION);
00557 glPushMatrix();
00558 glLoadIdentity();
00559 glMatrixMode(GL_MODELVIEW);
00560 glPushMatrix();
00561 glLoadIdentity();
00562
00563 mShaders[2].prog.Uniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3]));
00564 mShaders[2].prog.Uniform("ColorWeight",GLint(0));
00565 glActiveTexture(GL_TEXTURE0);
00566 glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture());
00567
00568 if (mFlags&DEFERRED_SHADING_BIT)
00569 {
00570 mShaders[2].prog.Uniform("unproj", mCachedProj[10], mCachedProj[14]);
00571 mShaders[2].prog.Uniform("NormalWeight",GLint(1));
00572 glActiveTexture(GL_TEXTURE1);
00573 glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID);
00574 GL_TEST_ERR
00575 }
00576
00577 if (mFlags&OUTPUT_DEPTH_BIT)
00578 {
00579 mShaders[2].prog.Uniform("Depth",GLint(2));
00580 glActiveTexture(GL_TEXTURE2);GL_TEST_ERR
00581 glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID);GL_TEST_ERR
00582 GL_TEST_ERR
00583 }
00584 else
00585 {
00586 glDisable(GL_DEPTH_TEST);
00587 glDepthMask(GL_FALSE);
00588 }
00589
00590
00591 vcg::Point3f viewVec(1./mCachedProj[0], 1./mCachedProj[5], -1);
00592
00593 glBegin(GL_QUADS);
00594 glColor3f(1, 0, 0);
00595 glTexCoord3f(viewVec.X(),viewVec.Y(),viewVec.Z());
00596 glMultiTexCoord2f(GL_TEXTURE1,1.,1.);
00597 glVertex3f(1,1,0);
00598
00599 glColor3f(1, 1, 0);
00600 glTexCoord3f(-viewVec.X(),viewVec.Y(),viewVec.Z());
00601 glMultiTexCoord2f(GL_TEXTURE1,0.,1.);
00602 glVertex3f(-1,1,0);
00603
00604 glColor3f(0, 1, 1);
00605 glTexCoord3f(-viewVec.X(),-viewVec.Y(),viewVec.Z());
00606 glMultiTexCoord2f(GL_TEXTURE1,0.,0.);
00607 glVertex3f(-1,-1,0);
00608
00609 glColor3f(1, 0, 1);
00610 glTexCoord3f(viewVec.X(),-viewVec.Y(),viewVec.Z());
00611 glMultiTexCoord2f(GL_TEXTURE1,1.,0.);
00612 glVertex3f(1,-1,0);
00613 glEnd();
00614 if (!(mFlags&OUTPUT_DEPTH_BIT))
00615 {
00616 glEnable(GL_DEPTH_TEST);
00617 glDepthMask(GL_TRUE);
00618 }
00619
00620 glUseProgram(0);
00621
00622
00623 glMatrixMode(GL_PROJECTION);
00624 glPopMatrix();
00625 glMatrixMode(GL_MODELVIEW);
00626 glPopMatrix();
00627
00628 GL_TEST_ERR
00629
00630 }
00631 #if 0
00632 void SplatRenderer::Draw(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget * gla)
00633 {
00634 if (m.vert.RadiusEnabled)
00635 {
00636 if (mCurrentPass==2)
00637 return;
00638
00639 enablePass(mCurrentPass);
00640 drawSplats(m, rm);
00641 }
00642 else if (mCurrentPass==2)
00643 {
00644 MeshRenderInterface::Draw(a, m, rm, gla);
00645 }
00646 }
00647 #endif
00648 template <class MeshType>
00649 void SplatRenderer<MeshType>::enablePass(int n)
00650 {
00651 if (mBindedPass!=n)
00652 {
00653 if (mBindedPass>=0)
00654 mShaders[mBindedPass].prog.Unbind();
00655 mShaders[n].prog.Bind();
00656 mBindedPass = n;
00657
00658
00659 if (n==0)
00660 {
00661 glDisable(GL_LIGHTING);
00662
00663 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
00664
00665 glAlphaFunc(GL_LESS,1);
00666 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00667 glDepthMask(GL_TRUE);
00668 glDisable(GL_BLEND);
00669 glEnable(GL_ALPHA_TEST);
00670 glEnable(GL_DEPTH_TEST);
00671
00672
00673
00674
00675 }
00676 if (n==1)
00677 {
00678 glDisable(GL_LIGHTING);
00679 glEnable(GL_POINT_SMOOTH);
00680 glActiveTexture(GL_TEXTURE0);
00681 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
00682
00683 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00684 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE,GL_ONE);
00685
00686
00687 glDepthMask(GL_FALSE);
00688 glEnable(GL_BLEND);
00689 glEnable(GL_DEPTH_TEST);
00690 glDisable(GL_ALPHA_TEST);
00691
00692
00693
00694 }
00695 if ( (n==0) || (n==1) )
00696 {
00697
00698 glActiveTexture(GL_TEXTURE0);
00699 if (mWorkaroundATI)
00700 {
00701 glBindTexture(GL_TEXTURE_2D, mDummyTexId);
00702 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
00703 glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
00704
00705 }
00706 glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
00707 glEnable(GL_POINT_SPRITE_ARB);
00708 }
00709 if (n==2)
00710 {
00711 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00712 glDepthMask(GL_TRUE);
00713 glDisable(GL_LIGHTING);
00714 glDisable(GL_BLEND);
00715 }
00716 }
00717 }
00718
00719
00720 template <class MeshType>
00721 void SplatRenderer<MeshType>::drawSplats(
00722 std::vector< std::vector<vcg::Point3f> * > & positions,
00723 std::vector< std::vector<vcg::Point3f> * > & normals,
00724 std::vector< std::vector<vcg::Point3<unsigned char> > * > & colors,
00725 std::vector<float> & radius,
00726 vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm)
00727 {
00728 for(unsigned int ii = 0; ii < positions.size();++ii)
00729 {
00730
00731 glBegin(GL_POINTS);
00732 glMultiTexCoord1f(GL_TEXTURE2, radius[ii] );
00733
00734 for(unsigned int vi= 0;vi< positions[ii]->size() ;++vi){
00735 vcg::Point3<unsigned char> co = (*colors[ii])[vi];
00736 glColor3ub ( co[0],co[1],co[2]);
00737 glNormal((*normals[ii])[vi]);
00738 glVertex( (*positions[ii])[vi]);
00739 }
00740 glEnd();
00741 }
00742 }
00743
00744
00745 template <class MeshType>
00746 void SplatRenderer<MeshType>::drawSplats(std::vector<MeshType*> & meshes, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm)
00747 {
00748
00749
00750 if(meshes.empty()) return;
00751 int nV = 0;
00752
00753
00754
00755
00756 const int IMMEDIATE_MODE_THR = 0;
00757
00758 unsigned int ii = 0;
00759 for(; ii < meshes.size();++ii){
00760 nV+=meshes[ii]->vn;
00761 if((nV>IMMEDIATE_MODE_THR) || (meshes[ii]->vn!=(int) meshes[ii]->vert.size()))
00762 break;
00763 }
00764 bool immediatemode = ii<meshes.size() ;
00765
00766
00767 if(immediatemode){
00768 for(unsigned int ii = 0; ii < meshes.size();++ii)
00769 {
00770 MeshType & m = *meshes[ii];
00771
00772
00773 if( (cm == vcg::GLW::CMPerFace) && (!vcg::tri::HasPerFaceColor( m)) )
00774 cm=vcg::GLW::CMNone;
00775 glPushMatrix();
00776 glMultMatrix( m.Tr);
00777 typename MeshType::VertexIterator vi;
00778 glBegin(GL_POINTS);
00779 if(cm==vcg::GLW::CMPerMesh)
00780 glColor( m.C());
00781
00782
00783 for(vi= m.vert.begin();vi!= m.vert.end();++vi)
00784 if(!(*vi).IsD())
00785 {
00786 glMultiTexCoord1f(GL_TEXTURE2, (*vi).cR());
00787 glNormal((*vi).cN());
00788 if (cm==vcg::GLW::CMPerVert) glColor((*vi).C());
00789 glVertex((*vi).P());
00790 }
00791 glEnd();
00792 glPopMatrix();
00793
00794 }
00795 return;
00796 }
00797
00798 for(unsigned int ii = 0; ii < meshes.size();++ii){
00799 MeshType & m = *meshes[ii];
00800
00801 glClientActiveTexture(GL_TEXTURE2);
00802 glTexCoordPointer(
00803 1,
00804 GL_FLOAT,
00805 size_t(&m.vert[1].R())-size_t(&m.vert[0].R()),
00806 &m.vert[0].R()
00807 );
00808 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00809 glClientActiveTexture(GL_TEXTURE0);
00810
00811
00812 vcg::GlTrimesh<MeshType> glw;
00813 glw.m = &m;
00814 glw.Draw(vcg::GLW::DMPoints,cm,tm);
00815
00816 glClientActiveTexture(GL_TEXTURE2);
00817 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00818 glClientActiveTexture(GL_TEXTURE0);
00819 }
00820 }
00821
00822 template <class MeshType>
00823 void SplatRenderer<MeshType>::UniformParameters::update(float* mv, float* proj, GLint* vp)
00824 {
00825
00826 float scale = vcg::Point3f(mv[0],mv[1],mv[2]).Norm();
00827
00828 radiusScale = scale;
00829 preComputeRadius = - std::max(proj[0]*vp[2], proj[5]*vp[3]);
00830 depthOffset = 2.0;
00831 oneOverEwaRadius = 0.70710678118654;
00832 halfVp = vcg::Point2f(0.5*vp[2], 0.5*vp[3]);
00833 rayCastParameter1 =vcg::Point3f(2./(proj[0]*vp[2]), 2./(proj[5]*vp[3]), 0.0);
00834 rayCastParameter2 =vcg::Point3f(-1./proj[0], -1./proj[5], -1.0);
00835 depthParameterCast = vcg::Point2f(0.5*proj[14], 0.5-0.5*proj[10]);
00836 }
00837 template <class MeshType>
00838 void SplatRenderer <MeshType>::UniformParameters::loadTo(Program& prg)
00839 {
00840 prg.Bind();
00841 prg.Uniform("expeRadiusScale",radiusScale);
00842 prg.Uniform("expePreComputeRadius",preComputeRadius);
00843 prg.Uniform("expeDepthOffset",depthOffset);
00844 prg.Uniform("oneOverEwaRadius",oneOverEwaRadius);
00845 prg.Uniform("halfVp",halfVp);
00846 prg.Uniform("rayCastParameter1",rayCastParameter1);
00847 prg.Uniform("rayCastParameter2",rayCastParameter2);
00848 prg.Uniform("depthParameterCast",depthParameterCast);
00849 }
00850
00851 #endif
00852