00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00026
00027 #include "glc_material.h"
00028 #include "../geometry/glc_geometry.h"
00029 #include "../glc_factory.h"
00030
00031 #include <QtDebug>
00032
00033
00034 quint32 GLC_Material::m_ChunkId= 0xA703;
00035
00037
00039
00040 GLC_Material::GLC_Material()
00041 :GLC_Object("Material")
00042 , m_AmbientColor()
00043 , m_DiffuseColor()
00044 , m_SpecularColor()
00045 , m_EmissiveColor()
00046 , m_Shininess(50.0)
00047 , m_WhereUsed()
00048 , m_OtherUsage()
00049 , m_pTexture(NULL)
00050 , m_Opacity(1.0)
00051 {
00052
00053
00054 initDiffuseColor();
00055
00056
00057 initOtherColor();
00058 }
00059
00060 GLC_Material::GLC_Material(const QColor &diffuseColor)
00061 :GLC_Object("Material")
00062 , m_AmbientColor()
00063 , m_DiffuseColor(diffuseColor)
00064 , m_SpecularColor()
00065 , m_EmissiveColor()
00066 , m_Shininess(50.0)
00067 , m_WhereUsed()
00068 , m_OtherUsage()
00069 , m_pTexture(NULL)
00070 , m_Opacity(1.0)
00071 {
00072
00073 initOtherColor();
00074 }
00075
00076
00077 GLC_Material::GLC_Material(const QString& name ,const GLfloat *pDiffuseColor)
00078 :GLC_Object(name)
00079 , m_AmbientColor()
00080 , m_DiffuseColor()
00081 , m_SpecularColor()
00082 , m_EmissiveColor()
00083 , m_Shininess(50.0)
00084 , m_WhereUsed()
00085 , m_OtherUsage()
00086 , m_pTexture(NULL)
00087 , m_Opacity(1.0)
00088 {
00089
00090
00091 if (pDiffuseColor != 0)
00092 {
00093 m_DiffuseColor.setRgbF(static_cast<qreal>(pDiffuseColor[0]),
00094 static_cast<qreal>(pDiffuseColor[1]),
00095 static_cast<qreal>(pDiffuseColor[2]),
00096 static_cast<qreal>(pDiffuseColor[3]));
00097 }
00098 else
00099 {
00100 initDiffuseColor();
00101 }
00102
00103 initOtherColor();
00104 }
00105 GLC_Material::GLC_Material(GLC_Texture* pTexture, const char *pName)
00106 :GLC_Object(pName)
00107 , m_AmbientColor()
00108 , m_DiffuseColor()
00109 , m_SpecularColor()
00110 , m_EmissiveColor()
00111 , m_Shininess(50.0)
00112 , m_WhereUsed()
00113 , m_OtherUsage()
00114 , m_pTexture(pTexture)
00115 , m_Opacity(1.0)
00116 {
00117 Q_ASSERT(NULL != m_pTexture);
00118
00119
00120
00121 initDiffuseColor();
00122
00123
00124 initOtherColor();
00125
00126
00127 }
00128
00129
00130 GLC_Material::GLC_Material(const GLC_Material &InitMaterial)
00131 :GLC_Object(InitMaterial)
00132 , m_AmbientColor(InitMaterial.m_AmbientColor)
00133 , m_DiffuseColor(InitMaterial.m_DiffuseColor)
00134 , m_SpecularColor(InitMaterial.m_SpecularColor)
00135 , m_EmissiveColor(InitMaterial.m_EmissiveColor)
00136 , m_Shininess(InitMaterial.m_Shininess)
00137 , m_WhereUsed()
00138 , m_OtherUsage()
00139 , m_pTexture(NULL)
00140 , m_Opacity(InitMaterial.m_Opacity)
00141 {
00142
00143 if (NULL != InitMaterial.m_pTexture)
00144 {
00145 m_pTexture= new GLC_Texture(*(InitMaterial.m_pTexture));
00146 Q_ASSERT(m_pTexture != NULL);
00147 }
00148
00149 }
00150
00151
00152 GLC_Material::~GLC_Material(void)
00153 {
00154 delete m_pTexture;
00155 }
00156
00157
00159
00161
00162 quint32 GLC_Material::chunckID()
00163 {
00164 return m_ChunkId;
00165 }
00166
00167
00168 QColor GLC_Material::ambientColor() const
00169 {
00170 return m_AmbientColor;
00171 }
00172
00173
00174 QColor GLC_Material::diffuseColor() const
00175 {
00176 return m_DiffuseColor;
00177 }
00178
00179
00180 QColor GLC_Material::specularColor() const
00181 {
00182 return m_SpecularColor;
00183 }
00184
00185
00186 QColor GLC_Material::emissiveColor() const
00187 {
00188 return m_EmissiveColor;
00189 }
00190
00191 QString GLC_Material::textureFileName() const
00192 {
00193 if (m_pTexture != NULL)
00194 {
00195 return m_pTexture->fileName();
00196 }
00197 else
00198 {
00199 return "";
00200 }
00201 }
00202
00203
00204 GLuint GLC_Material::textureID() const
00205 {
00206 if (m_pTexture != NULL)
00207 {
00208 return m_pTexture->GL_ID();
00209 }
00210 else
00211 {
00212 return 0;
00213 }
00214
00215 }
00216
00217
00218 bool GLC_Material::textureIsLoaded() const
00219 {
00220 if (m_pTexture != NULL)
00221 {
00222 return m_pTexture->isLoaded();
00223 }
00224 else
00225 {
00226 return false;
00227 }
00228 }
00229
00230
00231 bool GLC_Material::operator==(const GLC_Material& mat) const
00232 {
00233 bool result;
00234 if (this == &mat)
00235 {
00236 result= true;
00237 }
00238 else
00239 {
00240 result= m_AmbientColor == mat.m_AmbientColor;
00241 result= result && (m_DiffuseColor == mat.m_DiffuseColor);
00242 result= result && (m_SpecularColor == mat.m_SpecularColor);
00243 result= result && (m_EmissiveColor == mat.m_EmissiveColor);
00244 result= result && (m_Shininess == mat.m_Shininess);
00245 if ((NULL != m_pTexture) && (NULL != mat.m_pTexture))
00246 {
00247 result= result && ((*m_pTexture) == (*mat.m_pTexture));
00248 }
00249 else
00250 {
00251 result= result && (m_pTexture == mat.m_pTexture);
00252 }
00253 result= result && (m_Opacity == mat.m_Opacity);
00254 }
00255 return result;
00256 }
00257
00258
00259 uint GLC_Material::hashCode() const
00260 {
00261 QString stringKey= QString::number(m_AmbientColor.rgba());
00262 stringKey+= QString::number(m_DiffuseColor.rgba());
00263 stringKey+= QString::number(m_SpecularColor.rgba());
00264 stringKey+= QString::number(m_EmissiveColor.rgba());
00265 stringKey+= QString::number(m_Shininess);
00266 stringKey+= QString::number(m_Opacity);
00267 if (NULL != m_pTexture)
00268 {
00269 stringKey+= m_pTexture->fileName();
00270 }
00271
00272 return qHash(stringKey);
00273 }
00274
00276
00278
00279 void GLC_Material::setMaterial(const GLC_Material* pMat)
00280 {
00281 if (NULL != pMat->m_pTexture)
00282 {
00283 GLC_Texture* pTexture= new GLC_Texture(*(pMat->m_pTexture));
00284 setTexture(pTexture);
00285 }
00286 else if (NULL != m_pTexture)
00287 {
00288 qDebug() << "Delete texture";
00289 delete m_pTexture;
00290 m_pTexture= NULL;
00291 }
00292
00293 m_AmbientColor= pMat->m_AmbientColor;
00294
00295 m_DiffuseColor= pMat->m_DiffuseColor;
00296
00297 m_SpecularColor= pMat->m_SpecularColor;
00298
00299 m_EmissiveColor= pMat->m_EmissiveColor;
00300
00301 m_Shininess= pMat->m_Shininess;
00302
00303 m_Opacity= pMat->m_Opacity;
00304
00305 WhereUsed::const_iterator iGeom= m_WhereUsed.constBegin();
00306 while (iGeom != m_WhereUsed.constEnd())
00307 {
00308 iGeom.value()->updateTransparentMaterialNumber();
00309 ++iGeom;
00310 }
00311
00312 }
00313
00314
00315 void GLC_Material::setAmbientColor(const QColor& ambientColor)
00316 {
00317 m_AmbientColor= ambientColor;
00318 m_AmbientColor.setAlphaF(m_Opacity);
00319 }
00320
00321
00322 void GLC_Material::setDiffuseColor(const QColor& diffuseColor)
00323 {
00324 m_DiffuseColor= diffuseColor;
00325 m_DiffuseColor.setAlphaF(m_Opacity);
00326 }
00327
00328
00329 void GLC_Material::setSpecularColor(const QColor& specularColor)
00330 {
00331 m_SpecularColor= specularColor;
00332 m_SpecularColor.setAlphaF(m_Opacity);
00333 }
00334
00335
00336 void GLC_Material::setEmissiveColor(const QColor& lightEmission)
00337 {
00338 m_EmissiveColor= lightEmission;
00339 m_EmissiveColor.setAlphaF(m_Opacity);
00340 }
00341
00342
00343 void GLC_Material::setTexture(GLC_Texture* pTexture)
00344 {
00345 Q_ASSERT(NULL != pTexture);
00346
00347 if (m_pTexture != NULL)
00348 {
00349 delete m_pTexture;
00350 m_pTexture= pTexture;
00351 glLoadTexture();
00352 }
00353 else
00354 {
00355
00356 m_pTexture= pTexture;
00357 }
00358
00359
00360 }
00361
00362
00363 void GLC_Material::removeTexture()
00364 {
00365 if (m_pTexture != NULL)
00366 {
00367 delete m_pTexture;
00368 m_pTexture= NULL;
00369 }
00370 }
00371
00372
00373 bool GLC_Material::addGLC_Geom(GLC_Geometry* pGeom)
00374 {
00375 QMutexLocker mutexLocker(&m_Mutex);
00376
00377 WhereUsed::iterator iGeom= m_WhereUsed.find(pGeom->id());
00378
00379 if (iGeom == m_WhereUsed.end())
00380 {
00381
00382 m_WhereUsed.insert(pGeom->id(), pGeom);
00383 return true;
00384 }
00385 else
00386 {
00387 qDebug("GLC_Material::addGLC_Geom : Geometry not added");
00388 return false;
00389 }
00390 }
00391
00392
00393 bool GLC_Material::delGLC_Geom(GLC_uint Key)
00394 {
00395 QMutexLocker mutexLocker(&m_Mutex);
00396
00397 if (m_WhereUsed.contains(Key))
00398 {
00399 m_WhereUsed.remove(Key);
00400
00401 return true;
00402 }
00403 else
00404 {
00405 qDebug("GLC_Material::delGLC_Geom : Geometry not remove");
00406 return false;
00407 }
00408
00409 }
00410
00411 bool GLC_Material::addUsage(GLC_uint id)
00412 {
00413 QMutexLocker mutexLocker(&m_Mutex);
00414 if (!m_OtherUsage.contains(id))
00415 {
00416 m_OtherUsage << id;
00417 return true;
00418 }
00419 else
00420 {
00421 qDebug("GLC_Material::addUsage : id not added");
00422 return false;
00423 }
00424 }
00425
00426
00427 bool GLC_Material::delUsage(GLC_uint id)
00428 {
00429 QMutexLocker mutexLocker(&m_Mutex);
00430 if (m_OtherUsage.contains(id))
00431 {
00432 m_OtherUsage.remove(id);
00433 return true;
00434 }
00435 else
00436 {
00437 qDebug() << "GLC_Material::delUsage : id not removed " << m_Uid;
00438 return false;
00439 }
00440 }
00441
00442
00443
00444 void GLC_Material::setOpacity(const qreal alpha)
00445 {
00446 m_Opacity= alpha;
00447 m_AmbientColor.setAlphaF(m_Opacity);
00448 m_DiffuseColor.setAlphaF(m_Opacity);
00449 m_SpecularColor.setAlphaF(m_Opacity);
00450 m_EmissiveColor.setAlphaF(m_Opacity);
00451
00452 WhereUsed::const_iterator iGeom= m_WhereUsed.constBegin();
00453 while (iGeom != m_WhereUsed.constEnd())
00454 {
00455 iGeom.value()->updateTransparentMaterialNumber();
00456 ++iGeom;
00457 }
00458 }
00459
00461
00463
00464
00465 void GLC_Material::glLoadTexture(void)
00466 {
00467 if (m_pTexture != NULL)
00468 {
00469 m_pTexture->glLoadTexture();
00470 }
00471 }
00472
00473
00474 void GLC_Material::glExecute()
00475 {
00476 GLfloat pAmbientColor[4]= {ambientColor().redF(),
00477 ambientColor().greenF(),
00478 ambientColor().blueF(),
00479 ambientColor().alphaF()};
00480
00481 GLfloat pDiffuseColor[4]= {diffuseColor().redF(),
00482 diffuseColor().greenF(),
00483 diffuseColor().blueF(),
00484 diffuseColor().alphaF()};
00485
00486 GLfloat pSpecularColor[4]= {specularColor().redF(),
00487 specularColor().greenF(),
00488 specularColor().blueF(),
00489 specularColor().alphaF()};
00490
00491 GLfloat pLightEmission[4]= {emissiveColor().redF(),
00492 emissiveColor().greenF(),
00493 emissiveColor().blueF(),
00494 emissiveColor().alphaF()};
00495
00496 if (m_pTexture != NULL)
00497 {
00498 glEnable(GL_TEXTURE_2D);
00499 m_pTexture->glcBindTexture();
00500 }
00501 else
00502 {
00503 glDisable(GL_TEXTURE_2D);
00504 }
00505
00506 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pAmbientColor);
00507 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pDiffuseColor);
00508 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pSpecularColor);
00509 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pLightEmission);
00510 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &m_Shininess);
00511
00512 glColor4fv(pDiffuseColor);
00513
00514
00515 GLenum errCode;
00516 if ((errCode= glGetError()) != GL_NO_ERROR)
00517 {
00518 const GLubyte* errString;
00519 errString = gluErrorString(errCode);
00520 qDebug("GLC_Material::GlExecute OpenGL Error %s", errString);
00521 }
00522 }
00523
00524
00525 void GLC_Material::glExecute(float overwriteTransparency)
00526 {
00527 GLfloat pAmbientColor[4]= {ambientColor().redF(),
00528 ambientColor().greenF(),
00529 ambientColor().blueF(),
00530 overwriteTransparency};
00531
00532 GLfloat pDiffuseColor[4]= {diffuseColor().redF(),
00533 diffuseColor().greenF(),
00534 diffuseColor().blueF(),
00535 overwriteTransparency};
00536
00537 GLfloat pSpecularColor[4]= {specularColor().redF(),
00538 specularColor().greenF(),
00539 specularColor().blueF(),
00540 overwriteTransparency};
00541
00542 GLfloat pLightEmission[4]= {emissiveColor().redF(),
00543 emissiveColor().greenF(),
00544 emissiveColor().blueF(),
00545 overwriteTransparency};
00546
00547 if (m_pTexture != NULL)
00548 {
00549 glEnable(GL_TEXTURE_2D);
00550 m_pTexture->glcBindTexture();
00551 }
00552 else
00553 {
00554 glDisable(GL_TEXTURE_2D);
00555 }
00556
00557 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pAmbientColor);
00558 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pDiffuseColor);
00559 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pSpecularColor);
00560 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pLightEmission);
00561 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &m_Shininess);
00562
00563 glColor4fv(pDiffuseColor);
00564
00565
00566 GLenum errCode;
00567 if ((errCode= glGetError()) != GL_NO_ERROR)
00568 {
00569 const GLubyte* errString;
00570 errString = gluErrorString(errCode);
00571 qDebug("GLC_Material::GlExecute OpenGL Error %s", errString);
00572 }
00573 }
00574
00576
00578
00579
00580 void GLC_Material::initDiffuseColor(void)
00581 {
00582 m_DiffuseColor.setRgbF(1.0, 1.0, 1.0, 1.0);
00583 }
00584
00585
00586 void GLC_Material::initOtherColor(void)
00587 {
00588
00589 m_AmbientColor.setRgbF(0.8, 0.8, 0.8, 1.0);
00590
00591
00592 m_SpecularColor.setRgbF(0.5, 0.5, 0.5, 1.0);
00593
00594
00595 m_EmissiveColor.setRgbF(0.0, 0.0, 0.0, 1.0);
00596 }
00597
00598
00599
00600 QDataStream &operator<<(QDataStream &stream, const GLC_Material &material)
00601 {
00602 quint32 chunckId= GLC_Material::m_ChunkId;
00603 stream << chunckId;
00604
00605
00606 stream << material.id() << material.name();
00607
00608
00609 stream << material.ambientColor() << material.diffuseColor() << material.specularColor();
00610 stream << material.emissiveColor() << material.shininess() << material.opacity();
00611
00612
00613 bool hasTexture= material.hasTexture();
00614 stream << hasTexture;
00615 if (hasTexture)
00616 {
00617 GLC_Texture texture(*(material.textureHandle()));
00618 stream << texture;
00619 }
00620
00621 return stream;
00622 }
00623 QDataStream &operator>>(QDataStream &stream, GLC_Material &material)
00624 {
00625 quint32 chunckId;
00626 stream >> chunckId;
00627
00628 Q_ASSERT(chunckId == GLC_Material::m_ChunkId);
00629
00630
00631 GLC_uint id;
00632 QString name;
00633 stream >> id >> name;
00634 material.setId(id);
00635 material.setName(name);
00636
00637
00638 QColor ambient, diffuse, specular, lightEmission;
00639 float shininess;
00640 double alpha;
00641 stream >> ambient >> diffuse >> specular >> lightEmission;
00642 stream >> shininess >> alpha;
00643 material.setAmbientColor(ambient);
00644 material.setDiffuseColor(diffuse);
00645 material.setSpecularColor(specular);
00646 material.setEmissiveColor(lightEmission);
00647 material.setShininess(shininess);
00648 material.setOpacity(alpha);
00649
00650
00651 bool hasTexture;
00652 stream >> hasTexture;
00653 if (hasTexture)
00654 {
00655 GLC_Texture texture(GLC_Factory::instance()->context());
00656 stream >> texture;
00657 material.setTexture(new GLC_Texture(texture));
00658 }
00659 return stream;
00660 }