PutPixel(x,y, ired,igre,iblu, t)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

PutPixel(x,y, ired,igre,iblu, t)

Beitrag von Kekskiller »

Ich hatte mal vor nicht allzulanger Zeit in Blitzbasic eine kleine Transparenz-
Bildengine gebastelt, welche aber aufgrund von zu langsamer WritePixelFast-
Plottung leider in die Hose gegangen ist... Und da das System eigentlich recht
schnell und gut war, dachte ich mir, portieren wie mal die extrahierte Plot-
Routine nach PB und stellen sie hier aus. Ich hatte damals (ja, ist schon etwas
länger her seit der Portierung) das ganze in der Demo unter 16 bit Farbtiefe
getestet, hat eigentlich ganz nett ausgesehen. Naja, hier ist die Procedure
dazu:

Code: Alles auswählen

;Putpixel - plots a translucid pixel   
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   
;Ich weiss nicht genau, wie PutPixel   
;in höheren Farbtiefen läuft, müsste   
;aber im Prinzip relativ fehlerfrei    
;laufen. Benutzung auf eigene Gefahr ;]
;                                      
;best viewed in jaPBe                  

#ScreenWidth=640
#ScreenHeight=480

Procedure PutPixel(x.w,y.w, ired.w,igre.w,iblu.w, t.f)
If x.w>=0 And y.w>=0 And x.w<#ScreenWidth And y.w<#ScreenHeight
 ocol.l = Point(x.w,y.w)
 ored.w = Red(ocol.l)
 ogre.w = Green(ocol.l)
 oblu.w = Blue(ocol.l)
 
 If ored.w<ired.w
  fred.w = ored.w + ( Abs(ored.w - ired.w) * t.f )
 ElseIf ored.w>ired.w
  fred.w = ired.w + ( Abs(ored.w - ired.w) * t.f )
 ElseIf ored.w=ired.w
  fred.w=ored.w
 EndIf
 
 If ogre.w<igre.w
  fgre.w = ogre.w + ( Abs(ogre.w - igre.w) * t.f )
 ElseIf ogre.w>igre.w
  fgre.w = igre.w + ( Abs(ogre.w - igre.w) * t.f )
 ElseIf ogre.w=igre.w
  fgre.w=ogre.w
 EndIf
 
 If oblu.w<iblu.w
  fblu.w = oblu.w + ( Abs(oblu.w - iblu.w) * t.f )
 ElseIf oblu.w>iblu.w
  fblu.w = iblu.w + ( Abs(oblu.w - iblu.w) * t.f )
 ElseIf oblu.w=iblu.w
  fblu.w=oblu.w
 EndIf
 
 Plot(x.w, y.w, RGB(fred.w,fgre.w,fblu.w))
EndIf
EndProcedure
Ich weiß nicht genau, ob PB es mit 16 bit auch so größzügig an Farben
handhabt, aber in BB funktionierte das durchscheinde Plot prima.
Noch etwas zu der Transparenz: 0 (unsichtbar) bis 1 (rübergelegt).
Alles dazwischen ist entsprechend durchscheinend.
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1756
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

@kekskiller: veröffentlichst Du noch ein kleines Anwendungsbeispiel ? Bitte.... :praise:

Wäre gut für alle Anwender, die dies mal testen wollen, aber die Procedure nicht sofort in ein eigenes Programm einbauen und damit testen können. :D
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

Beitrag von Kekskiller »

Naja, eigentlich ist das Beispiel reicht anwendungsfrei, aber es erfüllt
halbwegs seinen Zweck. Aber als ich da rumgetestet habe, habe ich gemerkt,
dass PB anscheinend etwas bei den Ganzzahlligen Werten (0 und 1) bei der
darstellung meckert. Naja, egal, jedenfalls kann man hier mal ein kleines
Beispiel bewundern.

PS: Bitte (wer es kann) auf 32 bit umschalten, da sich somit die mögliche
Farbpracht besser entfalten kann :wink: .

Code: Alles auswählen

;Putpixel - plots a translucid pixel   
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   
;Ich weiss nicht genau, wie PutPixel   
;in höheren Farbtiefen läuft, müsste   
;aber im Prinzip relativ fehlerfrei    
;laufen. Benutzung auf eigene Gefahr ;]
;                                      
;best viewed in jaPBe                  

Declare PutPixel(x.w,y.w, ired.w,igre.w,iblu.w, t.f)

#ScreenWidth=640
#ScreenHeight=480

