diff Renderer/Engine/spe/DrawSpan.cc @ 762:10a8a80c2ea7

add lights
author yutaka@henri.cr.ie.u-ryukyu.ac.jp
date Sat, 06 Feb 2010 03:02:48 +0900
parents b7376415fa5f
children dc26593f8c40
line wrap: on
line diff
--- a/Renderer/Engine/spe/DrawSpan.cc	Thu Feb 04 14:50:01 2010 +0900
+++ b/Renderer/Engine/spe/DrawSpan.cc	Sat Feb 06 03:02:48 2010 +0900
@@ -10,6 +10,7 @@
 #include "SchedTask.h"
 #include "Tapestry.h"
 #include "SpanPack.h"
+#include <math.h>
 
 #if (__LITTLE_ENDIAN__)
 #define LITTLEENDIAN 1
@@ -55,6 +56,21 @@
                                   SchedTask *smanager,int x, int y, float z, int world_x, int world_y, float world_z);
 
 
+void
+normalize(float *v0, float *v1)
+{
+    float norm, dnorm;
+
+    norm = sqrt(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]);
+    if (norm > 0) {
+	dnorm = 1.0/norm;
+	v0[0] = v1[0]*dnorm;
+	v0[1] = v1[1]*dnorm;
+	v0[2] = v1[2]*dnorm;
+	v0[3] = v1[3]*dnorm;
+    }
+}
+
 static float
 innerProduct1(float *v0, float *v1)
 {
@@ -330,7 +346,7 @@
     float zpos2 = span->end_z;
 
     //spanを右から左に見ていくうちに、zが下がるのか、上がっていくのか。
-    float z_inclination = (zpos1 - zpos2) / x_len;
+    float z_inclination = (zpos2 - zpos1) / x_len;
     float world_z = zpos2;
 
     // Tile 内での座標
@@ -342,7 +358,7 @@
     for (int j = je; j >= js; j--) {
         float tex_x, tex_y, tex_z;
 
-	world_z += z_inclination;
+	world_z -= z_inclination;
 
         localx = getLocalX(x-1+j);
 
@@ -392,8 +408,12 @@
     int flag;
     float normal_vector[4] = {normal_x,normal_y,normal_z,0};
     // 光のベクトル,きめうちしちゃった。どうにかする
-    float light_vector[4] = {0,0,-1,0};
+    //float light_vector[4] = {0,0,-1,0};
+    float light_vector[4];
     float inner_product;
+    float *light_xyz = (float*)smanager->global_get(Light);
+
+    normalize(normal_vector, normal_vector);
 
     // 引数で受け取った color の rgb 情報の抜き出し
 #if LITTLEENDIAN
@@ -408,15 +428,46 @@
     rgb[0] = (color & 0x000000ff);
 #endif
 
-    // 法線ベクトルと光源ベクトルとの内積をとる
-    inner_product = innerProduct1(normal_vector,light_vector);
-    // 内積がマイナスの場合は色がない。
-    flag = (inner_product > 0);
+    int tmp_rgb[3] = {0,0,0};
+    int light_num = 4;
+    for (int i = 0; i < light_num; i++) {
+
+      //printf("light_xyz[%d] %f\n",i*4,light_xyz[i*4]);
+      //printf("light_xyz[%d] %f\n",i*4+1,light_xyz[i*4+1]);
+      //printf("light_xyz[%d] %f\n",i*4+2,light_xyz[i*4+2]);
+      //printf("light_xyz[%d] %f\n",i*4+3fg,light_xyz[i*4+3]);
+
+      light_vector[0] = world_x - light_xyz[i*4];
+      light_vector[1] = world_y - light_xyz[i*4+1];
+      light_vector[2] = light_xyz[i*4+2] - world_z;
+      light_vector[3] = light_xyz[i*4+3];
+
+      normalize(light_vector, light_vector);
+
+      // 法線ベクトルと光源ベクトルとの内積をとる
+      inner_product = innerProduct1(normal_vector,light_vector);
 
-    // 内積を rgb にかけていく
-    rgb[0] = (unsigned char)(rgb[0]*inner_product*flag);
-    rgb[1] = (unsigned char)(rgb[1]*inner_product*flag);
-    rgb[2] = (unsigned char)(rgb[2]*inner_product*flag);
+      //printf("inner_product %f\n",inner_product);
+
+      // 内積がマイナスの場合は色がない。
+      flag = (inner_product > 0);
+
+      // 内積を rgb にかけていく
+      tmp_rgb[0] += (unsigned char)(rgb[0]*inner_product*flag);
+      tmp_rgb[1] += (unsigned char)(rgb[1]*inner_product*flag);
+      tmp_rgb[2] += (unsigned char)(rgb[2]*inner_product*flag);
+
+    }
+
+    int rgb_flag[3];
+    for (int i = 0; i < 3; i++) {
+      rgb_flag[i] = (tmp_rgb[i] > 255);
+    }
+
+    rgb[0] = tmp_rgb[0]*(1 - rgb_flag[0]) + 255*(rgb_flag[0]);
+    rgb[1] = tmp_rgb[1]*(1 - rgb_flag[1]) + 255*(rgb_flag[1]);
+    rgb[2] = tmp_rgb[2]*(1 - rgb_flag[2]) + 255*(rgb_flag[2]);
+
 
     //計算した rgb を light_rgb にまとめる。
 #if LITTLEENDIAN