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