glc_geometry.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00025 #include "../shading/glc_selectionmaterial.h"
00026 #include "../glc_openglexception.h"
00027 #include "../glc_state.h"
00028 #include "glc_geometry.h"
00029
00031
00033
00034 GLC_Geometry::GLC_Geometry(const QString& name, const bool typeIsWire)
00035 : m_GeometryIsValid(false)
00036 , m_pBoundingBox(NULL)
00037 , m_MaterialHash()
00038 , m_UseColorPerVertex(false)
00039 , m_IsSelected(false)
00040 , m_WireData()
00041 , m_WireColor(Qt::black)
00042 , m_LineWidth(1.0f)
00043 , m_IsWire(typeIsWire)
00044 , m_TransparentMaterialNumber(0)
00045 , m_Id(glc::GLC_GenGeomID())
00046 , m_Name(name)
00047 {
00048
00049 }
00050
00051 GLC_Geometry::GLC_Geometry(const GLC_Geometry& sourceGeom)
00052 : m_GeometryIsValid(false)
00053 , m_pBoundingBox(NULL)
00054 , m_MaterialHash(sourceGeom.m_MaterialHash)
00055 , m_UseColorPerVertex(sourceGeom.m_UseColorPerVertex)
00056 , m_IsSelected(false)
00057 , m_WireData(sourceGeom.m_WireData)
00058 , m_WireColor(sourceGeom.m_WireColor)
00059 , m_LineWidth(sourceGeom.m_LineWidth)
00060 , m_IsWire(sourceGeom.m_IsWire)
00061 , m_TransparentMaterialNumber(sourceGeom.m_TransparentMaterialNumber)
00062 , m_Id(glc::GLC_GenGeomID())
00063 , m_Name(sourceGeom.m_Name)
00064 {
00065
00066 MaterialHash::const_iterator i= sourceGeom.m_MaterialHash.constBegin();
00067 while (i != sourceGeom.m_MaterialHash.constEnd())
00068 {
00069
00070 i.value()->addGLC_Geom(this);
00071 ++i;
00072 }
00073
00074 if (NULL != sourceGeom.m_pBoundingBox)
00075 {
00076 m_pBoundingBox= new GLC_BoundingBox(*sourceGeom.m_pBoundingBox);
00077 }
00078 }
00079
00080
00081 GLC_Geometry& GLC_Geometry::operator=(const GLC_Geometry& sourceGeom)
00082 {
00083 if (this != &sourceGeom)
00084 {
00085 clear();
00086 m_GeometryIsValid= false;
00087 m_pBoundingBox= NULL;
00088 m_MaterialHash= sourceGeom.m_MaterialHash;
00089 m_UseColorPerVertex= sourceGeom.m_UseColorPerVertex;
00090 m_IsSelected= false;
00091 m_WireData= sourceGeom.m_WireData;
00092 m_WireColor= sourceGeom.m_WireColor;
00093 m_LineWidth= sourceGeom.m_LineWidth;
00094 m_IsWire= sourceGeom.m_IsWire;
00095 m_TransparentMaterialNumber= sourceGeom.m_TransparentMaterialNumber;
00096 m_Id= glc::GLC_GenGeomID();
00097 m_Name= sourceGeom.m_Name;
00098 }
00099 return *this;
00100 }
00101
00102 GLC_Geometry::~GLC_Geometry()
00103 {
00104
00105 {
00106 MaterialHash::const_iterator i= m_MaterialHash.begin();
00107 while (i != m_MaterialHash.constEnd())
00108 {
00109
00110 i.value()->delGLC_Geom(id());
00111 if (i.value()->isUnused()) delete i.value();
00112 ++i;
00113 }
00114 }
00115 m_MaterialHash.clear();
00116
00117 delete m_pBoundingBox;
00118
00119 }
00120
00122
00124
00125
00126 unsigned int GLC_Geometry::faceCount(int) const
00127 {
00128 return 0;
00129 }
00130
00131
00132 unsigned int GLC_Geometry::VertexCount() const
00133 {
00134 return 0;
00135 }
00136
00138
00140
00141 void GLC_Geometry::clear()
00142 {
00143 clearGeometry();
00144 }
00145
00146
00147 void GLC_Geometry::replaceMasterMaterial(GLC_Material* pMaterial)
00148 {
00149 Q_ASSERT(!m_IsWire);
00150 if (!m_MaterialHash.isEmpty())
00151 {
00152 if (pMaterial != firstMaterial())
00153 {
00154
00155 MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00156 removeMaterial(iMaterial.value()->id());
00157
00158
00159 addMaterial(pMaterial);
00160 }
00161 }
00162 else
00163 {
00164 addMaterial(pMaterial);
00165 }
00166 }
00168 void GLC_Geometry::updateTransparentMaterialNumber()
00169 {
00170 m_TransparentMaterialNumber= 0;
00171 MaterialHash::const_iterator iMat= m_MaterialHash.constBegin();
00172 while (iMat != m_MaterialHash.constEnd())
00173 {
00174 if (iMat.value()->isTransparent())
00175 {
00176 ++m_TransparentMaterialNumber;
00177 }
00178 ++iMat;
00179 }
00180 if (m_WireColor.alpha() != 255)
00181 {
00182 qDebug() << "GLC_Geometry::updateTransparentMaterialNumber()";
00183 ++m_TransparentMaterialNumber;
00184 }
00185 }
00186
00187
00188 void GLC_Geometry::addMaterial(GLC_Material* pMaterial)
00189 {
00190 Q_ASSERT(!m_IsWire);
00191
00192 if (pMaterial != NULL)
00193 {
00194 const GLC_uint materialID= pMaterial->id();
00195 MaterialHash::const_iterator iMaterial= m_MaterialHash.find(materialID);
00196
00197 Q_ASSERT(iMaterial == m_MaterialHash.end());
00198
00199
00200 pMaterial->addGLC_Geom(this);
00201
00202 m_MaterialHash.insert(materialID, pMaterial);
00203
00204
00205 if (pMaterial->isTransparent())
00206 {
00207
00208 ++m_TransparentMaterialNumber;
00209 }
00210 }
00211 }
00212
00213 void GLC_Geometry::setWireColor(const QColor& color)
00214 {
00215 bool previousColorIsTransparent= (m_WireColor.alpha() != 255);
00216 bool newColorIsTransparent= (color.alpha() != 255);
00217
00218 if (previousColorIsTransparent != newColorIsTransparent)
00219 {
00220 if (newColorIsTransparent) ++m_TransparentMaterialNumber;
00221 else if (previousColorIsTransparent) --m_TransparentMaterialNumber;
00222 }
00223
00224 m_WireColor= color;
00225 }
00226
00227 void GLC_Geometry::copyVboToClientSide()
00228 {
00229 m_WireData.copyVboToClientSide();
00230 }
00231
00232 void GLC_Geometry::releaseVboClientSide(bool update)
00233 {
00234 m_WireData.releaseVboClientSide(update);
00235 }
00236
00238
00240
00241
00242 void GLC_Geometry::glLoadTexture(void)
00243 {
00244 MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00245
00246 while (iMaterial != m_MaterialHash.constEnd())
00247 {
00248
00249 iMaterial.value()->glLoadTexture();
00250 ++iMaterial;
00251 }
00252 }
00253
00254
00255 void GLC_Geometry::render(const GLC_RenderProperties& renderProperties)
00256 {
00257 Q_ASSERT(!m_IsWire || (m_IsWire && m_MaterialHash.isEmpty()));
00258 bool renderWire= (renderProperties.renderingFlag() == glc::TransparentRenderFlag) && isTransparent();
00259 renderWire= renderWire || ((renderProperties.renderingFlag() != glc::TransparentRenderFlag) && !isTransparent());
00260 if (!m_IsWire || renderWire)
00261 {
00262 if (m_MaterialHash.isEmpty() && !m_IsWire)
00263 {
00264 GLC_Material* pMaterial= new GLC_Material();
00265 pMaterial->setName(name());
00266 addMaterial(pMaterial);
00267 }
00268
00269 m_IsSelected= renderProperties.isSelected();
00270
00271
00272 if(!GLC_State::isInSelectionMode())
00273 {
00274 glPropGeom(renderProperties);
00275 }
00276
00277 glDraw(renderProperties);
00278
00279 m_IsSelected= false;
00280 m_GeometryIsValid= true;
00281
00282
00283 GLenum error= glGetError();
00284 if (error != GL_NO_ERROR)
00285 {
00286 GLC_OpenGlException OpenGlException("GLC_Geometry::glExecute " + name(), error);
00287 throw(OpenGlException);
00288 }
00289 }
00290 }
00291
00292
00293 void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties)
00294 {
00295 glLineWidth(lineWidth());
00296
00297 if(m_IsWire)
00298 {
00299 glLineWidth(m_LineWidth);
00300 glDisable(GL_LIGHTING);
00301 if (!renderProperties.isSelected())
00302 {
00303
00304 GLfloat color[4]= {static_cast<float>(m_WireColor.redF()),
00305 static_cast<float>(m_WireColor.greenF()),
00306 static_cast<float>(m_WireColor.blueF()),
00307 static_cast<float>(m_WireColor.alphaF())};
00308
00309 glColor4fv(color);
00310 }
00311 else
00312 {
00313 GLC_SelectionMaterial::glExecute();
00314 }
00315 }
00316 else if (m_MaterialHash.size() == 1)
00317 {
00318 GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value();
00319 if (pCurrentMaterial->hasTexture())
00320 {
00321 glEnable(GL_LIGHTING);
00322 pCurrentMaterial->glExecute();
00323 if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
00324 }
00325 else
00326 {
00327 glEnable(GL_LIGHTING);
00328 if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
00329 else pCurrentMaterial->glExecute();
00330 }
00331 }
00332 }
00333
00334
00335 void GLC_Geometry::removeMaterial(GLC_uint id)
00336 {
00337 Q_ASSERT(containsMaterial(id));
00338
00339 GLC_Material* pMaterial= m_MaterialHash.value(id);
00340
00341 pMaterial->delGLC_Geom(this->id());
00342 if (pMaterial->isTransparent())
00343 {
00344 --m_TransparentMaterialNumber;
00345 }
00346 if (pMaterial->isUnused()) delete pMaterial;
00347 m_MaterialHash.remove(id);
00348
00349 }
00350
00351
00352 void GLC_Geometry::clearGeometry()
00353 {
00354 m_GeometryIsValid= false;
00355
00356 delete m_pBoundingBox;
00357 m_pBoundingBox= NULL;
00358
00359
00360 {
00361 MaterialHash::const_iterator i= m_MaterialHash.begin();
00362 while (i != m_MaterialHash.constEnd())
00363 {
00364
00365 i.value()->delGLC_Geom(id());
00366 if (i.value()->isUnused()) delete i.value();
00367 ++i;
00368 }
00369 }
00370 m_MaterialHash.clear();
00371
00372 m_UseColorPerVertex= false;
00373 m_IsSelected= false;
00374 m_WireData.clear();
00375 m_IsWire= false;
00376 m_TransparentMaterialNumber= 0;
00377 m_Name.clear();
00378
00379 }