Bildschirm in Graustufen ausgeben?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
darius676
Beiträge: 501
Registriert: 08.03.2010 22:12
Computerausstattung: Intel i5 16GB RAM nVidia 1050, Win11
Atari Jaguar, Surface Pro 5,Surface Laptop i5 7200, XBOX ONE X, XBOX Series X
Wohnort: AT
Kontaktdaten:

Bildschirm in Graustufen ausgeben?

Beitrag von darius676 »

Hallo, alle miteinander....

vll. hat ja einer eine alternative Möglichkeit:

Code: Alles auswählen

Procedure E_GRAY_SCALE()

Define DC
Define COLORADJUSTMENT.COLORADJUSTMENT
DC=StartDrawing(ScreenOutput())
GetColorAdjustment_(DC, Coloradjustment)
SetStretchBltMode_(DC, #HALFTONE)
COLORADJUSTMENT\caColorfulness = e_colorness.l
COLORADJUSTMENT\caBrightness = e_brightnes.l
SetColorAdjustment_(DC, COLORADJUSTMENT)
StretchBlt_(DC, 0, 0, e_engine_internal_screen_w,e_engine_internal_screen_h, DC, 0, 0,e_engine_internal_screen_w,e_engine_internal_screen_h, #SRCCOPY)
StopDrawing()


EndProcedure
Dank einiger Codesnipsel (RSBasic sei Dank!) und etwas experimentieren kam ich auf obige Lösung, welche auch funktioniert,
jedoch viel Performance verbraucht.

Diese wird vor jedem Bildwechsel aufgerufen.

gibt es eine Möglichkeit das ohne StartDrawing() zu lösen?

vielen Dank :)





https://mark-dowen.itch.io/the-quest-of ... arfes-king
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Bildschirm in Graustufen ausgeben?

Beitrag von Mijikai »

Evtl. hilft Inline-ASM 8)

Hier eine schnelle Graustufen Routine (für x64) basierend auf Code von wilbert:

Code: Alles auswählen

Procedure.i GrayscaleFilter();Original by wilbert: https://www.purebasic.fr/english/viewtopic.php?p=482418#p482418
  Protected *pb,pp.i,pf.i,ph.i,pd.i
  *pb = DrawingBuffer()
  pp = DrawingBufferPitch()
  pf = Bool(DrawingBufferPixelFormat() & (#PB_PixelFormat_32Bits_BGR|#PB_PixelFormat_24Bits_BGR)) 
  ph = OutputHeight()
  pd = OutputDepth()
  !mov rdi,[p.p_pb]
  !mov rcx,[p.v_ph]
  !shr qword[p.v_pd],0x3 
  !GrayScaleFilter_Pitch:
  !mov rbx,[p.v_pp]
  !GrayScaleFilter_Loop:
  !cmp byte[p.v_pf],0x1
  !je GrayScaleFilter_BGR
  !GrayScaleFilter_RGB:
  !movzx eax,byte[rdi]
  !imul eax,0x36A02D
  !movzx edx,byte[rdi+0x1]
  !imul edx,0xB7C3AB
  !add eax,edx
  !movzx edx,byte[rdi+0x2]
  !imul edx, 0x128D18
  !jmp GrayScaleFilter_Process
  !GrayScaleFilter_BGR:
  !movzx eax,byte[rdi]
  !imul eax,0x128D18
  !movzx edx,byte [rdi+0x1]
  !imul edx,0xB7C3AB
  !add eax,edx
  !movzx edx,byte[rdi+0x2]
  !imul edx,0x36A02D
  !GrayScaleFilter_Process:
  !lea eax,[eax+edx+0x80000]
  !shr eax,0x18
  !mov [rdi], al
  !mov [rdi+0x1],al
  !mov [rdi+0x2],al
  !add rdi,[p.v_pd]
  !sub rbx,[p.v_pd]
  !cmp rbx,[p.v_pd]
  !jge GrayScaleFilter_Loop
  !add rdi,rbx
  !sub rcx,0x1
  !jnz GrayScaleFilter_Pitch
  ProcedureReturn
EndProcedure
Im Start- StopDrawing() Block aufrufen!
Am besten (für Geschwindigkeit) immer nur einen Start- StopDrawing() Aufruf pro Frame!

Da PureBasic immer einen neuen DC anfordert für jeden Start- StopDrawing() Block
wird das 2D Drawing schnell langsam da diese Aufrufe viel Zeit benötigen.
Keine Ahnung warum das so implementiert ist?

Hoffe es hilft, viel Spaß :)
Benutzeravatar
darius676
Beiträge: 501
Registriert: 08.03.2010 22:12
Computerausstattung: Intel i5 16GB RAM nVidia 1050, Win11
Atari Jaguar, Surface Pro 5,Surface Laptop i5 7200, XBOX ONE X, XBOX Series X
Wohnort: AT
Kontaktdaten:

Re: Bildschirm in Graustufen ausgeben?

Beitrag von darius676 »

Danke, dein Code Beispiel ist wesentlich schneller
Antworten