CudaVisualModel.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_GPU_CUDA_CUDAVISUALMODEL_INL
00026 #define SOFA_GPU_CUDA_CUDAVISUALMODEL_INL
00027 
00028 #include "CudaVisualModel.h"
00029 #include <sofa/helper/gl/template.h>
00030 
00031 namespace sofa
00032 {
00033 
00034 namespace gpu
00035 {
00036 
00037 namespace cuda
00038 {
00039 
00040 extern "C"
00041 {
00042 void CudaVisualModelCuda3f_calcTNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x);
00043 void CudaVisualModelCuda3f_calcQNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x);
00044 void CudaVisualModelCuda3f_calcVNormals(unsigned int nbElem, unsigned int nbVertex, unsigned int nbElemPerVertex, const void* velems, void* vnormals, const void* fnormals, const void* x);
00045 
00046 void CudaVisualModelCuda3f1_calcTNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x);
00047 void CudaVisualModelCuda3f1_calcQNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x);
00048 void CudaVisualModelCuda3f1_calcVNormals(unsigned int nbElem, unsigned int nbVertex, unsigned int nbElemPerVertex, const void* velems, void* vnormals, const void* fnormals, const void* x);
00049 
00050 
00051 } // extern "C"
00052 
00053 template<>
00054 class CudaKernelsCudaVisualModel<CudaVec3fTypes>
00055 {
00056 public:
00057     static void calcTNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x)
00058     {   CudaVisualModelCuda3f_calcTNormals(nbElem, nbVertex, elems, fnormals, x); }
00059     static void calcQNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x)
00060     {   CudaVisualModelCuda3f_calcQNormals(nbElem, nbVertex, elems, fnormals, x); }
00061     static void calcVNormals(unsigned int nbElem, unsigned int nbVertex, unsigned int nbElemPerVertex, const void* velems, void* vnormals, const void* fnormals, const void* x)
00062     {   CudaVisualModelCuda3f_calcVNormals(nbElem, nbVertex, nbElemPerVertex, velems, vnormals, fnormals, x); }
00063 };
00064 
00065 template<>
00066 class CudaKernelsCudaVisualModel<CudaVec3f1Types>
00067 {
00068 public:
00069     static void calcTNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x)
00070     {   CudaVisualModelCuda3f1_calcTNormals(nbElem, nbVertex, elems, fnormals, x); }
00071     static void calcQNormals(unsigned int nbElem, unsigned int nbVertex, const void* elems, void* fnormals, const void* x)
00072     {   CudaVisualModelCuda3f1_calcQNormals(nbElem, nbVertex, elems, fnormals, x); }
00073     static void calcVNormals(unsigned int nbElem, unsigned int nbVertex, unsigned int nbElemPerVertex, const void* velems, void* vnormals, const void* fnormals, const void* x)
00074     {   CudaVisualModelCuda3f1_calcVNormals(nbElem, nbVertex, nbElemPerVertex, velems, vnormals, fnormals, x); }
00075 };
00076 
00077 
00078 } // namespace cuda
00079 
00080 } // namespace gpu
00081 
00082 namespace component
00083 {
00084 
00085 namespace visualmodel
00086 {
00087 
00088 using namespace gpu::cuda;
00089 
00090 template<class TDataTypes>
00091 void CudaVisualModel< TDataTypes >::init()
00092 {
00093     this->getContext()->get(state);
00094     topology = this->getContext()->getMeshTopology();
00095     updateVisual();
00096 }
00097 
00098 template<class TDataTypes>
00099 void CudaVisualModel< TDataTypes >::reinit()
00100 {
00101     updateVisual();
00102 }
00103 
00104 template<class TDataTypes>
00105 void CudaVisualModel< TDataTypes >::updateTopology()
00106 {
00107     if (!topology || !state) return;
00108     if (!needUpdateTopology) return;
00109     needUpdateTopology = false;
00110     {
00111     const SeqTriangles& t = topology->getTriangles();
00112     triangles.clear();
00113     if (!t.empty())
00114     {
00115         triangles.fastResize(t.size());
00116         std::copy ( t.begin(), t.end(), triangles.hostWrite() );
00117     }
00118     }
00119     {
00120     const SeqQuads& q = topology->getQuads();
00121     quads.clear();
00122     if (!q.empty())
00123     {
00124         quads.fastResize(q.size());
00125         std::copy ( q.begin(), q.end(), quads.hostWrite() );
00126     }
00127     }
00128     const Triangle* tptr = triangles.hostRead();
00129     const Quad*     qptr = quads.hostRead();
00130     std::map<int,int> nelems;
00131     for (unsigned int i=0;i<triangles.size();i++)
00132     {
00133     const Triangle& e = tptr[i];
00134     for (unsigned int j=0;j<e.size();j++)
00135         ++nelems[e[j]];
00136     }
00137     for (unsigned int i=0;i<quads.size();i++)
00138     {
00139     const Quad& e = qptr[i];
00140     for (unsigned int j=0;j<e.size();j++)
00141         ++nelems[e[j]];
00142     }
00143     int nmax = 0;
00144     for (std::map<int,int>::const_iterator it = nelems.begin(); it != nelems.end(); ++it)
00145     if (it->second > nmax)
00146         nmax = it->second;
00147     int nbv = 0;
00148     if (!nelems.empty())
00149     nbv = nelems.rbegin()->first + 1;
00150     std::cout << "CUDA CudaVisualModel: "<<triangles.size()<<" triangles, "<<quads.size()<<" quads, "<<nbv<<"/"<<state->getX()->size()<<" attached points, max "<<nmax<<" elements per point."<<std::endl;
00151     initV(triangles.size()+quads.size(), nbv, nmax);
00152     
00153     nelems.clear();
00154     for (unsigned int i=0;i<triangles.size();i++)
00155     {
00156     const Triangle& e = tptr[i];
00157     for (unsigned int j=0;j<e.size();j++)
00158         setV(e[j], nelems[e[j]]++, i);
00159     }
00160     int i0 = triangles.size();
00161     for (unsigned int i=0;i<quads.size();i++)
00162     {
00163     const Quad& e = qptr[i];
00164     for (unsigned int j=0;j<e.size();j++)
00165         setV(e[j], nelems[e[j]]++, i0+i);
00166     }
00167 }
00168 
00169 
00170 template<class TDataTypes>
00171 void CudaVisualModel< TDataTypes >::updateNormals()
00172 {
00173     if (!topology || !state || !state->getX()->size()) return;
00174     const VecCoord& x = *state->getX();
00175     fnormals.resize(nbElement);
00176     vnormals.resize(x.size());
00177     if (triangles.size() > 0)
00178     Kernels::calcTNormals(
00179         triangles.size(),
00180         nbVertex,
00181         triangles.deviceRead(),
00182         fnormals.deviceWrite(),
00183         x.deviceRead());
00184     if (quads.size() > 0)
00185     Kernels::calcQNormals(
00186         quads.size(),
00187         nbVertex,
00188         quads.deviceRead(),
00189         fnormals.deviceWrite(triangles.size()),
00190         x.deviceRead());
00191     if (nbVertex > 0)
00192     Kernels::calcVNormals(
00193         nbElement,
00194         nbVertex,
00195         nbElementPerVertex,
00196         velems.deviceRead(),
00197         vnormals.deviceWrite(),
00198         fnormals.deviceRead(),
00199         x.deviceRead());
00200 }
00201 
00202 template<class TDataTypes>
00203 void CudaVisualModel< TDataTypes >::updateVisual()
00204 {
00205     if (!getContext()->getShowVisualModels()) return;
00206     updateTopology();
00207     if (computeNormals.getValue())
00208     updateNormals();
00209 }
00210 
00211 template<class TDataTypes>
00212 void CudaVisualModel< TDataTypes >::drawVisual()
00213 {
00214     if (!getContext()->getShowVisualModels()) return;
00215 
00216     if (!topology || !state || !state->getX()->size()) return;
00217 
00218     if (getContext()->getShowWireFrame())
00219         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00220 
00221     glEnable(GL_LIGHTING);
00222 
00223     //Enable<GL_BLEND> blending;
00224     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00225     glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00226     defaulttype::Vec4f ambient = matAmbient.getValue();
00227     defaulttype::Vec4f diffuse = matDiffuse.getValue();
00228     defaulttype::Vec4f specular = matSpecular.getValue();
00229     defaulttype::Vec4f emissive = matEmissive.getValue();
00230     float shininess = matShininess.getValue();
00231 
00232     if (shininess == 0.0f)
00233     {
00234     specular.clear();
00235     shininess = 1;
00236     }
00237 
00238     glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr());
00239     glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr());
00240     glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr());
00241     glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive.ptr());
00242     glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shininess);
00243 
00244     VecCoord& x = *state->getX();
00245 
00246     bool vbo = useVBO.getValue();
00247 
00248     GLuint vbo_x = vbo ? x.bufferRead(true) : 0;
00249     if (vbo_x)
00250     {
00251     glBindBuffer(GL_ARRAY_BUFFER, vbo_x);
00252     glVertexPointer (3, (sizeof(Real)==sizeof(double))?GL_DOUBLE:GL_FLOAT, sizeof(Coord), NULL);
00253     }
00254     else
00255     glVertexPointer (3, (sizeof(Real)==sizeof(double))?GL_DOUBLE:GL_FLOAT, sizeof(Coord), x.hostRead());
00256 
00257     if (computeNormals.getValue())
00258     {
00259     GLuint vbo_n = vbo ? vnormals.bufferRead(true) : 0;
00260     if (vbo_n)
00261     {
00262         glBindBuffer(GL_ARRAY_BUFFER, vbo_n);
00263         glNormalPointer ((sizeof(Real)==sizeof(double))?GL_DOUBLE:GL_FLOAT, sizeof(Coord), NULL);
00264     }
00265     else
00266         glNormalPointer ((sizeof(Real)==sizeof(double))?GL_DOUBLE:GL_FLOAT, sizeof(Coord), vnormals.hostRead());
00267     glEnableClientState(GL_NORMAL_ARRAY);
00268     }
00269     glEnableClientState(GL_VERTEX_ARRAY);
00270 
00271     if (triangles.size() > 0)
00272     {
00273     GLuint vbo_t = vbo ? triangles.bufferRead(true) : 0;
00274     if (vbo_t)
00275     {
00276         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_t);
00277         glDrawElements(GL_TRIANGLES, triangles.size() * 3, GL_UNSIGNED_INT, NULL);
00278     }
00279     else
00280         glDrawElements(GL_TRIANGLES, triangles.size() * 3, GL_UNSIGNED_INT, triangles.hostRead());
00281     }
00282 
00283     if (quads.size() > 0)
00284     {
00285     GLuint vbo_q = vbo ? quads.bufferRead(true) : 0;
00286     if (vbo_q)
00287     {
00288         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_q);
00289         glDrawElements(GL_QUADS, quads.size() * 4, GL_UNSIGNED_INT, NULL);
00290     }
00291     else
00292         glDrawElements(GL_QUADS, quads.size() * 4, GL_UNSIGNED_INT, quads.hostRead());
00293     }
00294 
00295     if (vbo)
00296     {
00297     glBindBuffer(GL_ARRAY_BUFFER, 0);
00298     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00299     }
00300     glDisableClientState(GL_NORMAL_ARRAY);
00301     glDisable(GL_LIGHTING);
00302 
00303     if (getContext()->getShowWireFrame())
00304         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00305 
00306     if (getContext()->getShowNormals())
00307     {
00308         glColor3f (1.0, 1.0, 1.0);
00309     for (unsigned int i = 0; i < x.size(); i++)
00310     {
00311         glBegin(GL_LINES);
00312         helper::gl::glVertexT(x[i]);
00313         Coord p = x[i] + vnormals[i]*0.01;
00314         helper::gl::glVertexT(p);
00315         glEnd();
00316     }
00317     }
00318 }
00319 
00320 } // namespace visualmodel
00321 
00322 } // namespace component
00323 
00324 } // namespace sofa
00325 
00326 #endif

Generated on Sun Nov 23 04:05:45 2008 for Sofa by  doxygen 1.5.7.1