00001 #include <windows.h>
00002 #include "lightmap.h"
00003 #include "collision.h"
00004 #include "bsp.h"
00005 #include "texture.h"
00006 #include "tga.h"
00007 #include "mmgr.h"
00008
00009 extern int numStaticLights;
00010 extern char AppDirectory[MAX_PATH];
00011 extern int numLightmaps;
00012 extern StaticLight* staticlight;
00013
00014 void SetStaticLights(StaticLight* staticlight)
00015 {
00016 staticlight[0].Position.x = -4.0;
00017 staticlight[0].Position.y = 9.0;
00018 staticlight[0].Position.z = -50.0;
00019 staticlight[0].Radius = 300.0;
00020 staticlight[0].Brightness = 5.0;
00021 staticlight[0].Red = 255.0;
00022 staticlight[0].Green = 255.0;
00023 staticlight[0].Blue = 255.0;
00024
00025 staticlight[1].Position.x = -28.0;
00026 staticlight[1].Position.y = 9.0;
00027 staticlight[1].Position.z = -50.0;
00028 staticlight[1].Radius = 300.0;
00029 staticlight[1].Brightness = 5.0;
00030 staticlight[1].Red = 255.0;
00031 staticlight[1].Green = 255.0;
00032 staticlight[1].Blue = 255.0;
00033
00034 staticlight[2].Position.x = -52.0;
00035 staticlight[2].Position.y = 9.0;
00036 staticlight[2].Position.z = -50.0;
00037 staticlight[2].Radius = 300.0;
00038 staticlight[2].Brightness = 5.0;
00039 staticlight[2].Red = 255.0;
00040 staticlight[2].Green = 255.0;
00041 staticlight[2].Blue = 255.0;
00042
00043 staticlight[3].Position.x = -4.0;
00044 staticlight[3].Position.y = 9.0;
00045 staticlight[3].Position.z = 50.0;
00046 staticlight[3].Radius = 300.0;
00047 staticlight[3].Brightness = 5.0;
00048 staticlight[3].Red = 255.0;
00049 staticlight[3].Green = 255.0;
00050 staticlight[3].Blue = 255.0;
00051
00052 staticlight[4].Position.x = -28.0;
00053 staticlight[4].Position.y = 9.0;
00054 staticlight[4].Position.z = 50.0;
00055 staticlight[4].Radius = 300.0;
00056 staticlight[4].Brightness = 5.0;
00057 staticlight[4].Red = 255.0;
00058 staticlight[4].Green = 255.0;
00059 staticlight[4].Blue = 255.0;
00060
00061 staticlight[5].Position.x = -52.0;
00062 staticlight[5].Position.y = 9.0;
00063 staticlight[5].Position.z = 50.0;
00064 staticlight[5].Radius = 300.0;
00065 staticlight[5].Brightness = 5.0;
00066 staticlight[5].Red = 255.0;
00067 staticlight[5].Green = 255.0;
00068 staticlight[5].Blue = 255.0;
00069
00070 staticlight[6].Position.x = 110.0;
00071 staticlight[6].Position.y = 5.0;
00072 staticlight[6].Position.z = 120.0;
00073 staticlight[6].Radius = 100.0;
00074 staticlight[6].Brightness = 30.0;
00075 staticlight[6].Red = 255.0;
00076 staticlight[6].Green = 255.0;
00077 staticlight[6].Blue = 255.0;
00078
00079 staticlight[7].Position.x = 140.0;
00080 staticlight[7].Position.y = 0.0;
00081 staticlight[7].Position.z = -20.0;
00082 staticlight[7].Radius = 100.0;
00083 staticlight[7].Brightness = 10.0;
00084 staticlight[7].Red = 0.0;
00085 staticlight[7].Green = 255.0;
00086 staticlight[7].Blue = 255.0;
00087
00088 staticlight[8].Position.x = 0.0;
00089 staticlight[8].Position.y = 25.0;
00090 staticlight[8].Position.z = 0.0;
00091 staticlight[8].Radius = 45.0;
00092 staticlight[8].Brightness = 12.0;
00093 staticlight[8].Red = 250.0;
00094 staticlight[8].Green = 170.0;
00095 staticlight[8].Blue = 50.0;
00096 }
00097
00098 void CreateLightmaps(int numpolys, POLYGON* polylist, Lightmap* lightmaplist)
00099 {
00100 const int Width = 16;
00101 const int Height = 16;
00102 VECTOR lumels[Width][Height];
00103 VECTOR edge1, edge2;
00104 VECTOR newedge1, newedge2;
00105 VECTOR Vect1, Vect2;
00106 VECTOR UVVector;
00107 VECTOR poly_normal;
00108 VECTOR lightvector;
00109 VECTOR pointonplane;
00110 float lumelcolor[Width][Height][3];
00111 float lightdistance;
00112 float uvMin_U;
00113 float uvMin_V;
00114 float uvMax_U;
00115 float uvMax_V;
00116 float cosAngle;
00117 float X, Y, Z;
00118 float Distance;
00119 float uvDelta_U;
00120 float uvDelta_V;
00121 float ufactor;
00122 float vfactor;
00123 float combinedred;
00124 float combinedgreen;
00125 float combinedblue;
00126 float intensity;
00127 int flag;
00128 char temp[256];
00129 unsigned char* lightmap = new unsigned char[Width * Height * 4];
00130
00131 for (int loop = 0; loop < numpolys; loop++)
00132 {
00133
00134 poly_normal = polylist[loop].GetNormal();
00135 poly_normal.Normalize();
00136 pointonplane = polylist[loop].Vertex[0].coords;
00137
00138
00139 if (fabs(poly_normal.x) > fabs(poly_normal.y) && fabs(poly_normal.x) > fabs(poly_normal.z))
00140 {
00141 flag = 1;
00142 lightmaplist[loop].vertex_u[0] = polylist[loop].Vertex[0].coords.y;
00143 lightmaplist[loop].vertex_v[0] = polylist[loop].Vertex[0].coords.z;
00144 lightmaplist[loop].vertex_u[1] = polylist[loop].Vertex[1].coords.y;
00145 lightmaplist[loop].vertex_v[1] = polylist[loop].Vertex[1].coords.z;
00146 lightmaplist[loop].vertex_u[2] = polylist[loop].Vertex[2].coords.y;
00147 lightmaplist[loop].vertex_v[2] = polylist[loop].Vertex[2].coords.z;
00148 }
00149 else if (fabs(poly_normal.y) > fabs(poly_normal.x) && fabs(poly_normal.y) > fabs(poly_normal.z))
00150 {
00151 flag = 2;
00152 lightmaplist[loop].vertex_u[0] = polylist[loop].Vertex[0].coords.x;
00153 lightmaplist[loop].vertex_v[0] = polylist[loop].Vertex[0].coords.z;
00154 lightmaplist[loop].vertex_u[1] = polylist[loop].Vertex[1].coords.x;
00155 lightmaplist[loop].vertex_v[1] = polylist[loop].Vertex[1].coords.z;
00156 lightmaplist[loop].vertex_u[2] = polylist[loop].Vertex[2].coords.x;
00157 lightmaplist[loop].vertex_v[2] = polylist[loop].Vertex[2].coords.z;
00158 }
00159 else
00160 {
00161 flag = 3;
00162 lightmaplist[loop].vertex_u[0] = polylist[loop].Vertex[0].coords.x;
00163 lightmaplist[loop].vertex_v[0] = polylist[loop].Vertex[0].coords.y;
00164 lightmaplist[loop].vertex_u[1] = polylist[loop].Vertex[1].coords.x;
00165 lightmaplist[loop].vertex_v[1] = polylist[loop].Vertex[1].coords.y;
00166 lightmaplist[loop].vertex_u[2] = polylist[loop].Vertex[2].coords.x;
00167 lightmaplist[loop].vertex_v[2] = polylist[loop].Vertex[2].coords.y;
00168 }
00169
00170
00171 uvMin_U = lightmaplist[loop].vertex_u[0];
00172 uvMin_V = lightmaplist[loop].vertex_v[0];
00173 uvMax_U = lightmaplist[loop].vertex_u[0];
00174 uvMax_V = lightmaplist[loop].vertex_v[0];
00175
00176 for (int i = 0; i < 3; i++)
00177 {
00178 if (lightmaplist[loop].vertex_u[i] < uvMin_U )
00179 uvMin_U = lightmaplist[loop].vertex_u[i];
00180 if (lightmaplist[loop].vertex_v[i] < uvMin_V )
00181 uvMin_V = lightmaplist[loop].vertex_v[i];
00182 if (lightmaplist[loop].vertex_u[i] > uvMax_U )
00183 uvMax_U = lightmaplist[loop].vertex_u[i];
00184 if (lightmaplist[loop].vertex_v[i] > uvMax_V )
00185 uvMax_V = lightmaplist[loop].vertex_v[i];
00186 }
00187
00188 uvDelta_U = uvMax_U - uvMin_U;
00189 uvDelta_V = uvMax_V - uvMin_V;
00190
00191 for (int i = 0; i < 3; i++)
00192 {
00193 lightmaplist[loop].vertex_u[i] -= uvMin_U;
00194 lightmaplist[loop].vertex_v[i] -= uvMin_V;
00195 lightmaplist[loop].vertex_u[i] /= uvDelta_U;
00196 lightmaplist[loop].vertex_v[i] /= uvDelta_V;
00197 }
00198
00199
00200 Distance = - (poly_normal.x * pointonplane.x + poly_normal.y * pointonplane.y + poly_normal.z * pointonplane.z);
00201
00202 switch (flag)
00203 {
00204 case 1:
00205 X = - (poly_normal.y * uvMin_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.x;
00206 UVVector.x = X;
00207 UVVector.y = uvMin_U;
00208 UVVector.z = uvMin_V;
00209 X = - (poly_normal.y * uvMax_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.x;
00210 Vect1.x = X;
00211 Vect1.y = uvMax_U;
00212 Vect1.z = uvMin_V;
00213 X = - (poly_normal.y * uvMin_U + poly_normal.z * uvMax_V + Distance ) / poly_normal.x;
00214 Vect2.x = X;
00215 Vect2.y = uvMin_U;
00216 Vect2.z = uvMax_V;
00217 break;
00218
00219 case 2:
00220 Y = - (poly_normal.x * uvMin_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.y;
00221 UVVector.x = uvMin_U;
00222 UVVector.y = Y;
00223 UVVector.z = uvMin_V;
00224 Y = - (poly_normal.x * uvMax_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.y;
00225 Vect1.x = uvMax_U;
00226 Vect1.y = Y;
00227 Vect1.z = uvMin_V;
00228 Y = - (poly_normal.x * uvMin_U + poly_normal.z * uvMax_V + Distance ) / poly_normal.y;
00229 Vect2.x = uvMin_U;
00230 Vect2.y = Y;
00231 Vect2.z = uvMax_V;
00232 break;
00233
00234 case 3:
00235 Z = - (poly_normal.x * uvMin_U + poly_normal.y * uvMin_V + Distance ) / poly_normal.z;
00236 UVVector.x = uvMin_U;
00237 UVVector.y = uvMin_V;
00238 UVVector.z = Z;
00239 Z = - (poly_normal.x * uvMax_U + poly_normal.y * uvMin_V + Distance ) / poly_normal.z;
00240 Vect1.x = uvMax_U;
00241 Vect1.y = uvMin_V;
00242 Vect1.z = Z;
00243 Z = - (poly_normal.x * uvMin_U + poly_normal.y * uvMax_V + Distance ) / poly_normal.z;
00244 Vect2.x = uvMin_U;
00245 Vect2.y = uvMax_V;
00246 Vect2.z = Z;
00247 break;
00248 }
00249
00250 edge1 = Vect1 - UVVector;
00251 edge2 = Vect2 - UVVector;
00252 for(int iX = 0; iX < Width; iX++)
00253 {
00254 for(int iY = 0; iY < Height; iY++)
00255 {
00256 ufactor = (iX / (float)Width);
00257 vfactor = (iY / (float)Height);
00258 newedge1.x = edge1.x * ufactor;
00259 newedge1.y = edge1.y * ufactor;
00260 newedge1.z = edge1.z * ufactor;
00261 newedge2.x = edge2.x * vfactor;
00262 newedge2.y = edge2.y * vfactor;
00263 newedge2.z = edge2.z * vfactor;
00264
00265 lumels[iX][iY] = UVVector + newedge2 + newedge1;
00266
00267 combinedred = 0.0;
00268 combinedgreen = 0.0;
00269 combinedblue = 0.0;
00270 for (int i = 0; i < numStaticLights; i++)
00271 {
00272 if (ClassifyPoint(staticlight[i].Position, pointonplane, poly_normal) == 1)
00273 {
00274 lightvector = staticlight[i].Position - lumels[iX][iY];
00275 lightdistance = lightvector.GetMagnitude();
00276 lightvector.Normalize();
00277 cosAngle = DotProduct(poly_normal, lightvector);
00278 if (lightdistance < staticlight[i].Radius)
00279 {
00280 intensity = (staticlight[i].Brightness * cosAngle) / lightdistance;
00281 combinedred += staticlight[i].Red * intensity;
00282 combinedgreen += staticlight[i].Green * intensity;
00283 combinedblue += staticlight[i].Blue * intensity;
00284 }
00285 }
00286 }
00287 if (combinedred > 255.0)
00288 combinedred = 255.0;
00289 if (combinedgreen > 255.0)
00290 combinedgreen = 255.0;
00291 if (combinedblue > 255.0)
00292 combinedblue = 255.0;
00293 lumelcolor[iX][iY][0] = combinedred;
00294 lumelcolor[iX][iY][1] = combinedgreen;
00295 lumelcolor[iX][iY][2] = combinedblue;
00296 }
00297 }
00298
00299 for(int iX = 0; iX < (Width * 4); iX += 4)
00300 {
00301 for(int iY = 0; iY < Height; iY += 1)
00302 {
00303 lightmap[iX + iY * Height * 4] = (char)lumelcolor[iX / 4][iY][0];
00304 lightmap[iX + iY * Height * 4 + 1] = (char)lumelcolor[iX / 4][iY][1];
00305 lightmap[iX + iY * Height * 4 + 2] = (char)lumelcolor[iX / 4][iY][2];
00306 lightmap[iX + iY * Height * 4 + 3] = 255;
00307 }
00308 }
00309
00310 sprintf(lightmaplist[loop].Texture.TexName, "%s", AppDirectory);
00311 strcat(lightmaplist[loop].Texture.TexName, "\\images\\lm");
00312 strcat(lightmaplist[loop].Texture.TexName, itoa(numLightmaps++, temp, 10));
00313 strcat(lightmaplist[loop].Texture.TexName, ".tga");
00314 tgaSave(lightmaplist[loop].Texture.TexName, Width, Height, 32, lightmap);
00315
00316 }
00317 delete[] lightmap;
00318 return;
00319 }
00320
00321 void CreateBSPLightmaps(BSP_node* node)
00322 {
00323 if (node->leaf)
00324 {
00325 node->nodelightmaplist = new Lightmap[node->numpolys];
00326 CreateLightmaps(node->numpolys, node->nodepolylist, node->nodelightmaplist);
00327 return;
00328 }
00329 CreateBSPLightmaps(node->frontnode);
00330 CreateBSPLightmaps(node->backnode);
00331 }
00332
00333 void LoadBSPLightmaps(BSP_node* node)
00334 {
00335 if (node->leaf)
00336 {
00337 for (int i = 0; i < node->numpolys; i++)
00338 {
00339 node->nodelightmaplist[i].Texture.LoadTGA(GL_LINEAR, GL_NEAREST_MIPMAP_LINEAR, GL_CLAMP, GL_CLAMP, 1);
00340
00341 }
00342 return;
00343 }
00344 LoadBSPLightmaps(node->frontnode);
00345 LoadBSPLightmaps(node->backnode);
00346 }
00347