00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021 #include <math.h>
00022
00023 #include <archon/util/color.H>
00024 #include <archon/util/image.H>
00025
00026 #include "surface.H"
00027
00028 namespace Archon
00029 {
00030 using namespace Utilities;
00031 using namespace Math;
00032
00033 namespace Raytracer
00034 {
00038 ColorRGBA Surface::shade(const Light &light, const Vector3 &normal,
00039 const Vector3 &viewDirection, const Vector3 &lightDirection,
00040 const ColorRGBA &surfaceColor) const
00041 {
00042
00043
00044
00045 Vector3 h = lightDirection;
00046 h += viewDirection;
00047 h /= 2;
00048
00049 const double f = diffuseReflection * dot(lightDirection, normal);
00050 const double s = specularReflection * pow(dot(normal, h), reflectiveExponent);
00051
00052 return Vector3(light.getColor()[0] * surfaceColor[0] * f + s,
00053 light.getColor()[1] * surfaceColor[1] * f + s,
00054 light.getColor()[2] * surfaceColor[2] * f + s);
00055 }
00056
00057 inline int modulo(int x, int y)
00058 {
00059 const int v = x % y;
00060 return v < 0 ? v + y : v;
00061 }
00062
00071 void Texture::getColor(const Vector2 &texturePoint, ColorRGBA &c) const
00072 {
00073 const int tileWidth = image.getWidth();
00074 const int tileHeight = image.getHeight();
00075
00076 const int width = tileWidth * horizontalTiles;
00077 const int height = tileHeight * verticalTiles;
00078
00079 const double x = width * texturePoint[0] - 0.5;
00080 const double y = height * texturePoint[1] - 0.5;
00081
00082
00083 const int xi = static_cast<int>(floor(x));
00084 const int yi = static_cast<int>(floor(y));
00085
00086 const int x0 = modulo(xi, tileWidth);
00087 const int x1 = (x0 + 1) % tileWidth;
00088 const int y0 = modulo(yi, tileHeight);
00089 const int y1 = (y0 + 1) % tileHeight;
00090
00091 const double xf = x - xi;
00092 const double yf = y - yi;
00093
00094 const double k1 = (1 - xf) * (1 - yf);
00095 const double k2 = xf * (1 - yf);
00096 const double k3 = (1 - xf) * yf;
00097 const double k4 = xf * yf;
00098
00099 ColorRGBA c1, c2, c3, c4;
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 image.getPixel(x0, y0, c1[0], c1[1], c1[2], c1[3]);
00136 image.getPixel(x1, y0, c2[0], c2[1], c2[2], c2[3]);
00137 image.getPixel(x0, y1, c3[0], c3[1], c3[2], c3[3]);
00138 image.getPixel(x1, y1, c4[0], c4[1], c4[2], c4[3]);
00139
00140
00141
00142 c[0] = k1 * c1[0] + k2 * c2[0] + k3 * c3[0] + k4 * c4[0];
00143 c[1] = k1 * c1[1] + k2 * c2[1] + k3 * c3[1] + k4 * c4[1];
00144 c[2] = k1 * c1[2] + k2 * c2[2] + k3 * c3[2] + k4 * c4[2];
00145 c[3] = k1 * c1[3] + k2 * c2[3] + k3 * c3[3] + k4 * c4[3];
00146 }
00147 }
00148 }
00149