materials.cpp
00001 #include "materials.h"
00002 #include <fstream>
00003 #ifdef __APPLE__
00004 #include <OpenGL/glu.h>
00005 #endif
00006 #include <QString>
00007
00008 #define REPORT_GL_ERROR(str) reportGLError(str, __FILE__, __LINE__)
00009
00010 #include <iostream>
00011
00012 static bool reportGLError( QString id, const char* file, int line )
00013 {
00014 GLenum error = glGetError();
00015 if(error)
00016 {
00017 std::cerr << "OpenGL error in file " << file << " on line " << line << " for command " << id.toStdString() << ":" << std::endl
00018 << gluErrorString(error) << std::endl;
00019
00020 return true;
00021 }
00022 return false;
00023 }
00024
00025
00029 util::Materials::Materials(std::string filename)
00030 : FileObject(filename)
00031 {
00032 for(int i = 0 ; i < 256 ; ++i)
00033 {
00034 mats[i].isDefault = true;
00035 }
00036 reread();
00037 }
00038
00040 void util::Materials::reread() {
00041 unsigned int index = 0;
00042 std::ifstream in(filename.c_str(), std::ios::binary);
00043
00044 while (!in.eof() && in.good() && in) {
00045 unsigned char mat[15];
00046
00047 for (int i = 0; i < 15; i++) {
00048 mat[i] = in.get();
00049 }
00050
00051 index = mat[0];
00052
00053 mats[index].isDefault = false;
00054
00055 mats[index].transparency = float(mat[1]) / 255.0;
00056
00057 mats[index].ambient[0] = float(mat[2]) / 255.0;
00058 if (mats[index].ambient[0] < 0.0 || mats[index].ambient[0] > 1.0) mats[index].ambient[0] = 0.2f;
00059 mats[index].ambient[1] = float(mat[3]) / 255.0;
00060 if (mats[index].ambient[1] < 0.0 || mats[index].ambient[1] > 1.0) mats[index].ambient[1] = 0.2f;
00061 mats[index].ambient[2] = float(mat[4]) / 255.0;
00062 if (mats[index].ambient[2] < 0.0 || mats[index].ambient[2] > 1.0) mats[index].ambient[2] = 0.2f;
00063 mats[index].ambient[3] = 1.0f - mats[index].transparency;
00064
00065 mats[index].diffuse[0] = float(mat[5]) / 255.0;
00066 if (mats[index].diffuse[0] < 0.0 || mats[index].diffuse[0] > 1.0) mats[index].diffuse[0] = 0.8f;
00067 mats[index].diffuse[1] = float(mat[6]) / 255.0;
00068 if (mats[index].diffuse[1] < 0.0 || mats[index].diffuse[1] > 1.0) mats[index].diffuse[1] = 0.8f;
00069 mats[index].diffuse[2] = float(mat[7]) / 255.0;
00070 if (mats[index].diffuse[2] < 0.0 || mats[index].diffuse[2] > 1.0) mats[index].diffuse[2] = 0.8f;
00071 mats[index].diffuse[3] = 1.0f - mats[index].transparency;
00072
00073 mats[index].emission[0] = float(mat[8]) / 255.0;
00074 if (mats[index].emission[0] < 0.0 || mats[index].emission[0] > 1.0) mats[index].emission[0] = 0.0f;
00075 mats[index].emission[1] = float(mat[9]) / 255.0;
00076 if (mats[index].emission[1] < 0.0 || mats[index].emission[1] > 1.0) mats[index].emission[1] = 0.0f;
00077 mats[index].emission[2] = float(mat[10]) / 255.0;
00078 if (mats[index].emission[2] < 0.0 || mats[index].emission[2] > 1.0) mats[index].emission[2] = 0.0f;
00079 mats[index].emission[3] = 1.0f - mats[index].transparency;
00080
00081 mats[index].specular[0] = float(mat[11]) / 255.0;
00082 if (mats[index].specular[0] < 0.0 || mats[index].specular[0] > 1.0) mats[index].specular[0] = 0.0f;
00083 mats[index].specular[1] = float(mat[12]) / 255.0;
00084 if (mats[index].specular[1] < 0.0 || mats[index].specular[1] > 1.0) mats[index].specular[1] = 0.0f;
00085 mats[index].specular[2] = float(mat[13]) / 255.0;
00086 if (mats[index].specular[2] < 0.0 || mats[index].specular[2] > 1.0) mats[index].specular[2] = 0.0f;
00087 mats[index].specular[3] = 1.0f - mats[index].transparency;
00088
00089 mats[index].shiny = float(mat[14]) / 255.0; if (mats[index].shiny < 0.0) mats[index].shiny = 0.0f;
00090 }
00091
00092 for (index = 0; index < 256; index++) {
00093 if(mats[index].isDefault)
00094 {
00095 mats[index].ambient[0] = 0.2f;
00096 mats[index].ambient[1] = 0.2f;
00097 mats[index].ambient[2] = 0.2f;
00098 mats[index].ambient[3] = 1.0f;
00099
00100 mats[index].diffuse[0] = 0.8f;
00101 mats[index].diffuse[1] = 0.8f;
00102 mats[index].diffuse[2] = 0.8f;
00103 mats[index].diffuse[3] = 1.0f;
00104
00105 mats[index].emission[0] = 0.0f;
00106 mats[index].emission[1] = 0.0f;
00107 mats[index].emission[2] = 0.0f;
00108 mats[index].emission[3] = 1.0f;
00109
00110 mats[index].specular[0] = 0.0f;
00111 mats[index].specular[1] = 0.0f;
00112 mats[index].specular[2] = 0.0f;
00113 mats[index].specular[3] = 1.0f;
00114
00115 mats[index].shiny = 0.0f;
00116 mats[index].transparency = 0.0f;
00117 }
00118 }
00119 }
00120
00124 void util::Materials::useMaterial(unsigned int index) {
00125 if (index > 255) index = 255;
00126
00127
00128
00129
00130
00131
00132 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00133 REPORT_GL_ERROR("glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);");
00134 glColor4fv(mats[index].diffuse);
00135 REPORT_GL_ERROR("glColor4fv(mats[index].diffuse);");
00136 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
00137 REPORT_GL_ERROR("glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);");
00138 glColor4fv(mats[index].emission);
00139 REPORT_GL_ERROR("glColor4fv(mats[index].emission);");
00140 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
00141 REPORT_GL_ERROR("glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);");
00142 glColor4fv(mats[index].specular);
00143 REPORT_GL_ERROR("glColor4fv(mats[index].specular);");
00144 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mats[index].shiny);
00145 REPORT_GL_ERROR(QString("glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, %1);").arg(mats[index].shiny));
00146 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
00147 REPORT_GL_ERROR("glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);");
00148 glColor4fv(mats[index].ambient);
00149 REPORT_GL_ERROR("glColor4fv(mats[index].ambient);");
00150 }
00151
00155 const util::Materials::Material& util::Materials::getMaterial(unsigned int index) {
00156 if (index > 255) index = 255;
00157 return mats[index];
00158 }
00159
00167 void util::Materials::blend(unsigned int ind1, unsigned int ind2, float t) {
00168 Material m;
00169
00170 if (t < 0.0) t = 0.0;
00171 else if (t > 1.0) t = 1.0;
00172
00173 float t1 = 1.0 - t;
00174
00175 m.ambient[0] = t * mats[ind1].ambient[0] + t1 * mats[ind2].ambient[0];
00176 m.ambient[1] = t * mats[ind1].ambient[1] + t1 * mats[ind2].ambient[1];
00177 m.ambient[2] = t * mats[ind1].ambient[2] + t1 * mats[ind2].ambient[2];
00178 m.ambient[3] = t * mats[ind1].ambient[3] + t1 * mats[ind2].ambient[3];
00179
00180 m.diffuse[0] = t * mats[ind1].diffuse[0] + t1 * mats[ind2].diffuse[0];
00181 m.diffuse[1] = t * mats[ind1].diffuse[1] + t1 * mats[ind2].diffuse[1];
00182 m.diffuse[2] = t * mats[ind1].diffuse[2] + t1 * mats[ind2].diffuse[2];
00183 m.diffuse[3] = t * mats[ind1].diffuse[3] + t1 * mats[ind2].diffuse[3];
00184
00185 m.specular[0] = t * mats[ind1].specular[0] + t1 * mats[ind2].specular[0];
00186 m.specular[1] = t * mats[ind1].specular[1] + t1 * mats[ind2].specular[1];
00187 m.specular[2] = t * mats[ind1].specular[2] + t1 * mats[ind2].specular[2];
00188 m.specular[3] = t * mats[ind1].specular[3] + t1 * mats[ind2].specular[3];
00189
00190 m.emission[0] = t * mats[ind1].emission[0] + t1 * mats[ind2].emission[0];
00191 m.emission[1] = t * mats[ind1].emission[1] + t1 * mats[ind2].emission[1];
00192 m.emission[2] = t * mats[ind1].emission[2] + t1 * mats[ind2].emission[2];
00193 m.emission[3] = t * mats[ind1].emission[3] + t1 * mats[ind2].emission[3];
00194
00195 m.shiny = t * mats[ind1].shiny + t1 * mats[ind2].shiny;
00196
00197 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m.ambient);
00198 REPORT_GL_ERROR("glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m.ambient);");
00199 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m.diffuse);
00200 REPORT_GL_ERROR("glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m.diffuse);");
00201 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, m.emission);
00202 REPORT_GL_ERROR("glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, m.emission);");
00203 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m.specular);
00204 REPORT_GL_ERROR("glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m.specular);");
00205 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m.shiny);
00206 REPORT_GL_ERROR("glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m.shiny);");
00207 }