* I use gradients on all the edges (for x, z, u and v).
* I then call my texture hline function (which again uses a gradient for z change). At each pixel I calculate the texel by:
tz1 = 1.0f / z; // tz1 is a temorary value tz2 = 1.0f / tz1; // tz2 is another temporary value ut = (u * tz1) * tz2; // ut is transformed u vt = (v * tz1) * tz2; // vt is transformed v Texel t = Texture.GetTexel(ut, vt);
How do I get rid of this swimming?
Thanks,
-dega
This is my actual code (java):
// LGL is a prefix I use so I know its a graphics class
// LGL_Vertex3D is vertex data which contains a vector names Position
// which has (x, y, z) along with transformed (sx, sy, sz)
// LGL_Color is just floats A, R, G, B (0.0f - 1.0f), it has ToInt() that returns
// the color as an integer
// LGL_Texture is just a 2D array of LGL_Color objects
// buffer is an array of integers representing pixels
// sw is an integer representing screen width
// sh is an integer representing screen height
// visibleZ is a method for the zbuffer (is visible, if so set the new z value)
// (Note: the verticies are sorted by increasing y value)
/* inside LGL_Texture */
public LGL_Color GetTexel(float u, float v)
{
// fWidth is texture width as a float, Width is it as an integer
// the same goes for fHeight and Height
return this.Texels[((int)(u * this.fWidth)) % this.Width][((int)(v * this.fHeight)) % this.Height];
}
/* end */
/* inside rasterizer code */
private void drawTextured(LGL_Vertex3D a, LGL_Vertex3D b, LGL_Vertex3D c, LGL_Texture tex)
{
int y = -1;
int dest;
// y positions of each vertex
float ay = (float)Math.ceil(a.Position.sy);
float by = (float)Math.ceil(b.Position.sy);
float cy = (float)Math.ceil(c.Position.sy);
// calculate gradients
float ftmp = 1.0f / (cy - ay);
float lg = (c.Position.sx - a.Position.sx) * ftmp;
float hg = 0.0f;
float lzg =(c.Position.sz - a.Position.sz) * ftmp;
float hzg = 0.0f;
float lx = a.Position.sx;
float lz = a.Position.sz;
float hx = 0.0f;
float hz = 0.0f;
float lug = (c.u - a.u) * ftmp;
float lvg = (c.v - a.v) * ftmp;
float hug = 0.0f;
float hvg = 0.0f;
float lu = a.u;
float lv = a.v;
float hu = 0.0f;
float hv = 0.0f;
boolean step = false;
if (ay != by)
{
// calculate more gradients for the other side
ftmp = 1.0f / (by - ay);
hg = (b.Position.sx - a.Position.sx) * ftmp;
hzg = (b.Position.sz - a.Position.sz) * ftmp;
hug = (b.u - a.u) * ftmp;
hvg = (b.v - a.v) * ftmp;
hx = lx;
hz = lz;
hu = lu;
hv = lv;
y = (int)ay;
dest = (int)by;
for (; y < dest; y++)
{
if (y >= 0)
{
if (y >= this.sh)
break;
thline(lx, lz, lu, lv, hx, hz, hu, hv, y, tex);
}
lx += lg;
lz += lzg;
lu += lug;
lv += lvg;
hx += hg;
hz += hzg;
hu += hug;
hv += hvg;
}
}
else
{
y = (int)ay;
thline(a.Position.sx, a.Position.sz, a.u, a.v, b.Position.sx, b.Position.sz, b.u, b.v, y, tex);
y++;
step = true; // we are on the next line
}
// repeat for lower half...
if (cy != by)
{
ftmp = 1.0f / (cy - by);
hx = b.Position.sx;
hz = b.Position.sz;
hu = b.u;
hv = b.v;
hg = (c.Position.sx - b.Position.sx) * ftmp;
hzg = (c.Position.sz - b.Position.sz) * ftmp;
hug = (c.u - b.u) * ftmp;
hvg = (c.v - b.v) * ftmp;
if (step)
{
lx += lg;
lz += lzg;
lu += lug;
lv += lvg;
hx += hg;
hz += hzg;
hu += hug;
hv += hvg;
}
dest = (int)cy;
for (; y <= dest; y++)
{
if (y >= 0)
{
if (y >= this.sh)
break;
thline(lx, lz, lu, lv, hx, hz, hu, hv, y, tex);
}
lx += lg;
lz += lzg;
lu += lug;
lv += lvg;
hx += hg;
hz += hzg;
hu += hug;
hv += hvg;
}
}
else
thline(c.Position.sx, c.Position.sz, c.u, c.v, b.Position.sx, b.Position.sz, b.u, b.v, (int)cy, tex);
}
private void thline(float x1, float z1, float lu, float lv, float x2, float z2, float ru, float rv, int y, LGL_Texture tex)
{
float ftmp;
// switch if needed
if (x2 < x1)
{
ftmp = x2;
x2 = x1;
x1 = ftmp;
ftmp = ru;
ru = lu;
lu = ftmp;
ftmp = rv;
rv = lv;
lv = ftmp;
ftmp = z2;
z2 = z1;
z1 = ftmp;
}
float tz1 = 0.0f;
float tz2 = 0.0f;
float ut = 0.0f;
float vt = 0.0f;
int lx = (int)Math.ceil(x1);
int rx = (int)Math.ceil(x2);
if (rx < 0 || lx >= this.sw)
return;
// gradients
ftmp = 1.0f / (float)(rx - lx);
float zg = (z2 - z1) * ftmp;
float ug = (ru - lu) * ftmp;
float vg = (rv - lv) * ftmp;
int off = y * this.sw;
// draw the textured hline
while (lx <= rx)
{
if (lx >= 0)
{
if (lx >= this.sw)
break;
if (visibleZ(lx, y, z1))
{
tz1 = 1.0f / z1;
tz2 = 1.0f / tz1;
ut = (lu * tz1) * tz2;
vt = (lv * tz1) * tz2;
this.buffer.Pixels[off + lx] = tex.GetTexel(ut, vt).ToInt();
}
}
lx++;
z1 += zg;
lu += ug;
lv += vg;
}
}














