Thank you ThomH for reading and your comment.ThomH wrote: ↑Mon Sep 21, 2020 10:21 pmthe classic serial implementation for affine texturing a polygon is just two adds per pixel. In pseudo-C:

... with appropriate modifications to fixed point. You can set up offset_x/y at the start of each scan line either by tracking them along each edge and doing a divide, or by plane or barycentric calculations.Code: Select all

`for(x = start ... end) { pixel[x][y] = pixel[texture_x][texture_y]; texture_x += offset_x; texture_y += offset_y; }`

For now I've managed to put the calculation under the following form:

Code: Select all

```
for(x = start ... end) {
pixel[x][y] = pixel[texture_x][texture_y];
texture_x = K * (y-y0) - R * (x-x0);
texture_y = S * (x-x0) - T * (y-y0);
}
with (x0, y0) screen coordinates of reference point of texture
and K, R, S and T being values computed with trigonometry
```

Which is similar to what you describe because:

- Along a given scanline, terms (y-y0) don't vary so they can be considered as constant and then it can be written like that:

Code: Select all

`texture_x = C_1 - R * (x-x0); texture_y = S * (x-x0) - C_2;`

- As for terms (x-x0), they only increment by one from one pixel to the following one.

So, considering the nth pixel in the scanline, its texture coordinates are:and considering its immediate neighbour on its rightCode: Select all

`texture_x[n] = C_1 - R * (x-x0); texture_y[n] = S * (x-x0) - C_2;`

Code: Select all

`texture_x[n+1] = C_1 - R * ((x+1)-x0) = C_1 - R*(x-x0) -R = texture_x[n] - R texture_y[n+1] = S * ((x+1)-x0) - C_2 = S*(x-x0) - C_2 + S = texture_y[n] + S`

Code: Select all

```
texture_x[n+1] = texture_x[n] -R
texture_y[n+1] = texture_y[n] + S
```

I have R and S under the shape Ra/Rb and Sa/Sb with Rb<Ra and Sb<Sa.

Either I do the division and work with Q8.8 fixed point values to keep precision and accuracy.

Code: Select all

```
R = Ra / Rb
S = Sa / Sb
for(x = start ... end) {
pixel[x][y] = pixel[texture_x][texture_y];
texture_x -= R;
texture_y += S;
}
```

Code: Select all

```
for(x = start ... end) {
pixel[x][y] = pixel[texture_x][texture_y];
texture_x += -Rb;
ErrorX = Ra - texture_x;
If (|ErrorX*2| > Rb) Then
texture_x -= Ra
texture_y += Sb;
ErrorY = Sa - texture_y;
If (|ErrorY*2| > Sb) Then
texture_y -= Sa
}
```

In second case, I have no division and then 3 or 4 8-bits additions for each pixel.

So it's hard to figure out what's more efficient.

For now I only protyped in python the formulae given at the beginning of this post (i.e I haven't integrated the iterative formulation of the texture_x/y calculation)

I use this simple texture file:

When I do a projection on a plane 3D surface (it's not real perspective fill .. it's just image stretching ) by using floating point arithmetic it gives the following result: (I draw triangles to see the shape onto which I map the image)

And when i use 8 bits integer calculation (with lookup tables for euclidian norm, arctan, sin and cosine), it gives:

It doesn't look too dirty but last steps of calculation (the ones that compute R=Ra/Rb and S=Sa/Sb) are still done on floating point values and they are not incremental. So it might get a bit dirtier when I will deal with that.

What are plane or barycentric calculations ?