AmbientLight3DCG
環境光を入れる
環境光を入れ、三角形のクラス(Tri)を描くようにしました。
環境光の計算は、
color.x * lw
とdiffuseの値を出してから、ambを足して
amb.x + color.x * lw
255を掛けます。
(amb.x + color.x * lw) * 255
Vertex amb = new Vertex(0.2f, 0.2f, 0.2f);
void drawTriangle(Tri tri, int[] pix, Vertex lightDir, Vertex color)
{
Vertex dest = new Vertex();
m3.normal(dest, tri.vv1, tri.vv2, tri.vv3);
float lw = m3.dot(dest,lightDir);
if (lw < 0) return;
int r = (int)((amb.x + color.x * lw) * 255);
int g = (int)((amb.y + color.y * lw) * 255);
int b = (int)((amb.z + color.z * lw) * 255);
if (r < 0) r = 0; if (255 < r) r = 255;
if (g < 0) g = 0; if (255 < g) g = 255;
if (b < 0) b = 0; if (255 < b) b = 255;
for (int i = 0; i < hei; i++) {
min[i] = 9999999;//minに巨大な数で初期化
max[i] = -9999999;//maxに微小な数
}
int v1x = (int)tri.vv1.x + cenWid;
int v2x = (int)tri.vv2.x + cenWid;
int v3x = (int)tri.vv3.x + cenWid;
int v1y = hei - (int)tri.vv1.y - cenHei;
int v2y = hei - (int)tri.vv2.y - cenHei;
int v3y = hei - (int)tri.vv3.y - cenHei;
int top_y = -9999999;
int low_y = 9999999;
if (low_y > v1y) low_y = v1y;
if (low_y > v2y) low_y = v2y;
if (low_y > v3y) low_y = v3y;
if (top_y < v1y) top_y = v1y;
if (top_y < v2y) top_y = v2y;
if (top_y < v3y) top_y = v3y;
drawLineTate(v1x, v1y, v2x, v2y);
drawLineTate(v2x, v2y, v3x, v3y);
drawLineTate(v3x, v3y, v1x, v1y);
for (int i = low_y; i < top_y; i++) {
for (int j = min[i]; j < max[i]; j++) {
if ( j < 0 | wid <= j) continue;//画面内に収める
pix[i * wid + j] = 255 << 24 | r << 16 | g << 8 | b;
}
}
}
void calcLineTate(int p1x, int p1y, int p2x, int p2y)
{
int x16_x1 = p1x << 16;//16bit倍
int x16_y1 = p1y << 16;
int x16_x2 = p2x << 16;
int x16_y2 = p2y << 16;
int len = Math.abs(p2y - p1y) + 1;
int zouka_x = (x16_x2 - x16_x1) / len;
int zouka_y = (x16_y2 - x16_y1) / len;
int tmp_x = x16_x1;
int tmp_y = x16_y1;
int index_y = 0;
int index_x = 0;
for (int i = 0; i < len; i++, tmp_x += zouka_x, tmp_y += zouka_y)
{
index_y = tmp_y >> 16;//最適化用ローカル変数
index_x = tmp_x >> 16;
if (index_y < 0 | hei <= index_y) continue;//画面から出たら描画無し
if (min[index_y] > (index_x)) min[index_y] = index_x;
if (max[index_y] < (index_x)) max[index_y] = index_x;
}
}
void drawLineTate(int p1x, int p1y, int p2x, int p2y)
{
int startY, endY, startX, endX;
if (p1y < p2y) { startY = p1y; endY = p2y; startX = p1x; endX = p2x;}
else { startY = p2y; endY = p1y; startX = p2x; endX = p1x;};
calcLineTate(startX, startY, endX, endY);
}
2008年01月07日(月) 19:48:21 Modified by eruvasu