123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- #include "Private.h"
- #include "AmbientLightVisitor.h"
- #include "Group.h"
- #include "Shape3D.h"
- #include "Polygon.h"
- #include "Config.h"
- #include "Light.h"
- AmbientLightVisitor * AmbientLightVisitor::p_AmbientLightVisitor = NULL;
- AmbientLightVisitor::AmbientLightVisitor(int size) {
- m_fStrength = (float)0.1;
- m_fBackground = (float)0.0;
- m_vLight.reserve(size);
- }
- AmbientLightVisitor::~AmbientLightVisitor() {
- p_AmbientLightVisitor = NULL;
- }
- AmbientLightVisitor * AmbientLightVisitor::getInstance() {
- if (p_AmbientLightVisitor == NULL) {
- p_AmbientLightVisitor = new AmbientLightVisitor();
- }
- return p_AmbientLightVisitor;
- }
- void AmbientLightVisitor::add(Light* l) {
- if (l == NULL) return;
- m_vLight.push_back(l);
- }
- void AmbientLightVisitor::clear() {
- m_vLight.clear();
- }
- void AmbientLightVisitor::setLightning(float s, float bg) {
- m_fStrength = s;
- m_fBackground = bg;
- #if OPENGL_LIGHTS
- GLfloat amb[] = {bg, bg, bg, 1};
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
- glEnable(GL_LIGHT0);
-
-
- GLfloat pos[] = {0.0f, 10000.0f, 0.0f, 0.0f};
- GLfloat light[] = {s, s, s, 1.0f};
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light);
- glLightfv(GL_LIGHT0, GL_SPECULAR, light);
- #endif
- }
- void AmbientLightVisitor::visit(Group * g) {
-
- if (g->m_iProperties & EM_GROUP_NO_LIGHT) return;
- if (g->m_iProperties & EM_GROUP_LIGHT_ONCE) {
- g->unsetProperty(EM_GROUP_LIGHT_ONCE);
- g->setProperty(EM_GROUP_NO_LIGHT);
- }
- vector<Shape3D*>::iterator iter = g->m_vShape3D.begin();
- vector<Shape3D*>::iterator end = g->m_vShape3D.end();
- for ( ; iter != end; iter++) {
- if ((*iter)->m_iProperties & (EM_SHAPE3D_HIDDEN | EM_SHAPE3D_ALWAYSLIT)) continue;
-
-
- this->visitAmbient((*iter));
- this->visitPoint((*iter));
- }
- }
- void AmbientLightVisitor::visitAmbient(Shape3D* s) {
- EM_COUT("AmbientLightVisitor::visit()" << endl, 0);
-
- EM_COUT_D("AmbientLightVisitor::visit() shape lights " <<
- (*shapeIter)->m_vLight.size() << " normal " <<
- (*shapeIter)->m_vNmlTrans.size() << endl, 0);
-
- vector<Color>::iterator diffuseIter = s->m_vLight.begin();
- vector<Color>::iterator diffuseEnd = s->m_vLight.end();
- vector<Color>::iterator specularIter = s->m_vSpecular.begin();
- vector<Vertex3D>::iterator nmlTransIter = s->m_vNmlTrans.begin();
- vector<Vertex3D>::iterator nmlAlignIter = s->m_vNmlAlign.begin();
-
-
-
-
- for ( ; diffuseIter != diffuseEnd;
- ++diffuseIter, ++nmlTransIter, ++nmlAlignIter, ++specularIter) {
-
- float fAngle = (*nmlTransIter).y;
- float fLight = fAngle/2 + 0.5;
-
- (*diffuseIter).r = fLight * m_fStrength + m_fBackground;
- (*diffuseIter).r = EM_MIN(1.0, (*diffuseIter).r);
- (*diffuseIter).g = (*diffuseIter).b = (*diffuseIter).r;
- EM_COUT_D("Light " << (*diffuseIter).r << " " << (*diffuseIter).g << " " <<
- (*diffuseIter).b << endl, 0);
-
-
- #if EM_USE_GLOBAL_SPECULAR
- if (s->m_iProperties & EM_SHAPE3D_SPECULAR) {
- Vertex3D vtxRef = {0,0,-1};
- Vertex3D vtxDir = {0,-1,0};
- EMath::reflection(vtxDir, (*nmlAlignIter), vtxRef, false);
- EMath::normalizeVector(vtxRef);
-
- float spe = EM_MAX(0.0f, vtxRef.z);
- float spe2 = spe * spe;
- float spe4 = spe2 * spe2;
- (*specularIter).r = (*specularIter).g = (*specularIter).b = spe4 * spe4 * 0.5;
- } else {
- (*specularIter).r = (*specularIter).g = (*specularIter).b = 0;
- }
- #else
- (*specularIter).r = (*specularIter).g = (*specularIter).b = 0;
- #endif
- }
- }
- void AmbientLightVisitor::visitPoint(Shape3D * s) {
- if (Config::getInstance()->useLights()) {
- vector<Light*>::iterator lightIter = m_vLight.begin();
- vector<Light*>::iterator lightEnd = m_vLight.end();
- EM_COUT("PointLightVisitor::visit() lights " << m_vLight.size(), 0);
- for ( ; lightIter != lightEnd; ++lightIter) {
- if (!(*lightIter)->m_bOn) continue;
-
-
-
- vector<Vertex3D>::iterator vtxTransIter = s->m_vVtxTrans.begin();
- vector<Vertex3D>::iterator vtxTransEnd = s->m_vVtxTrans.end();
- vector<Vertex3D>::iterator vtxAlignIter = s->m_vVtxAlign.begin();
- vector<Vertex3D>::iterator nmlTransIter = s->m_vNmlTrans.begin();
- vector<Vertex3D>::iterator nmlAlignIter = s->m_vNmlAlign.begin();
- vector<Color>::iterator diffuseIter = s->m_vLight.begin();
- vector<Color>::iterator specularIter = s->m_vSpecular.begin();
-
-
-
-
-
-
- for ( ; vtxTransIter != vtxTransEnd;
- ++vtxTransIter, ++vtxAlignIter, ++nmlTransIter,
- ++nmlAlignIter, ++diffuseIter, ++specularIter) {
- if ((*lightIter)->m_iProperties & EM_USE_DIFFUSE) {
- Vertex3D vtxLight;
-
- vtxLight.x = (*lightIter)->m_vtxTrans.x - (*vtxTransIter).x;
- vtxLight.y = (*lightIter)->m_vtxTrans.y - (*vtxTransIter).y;
- vtxLight.z = (*lightIter)->m_vtxTrans.z - (*vtxTransIter).z;
- float lengthsqr = EMath::vectorLengthSqr(vtxLight);
-
- if (((*lightIter)->m_iProperties & EM_USE_BOUNDS) &&
- lengthsqr > ((*lightIter)->m_fBounds*(*lightIter)->m_fBounds)) {
- continue;
- }
-
-
- float light;
- if ((*lightIter)->m_iProperties & EM_IGNORE_ANGLE_FULL) {
- light = 1;
- } else if ((*lightIter)->m_iProperties & EM_IGNORE_ANGLE_HALF) {
- EMath::normalizeVector(vtxLight);
- float angle = EMath::dotProduct((*nmlTransIter), vtxLight);
- light = angle;
- if (light > 0.0f) light = 1.0f;
- } else {
- EMath::normalizeVector(vtxLight);
- float angle = EMath::dotProduct((*nmlTransIter), vtxLight);
- light = angle;
- light = EM_MAX(0.0f, light);
- }
-
- float k;
- if ((*lightIter)->m_iProperties & EM_IGNORE_DISTANCE) {
- k = light;
- } else {
- k = light / ((*lightIter)->m_fConstant +
- (*lightIter)->m_fLinear * EMath::emSqrt(lengthsqr) +
- (*lightIter)->m_fQuadratic * lengthsqr);
- }
- (*diffuseIter).r += k * (*lightIter)->m_fR;
- (*diffuseIter).g += k * (*lightIter)->m_fG;
- (*diffuseIter).b += k * (*lightIter)->m_fB;
- }
-
- #if EM_USE_SOURCE_SPECULAR
- if ((s->m_iProperties & EM_SHAPE3D_SPECULAR) &&
- ((*lightIter)->m_iProperties & EM_USE_SPECULAR)) {
- float specular;
- Vertex3D vtxRef = {0.0f ,0.0f , -1.0f};
- Vertex3D vtxDir;
- vtxDir.x = (*vtxAlignIter).x - (*lightIter)->m_vtxAlign.x;
- vtxDir.y = (*vtxAlignIter).y - (*lightIter)->m_vtxAlign.y;
- vtxDir.z = (*vtxAlignIter).z - (*lightIter)->m_vtxAlign.z;
- EMath::reflection(vtxDir, (*nmlAlignIter), vtxRef, false);
- EMath::normalizeVector(vtxRef);
-
- float spe = EM_MAX(0.0f, vtxRef.z);
- float spe2 = spe * spe;
- float spe4 = spe2 * spe2;
- specular = spe4 * spe4;
-
- (*specularIter).r += specular * (*lightIter)->m_fR;
- (*specularIter).g += specular * (*lightIter)->m_fG;
- (*specularIter).b += specular * (*lightIter)->m_fB;
- }
- #endif
- EM_COUT_D("PointLightVisitor::visit() factor " << k, 0);
- EM_COUT_D("PointLightVisitor::visit() specular " << specular, 0);
- }
- }
- }
-
-
- vector<Color>::iterator diffuseIter = s->m_vLight.begin();
- vector<Color>::iterator diffuseEnd = s->m_vLight.end();
- vector<Color>::iterator specularIter = s->m_vSpecular.begin();
- vector<Color>::iterator colorIter = s->m_vColor.begin();
- vector<Color>::iterator litColorIter = s->m_vLitColor.begin();
-
-
- for (; diffuseIter != diffuseEnd;
- ++diffuseIter, ++specularIter, ++colorIter, ++litColorIter) {
- (*litColorIter).r = (*colorIter).r * (*diffuseIter).r + (*specularIter).r;
- (*litColorIter).g = (*colorIter).g * (*diffuseIter).g + (*specularIter).g;
- (*litColorIter).b = (*colorIter).b * (*diffuseIter).b + (*specularIter).b;
- (*litColorIter).a = (*colorIter).a;
- }
-
-
-
-
-
-
-
-
-
- }
|