Dim rect(20,4)
For z=1 To 20
  rect(z,0)=Random(#ScreenWidth-50)
  rect(z,1)=Random(#ScreenHeight-50)
  rect(z,2)=Random(100)+155
  rect(z,3)=Random(100)+155
  rect(z,4)=Random(100)+155
Next

Global mx,my,z

  InitSprite()
  OpenScreen(640,480, 16, "test")
  InitMouse()
  
  Repeat
    ExamineMouse()
    ClearScreen(255,255,255)
      StartDrawing(ScreenOutput())
        DrawingMode(0)
        For z=1 To 20
          Box(rect(z,0),rect(z,1), 50,50, RGB(rect(z,2),rect(z,3),rect(z,4)))
        Next
        mx=MouseX()
        my=MouseY()
        DrawingMode(4)
        Box(mx-1,my-1, 42,42, 0)
        For zx=0 To 39
          For zy=0 To 39
            PutPixel(mx+zx,my+zy, 100,255,155, 0.5)
          Next
        Next
      StopDrawing()
    FlipBuffers()
  Until MouseButton(1)

Procedure PutPixel(x.w,y.w, ired.w,igre.w,iblu.w, t.f)
If x.w>=0 And y.w>=0 And x.w<#ScreenWidth And y.w<#ScreenHeight
 ocol.l = Point(x.w,y.w)
 ored.w = Red(ocol.l)
 ogre.w = Green(ocol.l)
 oblu.w = Blue(ocol.l)
 
 If ored.w<ired.w
  fred.w = ored.w + ( Abs(ored.w - ired.w) * t.f )
 ElseIf ored.w>ired.w
  fred.w = ired.w + ( Abs(ored.w - ired.w) * t.f )
 ElseIf ored.w=ired.w
  fred.w=ored.w
 EndIf
 
 If ogre.w<igre.w
  fgre.w = ogre.w + ( Abs(ogre.w - igre.w) * t.f )
 ElseIf ogre.w>igre.w
  fgre.w = igre.w + ( Abs(ogre.w - igre.w) * t.f )
 ElseIf ogre.w=igre.w
  fgre.w=ogre.w
 EndIf
 
 If oblu.w<iblu.w
  fblu.w = oblu.w + ( Abs(oblu.w - iblu.w) * t.f )
 ElseIf oblu.w>iblu.w
  fblu.w = iblu.w + ( Abs(oblu.w - iblu.w) * t.f )
 ElseIf oblu.w=iblu.w
  fblu.w=oblu.w
 EndIf
 
 Plot(x.w, y.w, RGB(fred.w,fgre.w,fblu.w))
EndIf
EndProcedure
Bei mir haut es da manchmal bei ganzzahligen Sachen nicht hin, aber egal...
Auch nach einer Überarbeitung kann ich mir das Problem noch immer nicht
ganz erklären. Scheint wohl doch direkt was mit der Screenmodeverteilung
zu tun zu haben.
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1756
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

Danke für das Beispiel ! :D
Respekt :allright:

Läuft bei mir (GeforceMX460) sowohl mit 16 Bit als auch 32 Bit klaglos.
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Hier auch keine Probleme. Allerdings, bei 100 x 100 Pixel kam das Programm schon recht gut zum Stocken. Bei 200 x 200 war Sense mit 4 FPS. Gut, ist sicher auch nicht so sinnvoll 40000 Pixel per Plot anzuzeigen. :mrgreen:
Da greift man besser auf Sprite3Ds zurück welche auch transparentwerte haben können. Aber für kleine Flächen und ohne Sprite3D und somit auch auf Linux anwendbar (nicht getestet, sollte aber gehen da es ja nur den Plott-Befehl verwendet) ist es schon ganz brauchbar.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

Würdest du überall LONG-Variablen nutzen, könnte die Procedure sogar noch schneller werden. Habe jetzt aber keinen Test gemacht. 32-Bit-Variablen werden von einer 32-Bit-CPU eben schneller verarbeitet.

Code: Alles auswählen

Procedure PutPixel(x.l, y.l, ired.l, igre.l, iblu.l, t.f)
  Protected ocol.l, ored.l, ogre.l, oblu.l

  If x >= 0 And y >= 0 And x < #ScreenWidth And y < #ScreenHeight
    ocol = Point(x, y)
    ored = Red(ocol)
    ogre = Green(ocol)
    oblu = Blue(ocol)

    If ored < ired
      fred = ored + (Abs(ored - ired) * t.f)
    ElseIf ored > ired
      fred = ired + (Abs(ored - ired) * t.f)
    ElseIf ored = ired
      fred = ored
    EndIf

    If ogre < igre
      fgre = ogre + (Abs(ogre - igre) * t.f)
    ElseIf ogre > igre
      fgre = igre + (Abs(ogre - igre) * t.f)
    ElseIf ogre = igre
      fgre = ogre
    EndIf

    If oblu < iblu
      fblu = oblu + (Abs(oblu - iblu) * t.f)
    ElseIf oblu > iblu
      fblu = iblu + (Abs(oblu - iblu) * t.f)
    ElseIf oblu = iblu
      fblu = oblu
    EndIf

    Plot(x, y, RGB(fred, fgre, fblu))
  EndIf
EndProcedure
Bild
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Beitrag von GPI »

Noch stärker optimiert (und mit windowedScreen):

Code: Alles auswählen

;Putpixel - plots a translucid pixel  
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
;Ich weiss nicht genau, wie PutPixel  
;in höheren Farbtiefen läuft, müsste  
;aber im Prinzip relativ fehlerfrei  
;laufen. Benutzung auf eigene Gefahr ;] 
;                   
;best viewed in jaPBe         

Declare PutPixel(x,y, ired,igre,iblu, t) 

#ScreenWidth=640 
#ScreenHeight=480 

Dim rect(20,4) 
For z=1 To 20 
  rect(z,0)=Random(#ScreenWidth-50) 
  rect(z,1)=Random(#ScreenHeight-50) 
  rect(z,2)=Random(100)+155 
  rect(z,3)=Random(100)+155 
  rect(z,4)=Random(100)+155 
Next 

Global mx,my,z 

InitSprite() 
OpenWindow(0,0,0,700,500,#PB_Window_SystemMenu,"Test")
OpenWindowedScreen(WindowID(),0,0,640,480, #False,0,0) 
InitMouse() 
 
Repeat 
  ExamineMouse() 
  ClearScreen(255,255,255) 
  StartDrawing(ScreenOutput()) 
  DrawingMode(0) 
  For z=1 To 20 
    Box(rect(z,0),rect(z,1), 50,50, RGB(rect(z,2),rect(z,3),rect(z,4))) 
  Next 
  mx=MouseX() 
  my=MouseY() 
  DrawingMode(4) 
  Box(mx-1,my-1, 42,42, 0) 
  For zx=0 To 39 
    For zy=0 To 39 
      DrawText( Str(mx)+" "+Str(my)+"|")
      PutPixel(mx+zx,my+zy, 100,255,155, 50) 
      ;Plot(mx+zx,my+zy,$7F7F7F)
    Next 
  Next 
  StopDrawing() 
  FlipBuffers() 
Until MouseButton(1) 

Procedure PutPixel(x,y, ired,igre,iblu, t) 
  If x>=0 And y>=0 And x<#ScreenWidth And y<#ScreenHeight 
    ocol = Point(x,y) 
    ored = Red(ocol)
    ogre = Green(ocol) 
    oblu = Blue(ocol) 
    
    fred= ored- (ored-ired)*t/100
    fgre= ogre- (ogre-igre)*t/100
    fblu= oblu- (oblu-iblu)*t/100
      
    FrontColor(fred,fgre,fblu)
    Plot(x, y);, RGB(fred,fgre,fblu)) 
  EndIf 
EndProcedure
Übrigends: Hab ein Bug gefunden:

Wenn ich statt

Code: Alles auswählen

 FrontColor(fred,fgre,fblu)
    Plot(x, y);, RGB(fred,fgre,fblu)) 
das schreibe

Code: Alles auswählen

Plot(x, y, RGB(fred,fgre,fblu)) 
hab ich nur müll auf den Bildschirm. Kann das wer bestätigen?
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

@GPI

Bestätigt. Lauter Grüne Striche horizontal verteilt in der Gesamthöhe des Quadrates.

MfG Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

(...)hab ich nur müll auf den Bildschirm. Kann das wer bestätigen?
Naja, ist ja logisch oder? Wenn man den Color-Parameter raus nimmt, dann nimmt er die Farbe welche durch FrontColor() gesetzt wurde. Wenn diese fehlt, ist das Objekt immer schwarz (also wenn ich die Zeile rausnehme ist die transparente Box komplett schwarz). Wenn man dann aber den Color-Parameter ent-kommentiert, geht es auch so wieder ohne das FrontColor().

//EDIT: Aber grüne Streifen oder sowas hab ich nicht. Nur dass eben nichts mehr transparent ist sondern dicht schwarz.
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

GPI hat geschrieben:Übrigends: Hab ein Bug gefunden:

Wenn ich statt

Code: Alles auswählen

 FrontColor(fred,fgre,fblu)
    Plot(x, y);, RGB(fred,fgre,fblu)) 
das schreibe

Code: Alles auswählen

Plot(x, y, RGB(fred,fgre,fblu)) 
hab ich nur müll auf den Bildschirm. Kann das wer bestätigen?
Das ist schon sehr lange bekannt.

Grund:
Plot(x,y) läuft über GDI und nimmt die Farbe von FrontColor().
Plot(x,y,color) läuft dagegen über direkten Speicherzugriff
und ist falsch.

Dieser Fehler wurde schon mehrfach gemeldet und ist
Fred schon lange bekannt (er selbst hat mir vor langer
Zeit den Grund dafür gesagt, da mich das damals auch
wunderte).
Könnte höchstens noch sein das er es mal gefixt hatte und
nun wieder kaputtgespielt oder alten Code genommen hat.
Wär' nicht das erste mal...
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten