Seite 1 von 1

Bildschirm in Graustufen ausgeben?

Verfasst: 28.07.2021 20:43
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

Re: Bildschirm in Graustufen ausgeben?

Verfasst: 30.07.2021 21:23
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ß :)

Re: Bildschirm in Graustufen ausgeben?

Verfasst: 03.08.2021 20:36
von darius676
Danke, dein Code Beispiel ist wesentlich schneller