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 ¢er = 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
1.5.6