Thanks, that will need some time to check if I can adapt your code to be 100% safe for my AntiLine function, at the moment I have a small problem I have to check...
When hitting the right border, my antialiasing code makes a (wrong) point at the left side of the screen. This could be a problem, when this will below the screen area (and out of the screen memory range)...
Code: Select all
EnableExplicit
#AllowAssembler=1
Global OptAntialiasing=#True
Global Directmemory=#True
Global Dim AntiA(255)
Global Dim AntiB(255)
Global ScreenX=GetSystemMetrics_(#SM_CXSCREEN)
Global ScreenY=GetSystemMetrics_(#SM_CYSCREEN)
Structure DxStructure
StructureUnion
l.l
w.w
EndStructureUnion
EndStructure
Global DxMem,DxMul,DxPix; Plot-Beschleunigung...
Global *DX.DxStructure
Declare MergePixel32(x,y,r,g,b,w)
Declare MergePixel24(x,y,r,g,b,w)
Declare MergePixel16(x,y,r,g,b,w)
Declare MergePixel(x,y,r,g,b,w)
Prototype MergePixelType(x,y,r,g,b,w)
Global MergePixelRoutine.MergePixelType
Macro ColRGB(r,g,b)
( r&$ff + (g&$ff)<<8 + (b&$ff)<<16 )
EndMacro
Macro ColRed(col)
(col&$ff)
EndMacro
Macro ColGreen(col)
(col>>8&$ff)
EndMacro
Macro ColBlue(col)
(col>>16&$ff)
EndMacro
Macro ColMix(c,r,g,b,w,iw)
;
; 24/32 Bit-Pixel: bbbbbbbb|gggggggg|rrrrrrrr
( (r*w+ColRed(c)*(iw))>>8 + (g*w+ColGreen(c)*(iw))&$ff00 + (b*w+ColBlue(c)*(iw))<<8&$ff0000 )
;( (r*w+ColRed(c)*(255-w))>>8 + (g*w+ColGreen(c)*(255-w))&$ff00 + (b*w+ColBlue(c)*(255-w))<<8&$ff0000 )
;
; nach [w*a+(255-w)*b]/256 = [w*(a-b)+255*b]/256 ~ [w+(a-b)]/256 + b sparen wir eine Multiplikation...
;( (w*(r-ColRed(c)))>>8 + (w*(g-ColGreen(c)))&$ff00 + (w*(b-ColBlue(c)))<<8&$ff0000 + c)
EndMacro
Macro ColMurx(c,r,g,b,w,iw)
;
; 16 Bit-Pixel: rrrr|rggg|ggxb|bbbb (wobei "x" bei grün verwendet wird)
( (r*w+(c>>8&$f8)*(iw))&$f800 + ((g*w+(c>>3&$f8)*(iw))&$f800)>>5 + (b*w+(c<<3&$f8)*(iw))>>11 )
;( (r*w+(c>>8&$f8)*(255-w))&$f800 + ((g*w+(c>>3&$f8)*(255-w))&$f800)>>5 + (b*w+(c<<3&$f8)*(255-w))>>11 )
;
; nach [w*a+(255-w)*b]/256 = [w*(a-b)+255*b]/256 ~ [w+(a-b)]/256 + b sparen wir eine Multiplikation...
;( (w*(r-c>>8&$f8)+c)&$f800 + ((w*(g-c>>3&$f8))>>5+c)&$7c0 + (w*(b-c<<3&$f8))>>11 +c&$1f )
EndMacro
Procedure MergePixel32(x,y,r,g,b,w)
CompilerIf #AllowAssembler
MOV eax,x
MOV ecx,y
CMP eax,ScreenX ; x > ScreenX ?
JG exitMP32
CMP ecx,ScreenY ; y > SreenY ?
JG exitMP32
OR eax,ecx ; x OR y < 0?
JS exitMP32
;*DX=DxMem+x<<2+y*DxMul
IMUL ecx,DxMul ; y*DxMul
MOV eax,x ; x
SHL eax,2 ; x*4
ADD eax,ecx ; x*4+y*DxMul
ADD eax,DxMem ; DxMem+x<<2+y*DxMul
MOV *DX,eax ; -> *DX
;*DX\l=ColMix(*DX\l,b,g,r,w,255-w)
MOV ebx,*DX\l ; color
MOV edx,255 ; 255
MOV ecx,w ; w (ecx)
SUB edx,ecx ; 255-w (edx)
MOV eax,ebx ; color
AND eax,$ff ; cr=Red(color)
MUL dl ; cr*(255-w)
MOV edi,eax ; parken
MOV eax,r ; r
MUL cl ; r*w
ADD eax,edi ; r*w+cr*(255-w)
SAR eax,8 ; [r*w+cr*(255-w)] >>8
MOV esi,eax ; rot
MOV eax,ebx ; color
SAR eax,8 ; >>8
AND eax,$ff ; cg=Green(color)
MUL dl ; cr*(255-w)
MOV edi,eax ; parken
MOV eax,g ; g
MUL cl ; g*w
ADD eax,edi ; g*w+cg*(255-w)
AND eax,$ff00 ; [g*w+cg*(255-w)] &$ff00
ADD esi,eax; grün|rot
MOV eax,ebx ; color
SAR eax,16 ; >>16
AND eax,$ff ; cb=Blue(color)
MUL dl ; cb*(255-w)
MOV edi,eax ; parken
MOV eax,b ; b
MUL cl ; b*w
ADD eax,edi ; b*w+cb*(255-w)
AND eax,$ff00 ; [b*w+cb*(255-w)] &$ff00
SAL eax,8
ADD esi,eax; blau|grün|rot
MOV *DX\l,esi
!exitMP32:
CompilerElse
; If x>=0 And x<ScreenX And y>=0 And y<ScreenY
*DX=DxMem+x<<2+y*DxMul
*DX\l=ColMix(*DX\l,b,g,r,w,255-w)
; EndIf
CompilerEndIf
EndProcedure
Procedure MergePixel24(x,y,r,g,b,w)
CompilerIf #AllowAssembler
MOV eax,x
MOV ecx,y
CMP eax,ScreenX ; x > ScreenX ?
JG exitMP24
CMP ecx,ScreenY ; y > SreenY ?
JG exitMP24
OR eax,ecx ; x OR y < 0?
JS exitMP24
IMUL eax,DxMul ; y*DxMul
;MUL ecx,3
;ADD eax,ecx ; x*3+y*DxMul
ADD eax,ecx ; y*DxMul+x
ADD eax,ecx ; y*DxMul+2*x
ADD eax,ecx ; y*DxMul+3*x
MOV x,eax ; -> x
*DX=DxMem+x ; anstelle von x*3+y*DxMul
*DX\l=ColMix(*DX\l,b,g,r,w,255-w)|(*DX\l&$FF000000)
!exitMP24:
CompilerElse
; If x>=0 And x<ScreenX And y>=0 And y<ScreenY
*DX=DxMem+x*3+y*DxMul
*DX\l=ColMix(*DX\l,b,g,r,w,255-w)|(*DX\l&$FF000000)
; EndIf
CompilerEndIf
EndProcedure
Procedure MergePixel16(x,y,r,g,b,w)
CompilerIf #AllowAssembler
MOV eax,x
MOV ecx,y
CMP eax,ScreenX ; x > ScreenX ?
JG exitMP16
CMP ecx,ScreenY ; y > SreenY ?
JG exitMP16
OR eax,ecx ; x OR y < 0?
JS exitMP16
;*DX=DxMem+x<<1+y*DxMul
IMUL ecx,DxMul ; y*DxMul
MOV eax,x ; x
SHL eax,1 ; x*2
ADD eax,ecx ; x*2+y*DxMul
ADD eax,DxMem ; DxMem+x<<1+y*DxMul
MOV *DX,eax ; -> *DX
;*DX\w=ColMurx(*DX\w,r,g,b,w,255-w)
MOV bx,*DX\w ; color
MOV edx,255 ; 255
MOV ecx,w ; w (ecx)
SUB edx,ecx ; 255-w (edx)
MOV eax,ebx ; color
SAR eax,8 ; <<8
AND eax,$f8 ; cr=Red(color)
MUL dl ; cr*(255-w)
MOV edi,eax ; parken
MOV eax,r ; r
MUL cl ; r*w
ADD eax,edi ; r*w+cr*(255-w)
AND eax,$f800
MOV esi,eax ; rot
MOV eax,ebx ; color
SAR eax,3 ; >>3
AND eax,$f8 ; cg=Green(color)
MUL dl ; cr*(255-w)
MOV edi,eax ; parken
MOV eax,g ; g
MUL cl ; g*w
ADD eax,edi ; g*w+cg*(255-w)
SAR eax,5 ; >>5
AND eax,$ff00 ; [g*w+cg*(255-w)] &$ff00
ADD esi,eax; grün|rot
MOV eax,ebx ; color
SAL eax,3 ; <<3
AND eax,$f8 ; cb=Blue(color)
MUL dl ; cb*(255-w)
MOV edi,eax ; parken
MOV eax,b ; b
MUL cl ; b*w
ADD eax,edi ; b*w+cb*(255-w)
AND eax,$ff00 ; [b*w+cb*(255-w)] &$ff00
SAR eax,11 ; >>11
ADD eax,esi; blau|grün|rot
MOV *DX\w,ax
!exitMP16:
CompilerElse
; If x>=0 And x<ScreenX And y>=0 And y<ScreenY
*DX=DxMem+x<<1+y*DxMul
*DX\w=ColMurx(*DX\w,r,g,b,w,255-w)
; Plot(x,y,ColMix(Point(x,y),r,g,b,w,255-w))
; SetPixel_(hdc,x,y,col)
; EndIf
CompilerEndIf
EndProcedure
Procedure MergePixel(x,y,r,g,b,w)
CompilerIf #AllowAssembler
!mov eax,dword[p.v_x]
!mov ecx,dword[p.v_y]
!cmp eax,v_ScreenX ; x > ScreenX ?
!jg exitMP
!cmp ecx,v_ScreenY ; y > SreenY ?
!jg exitMP
!or eax,ecx ; x OR y < 0?
!js exitMP
Plot(x,y,ColMix(Point(x,y),r,g,b,w,255-w))
!exitMP:
CompilerElse
; If x>=0 And x<ScreenX And y>=0 And y<ScreenY
Plot(x,y,ColMix(Point(x,y),r,g,b,w,255-w))
; EndIf
CompilerEndIf
EndProcedure
Procedure AntiLineXY(x1,y1,x2,y2,col)
If OptAntialiasing
Protected r = ColRed(col)
Protected g = ColGreen(col)
Protected b = ColBlue(col)
Protected xd=x2-x1
Protected yd=y2-y1
Protected x,y,xf,yf
Protected grad,w
;Debug Str(x1)+", "+Str(y1)+", "+Str(x2)+", "+Str(y2)
CompilerIf #AllowAssembler
MergePixelRoutine(x1,y1,r,g,b,255)
CompilerElse
If x1>=0 And x1<ScreenX And y1>=0 And y1<ScreenY
MergePixelRoutine(x1,y1,r,g,b,255)
EndIf
CompilerEndIf
CompilerIf #AllowAssembler
MergePixelRoutine(x2,y2,r,g,b,255)
CompilerElse
If x2>=0 And x2<ScreenX And y2>=0 And y2<ScreenY
MergePixelRoutine(x2,y2,r,g,b,255)
EndIf
CompilerEndIf
If xd=0 Or yd=0
LineXY(x1,y1,x2,y2,col)
ProcedureReturn
EndIf
If Abs(xd)>Abs(yd)
If (x1>x2)
Swap x1,x2
Swap y1,y2
xd=-xd
yd=-yd
EndIf
grad=yd<<16/xd
yf=y1<<16
For x=x1+1 To x2-1
yf+grad
w=(yf>>8)&$FF
y=yf>>16
CompilerIf #AllowAssembler
MergePixelRoutine(x,y,r,g,b,AntiA(w))
MergePixelRoutine(x,y+1,r,g,b,AntiB(w))
CompilerElse
If x>=0 And x<ScreenX
If y>=0 And y<ScreenY
MergePixelRoutine(x,y,r,g,b,AntiA(w))
EndIf
If y>=-1 And y+1<ScreenY
MergePixelRoutine(x,y+1,r,g,b,AntiB(w))
EndIf
EndIf
CompilerEndIf
Next
Else
If (y1>y2)
Swap x1,x2
Swap y1,y2
xd=-xd
yd=-yd
EndIf
grad=xd<<16/yd
xf=x1<<16
For y=y1+1 To y2-1
xf+grad
w=(xf>>8)&$FF
x=xf>>16
CompilerIf #AllowAssembler
MergePixelRoutine(x,y,r,g,b,AntiA(w))
MergePixelRoutine(x+1,y,r,g,b,AntiB(w))
CompilerElse
If y>=0 And y<ScreenY
If x>=0 And x<ScreenX
MergePixelRoutine(x,y,r,g,b,AntiA(w))
EndIf
If x>=-1 And x+1<ScreenX
MergePixelRoutine(x+1,y,r,g,b,AntiB(w))
EndIf
EndIf
CompilerEndIf
Next
EndIf
Else
LineXY(x1,y1,x2,y2,col)
EndIf
EndProcedure
Procedure ClipAntiLineXY(x1,y1,x2,y2,col)
;fast done Liang-Barsky line clipping algo
;by djes 09/2007
Protected minx=0
Protected miny=0
Protected maxx = screenx
Protected maxy = screeny
Protected t0.f
Protected t1.f
Protected dx.f
Protected dy.f
Protected p.f
Protected q.f
Protected r.f
t0.f = 0
t1.f = 1
dx.f = x2 - x1
dy.f = y2 - y1
;*************************
p.f = - dx
q.f = - (minx - x1)
r.f = q/p
If p = 0 And q < 0
Goto ENDCLIP
EndIf
If p < 0
If r > t1
Goto ENDCLIP
EndIf
If r > t0
t0 = r
EndIf
ElseIf p > 0
If r < t0
Goto ENDCLIP
EndIf
If r < t1
t1 = r
EndIf
EndIf
;*************************
p.f = dx
q.f = maxx - x1
r.f = q/p
If p = 0 And q < 0
Goto ENDCLIP
EndIf
If p < 0
If r > t1
Goto ENDCLIP
EndIf
If r > t0
t0 = r
EndIf
ElseIf p > 0
If r < t0
Goto ENDCLIP
EndIf
If r < t1
t1 = r
EndIf
EndIf
;*************************
p.f = - dy
q.f = - (miny - y1)
r.f = q/p
If p = 0 And q < 0
Goto ENDCLIP
EndIf
If p < 0
If r > t1
Goto ENDCLIP
EndIf
If r > t0
t0 = r
EndIf
ElseIf p > 0
If r < t0
Goto ENDCLIP
EndIf
If r < t1
t1 = r
EndIf
EndIf
;*************************
p.f = dy
q.f = maxy - y1
r.f = q/p
If p = 0 And q < 0
Goto ENDCLIP
EndIf
If p < 0
If r > t1
Goto ENDCLIP
EndIf
If r > t0
t0 = r
EndIf
ElseIf p > 0
If r < t0
Goto ENDCLIP
EndIf
If r < t1
t1 = r
EndIf
EndIf
;*************************
ENDCLIP:
If t1 < 1
x2 = x1 + t1*dx
y2 = y1 + t1*dy
EndIf
If t0 > 0
x1 = x1 + t0*dx
y1 = y1 + t0*dy
EndIf
Debug x1
Debug y1
Debug x2
Debug y2
AntiLineXY(x1,y1,x2,y2,col)
EndProcedure
Procedure.l Limit(x.l)
CompilerIf #AllowAssembler
!mov eax,dword[p.v_x]
!xor edx,edx ; set EDX to zero
!cmp eax,0 ; compare with top limit
!cmovl eax,edx ;
!mov edx,255 ; 255
!cmp eax,edx ; compare with bottom limit
!cmovg eax,edx ; if lower, set value to bottom limit
ProcedureReturn
CompilerElse
If x<0
ProcedureReturn 0
ElseIf x>255
ProcedureReturn 255
Else
ProcedureReturn x
EndIf
CompilerEndIf
EndProcedure
Procedure AntiTable()
Protected dummy,k
Dummy=5<<4
For k=0 To 255
AntiA(k)=Limit(255-k+Dummy)
AntiB(k)=Limit(k+Dummy)
Next k
EndProcedure
Procedure Demo()
Protected i,win
win=OpenWindow(0,0,0,ScreenX,ScreenY,"",#PB_Window_ScreenCentered | #PB_Window_BorderLess)
InitSprite()
OpenWindowedScreen(win,0,0,ScreenX,ScreenY,0,0,0)
StartDrawing(ScreenOutput())
If DirectMemory
DxMem=DrawingBuffer()
DxMul=DrawingBufferPitch()
DxPix=DrawingBufferPixelFormat(); liefert bei einigen Notebooks leider 0...
If DxPix=0
i=GetDC_(0)
Select GetDeviceCaps_(i,#BITSPIXEL)
Case 32
DxPix=#PB_PixelFormat_32Bits_RGB
Case 24
DxPix=#PB_PixelFormat_24Bits_RGB
Case 15,16
DxPix=#PB_PixelFormat_16Bits
EndSelect
ReleaseDC_(0,i)
EndIf
If DxPix>=#PB_PixelFormat_32Bits_RGB
MergePixelRoutine=@MergePixel32()
ElseIf DxPix>=#PB_PixelFormat_24Bits_RGB
MergePixelRoutine=@MergePixel24()
ElseIf DxPix>=#PB_PixelFormat_15Bits
MergePixelRoutine=@MergePixel16()
Else
OptAntialiasing=0
End
EndIf
Else
MergePixelRoutine=@MergePixel()
End
EndIf
AntiLineXY(0,-4,screenx,screeny-4,$c0c0e0)
ClipAntiLineXY(0,-2,screenx,screeny-2,$f0c0c0)
StopDrawing()
FlipBuffers(#PB_Screen_SmartSynchronization)
Repeat
Until GetAsyncKeyState_(#VK_SPACE)
EndProcedure
AntiTable()
Demo()