Emitter.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   Emitter.h
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Fall 2008
00006    
00007    @brief
00008       Abstract representation of emittance defined at a single point on a 
00009    surface in 3-space (describing a light).
00010    
00011       The reason Emitter subclasses BSDF is for convenience during generation 
00012    and evaluation of paths in bidirectional path tracing.  Emittance at a 
00013    point in a given direction, Le(x,wo), is broken into two parts, 
00014    Le0(x), and Le1(x), as originally detailed by Veach and Guibas
00015    (see Eric Veach's thesis, section 8.3.2).  Scattering at a vertex can then 
00016    be uniformly viewed as evaluation / sampling of a BSDF, including initial, 
00017    fake 'scattering' at a light source, which can be viewed as a special case 
00018    of scattering with no incident vector (the incident vector is thus 
00019    disregarded).
00020    
00021    @see Emitter::getBSDF() or the Path class for more details.
00022    <!-------------------------------------------------------------------->**/
00023 
00024 #include "Emitter.h"
00025 #include "Material.h"
00026 
00027 #include <GLState.h>
00028 #include <Shape.h>
00029 
00030 #include <GL/gl.h>
00031 #include <GL/glu.h>
00032 
00033 void Emitter::init() {
00034    ASSERT(m_parent);
00035    
00036    m_power = m_parent->getValue<SpectralSampleSet>("power", 
00037                                                    SpectralSampleSet::black());
00038    
00039    const real_t surfaceArea = 
00040       (m_pt.shape ? m_pt.shape->getSurfaceArea() : 0);
00041    
00042    if (NEQ(surfaceArea, 0)) {
00043       m_radiantExitance = m_power / surfaceArea;
00044    } else {
00045       m_radiantExitance = m_power;
00046    }
00047    
00048    BSDF::init();
00049 }
00050 
00051 bool Emitter::isEmitter() {
00052    return (getPower() != SpectralSampleSet::black());
00053 }
00054 
00055 SpectralSampleSet Emitter::getPower() {
00056    return m_power;
00057 }
00058 
00059 SpectralSampleSet Emitter::getRadiantExitance() {
00060    return m_radiantExitance;
00061 }
00062 
00063 SpectralSampleSet Emitter::getLe0() {
00064    return m_radiantExitance;
00065 }
00066 
00067 SpectralSampleSet Emitter::getLe1(const Vector3 &wo) {
00068    return getLe(wo) / getLe0();
00069 }
00070 
00071 void Emitter::preview(Shape *shape) {
00072    ASSERT(m_parent);
00073    
00074    //unsigned lightIndex = m_parent->getValue<unsigned int>("glLightIndex", 0);
00075    //ASSERT(lightIndex >= 0 && lightIndex <= 8);
00076    //lightIndex += GL_LIGHT0;
00077    
00078    GLint lightIndex = GLState::getFreeLight();
00079    //cerr << "LightIndex: " << (lightIndex - GL_LIGHT0) << endl;
00080    
00081    if (lightIndex < GL_LIGHT0)
00082       return;
00083    
00084    // enable light
00085    glEnable(lightIndex);
00086    GL_CHECK_ERROR();
00087    
00088    // light position
00089    glPushMatrix();
00090    glLoadIdentity();
00091    
00092    const Point3 &center    = shape->getAABB().getCenter();
00093    const GLfloat centerf[] = {
00094       center[0], center[1], center[2], center[3]
00095    };
00096    
00097    glLightfv(lightIndex, GL_POSITION, centerf);
00098    GL_CHECK_ERROR();
00099    
00100    
00101    // light color
00102    const Vector3 &diffuseColor  = m_parent->getValue<Vector3>(
00103       "glDiffuseColor",  Vector3(1, 1, 1));
00104    const Vector3 &specularColor = m_parent->getValue<Vector3>(
00105       "glSpecularColor", Vector3(1, 1, 1));
00106    
00107    const GLfloat diffuse[] = {
00108       diffuseColor[0], diffuseColor[1], diffuseColor[2], 1
00109    };
00110    
00111    const GLfloat specular[] = {
00112       specularColor[0], specularColor[1], specularColor[2], 1
00113    };
00114    
00115    glLightfv(lightIndex, GL_DIFFUSE,  diffuse);
00116    glLightfv(lightIndex, GL_SPECULAR, specular);
00117    
00118    GL_CHECK_ERROR();
00119    
00120    // light function (attenuation)
00121    const Vector3 &attenuation = m_parent->getValue<Vector3>(
00122       "glAttenuation", Vector3(1, 0, 0));
00123    
00124    glLightf(lightIndex, GL_CONSTANT_ATTENUATION, attenuation[0]);
00125    glLightf(lightIndex, GL_LINEAR_ATTENUATION, attenuation[1]);
00126    glLightf(lightIndex, GL_QUADRATIC_ATTENUATION, attenuation[2]);
00127    
00128    glTranslatef(centerf[0], centerf[1], centerf[2]);
00129    
00130    glPushAttrib(GL_POLYGON_BIT | GL_LIGHTING_BIT);
00131    //GLint params[2];
00132    //glGetInteverv(GL_POLYGON_MODE, params);
00133    
00134    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00135    glDisable(GL_LIGHTING);
00136    
00137    glColor3f(204 / 255.0f, 51 / 255.0f, 1);
00138    GLUquadric *quadric = gluNewQuadric();
00139    gluSphere(quadric, 0.25, 20, 20);
00140    gluDeleteQuadric(quadric);
00141    
00142    //glPolygonMode(params[0], params[1]);
00143    
00144    glPopAttrib(); // GL_POLYGON_BIT | GL_LIGHTING_BIT
00145    
00146    glPopMatrix();
00147    
00148    GL_CHECK_ERROR();
00149 }
00150 
00151 Event Emitter::sample() {
00152    ASSERT(m_sampler);
00153    
00154    Event e = m_sampler->sample();
00155    e.setParent(this);
00156    
00157    return e;
00158 }
00159 
00160 real_t Emitter::getPdf(const Event &event) {
00161    ASSERT(m_sampler);
00162    //const Vector3 &wo = event.getValue<const Vector3&>();
00163    
00164    return m_sampler->getPdf(event);
00165 }
00166 
00167 SpectralSampleSet Emitter::getBSDF(const Vector3 &/* wi unused */, 
00168                                    const Vector3 &wo)
00169 {
00170    return getLe1(wo);
00171 }
00172 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6