Dark Bit Factory & Gravity
PROGRAMMING => General coding questions => Topic started by: taj on October 05, 2006
-
Can anyone point me to some C source code that does fixed point triangle rendering in software, preferably with textures? Even better with mip-maps.
I'd like it free of licenses if possible...
-
I can make you one if you like but it would be in freebasic so you'd have to convert it.
Mip mapping is where you have several versions of a texture in memory, depending on the area of the triangle you are rendering, you use the texture that fits the size of the triangle the best, speeds things up a lot and helps get rid of jumping pixels.
This is a link that helped me a lot;
http://www.whisqu.com/per/docs/graphics16.htm It contains pseudo code.
-
Shockwave thanks a lot, but dotn go to the trouble of writing the code. This is for a work project and it wouldnt be right for you to do that without us paying and as I'm doing this "skunk works" style (without managment approval) I can't pay you. I'll keep looking for some license free code or I'll find time and write it myself.
-
DOS:ASM (PASCAL/BASIC) calling...
From Rellib. My old Dos sofware QB library.
;;;Fix point Textured triangle routine. :*)
;;;Call with:
;;;Declare sub (Byval Layer%, Byval x1%, Byval y1%,Byval u1%,Byval v1%, Byval x2%,_
;;; Byval y2%,Byval u2%,Byval v2%, Byval x3%, Byval y3%,Byval u3%,Byval v3%, Byval TSEG%, Byval TOFF%)
.Model Medium, BASIC
.386
.Code
align 2
;;*****************Near procedure for preclipped Textured Hline*****************************************
HTline Proc near\
x1:word, x2:word, y:word, lu:dword, ru:dword, lv:dword, rv:dword, Tsize:word
Local udelta: dword
Local vdelta: dword
Local u: dword
Local v: dword
Local dy: word
Local TsizeM1: word
Local Toff: word
Local wid: word
;GS = Xshift
mov ax, x1
mov bx, x2
cmp ax,bx
jle Short @Postswapx
xchg ax, bx
mov ecx, lu
mov edx, ru
xchg ecx, edx
mov x1, ax
mov x2, bx
mov eax, lv
mov ebx, rv
xchg eax, ebx
mov lu, ecx
mov ru, edx
mov lv, eax
mov rv, ebx
@PostSwapX:
mov ecx, lu
mov edx, lv
mov u, ecx
mov v, edx
;U
mov ax, x1
mov bx, x2
mov edx, ru
mov ecx, lu
;Gdx% = (Gx2% - Gx1%) + 1 'Get Xdelta(+1) for the Div by 0 error
;Cdx& = Clr2& - Clr1& 'Color delta ;deltac& = Cdx& \ Gdx% 'Interpolate
;col& = Clr1& 'save orig color to be safe
sub edx, ecx
sub bx, ax
jz @NolineH
mov dy, bx ;save ydelta
mov ax, bx
cwde ;eax = gdx
mov ecx, edx ;ecx = cdx
xchg eax, ecx ;eax = cdx : ecx = gdx
cdq ;eax:edx = cdx
idiv ecx ;eax = edxedx\ecx
mov udelta, eax
;V
mov edx, rv
mov ecx, lv
;Gdx% = (Gx2% - Gx1%) + 1 'Get Xdelta(+1) for the Div by 0 error
;Cdx& = Clr2& - Clr1& 'Color delta ;deltac& = Cdx& \ Gdx% 'Interpolate
;col& = Clr1& 'save orig color to be safe
sub edx, ecx
mov ax, dy
cwde ;eax = gdx
mov ecx, edx ;ecx = cdx
xchg eax, ecx ;eax = cdx : ecx = gdx
cdq ;eax:edx = cdx
idiv ecx ;eax = edxedx\ecx
mov vdelta, eax
mov ax, x1
mov bx, x2
;;;;;;;;;;
cmp ax,319
jg @NolineH
cmp ax,0
jl @clipLeft
@PostclipLeft:
cmp bx,0
jl @NolineH
cmp bx,319
jg @clipRight
@PostclipRight:
mov cx, Tsize
mov dx, bx ;dx = (bx - ax)+1
inc dx
dec cx
mov TsizeM1, cx
sub dx, ax
jz @NolineH
mov cx, y ;put in y value
xchg ch, cl ;y = y *256 ;di& = cx * 320& + ax
mov di, cx ;di = 256
shr di, 2 ;di = 64
add di, cx ;di = 256+64 = 320
add di, ax ;di = y*320+x
;FOR l% = Gx1% TO Gx2% 'Rasterizer loop
; PSET (l%, yy%), col& \ FIXPOINT 'Use poke for speed
; col& = col& + deltac& 'DDA
;NEXT l%
;;xloop okay
Mov Toff, fs
mov bx, dx ;do divide
cmp bx, 4
jle @Less4
and bl, 3
shr dx, 2
mov ch, bl ;odd pixels I used dy to conserve mem. :*)
mov wid, dx
mov ax, gs ;shift counter
mov cl, al ;use cl
mov ebx, u ;save u and v
mov edx, v
@xloop:
;1.
;;v
mov eax, edx
shr eax, 16
and ax, TsizeM1
shl ax, cl
mov si, ax
add si, Toff
;;u
mov eax, ebx
shr eax, 16
and ax, TsizeM1
add si, ax
mov al,[si+4]
mov es:[di], al
add ebx, udelta
add edx, vdelta
;2.
;;v
mov eax, edx
shr eax, 16
and ax, TsizeM1
shl ax, cl
mov si, ax
add si, Toff
;;u
mov eax, ebx
shr eax, 16
and ax, TsizeM1
add si, ax
mov al,[si+4]
mov es:[di+1], al
add ebx, udelta
add edx, vdelta
;3.
;;v
mov eax, edx
shr eax, 16
and ax, TsizeM1
shl ax, cl
mov si, ax
add si, Toff
;;u
mov eax, ebx
shr eax, 16
and ax, TsizeM1
add si, ax
mov al,[si+4]
mov es:[di+2], al
add ebx, udelta
add edx, vdelta
;4.
;;v
mov eax, edx
shr eax, 16
and ax, TsizeM1
shl ax, cl
mov si, ax
add si, Toff
;;u
mov eax, ebx
shr eax, 16
and ax, TsizeM1
add si, ax
mov al,[si+4]
mov es:[di+3], al
add ebx, udelta
add edx, vdelta
add di, 4
dec wid
jnz @xloop
test ch,ch
jz short @NolineH
@xloop2:
;1.
;;v
mov eax, edx
shr eax, 16
and ax, TsizeM1
shl ax, cl
mov si, ax
add si, Toff
;;u
mov eax, ebx
shr eax, 16
and ax, TsizeM1
add si, ax
mov al,[si+4]
mov es:[di], al
add ebx, udelta
add edx, vdelta
inc di
dec ch
jnz @xloop2
@NolineH:
Ret
@clipLeft:
mov cx, ax ;save in cx
neg cx ;cx = clipped width
mov dx,bx
sub dx,ax
add ax,dx
cmp ax,0
jl short @NolineH
xor eax, eax
mov ax, cx
imul eax, udelta ;eax=wid*udelta
add u, eax ;add to u to clip
xor eax,eax
mov ax, cx
imul eax, vdelta ;eax=wid*vdelta
add v, eax ;add to v to clip
xor eax,eax
Jmp @PostclipLeft
@clipRight:
mov bx,319
Jmp @PostclipRight
;Less then 4
@Less4:
mov wid, dx
mov ax, gs ;shift counter
mov cl, al ;use cl
mov ebx, u ;save u and v
mov edx, v
@xloopLess4:
;;v
mov eax, edx
shr eax, 16
and ax, TsizeM1
shl ax, cl
mov si, ax
add si, Toff
;;u
mov eax, ebx
shr eax, 16
and ax, TsizeM1
add si, ax
mov al,[si+4]
mov es:[di], al
add ebx, udelta
add edx, vdelta
inc di
dec wid
jnz short @xloopLess4
Ret
EndP
;;*****************Procedure for Textured Triangle Filler**************************************************
Public RelTriT
RelTriT Proc Uses es di ds si,\
Layer:word, x1:word, y1:word, u1:word, v1:word, x2:word, y2:word, u2:word, v2:word,\
x3:word, y3:word, u3:word, v3:word, Tseg: word, Toff: word
Local delta1: dword
Local delta2: dword
Local delta3: dword
Local Lx: dword
Local Rx: dword
Local udelta1: dword
Local udelta2: dword
Local udelta3: dword
Local Lu: dword
Local Ru: dword
Local vdelta1: dword
Local vdelta2: dword
Local vdelta3: dword
Local Lv: dword
Local Rv: dword
Local ycounter: word
Local Tsize: word
Local xshift: word
mov ax, y1
mov bx, y2
cmp bx, ax ;cmp y2, y1
jge short @noswapy1
xchg ax, bx ;xchg y1, y2
mov cx, x1
mov dx, x2
xchg cx, dx ;xchg x1, x2
mov y1, ax
mov y2, bx
mov x1, cx
mov x2, dx
mov cx, u1
mov dx, u2
xchg cx, dx
mov u1, cx
mov u2, dx
mov cx, v1
mov dx, v2
xchg cx, dx
mov v1, cx
mov v2, dx
@noswapy1:
mov ax, y3
mov bx, y1
cmp ax, bx ;cmp y3, y1
jge short @noswapy2
xchg ax, bx ;xchg y3, y1
mov cx, x3
mov dx, x1
xchg cx, dx ;xchg x3, x1
mov y3, ax
mov y1, bx
mov x3, cx
mov x1, dx
mov cx, u3
mov dx, u1
xchg cx, dx
mov u3, cx
mov u1, dx
mov cx, v3
mov dx, v1
xchg cx, dx
mov v3, cx
mov v1, dx
@noswapy2:
mov ax, y3
mov bx, y2
cmp ax, bx ;cmp y3, y2
jge short @noswapy3
xchg ax, bx ;xchg y3, y2
mov cx, x3
mov dx, x2
xchg cx, dx ;xchg x3, x2
mov y3, ax
mov y2, bx
mov x3, cx
mov x2, dx
mov cx, u3
mov dx, u2
xchg cx, dx
mov u3, cx
mov u2, dx
mov cx, v3
mov dx, v2
xchg cx, dx
mov v3, cx
mov v2, dx
@noswapy3:
mov delta1, 0
mov udelta1, 0
mov vdelta1, 0
mov bx, y2 ;bx = y2
sub bx, y1 ;bx = bx - y1
jz short @delta1_is_zero ;IF bx <> 0 THEN
mov ax, x2 ;ax = x2
sub ax, x1 ;ax = ax - x1
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
movsx ecx, bx ;ecx& = bx
idiv ecx ;delta1& = edxeax& \ ecx&
mov delta1, eax
;uDelta1& = du1 * FIXPOINT \ dy1
mov ax, u2 ;ax = u2
sub ax, u1 ;ax = ax - u1
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
idiv ecx ;delta1& = edxeax& \ ecx&
mov udelta1, eax
;vDelta1& = dv1 * FIXPOINT \ dy1
mov ax, v2 ;ax = u2
sub ax, v1 ;ax = ax - u1
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
idiv ecx ;delta1& = edxeax& \ ecx&
mov vdelta1, eax
@delta1_is_zero:
mov delta2, 0
mov udelta2, 0
mov vdelta2, 0
mov bx, y3 ;bx = y3
sub bx, y2 ;bx = bx - y2
jz short @delta2_is_zero ;IF bx <> 0 THEN
mov ax, x3 ;ax = x3
sub ax, x2 ;ax = ax - x2
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
movsx ecx, bx ;ecx& = bx
idiv ecx ;delta1& = edxeax& \ ecx&
mov delta2, eax
;uDelta1& = du2 * FIXPOINT \ dy2
mov ax, u3 ;ax = u3
sub ax, u2 ;ax = ax - u3
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
idiv ecx ;delta1& = edxeax& \ ecx&
mov udelta2, eax
;vDelta1& = dv2 * FIXPOINT \ dy2
mov ax, v3 ;ax = v3
sub ax, v2 ;ax = ax - v3
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
idiv ecx ;delta1& = edxeax& \ ecx&
mov vdelta2, eax
@delta2_is_zero:
mov delta3, 0
mov udelta3, 0
mov vdelta3, 0
mov bx, y1 ;bx = y1
sub bx, y3 ;bx = bx - y3
jz short @delta3_is_zero ;IF bx <> 0 THEN
mov ax, x1 ;ax = x1
sub ax, x3 ;ax = ax - x3
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
movsx ecx, bx ;ecx& = bx
idiv ecx ;delta1& = edxeax& \ ecx&
mov delta3, eax
;uDelta1& = du3 * FIXPOINT \ dy3
mov ax, u1 ;ax = u1
sub ax, u3 ;ax = ax - u3
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
idiv ecx ;delta1& = edxeax& \ ecx&
mov udelta3, eax
;vDelta1& = dv3 * FIXPOINT \ dy3
mov ax, v1 ;ax = v1
sub ax, v3 ;ax = ax - v3
shl eax, 16 ;eax& = eax& * FIXPOINT
cdq ;edx& = eax&
;edxeax& = edx&
idiv ecx ;delta1& = edxeax& \ ecx&
mov vdelta3, eax
@delta3_is_zero:
Mov es, Layer
Mov ds, TSEG
mov ax, TOFF
mov fs, ax
mov si, ax
mov bx, [si]
shr bx,3 ;width
mov Tsize, bx
;calculate shifts
mov ax, bx
cmp ax, 2
jne short @xpow4
mov bx, 1
jmp short @SizeOK
@xpow4:
cmp ax, 4
jne short @xpow8
mov bx, 2
jmp short @SizeOK
@xpow8:
cmp ax, 8
jne short @xpow16
mov bx, 3
jmp short @SizeOK
@xpow16:
cmp ax, 16
jne short @xpow32
mov bx, 4
jmp short @SizeOK
@xpow32:
cmp ax, 32
jne short @xpow64
mov bx, 5
jmp short @SizeOK
@xpow64:
cmp ax, 64
jne short @xpow128
mov bx, 6
jmp short @SizeOK
@xpow128:
cmp ax, 128
jne short @xpow256
mov bx, 7
jmp short @SizeOK
@xpow256:
cmp ax, 256
jne @exit
mov bx, 8
@SizeOK:
;Flat bottom
;Top part of triangle
mov gs, bx ;save xshift
mov ax, x1 ;ax = x1
cwde ;eax& = ax
sal eax, 16 ;eax& = eax& * FIXPOINT
mov ebx, eax ;ebx& = eax&
mov lx, eax
mov rx, ebx
mov ax, u1 ;ax = u1
cwde ;eax& = ax
sal eax, 16 ;eax& = eax& * FIXPOINT
mov ebx, eax ;ebx& = eax&
mov lu, eax
mov ru, ebx
mov ax, v1 ;ax = v1
cwde ;eax& = ax
sal eax, 16 ;eax& = eax& * FIXPOINT
mov ebx, eax ;ebx& = eax&
mov lv, eax
mov rv, ebx
mov cx, y1 ;cx = y1
mov ycounter, cx
@Loop1:
cmp ycounter, 0
jl short @Noline1
cmp ycounter, 199
jg short @Noline1
mov eax, lx
mov ebx, rx
sar eax, 16 ;ax = eax& \ FIXPOINT
sar ebx, 16 ;bx = ebx& \ FIXPOINT
Push ax ;x1
push bx ;x2
mov ecx, lu ;u1
mov edx, ru ;u2
mov ax, ycounter
push ax
Push ecx ;Lu
push edx ;Ru
mov eax, lv
mov ebx, rv
Push eax ;Lv
push ebx ;Rv
mov cx, Tsize
push cx
call HTline
@Noline1:
mov eax, delta1
mov ebx, delta3
mov ecx, udelta1
mov edx, udelta3
add lx, eax ;eax& = eax& + delta1&
add rx, ebx ;ebx& = ebx& + delta3&
add lu, ecx ;eax& = eax& + udelta1&
add ru, edx ;ebx& = ebx& + udelta3&
mov eax, vdelta1
mov ebx, vdelta3
add lv, eax ;eax& = eax& + vdelta1&
add rv, ebx ;ebx& = ebx& + vdelta3&
inc ycounter
mov cx, ycounter
cmp cx, y2
jle short @Loop1
mov ebx, delta3
sub rx, ebx ;subtexel accuracy
mov edx, udelta3
sub ru, edx
mov eax, vdelta3
sub rv, eax
;Flat top
;Lower part of triangle
mov ax, x2 ;ax = x2
cwde ;eax& = ax
sal eax, 16 ;eax& = eax& * FIXPOINT
mov lx, eax
mov ax, u2 ;ax = u2
cwde ;eax& = ax
sal eax, 16 ;eax& = eax& * FIXPOINT
mov lu, eax
mov ax, v2 ;ax = v2
cwde ;eax& = ax
sal eax, 16 ;eax& = eax& * FIXPOINT
mov lv, eax
mov cx, y2 ;cx = y2
mov ycounter, cx
@Loop2:
cmp ycounter, 0
jl short @Noline2
cmp ycounter, 199
jg short @Noline2
mov eax, lx
mov ebx, rx
sar eax, 16 ;ax = eax& \ FIXPOINT
sar ebx, 16 ;bx = ebx& \ FIXPOINT
Push ax ;x1
push bx ;x2
mov ecx, lu ;u1
mov edx, ru ;u2
mov ax, ycounter
push ax
Push ecx ;Lu
push edx ;Ru
mov eax, lv
mov ebx, rv
Push eax ;Lv
push ebx ;Rv
mov cx, Tsize
push cx
call HTline
@Noline2:
mov eax, delta2
mov ebx, delta3
mov ecx, udelta2
mov edx, udelta3
add lx, eax ;eax& = eax& + delta2&
add rx, ebx ;ebx& = ebx& + delta3&
add lu, ecx ;eax& = eax& + udelta2&
add ru, edx ;ebx& = ebx& + udelta3&
mov eax, vdelta2
mov ebx, vdelta3
add lv, eax ;eax& = eax& + vdelta2&
add rv, ebx ;ebx& = ebx& + vdelta3&
inc ycounter
mov cx, ycounter
cmp cx, y3
jl short @Loop2
@exit:
Ret
EndP
End
For what it's worth here's how it works....
http://rel.betterwebber.com/mytutes/3dtutes/chapter3/chapter3.htm
BTW, you may have to scroll below (way below).
;*)
-
Ooops!!! You wanted C code.
You accept TurboC? Never did sofware In devcpp.
http://rel.betterwebber.com/junk.php?id=37
-
Yeah unfortunately the processor is not an i386 so the ams is no use but the C code could very very useful. I'll check it out. Thanks relsoft, have some chicken karma.
-
heres a gba fixed point affine c routine excluding the gba stuff it should work with windows just fine note the only thing ive excluded from the source is the giant texture array which was a raw 16 bit bmp.
#define SHIFT 8
#define SCALE (1<<SHIFT)
#define TWOPOINTFIVE (0x280<<(SHIFT-8))
typedef struct
{
s32 x;
s32 u;
s32 v;
} EDGE;
s32 zin[360];
s32 coz[360];
typedef struct
{
s32 x,y,z;
} VECTOR;
typedef s32 MATRIX[3][3];
typedef struct
{
u16 face;
s32 z;
} SORTER;
// uv stuff
typedef struct
{
u8 point_index;
s16 u, v;
} VERTEX;
typedef struct
{
VERTEX pt[3];
} FACE;
#define N_FACES 12
#define N_POINTS 8
FACE faces[N_FACES]=
{
{
{{0,0,0},
{2,TEX_X-1,0},
{6,TEX_X-1,TEX_Y-1}},
},
{
{{0,0,0},
{6,TEX_X-1,TEX_Y-1},
{4,0,TEX_Y-1}}
},
{
{{0,0,0},
{1,TEX_X-1,0},
{3,TEX_X-1,TEX_Y-1}}
},
{
{{0,0,0},
{3,TEX_X-1,TEX_Y-1},
{2,0,TEX_Y-1}}
},
{
{{4,0,0},
{6,TEX_X-1,0},
{7,TEX_X-1,TEX_Y-1}}
},
{
{{4,0,0},
{7,TEX_X-1,TEX_Y-1},
{5,0,TEX_Y-1}}
},
{
{{1,0,0},
{0,TEX_X-1,0},
{4,TEX_X-1,TEX_Y-1}}
},
{
{{1,0,0},
{4,TEX_X-1,TEX_Y-1},
{5,0,TEX_Y-1}}
},
{
{{2,0,0},
{3,TEX_X-1,0},
{7,TEX_X-1,TEX_Y-1}}
},
{
{{2,0,0},
{7,TEX_X-1,TEX_Y-1},
{6,0,TEX_Y-1}}
},
{
{{5,0,0},
{1,TEX_X-1,0},
{3,TEX_X-1,TEX_Y-1}}
},
{
{{5,0,0},
{3,TEX_X-1,TEX_Y-1},
{7,0,TEX_Y-1}}
}
};
const VECTOR points[N_POINTS]=
{
{1<<SHIFT,1<<SHIFT,1<<SHIFT},
{1<<SHIFT,1<<SHIFT,-1<<SHIFT},
{1<<SHIFT,-1<<SHIFT,1<<SHIFT},
{1<<SHIFT,-1<<SHIFT,-1<<SHIFT},
{-1<<SHIFT,1<<SHIFT,1<<SHIFT},
{-1<<SHIFT,1<<SHIFT,-1<<SHIFT},
{-1<<SHIFT,-1<<SHIFT,1<<SHIFT},
{-1<<SHIFT,-1<<SHIFT,-1<<SHIFT},
};
VECTOR rotated[N_POINTS];
SORTER sorter[N_FACES];
MATRIX matrix;
u32 count,xbegin,xend;
s32 x_scale = 40<<SHIFT;
s32 y_scale = 40<<SHIFT;
s32 z_scale = 1<<SHIFT;
u16 tilt=0,turn=0,roll=0;
#define SCREENX 160
#define SCREENY 128
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
void plotsprite(u16 xpos,u16 ypos);
u8 gnewframe;
u16 *frameptr;
void filltriangle(FACE *);
void vblFunc();
void setup();
int main(void)
{
u8 swap;
s32 z;
s32 A,B,C,D,E,F,AD,BD;
u16 p,f,j;
ham_Init();
ham_SetBgMode(5);
ham_RotBgEx(2, 0, 0, 0, 0, 0, (256*GFX_MODE5_WIDTH)/GBA_SCREEN_WIDTH, //make width fullscreen
(256*GFX_MODE5_HEIGHT)/GBA_SCREEN_HEIGHT); // make height fullscreen
ham_StartIntHandler(INT_TYPE_VBL,(void *)&vblFunc);
setup();
while(TRUE)
{
if (gnewframe)
{
u8 buffer = ham_GetBGBuffer();
if (buffer==1) frameptr=(u16*)0x6000000;
else frameptr=(u16*)0x600a000;
plotsprite(0,0);
//rem prepare the rotation matrix
if (tilt > 359){tilt = 0;}
if (turn > 359){turn = 0;}
if (roll > 359){roll = 0;}
A=coz[tilt];B=zin[tilt];
C=coz[turn];D=zin[turn];
E=coz[roll];F=zin[roll];
AD=(A*D)>>SHIFT;
BD=(B*D)>>SHIFT;
matrix[0][0]=(C*E)>>SHIFT;
matrix[1][0]=(-C*F)>>SHIFT;
matrix[2][0]=D;
matrix[0][1]=((BD*E)+(A*F))>>SHIFT;
matrix[1][1]=((-BD*F)+(A*E))>>SHIFT;
matrix[2][1]=(-B*C)>>SHIFT;
matrix[0][2]=((-AD*E)+(B*F))>>SHIFT;
matrix[1][2]=((AD*F)+(B*E))>>SHIFT;
matrix[2][2]=(A*C)>>SHIFT;
//rem rotate all the points using the matrix
for (p=0;p<N_POINTS; p++)
{
rotated[p].x = ((matrix[0][0] * points[p].x)>>SHIFT) + ((matrix[0][1] * points[p].y)>>SHIFT) + ((matrix[0][2] * points[p].z)>>SHIFT);
rotated[p].x = (rotated[p].x * x_scale)>>SHIFT;
rotated[p].y = ((matrix[1][0] * points[p].x)>>SHIFT) + ((matrix[1][1] * points[p].y)>>SHIFT) + ((matrix[1][2] * points[p].z)>>SHIFT);
rotated[p].y = (rotated[p].y * y_scale)>>SHIFT;
rotated[p].z = ((matrix[2][0] * points[p].x)>>SHIFT) + ((matrix[2][1] * points[p].y)>>SHIFT) + ((matrix[2][2] * points[p].z)>>SHIFT);
//rem now do the perspective calculation
z = ((1L<<SHIFT)<<SHIFT)/(rotated[p].z + TWOPOINTFIVE);
rotated[p].x = ((SCREENX/2)<<SHIFT) + ((rotated[p].x * z)>>SHIFT);
rotated[p].y = ((SCREENY/2)<<SHIFT) - ((rotated[p].y * z)>>SHIFT);
}
//rem set up the sorting array
for (f=0;f<N_FACES;f++)
{
s32 z0,z1,z2;
u8 p0,p1,p2;
p0 = faces[f].pt[0].point_index;
p1 = faces[f].pt[1].point_index;
p2 = faces[f].pt[2].point_index;
z0 = rotated[p0].z;
z1 = rotated[p1].z;
z2 = rotated[p2].z;
sorter[f].face = f;
//near z
//sorter[f].z = max(z0,max(z1,z2));
//far z
//sorter[f].z = min(z0,min(z1,z2));
//ave z
sorter[f].z = (z0+z1+z2);
}
do
{
swap= 0;
for (j=0;j<N_FACES-1;j++)
{
if (sorter[j+1].z > sorter[j].z)
{
SORTER tmp;
tmp = sorter[j+1];
sorter[j+1]=sorter[j];
sorter[j]=tmp;
swap = 1;
}
}
} while (swap);
for (f=0;f<N_FACES;f++)
{
u16 face;
face = sorter[f].face;
filltriangle(&faces[face]);
//just plot the corners
/*
u16 p0,p1,p2;
p0 = faces[face].pt[0].point_index;
p1 = faces[face].pt[1].point_index;
p2 = faces[face].pt[2].point_index;
ham_PutPixel(rotated[p0].x, rotated[p0].y, 0x7fff);
ham_PutPixel(rotated[p1].x, rotated[p1].y, 0x7fff);
ham_PutPixel(rotated[p2].x, rotated[p2].y, 0x7fff);
*/
}
tilt = tilt+5;
turn = turn+6;
roll = roll+7;
//rem flip and the screens
ham_FlipBGBuffer();
ham_ClearBackBuffer(0);
gnewframe=0;
}
}
return 0;
}
void setup()
{
s32 coza;
for(coza=0;coza<359;coza++)
{
zin[coza] = sin(coza/180.0*3.14159)*SCALE;
coz[coza] = cos(coza/180.0*3.14159)*SCALE;
}
}
void vblFunc()
{
gnewframe=1;
}
void plotsprite(u16 xpos ,u16 ypos)
{
/*
u16 texptr=0;
s16 x,y;
for (y=0;y<SCREENY;y++)
{
for (x=0;x<SCREENX;x++)
{
*frameptr++=bground5[texptr++];
}
frameptr+=SCREENX-SCREENX;
}
u8 buffer = ham_GetBGBuffer();
if (buffer==1) frameptr=(u16*)0x6000000;
else frameptr=(u16*)0x600a000;
*/
u16 *src = bground5;
u16 *dst = frameptr;
u16 x,y;
for (y = 0; y < SCREENY; y++)
{
for (x = 0; x < SCREENX; x++)
*dst++ = *src++;
}
}
#define FSHIFT 16
#define FSCALE (1L<<FSHIFT)
void scan(EDGE *L,EDGE *R, s32 y)
{
s32 x0,x1,u,v,du,dv,dx;
u16 *screenptr16;
if (y<0 || y>=160) return;
if (L->x > R->x)
{
EDGE *t=L;
L=R;
R=t;
}
x0=L->x>>FSHIFT;
x1=R->x>>FSHIFT;
dx = x1-x0;
if (!dx) return;
if (x0>=SCREENY)
return;
else if (x0<0)
x0=0;
if (x1<0)
return;
else if (x1>=SCREENX)
x1=SCREENX;
u=L->u;
v=L->v;
du = (R->u - L->u) / dx;
dv = (R->v - L->v) / dx;
screenptr16 = frameptr + x0 + y * SCREENX;
while (dx--)
{
*screenptr16++ = texture[(u>>FSHIFT)+TEX_X*(v>>FSHIFT)];
u+=du;
v+=dv;
}
}
void filltriangle(FACE *face)
{
s32 xx[3], yy[3];
u8 i0,i1,i2;
s32 dyL, dyT, dyB;
s32 rdyL,rdyT,rdyB;
s32 Y;
s32 dxL, dxT, dxB;
s32 duL, duT, duB;
s32 dvL, dvT, dvB;
EDGE L,R;
yy[0]=rotated[face->pt[0].point_index].y>>SHIFT;
yy[1]=rotated[face->pt[1].point_index].y>>SHIFT;
yy[2]=rotated[face->pt[2].point_index].y>>SHIFT;
xx[0]=rotated[face->pt[0].point_index].x>>SHIFT;
xx[1]=rotated[face->pt[1].point_index].x>>SHIFT;
xx[2]=rotated[face->pt[2].point_index].x>>SHIFT;
i0 = 0;
i1 = 1;
i2 = 2;
if (yy[0]<=yy[1] && yy[0]<=yy[2])
{
//y0 is smallest
if (yy[1]>yy[2])
{
//y1 is largest
i1 = 2;
i2 = 1;
}
else
{
//y2 is largest
}
}
else if (yy[1]<=yy[0] && yy[1]<=yy[2])
{
i0 = 1;
//y1 is smallest
if (yy[0]<yy[2])
{
//y2 is largest
i1 = 0;
}
else
{
//y0 is largest
i1 = 2;
i2 = 0;
}
}
else
{
i0 = 2;
//y2 is smallest
if (yy[1]<yy[0])
{
//y0 is largest
i2 = 0;
}
else
{
//y1 is largest
i2 = 1;
i1 = 0;
}
}
dyL = yy[i2]-yy[i0];
if (dyL==0) return;
rdyL = FSCALE / dyL;
dxL = (xx[i2]-xx[i0]) * rdyL;
duL = (face->pt[i2].u-face->pt[i0].u) * rdyL;
dvL = (face->pt[i2].v-face->pt[i0].v) * rdyL;
dyT = yy[i1]-yy[i0];
L.x=xx[i0]<<FSHIFT;
Y=yy[i0];
L.u=face->pt[i0].u<<FSHIFT;
L.v=face->pt[i0].v<<FSHIFT;
if (dyT!=0)
{
rdyT = FSCALE / dyT;
dxT = (xx[i1]-xx[i0]) * rdyT;
duT = (face->pt[i1].u-face->pt[i0].u) * rdyT;
dvT = (face->pt[i1].v-face->pt[i0].v) * rdyT;
R=L;
while (Y < yy[i1])
{
scan(&L,&R,Y);
Y++;
L.x+=dxL;
R.x+=dxT;
L.u+=duL;
L.v+=dvL;
R.u+=duT;
R.v+=dvT;
}
}
//bottom
R.x=xx[i1]<<FSHIFT;
R.u=face->pt[i1].u<<FSHIFT;
R.v=face->pt[i1].v<<FSHIFT;
dyB = yy[i2]-yy[i1];
if (dyB!=0)
{
rdyB = FSCALE / dyB;
dxB = (xx[i2]-xx[i1]) * rdyB;
duB = (face->pt[i2].u-face->pt[i1].u) * rdyB;
dvB = (face->pt[i2].v-face->pt[i1].v) * rdyB;
while (Y < yy[i2])
{
scan(&L,&R,Y);
Y++;
L.x+=dxL;
R.x+=dxB;
L.u+=duL;
L.v+=dvL;
R.u+=duB;
R.v+=dvB;
}
}
}
-
and again, thanks a lot! Karma up!
-
:) Looks like you're innundated with softrenderers!
-
But none do mipmapping yet ...
-
->nino - you should probably credit that code, especially since you're giving it away...
->Taj,
Mipmapping's a separate problem from drawing textured triangles - you just have to pick the right sized texture first. One way of doing this is looking at the z of the triangle and picking smaller textures for far away z, but a far better way is to work out the area of the triangle being rendered in pixels (ie. use a 2d cross product on the screen coordinates) and how many texels it needs (ie. use a 2d cross on the vertex uv's) and work out which texture supplies roughly the right number of texels for that screen area (division, and a lookup).
Jim
-
woops sorry jim yeah its jims code for an old project me him and sg did on or old forum, i credited you over on my gba tuts for the render so thought that would be ok sorry for that :-X
if youd like jim i could change the above peice of code with one of my own renders when i dig it out and also remove the demo from my gba tut?
-
Just a simple credit is fine. I have absolutely no problem with people using my code, otherwise I wouldn't post it :D
Jim
-
thanks jim