00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Canvas.h"
00011 #include "color.h"
00012 #include "xmath.h"
00013 #include "TriangleMesh.h"
00014 #include "Sphere.h"
00015
00016 #include <iostream>
00017 #include <sstream>
00018 #include <iomanip>
00019
00020
00021 using namespace columbia;
00022
00023
00024
00025
00026
00027 inline RGB compute_lighting(RGB const& material_col, RGB const& light_col, Vector const& light_dir, Vector* normal=0)
00028 {
00029 if(normal)
00030 {
00031 float pro = normal->x * light_dir.x + normal->y * light_dir.y + normal->z * light_dir.z;
00032 if(pro < 0)
00033 return Black;
00034
00035 return
00036 (material_col * light_col) *
00037 ( (pro / (sqrt(normal->x * normal->x + normal->y * normal->y + normal->z * normal->z) *
00038 sqrt(light_dir.x * light_dir.x + light_dir.y * light_dir.y + light_dir.z * light_dir.z) )) );
00039 }
00040 return material_col;
00041 }
00042
00043
00044 int main1(int argc, char** argv)
00045 {
00046 bool draw_wireframe = false;
00047 if(argc > 2)
00048 draw_wireframe = (argv[2][0]=='w');
00049 float scale_factor = 0.15;
00050 if(argc > 3)
00051 scale_factor *= argv[3][0] - '0';
00052
00053 try
00054 {
00055 Canvas teximage;
00056 teximage.Checkerboard();
00057 teximage.WritePPM("c.ppm");
00058 teximage.ReadPPM("c.ppm");
00059 teximage.WritePPM("c2.ppm");
00060
00061 teximage.ReadPPM("o.ppm");
00062 teximage.WritePPM("o2.ppm");
00063
00064
00065
00066 Canvas canvas;
00067
00068
00069 canvas.SetTextureImage(&teximage);
00070 canvas.filename = "t.ppm";
00071
00072
00073
00074
00075
00076
00077 TriangleMesh msh(argc > 1? argv[1] : "hellskull.obj");
00078
00079 Vector translate = - msh.bbox.center;
00080
00081 float scale_x = canvas.hReso / (msh.bbox.max.x - msh.bbox.min.x) ;
00082 float scale_y = canvas.vReso / (msh.bbox.max.y - msh.bbox.min.y) ;
00083 float scale = std :: min (scale_x, scale_y) * scale_factor;
00084 float z_range = msh.bbox.max.z - msh.bbox.min.z;
00085
00086 RGB material_col = Firebrick;
00087 RGB light_col1 = White;
00088 RGB light_col2 = White * .0;
00089
00090 Vector light_dir1(.0, 0, 1);
00091
00092
00093 for(int f = 0; f < msh.total_triangles; ++f)
00094 {
00095 int i = msh.F[f].i, j = msh.F[f].j, k = msh.F[f].k;
00096 int ni = msh.F[f].ni, nj = msh.F[f].nj, nk = msh.F[f].nk;
00097 int ti = msh.F[f].ti, tj = msh.F[f].tj, tk = msh.F[f].tk;
00098
00099 static Point texI, texJ, texK;
00100 static RGB colI, colJ, colK;
00101 Point *texi = 0, *texj = 0, *texk = 0;
00102 RGB *coli = 0, *colj = 0, *colk = 0;
00103
00104 if(! msh.has_normal && (! (msh.has_texture=0) || draw_wireframe) )
00105 {
00106 colI = material_col * ( (msh.V[i].z - msh.bbox.min.z) / z_range );
00107 colJ = material_col * ( (msh.V[j].z - msh.bbox.min.z) / z_range );
00108 colK = material_col * ( (msh.V[k].z - msh.bbox.min.z) / z_range );
00109 coli = &colI, colj = &colJ, colk = &colK;
00110 }
00111 else
00112 {
00113 if(msh.has_normal)
00114 {
00115 colI = compute_lighting(material_col, light_col1, light_dir1, &msh.N[ni]);
00116 colJ = compute_lighting(material_col, light_col1, light_dir1, &msh.N[nj]);
00117 colK = compute_lighting(material_col, light_col1, light_dir1, &msh.N[nk]);
00118 coli = &colI, colj = &colJ, colk = &colK;
00119 }
00120 if(! draw_wireframe && msh.has_texture)
00121 {
00122 texI = msh.T[ti], texJ = msh.T[tj], texK = msh.T[tk];
00123 texi = &texI, texj = &texJ, texk = &texK;
00124 }
00125 }
00126
00127 if(draw_wireframe)
00128 canvas.WireTriangle( (msh.V[i] + translate) * scale, *coli,
00129 (msh.V[j] + translate) * scale, *colj,
00130 (msh.V[k] + translate) * scale, *colk);
00131 else
00132 {
00133 canvas.SolidTriangle( (msh.V[i] + translate) * scale, texi, coli,
00134 (msh.V[j] + translate) * scale, texj, colj,
00135 (msh.V[k] + translate) * scale, texk, colk);
00136 }
00137 }
00138
00139 canvas.WritePPM();
00140 }
00141
00142 catch(char const* msg)
00143 {
00144 std :: cerr << msg << std :: endl;
00145 }
00146
00147
00148 return 0;
00149 }
00150