00001 #include <gra/shader/GLShader.h>
00002 #include <GL/gl.h>
00003
00004 using namespace gra;
00005
00006 void GLShader::_illum_vertices(Mesh& mesh) const
00007 {
00008 Vector3 v;
00009
00010 glBegin(GL_POINTS); {
00011 mesh.resetActSolid();
00012 do {
00013 mesh.resetVertWalkInSolid();
00014 do {
00015 if (_shadingMode == SMOOTH || _shadingMode == TEXTURE) {
00016 v.set(mesh.getActVertNormal());
00017 glNormal3f(v.x,v.y,v.z);
00018 }
00019 if (_shadingMode == TEXTURE) {
00020 #warning "TODO: Texture coordinates from mesh"
00021 }
00022 v.set(mesh.getActVert());
00023 glVertex3f(v.x,v.y,v.z);
00024 } while (mesh.stepInVertWalkInSolid());
00025 } while (mesh.goToNextSolid());
00026 } glEnd();
00027 }
00028
00029 void GLShader::_illum_edges(Mesh& mesh) const
00030 {
00031 Vector3 u,v;
00032
00033 glBegin(GL_LINES); {
00034 mesh.resetActSolid();
00035 do {
00036 mesh.resetEdgeWalkInSolid();
00037 do {
00038 if (_shadingMode == SMOOTH || _shadingMode == TEXTURE) {
00039 u.set(mesh.getActVertNormal1(false));
00040 v.set(mesh.getActVertNormal2(false));
00041 glNormal3f(u.x,u.y,u.z);
00042 glNormal3f(v.x,v.y,v.z);
00043 }
00044 if (_shadingMode == TEXTURE) {
00045 #warning "TODO: Texture coordinates from mesh"
00046 }
00047 u.set(mesh.getActVert1(false));
00048 v.set(mesh.getActVert2(false));
00049 glVertex3f(u.x,u.y,u.z);
00050 glVertex3f(v.x,v.y,v.z);
00051
00052 cerr << u << "--" << v << endl;
00053 } while (mesh.stepInEdgeWalkInSolid());
00054 } while (mesh.goToNextSolid());
00055 } glEnd();
00056 }
00057
00058 void GLShader::_illum_facets(GLenum polMode, Mesh& mesh) const
00059 {
00060 Vector3 v;
00061
00062 if (_shadingMode == FLAT)
00063 glShadeModel(GL_FLAT);
00064
00065 if (_shadingMode == SMOOTH || _shadingMode == TEXTURE)
00066 glShadeModel(GL_SMOOTH);
00067
00068 switch (_facetMode) {
00069 case FRONT:
00070 glCullFace(GL_BACK);
00071 glEnable(GL_CULL_FACE);
00072 glPolygonMode(GL_FRONT, polMode);
00073 break;
00074 case BACK:
00075 glCullFace(GL_FRONT);
00076 glEnable(GL_CULL_FACE);
00077 glPolygonMode(GL_BACK, polMode);
00078 break;
00079 case FRONT_AND_BACK:
00080 glDisable(GL_CULL_FACE);
00081 glPolygonMode(GL_FRONT_AND_BACK, polMode);
00082 break;
00083 default:
00084 fprintf(stderr,"GLShader::_illum_facets(): Uknown facet mode, using AUTO\n");
00085 case AUTO:
00086 if (mesh.hasOutwardNormals()) {
00087 glCullFace(GL_BACK);
00088 glEnable(GL_CULL_FACE);
00089 glPolygonMode(GL_FRONT, polMode);
00090 } else {
00091 glDisable(GL_CULL_FACE);
00092 glPolygonMode(GL_FRONT_AND_BACK,polMode);
00093 }
00094 break;
00095 }
00096
00097 mesh.resetActSolid();
00098 do {
00099 mesh.resetActPlane();
00100 do {
00101 glBegin(GL_POLYGON); {
00102 if (_shadingMode == FLAT) {
00103 v.set(mesh.getActPlaneNormal());
00104 glNormal3f(v.x,v.y,v.z);
00105 }
00106 mesh.resetActEdge();
00107 do {
00108 if (_shadingMode == SMOOTH || _shadingMode == TEXTURE) {
00109 v.set(mesh.getActVertNormal1(true));
00110 glNormal3f(v.x,v.y,v.z);
00111 }
00112 if (_shadingMode == TEXTURE) {
00113 #warning "TODO: Texture coordinates from mesh"
00114 }
00115 v.set(mesh.getActVert1(true));
00116 glVertex3f(v.x,v.y,v.z);
00117 } while (mesh.goToNextEdge());
00118 } glEnd();
00119
00120 } while (mesh.goToNextPlane());
00121 } while (mesh.goToNextSolid());
00122 }
00123
00124 bool GLShader::_use_precomputed_energy(PolygonalEnergy& energy) const
00125 {
00126 Vector3 v;
00127 AutoPtr<Mesh> * pAMesh = energy.getMesh();
00128 if (!pAMesh) return false;
00129 Mesh* pMesh = pAMesh->origObject();
00130 if (!pMesh) return false;
00131
00132 PolygonalEnergy::Regions regions = energy.getRegionsDescr();
00133 if (regions != PolygonalEnergy::VERTEX_BASED &&
00134 regions != PolygonalEnergy::FACET_BASED) return false;
00135
00136 pMesh->resetActSolid();
00137 do {
00138 pMesh->resetActPlane();
00139 do {
00140 glBegin(GL_POLYGON); {
00141 if (regions == PolygonalEnergy::FACET_BASED) {
00142 (void) energy.getRegionEnergy(pMesh->getActPlaneID(), v);
00143 glColor3f(v.x,v.y,v.z);
00144 }
00145 pMesh->resetActEdge();
00146 do {
00147 if (regions == PolygonalEnergy::VERTEX_BASED) {
00148 (void) energy.getRegionEnergy(pMesh->getActVertID1(true), v);
00149 glColor3f(v.x,v.y,v.z);
00150 }
00151 v.set(pMesh->getActVert1(true));
00152 glVertex3f(v.x,v.y,v.z);
00153 } while (pMesh->goToNextEdge());
00154 } glEnd();
00155 } while (pMesh->goToNextPlane());
00156 } while (pMesh->goToNextSolid());
00157
00158 return true;
00159 }
00160
00161
00162
00163 bool GLShader::setRenderedShape(SceneGraphObject * pShape,
00164 const Matrix4 * pTrMat)
00165 {
00166 _pShape = pShape;
00167
00168 if (!_pShape || !_pShape->supportsEnergy()) return false;
00169
00170
00171
00172
00173 if (_exploitEnergy) {
00174 AutoPtr<EnergyCoat>* pAE = pShape->getEnergyState();
00175 if (pAE) {
00176 EnergyCoat * pCoat = pAE->origObject();
00177 if (pCoat) {
00178 PolygonalEnergy* pE = dynamic_cast<PolygonalEnergy*>(pCoat);
00179 if (pE) return _use_precomputed_energy(*pE);
00180 }
00181 }
00182 }
00183
00184 GLint renderMode;
00185 glGetIntegerv(GL_RENDER_MODE, &renderMode);
00186
00187
00188
00189
00190 (_shadingMode == COLOR) ? glDisable(GL_LIGHTING) : glEnable(GL_LIGHTING);
00191
00192
00193
00194 Geometry* pGeom = pShape->geometry();
00195 if (!pGeom) return false;
00196 Mesh * pMesh = pGeom->mesh(_meshDensity);
00197 if (!pMesh) return false;
00198
00199 MatVisitor matVisitor;
00200 pShape->inspectMaterials(matVisitor);
00201
00202 float alpha = 1.0 - matVisitor.avgTransparency();
00203
00204 if (_shadingMode == COLOR) {
00205 glEnable(GL_COLOR_MATERIAL);
00206 glColor4f(matVisitor.diffuse().x,
00207 matVisitor.diffuse().y,
00208 matVisitor.diffuse().z,
00209 alpha);
00210 } else {
00211 float ambient[4] = { matVisitor.ambient().x,
00212 matVisitor.ambient().y,
00213 matVisitor.ambient().z,
00214 alpha };
00215 float diffuse[4] = { matVisitor.diffuse().x,
00216 matVisitor.diffuse().y,
00217 matVisitor.diffuse().z,
00218 alpha };
00219 float specular[4] = { matVisitor.specular().x,
00220 matVisitor.specular().y,
00221 matVisitor.specular().z,
00222 alpha };
00223 glDisable(GL_COLOR_MATERIAL);
00224 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
00225 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
00226 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
00227 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, matVisitor.intRoughness());
00228 }
00229
00230 glMatrixMode(GL_MODELVIEW);
00231 if (pTrMat) {
00232 float m[16];
00233 Matrix4 trMat(*pTrMat);
00234 trMat.transpose();
00235 trMat.get(m);
00236 glPushMatrix();
00237 glMultMatrixf(m);
00238 }
00239
00240 switch (_meshMode) {
00241 case VERTICES:
00242 _illum_vertices(*pMesh);
00243 break;
00244 case EDGES:
00245 _illum_edges(*pMesh);
00246 break;
00247 case FACETS:
00248 _illum_facets(GL_FILL, *pMesh);
00249 break;
00250 case FACET_EDGES:
00251 _illum_facets(GL_LINE, *pMesh);
00252 break;
00253 case FACET_CORNERS:
00254 _illum_facets(GL_POINT, *pMesh);
00255 break;
00256 default:
00257 fprintf(stderr,"GLShader Error: Unsuported mesh mode\n");
00258 };
00259
00260 if (pTrMat) glPopMatrix();
00261
00262 delete pMesh;
00263 return true;
00264 }
00265
00266