/********************************************************** * * AddEdgeToList * * parameters IN: * VertexCell * vertex1 * VertexCell * vertex2 * *********************************************************/ void AddEdgeToList (VertexCell * vertex1, VertexCell * vertex2) { VertexCell * tempVertex; MyVector dw; EdgeBox * edgeBox; if (vertex1->screenPos.GetY() > vertex2->screenPos.GetY()) { tempVertex = vertex1; vertex1 = vertex2; vertex2 = tempVertex; } int y1 = vertex1->screenPos.GetY(); int y2 = vertex2->screenPos.GetY(); if (y1 != y2) { int dy = y2 - y1; double currX = vertex1->screenPos.GetX(); double currZ = vertex1->screenPos.GetZ(); double currI = lightVector.DotProduct (vertex1->vertexNormal); MyVector currW = vertex1->worldPos; double dx = (vertex2->screenPos.GetX() - currX) / dy; double dz = (vertex2->screenPos.GetZ() - currZ) / dy; double di = (lightVector.DotProduct (vertex2->vertexNormal) - currI) / dy; dw.SetX( (vertex2->worldPos.GetX() - currW.GetX()) / dy); dw.SetY( (vertex2->worldPos.GetY() - currW.GetY()) / dy); dw.SetZ( (vertex2->worldPos.GetZ() - currW.GetZ()) / dy); for (int y = y1; y <= y2 - 1; y++) { edgeBox = new EdgeBox; edgeBox->x = currX; edgeBox->z = (int)currZ; edgeBox->i = currI; edgeBox->w = currW; edgeBox->next = edgeListAt[y]; edgeListAt[y] = edgeBox; currX += dx; currZ += dz; currI += di; currW.SetX( currW.GetX() + dw.GetX()); currW.SetY( currW.GetY() + dw.GetY()); currW.SetZ( currW.GetZ() + dw.GetZ()); } } }
/********************************************************** * * RenderSpan * * parameters IN: * int y * EdgeBox ** edgeBox1 * EdgeBox ** edgeBox2 * *********************************************************/ void RenderSpan (int y, EdgeBox ** edgeBox1, EdgeBox ** edgeBox2) { EdgeBox * tempEdgeBox; int x, z; double dz, di; MyVector dw; if ((*edgeBox1)->x > (*edgeBox2)->x) { tempEdgeBox = *edgeBox1; *edgeBox1 = *edgeBox2; *edgeBox2 = tempEdgeBox; } int x1 = (int)(*edgeBox1)->x; int x2 = (int)(*edgeBox2)->x; if (x1 != x2) { int dx = x2 - x1; double currZ = (*edgeBox1)->z; double currI = (*edgeBox1)->i; MyVector currW = (*edgeBox1)->w; dz = ((*edgeBox2)->z - currZ) / dx; di = ((*edgeBox2)->i - currI) / dx; dw.SetX( ((*edgeBox2)->w.GetX() - currW.GetX()) / dx); dw.SetY( ((*edgeBox2)->w.GetY() - currW.GetY()) / dx); dw.SetZ( ((*edgeBox2)->w.GetZ() - currW.GetZ()) / dx); for (x = x1; x <= x2 - 1; x++) { z = (int)currZ; if (z < zBufferAt[x][y]) { zBufferAt[x][y] = z; RenderPixel (x, y, currI, currW); } currZ += dz; currI += di; currW.SetX( currW.GetX() + dw.GetX()); currW.SetY( currW.GetY() + dw.GetY()); currW.SetZ( currW.GetZ() + dw.GetZ()); } } }
/********************************************************** * * woodGrain * * parameters IN: * MyVector w * * return value : double * *********************************************************/ double woodGrain (MyVector w) { double ang; double rad = sqrt (w.GetX() * w.GetX() + w.GetZ() * w.GetZ()); if (w.GetZ() == 0) { ang = Util::PI() / 2.; } else { ang = arcTangent (w.GetX(), w.GetZ()); } rad += 2. * sin (20. * ang + w.GetY() / 150.); int grain = (int)fmod(rad, 60); // return remainder if (grain < 30) { return 1.4; } else { return 0.25; } }