PageRenderTime 121ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/ex10/src/Material.cpp

https://github.com/hashier/CG2
C++ | 247 lines | 202 code | 31 blank | 14 comment | 43 complexity | afeb479f21d5cdc784ccea87f32f2daf MD5 | raw file
  1. #include "Material.h"
  2. Material::Material() {
  3. mShaderProgram = NULL;
  4. setAmbientColor();
  5. setDiffuseColor();
  6. setEmissiveColor();
  7. setSpecularColor();
  8. mUniformsInitialized = false;
  9. for (unsigned int i = 0; i < MATERIAL_COMPONENT_COUNT; ++i) {
  10. mMaterialComponentEnabled[i] = false;
  11. }
  12. }
  13. Material::~Material() {
  14. // do not delete mShaderProgram, since it may be used by other materials //
  15. }
  16. void Material::setMaterialComponent(unsigned int comp, GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
  17. if (comp < MATERIAL_COMPONENT_COUNT) {
  18. MaterialComponent &mat = mMaterialComponent[comp];
  19. mMaterialComponentEnabled[comp] = true;
  20. mat.isEnabled = true;
  21. mat.value[0] = r;
  22. mat.value[1] = g;
  23. mat.value[2] = b;
  24. mat.value[3] = a;
  25. mUniformsInitialized = false;
  26. }
  27. }
  28. void Material::setMaterialComponentUniformNames(unsigned int comp, const char *uniformLocationName, const char *uniformIsEnabledName) {
  29. if (comp < MATERIAL_COMPONENT_COUNT) {
  30. mMaterialComponent[comp].uniformLocationName = std::string(uniformLocationName);
  31. mMaterialComponent[comp].uniformIsEnabledName = std::string(uniformIsEnabledName);
  32. if (mMaterialComponent[comp].uniformIsEnabledName.size() == 0) {
  33. std::stringstream sstr;
  34. sstr << mMaterialComponent[comp].uniformLocationName << "Enabled";
  35. mMaterialComponent[comp].uniformIsEnabledName = sstr.str();
  36. }
  37. mUniformsInitialized = false;
  38. }
  39. }
  40. void Material::setMaterialTexture(unsigned int layer, const char *textureFile) {
  41. if (layer < TEX_LAYER_COUNT) {
  42. if (loadTextureData(textureFile, mTexture[layer])) {
  43. if (layer < NORMAL_TEX) {
  44. mMaterialComponentEnabled[layer + 1] = true;
  45. }
  46. mUniformsInitialized = false;
  47. }
  48. }
  49. }
  50. void Material::setMaterialTextureUniformNames(unsigned int layer, const char *uniformLocationName, const char *uniformIsEnabledName) {
  51. if (layer < TEX_LAYER_COUNT) {
  52. mTexture[layer].uniformLocationName = std::string(uniformLocationName);
  53. mTexture[layer].uniformIsEnabledName = std::string(uniformIsEnabledName);
  54. if (mTexture[layer].uniformIsEnabledName.size() == 0) {
  55. std::stringstream sstr;
  56. sstr << mTexture[layer].uniformLocationName << "Enabled";
  57. mTexture[layer].uniformIsEnabledName = sstr.str();
  58. }
  59. mUniformsInitialized = false;
  60. }
  61. }
  62. void Material::setAmbientColor(GLfloat r, GLfloat g, GLfloat b) {
  63. setMaterialComponent(AMBIENT_COMP, r, g, b);
  64. }
  65. void Material::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b) {
  66. setMaterialComponent(DIFFUSE_COMP, r, g, b);
  67. }
  68. void Material::setEmissiveColor(GLfloat r, GLfloat g, GLfloat b) {
  69. setMaterialComponent(EMISSIVE_COMP, r, g, b);
  70. }
  71. void Material::setSpecularColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
  72. setMaterialComponent(SPECULAR_COMP, r, g, b, a);
  73. }
  74. void Material::setDiffuseTexture(const char *filename) {
  75. setMaterialTexture(DIFFUSE_TEX, filename);
  76. }
  77. void Material::setSpecularTexture(const char *filename) {
  78. setMaterialTexture(SPECULAR_TEX, filename);
  79. }
  80. void Material::setEmissiveTexture(const char *filename) {
  81. setMaterialTexture(EMISSIVE_TEX, filename);
  82. }
  83. void Material::setNormalTexture(const char *filename) {
  84. setMaterialTexture(NORMAL_TEX, filename);
  85. }
  86. void Material::setShaderProgram(Shader *shaderProgram) {
  87. mShaderProgram = shaderProgram;
  88. std::cerr << "(Material::setShaderProgram) - Set new shaderprogram (ID: " << mShaderProgram->getProgramID() << ")" << std::endl;
  89. // init default uniform locations //
  90. setMaterialComponentUniformNames(AMBIENT_COMP, "ambientColor");
  91. setMaterialComponentUniformNames(DIFFUSE_COMP, "diffuseColor");
  92. setMaterialComponentUniformNames(SPECULAR_COMP, "specularColor");
  93. setMaterialComponentUniformNames(EMISSIVE_COMP, "emissiveColor");
  94. setMaterialTextureUniformNames(DIFFUSE_TEX, "diffuseTex");
  95. setMaterialTextureUniformNames(SPECULAR_TEX, "specularTex");
  96. setMaterialTextureUniformNames(EMISSIVE_TEX, "emissiveTex");
  97. setMaterialTextureUniformNames(NORMAL_TEX, "normalTex");
  98. }
  99. Shader *Material::getShaderProgram() {
  100. return mShaderProgram;
  101. }
  102. void Material::initUniforms() {
  103. if (mShaderProgram) {
  104. // init active components //
  105. for (unsigned int comp = 0; comp < MATERIAL_COMPONENT_COUNT; ++comp) {
  106. // init uniform locations for material component //
  107. if (mMaterialComponent[comp].uniformLocationName.size() > 0) {
  108. // if name for uniform is defined -> try to get uniform location //
  109. mMaterialComponent[comp].uniformLocation = mShaderProgram->getUniformLocation(mMaterialComponent[comp].uniformLocationName.c_str());
  110. if (mMaterialComponent[comp].uniformLocation < 0) {
  111. std::cerr << "(Material::initUniforms) - Could not access uniform location for material component \"" << mMaterialComponent[comp].uniformLocationName << "\"" << std::endl;
  112. }
  113. mMaterialComponent[comp].uniformIsEnabled = mShaderProgram->getUniformLocation(mMaterialComponent[comp].uniformIsEnabledName.c_str());
  114. if (mMaterialComponent[comp].uniformIsEnabled < 0) {
  115. std::cerr << "(Material::initUniforms) - Could not access uniform location for material component enable \"" << mMaterialComponent[comp].uniformIsEnabledName << "\"" << std::endl;
  116. }
  117. }
  118. }
  119. for (unsigned int texLayer = 0; texLayer < TEX_LAYER_COUNT; ++texLayer) {
  120. if (mTexture[texLayer].uniformLocationName.size() > 0) {
  121. mTexture[texLayer].uniformLocation = mShaderProgram->getUniformLocation(mTexture[texLayer].uniformLocationName.c_str());
  122. if (mTexture[texLayer].uniformLocation < 0) {
  123. std::cerr << "(Material::initUniforms) - Could not access uniform location for texture \"" << mTexture[texLayer].uniformLocationName << "\"" << std::endl;
  124. }
  125. mTexture[texLayer].uniformIsEnabled = mShaderProgram->getUniformLocation(mTexture[texLayer].uniformIsEnabledName.c_str());
  126. if (mTexture[texLayer].uniformIsEnabled < 0) {
  127. std::cerr << "(Material::initUniforms) - Could not access uniform location for texture enable \"" << mTexture[texLayer].uniformIsEnabledName << "\"" << std::endl;
  128. }
  129. }
  130. }
  131. mUniformsInitialized = true;
  132. }
  133. }
  134. void Material::enable() {
  135. if (mShaderProgram != NULL && mShaderProgram->ready()) {
  136. mShaderProgram->enable();
  137. if (!mUniformsInitialized) {
  138. initUniforms();
  139. }
  140. } else {
  141. return;
  142. }
  143. for (unsigned int comp = 0; comp < MATERIAL_COMPONENT_COUNT; ++comp) {
  144. MaterialComponent &mat = mMaterialComponent[comp];
  145. if (mMaterialComponentEnabled[comp]) {
  146. // enable material component, if trigger uniform is defined //
  147. if (mat.uniformIsEnabled >= 0) {
  148. glUniform1i(mat.uniformIsEnabled, 1);
  149. }
  150. // link material value //
  151. glUniform4f(mat.uniformLocation, mat.value[0], mat.value[1], mat.value[2], mat.value[3]);
  152. } else {
  153. // disable material component, if trigger uniform is defined //
  154. if (mat.uniformIsEnabled >= 0) {
  155. glUniform1i(mat.uniformIsEnabled, 0);
  156. }
  157. }
  158. }
  159. for (unsigned int layer = 0; layer < TEX_LAYER_COUNT; ++layer) {
  160. if (mTexture[layer].isEnabled) {
  161. // enable texture, if trigger uniform defined //
  162. if (mTexture[layer].uniformIsEnabled >= 0) {
  163. glUniform1i(mTexture[layer].uniformIsEnabled, 1);
  164. }
  165. // link texture //
  166. glActiveTexture(GL_TEXTURE0 + layer);
  167. glBindTexture(GL_TEXTURE_2D, mTexture[layer].glTextureLocation);
  168. glUniform1i(mTexture[layer].uniformLocation, layer);
  169. } else {
  170. // disable texture, if trigger uniform defined //
  171. if (mTexture[layer].uniformIsEnabled >= 0) {
  172. glUniform1i(mTexture[layer].uniformIsEnabled, 0);
  173. }
  174. }
  175. }
  176. }
  177. void Material::disable() {
  178. if (mShaderProgram != NULL) {
  179. mShaderProgram->disable();
  180. }
  181. for (unsigned int layer = 0; layer < TEX_LAYER_COUNT; ++layer) {
  182. glActiveTexture(GL_TEXTURE0 + layer);
  183. glBindTexture(GL_TEXTURE_2D, 0);
  184. }
  185. }
  186. bool Material::loadTextureData(const char *textureFile, Texture &texture) {
  187. IplImage *image = cvLoadImage(textureFile, CV_LOAD_IMAGE_COLOR);
  188. if (image != NULL) {
  189. texture.width = image->width;
  190. texture.height = image->height;
  191. texture.data = new unsigned char[image->imageSize];
  192. if (image->origin == 0) {
  193. // flip rows of the image from top to bottom //
  194. cvFlip(image);
  195. }
  196. memcpy(texture.data, image->imageData, image->imageSize);
  197. std::cout << "(Material::loadTextureData) - imported \"" << textureFile << "\" (" << texture.width << ", " << texture.height << ")" << std::endl;
  198. glEnable(GL_TEXTURE_2D);
  199. // init openGL texture //
  200. if (texture.glTextureLocation <= 0) {
  201. // texture has not been generated yet //
  202. glGenTextures(1, &texture.glTextureLocation);
  203. }
  204. glBindTexture(GL_TEXTURE_2D, texture.glTextureLocation);
  205. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  206. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  207. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  208. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  209. gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texture.width, texture.height, GL_BGR, GL_UNSIGNED_BYTE, texture.data);
  210. glDisable(GL_TEXTURE_2D);
  211. texture.isEnabled = true;
  212. mUniformsInitialized = false;
  213. }
  214. cvReleaseImage(&image);
  215. return texture.isEnabled;
  216. }