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 #include <sofa/component/visualmodel/OglModel.h>
00026 #include <sofa/helper/system/gl.h>
00027 #include <sofa/helper/system/glut.h>
00028 #include <sofa/helper/gl/RAII.h>
00029 #include <sofa/helper/vector.h>
00030 #include <sofa/defaulttype/Quat.h>
00031 #include <sofa/core/ObjectFactory.h>
00032 #include <sofa/core/componentmodel/topology/BaseMeshTopology.h>
00033 #include <sstream>
00034
00035 namespace sofa
00036 {
00037
00038 namespace component
00039 {
00040
00041 namespace visualmodel
00042 {
00043
00044 using namespace sofa::defaulttype;
00045
00046 SOFA_DECL_CLASS(OglModel)
00047
00048 int OglModelClass = core::RegisterObject("Generic visual model for OpenGL display")
00049 .add< OglModel >()
00050 ;
00051
00052
00053 OglModel::OglModel()
00054 : premultipliedAlpha(initData(&premultipliedAlpha, (bool) false, "premultipliedAlpha", "is alpha premultiplied ?"))
00055 , tex(NULL)
00056 {
00057 }
00058
00059 OglModel::~OglModel()
00060 {
00061 if (tex!=NULL) delete tex;
00062 }
00063
00064 void OglModel::internalDraw()
00065 {
00066
00067 if (!getContext()->getShowVisualModels()) return;
00068 if (getContext()->getShowWireFrame())
00069 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00070
00071 glEnable(GL_LIGHTING);
00072
00073
00074 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00075 glColor3f(1.0 , 1.0, 1.0);
00076 Vec4f ambient = material.getValue().useAmbient?material.getValue().ambient:Vec4f();
00077 Vec4f diffuse = material.getValue().useDiffuse?material.getValue().diffuse:Vec4f();
00078 Vec4f specular = material.getValue().useSpecular?material.getValue().specular:Vec4f();
00079 Vec4f emissive = material.getValue().useEmissive?material.getValue().emissive:Vec4f();
00080 float shininess = material.getValue().useShininess?material.getValue().shininess:45;
00081
00082 if (shininess == 0.0f)
00083 {
00084 specular.clear();
00085 shininess = 1;
00086 }
00087
00088 if (isTransparent()) {
00089 emissive[3] = 0;
00090 ambient[3] = 0;
00091
00092 specular[3] = 0;
00093 }
00094 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, ambient.ptr());
00095 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse.ptr());
00096 glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular.ptr());
00097 glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, emissive.ptr());
00098 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shininess);
00099
00100 glVertexPointer (3, GL_FLOAT, 0, vertices.getData());
00101 glNormalPointer (GL_FLOAT, 0, vnormals.getData());
00102 glEnableClientState(GL_NORMAL_ARRAY);
00103 glEnableClientState(GL_VERTEX_ARRAY);
00104 if (tex)
00105 {
00106 glEnable(GL_TEXTURE_2D);
00107 tex->bind();
00108 glTexCoordPointer(2, GL_FLOAT, 0, vtexcoords.getData());
00109 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00110 }
00111
00112 if (isTransparent())
00113 {
00114 glEnable(GL_BLEND);
00115 glDepthMask(GL_FALSE);
00116 glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
00117
00118 for (unsigned int i=0; i<xforms.size(); i++)
00119 {
00120 float matrix[16];
00121 xforms[i].writeOpenGlMatrix(matrix);
00122 glPushMatrix();
00123 glMultMatrixf(matrix);
00124
00125 if (!triangles.empty())
00126 glDrawElements(GL_TRIANGLES, triangles.size() * 3, GL_UNSIGNED_INT, triangles.getData());
00127 if (!quads.empty())
00128 glDrawElements(GL_QUADS, quads.size() * 4, GL_UNSIGNED_INT, quads.getData());
00129
00130 glPopMatrix();
00131 }
00132 if (premultipliedAlpha.getValue())
00133 glBlendFunc(GL_ONE, GL_ONE);
00134 else
00135 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00136 }
00137
00138 for (unsigned int i=0; i<xforms.size(); i++)
00139 {
00140
00141 float matrix[16];
00142 xforms[i].writeOpenGlMatrix(matrix);
00143
00144 glPushMatrix();
00145 glMultMatrixf(matrix);
00146
00147
00148 if (!triangles.empty())
00149 glDrawElements(GL_TRIANGLES, triangles.size() * 3, GL_UNSIGNED_INT, triangles.getData());
00150 if (!quads.empty())
00151 glDrawElements(GL_QUADS, quads.size() * 4, GL_UNSIGNED_INT, quads.getData());
00152
00153 glPopMatrix();
00154 }
00155 if (tex)
00156 {
00157 tex->unbind();
00158 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00159 glDisable(GL_TEXTURE_2D);
00160 }
00161 glDisableClientState(GL_NORMAL_ARRAY);
00162 glDisable(GL_LIGHTING);
00163 if (isTransparent()) {
00164 glDisable(GL_BLEND);
00165 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00166
00167 glDepthMask(GL_TRUE);
00168 }
00169
00170 if (getContext()->getShowWireFrame())
00171 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00172
00173 if (getContext()->getShowNormals())
00174 {
00175 glColor3f (1.0, 1.0, 1.0);
00176 for (unsigned int i=0; i<xforms.size(); i++)
00177 {
00178 float matrix[16];
00179 xforms[i].writeOpenGlMatrix(matrix);
00180 glPushMatrix();
00181 glMultMatrixf(matrix);
00182
00183 for (unsigned int i = 0; i < vertices.size(); i++)
00184 {
00185 glBegin(GL_LINES);
00186 glVertex3fv (vertices[i].ptr());
00187 Coord p = vertices[i] + vnormals[i];
00188 glVertex3fv (p.ptr());
00189 glEnd();
00190 }
00191
00192 glPopMatrix();
00193 }
00194 }
00195
00196 }
00197
00198 bool OglModel::loadTexture(const std::string& filename)
00199 {
00200 helper::io::Image *img = helper::io::Image::Create(filename);
00201 if (!img)
00202 return false;
00203 tex = new helper::gl::Texture(img);
00204 return true;
00205 }
00206
00207 void OglModel::initVisual()
00208 {
00209 if (tex)
00210 {
00211 tex->init();
00212 }
00213 }
00214
00215 void OglModel::initTextures()
00216 {
00217 if (tex)
00218 {
00219 tex->init();
00220 }
00221 }
00222
00223 }
00224
00225 }
00226
00227 }
00228