00001 #include "Shader.h" 00002 00003 #include <cassert> 00004 00005 #include "Primitive.h" 00006 #include "TexCoordinate.h" 00007 #include "RGBAColor.h" 00008 #include "Texture.h" 00009 00010 00011 Shader::Shader(Scene* scene) 00012 : mScene(scene), 00013 mBumpTexture(0), 00014 mBumpCoeff(1.0f) 00015 { 00016 assert(scene); 00017 } 00018 00019 00020 unsigned int Shader::textureCount() const 00021 { 00022 return mTextures.size(); 00023 } 00024 00025 void Shader::addTexture(Texture* tex) 00026 { 00027 assert(tex); 00028 mTextures.push_back(tex); 00029 } 00030 00031 void Shader::removeTexture(Texture* tex) 00032 { 00033 for (std::vector<Texture*>::iterator it=mTextures.begin(); it != mTextures.end(); ) 00034 { 00035 if ((*it) == tex) 00036 it = mTextures.erase(it); 00037 else 00038 it++; 00039 } 00040 } 00041 00042 const Texture * Shader::texture(unsigned int i) const 00043 { 00044 if (i >= textureCount()) 00045 return NULL; 00046 return mTextures[i]; 00047 } 00048 00049 const Texture* Shader::bumpTexture() const 00050 { 00051 assert(mBumpTexture!=0); 00052 return mBumpTexture; 00053 } 00054 00055 void Shader::setBumpTexture(Texture* tex) 00056 { 00057 mBumpTexture = tex; 00058 } 00059 00060 const Vec3f Shader::normal(const Ray & ray) const 00061 { 00062 if(mBumpTexture==0) 00063 { 00064 return ray.hit()->normal(ray); 00065 } 00066 else 00067 { 00068 const TexCoordinate tex = ray.hit()->texCoord(ray); 00069 00070 Vec3f dPdu, dPdv; 00071 ray.hit()->axes(ray, dPdu, dPdv); 00072 00073 const float deltax = 1.0f / mBumpTexture->resX(); //one pixel step 00074 const float deltay = 1.0f / mBumpTexture->resY(); 00075 const RGBAColor value = mBumpTexture->texel(tex.x(),tex.y()); 00076 00077 const TexCoordinate xplus1(tex.x() + deltax, tex.y() ); 00078 const TexCoordinate yplus1(tex.x() , tex.y() + deltay); 00079 00080 //aprocimate the derivates for the texture 00081 const float du = mBumpTexture->texel( xplus1 ).r() - value.r(); 00082 const float dv = mBumpTexture->texel( yplus1 ).r() - value.r(); 00083 const Vec3f normal = ray.hit()->normal(ray); 00084 00085 //new normal as in the bump mapping formula 00086 const Vec3f newnormal = normal + mBumpCoeff * (du*dPdu + dv*dPdv); 00087 00088 return newnormal.normal(); 00089 } 00090 }