ralle hat geschrieben:
Ok, damit klappt es, teilweise. Malt jetzt in einer schicken Geschwindigkeit bunte Pixel auf den Screen, jedoch bleibt die untere Rechte Ecke immer Schwarz.
Ralle
Teste mal folgenden Code,weiss zwar nich mehr genau wo ich ihn herhab,ist ein sehr schönes Beispiel.Hab ihn an PB 4.50 angepasst.
Code:
;=========================================;
; ;
; C I N T A M A N I ;
; ;
; Directdraw Graphics Library ;
; ;
;_________________________________________;
; ;
; CC : A + SA ;
; jayagopal.das -- May 15, 2009 ;
; ;
;=========================================;
;-Constants
;#screenW =1600: #screenH = 900
;#screenW =1024: #screenH = 768
;#screenW = 800: #screenH = 600
#screenW = 640: #screenH = 480
;#screenW = 320: #screenH = 240
#RD=0
#GR=1
#BL=2
#Background=-2
#Foreground=-1
;-Procedure Declarations
;Graphics
Declare redraw() ; draw the virtual-screen on the real one
Declare clear(x1=0,y1=0,x2=#screenW-1,y2=#screenH-1) ; restore the background (or a portion of it)
Declare addPage() ; add a screen page
Declare deletePage(pageNumber) ;NOT TESTED YET!!!
Declare copyPageFore(pageNumber) ; copy a screen page to the foreground
Declare copyPageBack(pageNumber) ; copy a screen page to the background
Declare.c virtualScreen(x,y,channel,intensity=-1) ; read/write the appropriate screen page
Declare mLine(x1,y1,x2,y2,r=255,g=255,b=255,a=255,antialias=0) ; manual line drawing routine
Declare mCircle(x,y,rad,r=255,g=255,b=255,a=255,antialias=0) ; manual circle drawing routine
Declare pixel(x,y,r=255,g=255,b=255,a=255) ; write a pixel to the virtual screen
;Calculation
Declare.f frac(num.f) ; return the fractional part of a number
Declare.f radius(dx,dy) ; return a value from the radius table
; Declare Sign(n) ; return the sign of a number
;-Global arrays and variables
Global Dim radiusTable.f(#screenW,#screenH) ; to speed up distance calculations
Global *foreground=AllocateMemory(#screenW*#screenH*4) ; the foreground screen page
Global *background=AllocateMemory(#screenW*#screenH*4) ; the background screen page
Global Dim *page(0) ; used for storing additional screen pages
Global pageCount=0
Global Buffer ; starting address for screen memory
Global Pitch ; bytes in one screen-line
Global drawPage ; the page to draw to
;==========STARTING FROM HERE, this can be in another file==================
;-Initialization
If InitSprite()=0 Or InitKeyboard()=0 Or InitMouse()=0: End: EndIf
If OpenScreen(#screenW, #screenH, 32, "PB DirectGraphics Library Example")
;- Main Loop
;{ contains examples of drawing using these procedures
;draw some static on a gradient on 4 different pages
For i=1 To 4
addPage()
drawPage=i ;this is the page-number to draw to (index starts from 1)
For y=0 To #screenH-1: For x=0 To #screenW-1
pixel(x,y,Int(x/#screenW*255),Int(y/#screenH*255),Int((x+y)/(#screenW+#screenH)*255)): pixel(x,y,Random(64),Random(64),Random(64),128)
Next: Next
Next
;some variables for drawing the thingy
rad=#screenH*0.14: circumference=rad*2*#PI: t.f: ti.f
Repeat
ExamineKeyboard()
ExamineMouse()
drawPage=#Foreground
;draw a weird thingy that spins And follows the mouse
;mx=MouseX(): my=MouseY()
mx=DesktopMouseX(): my=DesktopMouseY()
mLine(#screenW/2,#screenH/2,mx,my,255,255,255,155,1)
t=ti: ti+0.05
For i=0 To 23
t+(#PI/12): px=mx+rad*Cos(t): py=my+rad*Sin(t)
mLine(mx,my,px,py,255,255,255,155,1)
mCircle(px,py,#screenH*0.02,255,255,255,155,1)
Next
;draw some random lines, circles and pixels
For i=1 To 3000: pixel(Random(#screenW),Random(#screenH), Random(255),Random(255),Random(255), Random(155)): Next
For i=1 To 10
mLine(Random(#screenW),Random(#screenH), Random(#screenW),Random(#screenH), Random(255),Random(255),Random(255), Random(55),1)
mCircle(Random(#screenW),Random(#screenH), Random(#screenW), Random(255),Random(255),Random(255), Random(55),1)
Next
mCircle(#screenW/2,#screenH/2,#screenH*0.3, 255,255,255,155,0) ;standing circle
mCircle(#screenW/2,#screenH/2,#screenH*0.4, 255,255,255,155,1) ;standing antialiased circle
mLine(#screenW*0.375,#screenH,#screenW,#screenH*0.375, 255,255,255,155,0) ;standing line
mLine(0,#screenH/2,#screenW/2,0, 255,255,255,155,1) ;standing antialiased line
;cycle the background through all the extra pages (this will not effect the foreground, but WILL overwrite the background)
If q=pageCount: q=1: EndIf: copyPageBack(q): q+1
drawPage=#Background
;draw directly onto the background (even after the foreground is drawn) -- this will be updated after clear() is called
For r =1 To 50: mCircle(100,100, r, Random(255),Random(255),Random(255), Random(55),1): Next
redraw()
clear() ;full clear
;halfDim=rad+#screenH*0.02+1: clear(mx-halfDim,my-halfDim,mx+halfDim,my+halfDim) ;example of clearing just a portion
Until KeyboardPushed(#PB_Key_Escape) ;}
Else
MessageRequester("Error","Sorry, some problem drawing the screen?",0)
EndIf
End
;==========AND ENDING HERE, this can be in another file==================
;-Graphics procedures
Procedure redraw()
restoredrawPage=drawPage
drawPage=#Foreground
If StartDrawing(ScreenOutput())
Buffer = DrawingBuffer() ; Get the start address of the screen buffer.
Pitch = DrawingBufferPitch() ; Get the length (in bytes) of one horizontal line.
For y=0 To #screenH-1
*Line.l = Buffer+Pitch*y
For x=0 To #screenW-1
PokeC(*Line, virtualScreen(x,y,#BL)): *Line+1
PokeC(*Line, virtualScreen(x,y,#GR)): *Line+1
PokeC(*Line, virtualScreen(x,y,#RD)): *Line+2
Next
Next
StopDrawing()
FlipBuffers() ; Page flipping
EndIf
drawPage=restoredrawPage
EndProcedure
Procedure clear(x1=0,y1=0,x2=#screenW-1,y2=#screenH-1)
If x1=0 And y1=0 And x2=#screenW-1 And y2=#screenH-1
CopyMemory(*background,*foreground,#screenW*#screenH*4)
Else
;restore the specified portion
If x1>x2: Swap x1, x2: EndIf
If y1>y2: Swap y1, y2: EndIf
If x1<0: x1=0: EndIf: If x2>#screenW-1: x2=#screenW-1: EndIf
If y1<0: y1=0: EndIf: If y2>#screenH-1: y2=#screenH-1: EndIf
width=(x2-x1)*4
For y=y1 To y2
offset=y*#screenW*4+x1*4
CopyMemory(*background+offset,*foreground+offset,width)
Next
EndIf
EndProcedure
Procedure addPage()
pageCount=ArraySize(*page())+1
ReDim *page(pageCount)
*page(pageCount)=AllocateMemory(#screenW*#screenH*4)
EndProcedure
Procedure deletePage(pageNumber)
FreeMemory(*page(pageNumber))
For i=pageNumber To pageCount: *page(i)=*page(i+1): Next
pageCount-1
EndProcedure
Procedure copyPageFore(pageNumber)
If pageNumber>0 And pageNumber<=pageCount
CopyMemory(*page(pageNumber),*foreground,#screenW*#screenH*4)
EndIf
EndProcedure
Procedure copyPageBack(pageNumber)
If pageNumber>0 And pageNumber<=pageCount
CopyMemory(*page(pageNumber),*background,#screenW*#screenH*4)
EndIf
EndProcedure
Procedure.c virtualScreen(x,y,channel,intensity=-1)
Select drawPage
Case #Foreground: *pageAddress=*foreground
Case #Background: *pageAddress=*background
Default: *pageAddress=*page(drawPage)
EndSelect
If intensity=-1
intensity=PeekC(*pageAddress+y*#screenW*4+x*4+channel)
ProcedureReturn intensity
Else
PokeC(*pageAddress+y*#screenW*4+x*4+channel,intensity)
ProcedureReturn 1
EndIf
EndProcedure
Procedure mLine(x1,y1,x2,y2,r=255,g=255,b=255,a=255,antialias=0)
If antialias: gradient.f: y.f: C1.f: C2.f: xend.f: yend.f: xgap.f: deltax.f: deltay.f: EndIf ;initialize floats
If Abs(y2-y1) > Abs(x2-x1): steep=1: EndIf ;detect slopes>.5
If steep: Swap x1, y1: Swap x2, y2: EndIf
If x1>x2: Swap x1, x2: Swap y1, y2: EndIf
;ix1=x1:ix2=x2
deltax=x2-x1
deltay=Abs(y2-y1)
error=deltax/2
y=y1
If antialias And deltax<>0
gradient=deltay/deltax+0.0010001 ;get slope
;generate antialiased endpoints
xend=Int(x1+0.5)
yend=y1+gradient*(xend-x1)
xgap=1-frac(x1)
ix1=Int(xend)
iy1=Int(yend)
C2=frac(yend+0.5)*xgap
C1=1-C2
;If steep: pixel(iy1,ix1,r,g,b,a*C1): pixel(iy1+1,ix1,r,g,b,a*C2)
;Else: pixel(ix1,iy1,r,g,b,a*C1): pixel(ix1,iy1+1,r,g,b,a*C2): EndIf
;y=yend+gradient
xend=Int(x2+0.5)
yend=y2+gradient*(xend-x2)
xgap=1-frac(x2)
ix2=Int(xend)
iy2=Int(yend)
C2=frac(yend+0.5)*xgap
C1=1-C2
;If steep: pixel(iy2,ix2,r,g,b,a*C1): pixel(iy2+1,ix2,r,g,b,a*C2)
;Else: pixel(ix2,iy2,r,g,b,a*C1): pixel(ix2,iy2+1,r,g,b,a*C2): EndIf
EndIf
If y1<y2: ystep = 1: Else: ystep = -1: gradient*-1: EndIf
For x=x1 To x2
If Not antialias ;bresenham's algorithm
If steep: pixel(y,x,r,g,b,a): Else: pixel(x,y,r,g,b,a): EndIf
error-deltay
If error<0: y+ystep: error+deltax: EndIf
Else ;wu's algorithm
C2=frac(y+0.5)
C1=1-C2
If steep: pixel(y+0,x,r,g,b,a*C1): Else: pixel(x,y+0,r,g,b,a*C1): EndIf
If steep: pixel(y+1,x,r,g,b,a*C2): Else: pixel(x,y+1,r,g,b,a*C2): EndIf
y+gradient
EndIf
Next
EndProcedure
Procedure mCircle(x,y,rad,r=255,g=255,b=255,a=255,antialias=0)
If rad>0
ys.f
If antialias: C1.f: C2.f: Else: C1=1: EndIf
For xs = -rad*0.7071 To -1
ys=Sqr(rad*rad-xs*xs)
If antialias: C2=frac(ys+0.5): C1=1-C2: EndIf
pixel(x+xs,y+ys,r,g,b,a*C1)
pixel(x-xs,y+ys,r,g,b,a*C1)
pixel(x+xs,y-ys,r,g,b,a*C1)
pixel(x-xs,y-ys,r,g,b,a*C1)
pixel(x+ys,y+xs,r,g,b,a*C1)
pixel(x-ys,y+xs,r,g,b,a*C1)
pixel(x+ys,y-xs,r,g,b,a*C1)
pixel(x-ys,y-xs,r,g,b,a*C1)
If antialias
pixel(x+xs,y+ys+1,r,g,b,a*C2)
pixel(x-xs,y+ys+1,r,g,b,a*C2)
pixel(x+xs,y-ys-1,r,g,b,a*C2)
pixel(x-xs,y-ys-1,r,g,b,a*C2)
pixel(x+ys+1,y+xs,r,g,b,a*C2)
pixel(x-ys-1,y+xs,r,g,b,a*C2)
pixel(x+ys+1,y-xs,r,g,b,a*C2)
pixel(x-ys-1,y-xs,r,g,b,a*C2)
EndIf
Next
If antialias: C2=frac(rad+0.5): C1=1-C2: Else: C1=1: EndIf
pixel(x,y+rad,r,g,b,a*C1)
pixel(x,y-rad,r,g,b,a*C1)
pixel(x+rad,y,r,g,b,a*C1)
pixel(x-rad,y,r,g,b,a*C1)
If antialias
pixel(x,y+rad+1,r,g,b,a*C2)
pixel(x,y-rad-1,r,g,b,a*C2)
pixel(x+rad+1,y,r,g,b,a*C2)
pixel(x-rad-1,y,r,g,b,a*C2)
EndIf
;circumference=rad*2*#PI
;;generic calculation:
;t.f
;For i = 1 To circumference
; t+2*#PI/circumference
; pixel(x+rad*Cos(t), y+rad*Sin(t), r,g,b,a)
;Next
EndIf
EndProcedure
Procedure pixel(x,y,r=255,g=255,b=255,a=255)
If r<0 : r=0 : EndIf
If g<0 : g=0 : EndIf
If b<0 : b=0 : EndIf
If a<0 : a=0 : EndIf
If r>255 : r=255 : EndIf
If g>255 : g=255 : EndIf
If b>255 : b=255 : EndIf
If a>255 : a=255 : EndIf
If x>=0 And x<#screenW And y>=0 And y<#screenH
If a<255
ar=255-a
r=virtualScreen(x,y,#RD)*ar/255+b*a/255
g=virtualScreen(x,y,#GR)*ar/255+g*a/255
b=virtualScreen(x,y,#BL)*ar/255+r*a/255
EndIf
virtualScreen(x,y,#RD,r)
virtualScreen(x,y,#GR,g)
virtualScreen(x,y,#BL,b)
EndIf
EndProcedure
;-Calculation procedures
Procedure.f frac(num.f)
num=num-Int(num)
ProcedureReturn num
EndProcedure
Procedure.f radius(dx,dy)
ProcedureReturn radiusTable(Int(Abs(dx)),Int(Abs(dy)))
EndProcedure
; Procedure Sign(n)
; ProcedureReturn n/Abs(n)
; EndProcedure