00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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 }
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 }
00079
00080 }
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
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 }
00321
00322 }
00323
00324 }
00325
00326 #endif