The process of culling backfaces is simply checking the visibility of one-sided polygons based on whether they are facing towards the camera / player or away. If they are facing away then it is a back-facing side, rather than front-facing, and must be skipped during rendering. To determine this, I must calculate a normal vector. Every 3D triangle has two of these normals: one points outward from it and one points inward. The one you get depends on whether the calculation is made from vertices going
The goal here is to quickly rotate points by a certain number of degrees using precalculated SINE/COSINE values and without floating point, e.g. only integers. In order to do that I am using fixed point ^{[1]} and a lookup table. So first I want to discuss fixed point a bit to get our feet wet.
Fixed point is a technique where one designates a number of high bits in an integer to the whole portion and leaves the remaining lower bits to represent a fractional part. This is usually expressed
Since the first part I blogged a few weeks ago, I've written the method QTEX() ^{[1]} which maps an 8x8x1 (monochrome) texture onto a quadrilateral (four vertices). This uses fixed point for all coordinates and deltas so there are rounding errors, especially in the inner loop when drawing a scan line because I use a single byte per U/V delta. In fact, here's an image which demonstrates the problem:
No matter how I adjust the U/V coordinates
These wonderful digital processing units of ours are, at their heart, very fast binary adders. There may be a SUBtract instruction but this is the same as adding the two's complement of a number. ^{[1]} Knowing this is important when I'm mixing signed and unsigned numbers; I must be discriminate.
In the current case, I'm storing texture coordinates as whole byte values which I will then interpret as fixed point. To clarify this a little, I'll explain the concepts with nibbles instead of
The DIV and IDIV instructions perform integer divisions simply and relatively quickly as opposed to creating a simple loop. Let me start by showing how one could divide an integer without these instructions. The following assembly function (CALL 110) will divide BX by CX and put the quotient in AX:
Code:0110 31C0 XOR AX,AX 0112 39CB CMP BX,CX 0114 7206 JB 011C 0116 40 INC AX 0117 29CB SUB BX,CX 0119 EBF7 JMP 0112