Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[VB.NET GDI] Kan dit vlugger/beter

Pagina: 1
Acties:

  • ? ?
  • Registratie: Mei 2007
  • Niet online
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        Dim b As New Bitmap(_width * 3, _height * 3)
        Dim g As Graphics = Graphics.FromImage(b)
        g.FillRectangle(Brushes.White, 0, 0, _width * 3, _height * 3)
        For x As Integer = 0 To _width - 1
            For y As Integer = 0 To _height - 1
                Select Case (land(x, y).state)
                    Case Cell.cellstate.alive
                        g.FillRectangle(Brushes.Blue, x * 3, y * 3, 3, 3)
                    Case Cell.cellstate.dead
                        g.FillRectangle(Brushes.White, x * 3, y * 3, 3, 3)
                    Case Cell.cellstate.lonely
                        g.FillRectangle(Brushes.White, x * 3, y * 3, 3, 3)
                    Case Cell.cellstate.overcrowed
                        g.FillRectangle(Brushes.White, x * 3, y * 3, 3, 3)
                End Select
            Next
        Next
        Form1.PictureBox1.Image = b
        g.Dispose()


Ik heb Conways' Game Of Life gemaakt, voor een veld van 100x100 duurt een draw ongeveer 100ms
Voor 300x200 duurt dat al een 700ms ...

land(x,y) is een array van Cell objecten (moeilijke naam voor een integer die 1 2 3 4 5 kan zijn, afhankelijk van de status)

Die array moet ik toch veld per veld afgaan om te tekenen? Maar hoe maak ik dit nu sneller...

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Tja, ik vermoed dat de tijd gaat zitten in de overhead van elke aanroep van FillRectangle. Want achter de schermen gebeurt er nogal wat om zo'n methodeaanroep naar GDI (dat is buiten de .Net wereld) te doen.

Een mogelijk alternatief is om gebruik te maken van de "setPixel" methode van een bitmap, of direct in de bitmap frutselen via "lockBits".

[ Voor 6% gewijzigd door Infinitive op 05-09-2007 21:31 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
moet je dit persee via een bitmap doen, zoever ik dit even snel zie maak je alleen maar heel veel gekleurde vakjes, kun je dit niet doen met een array van shapes, daar veel van spawnen ze naast elkaar zetten en dan kleurtjes maken? Je kunt ze netjes @ runtime maken en neerzetten. En zo heb je ook iets meer directe controle op je shapejes, je hoeft bijvoorbeeld niet de hele bitmap opnieuw te bouwen, maar alleen 1 vakje van te kleur te laten veranderen.

(verder heb ik niet zelf even gekeken of dit sneller efficienter is, 700shapes zal ook wel niet heel erg fijn zijn vermoed ik)

~ Mijn prog blog!


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Maar waarom moet je elke keer de volledige image opnieuw schrijven? Je kunt toch ook de vorige 'onthouden' en alleen de wijzigingen ten opzichte van de vorige run op de image tekenen.

Je hoeft dan alleen maar een queue bij te houden met daarin een structure met coordinaten x, y en CellState.

Doordat je minder render acties uitvoert, zal de gehele procedure sneller worden.

Je gaat dus eigenlijk met incremental images werken. Eventueel zou je na 30 incremental updates op de achtergrond een nieuwe basis image kunnen genereren.

If it isn't broken, fix it until it is..


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
Dit gaat véél sneller als je WPF gebruikt. Ik had ook een control gemaakt om een lijntje te tekenen met GDI, maar daarin zat met name de bottleneck dat ik .NET het control liet uitknippen om de vorm van het lijntje zodat meerdere lijntjes elkaar konden overlappen. Bij meer dan 20 lijntjes op een scherm ging toen de performance drastisch omlaag. Ik heb het toen omgeschreven nar WPF en het gaat als de brandweer nu :)

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 13-10 22:03

MrSleeves

You'll thank me later.

In weze maak je eerst de hele Bitmap wit (mooier is wellicht g.Clear(Color.White). Daarna hoef je toch alleen maar te checken op alive, dus de FillRectangle op regel 10, 12 en 14 vervallen. Zou wel wat moeten schelen.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

MrSleeves schreef op donderdag 06 september 2007 @ 09:12:
In weze maak je eerst de hele Bitmap wit (mooier is wellicht g.Clear(Color.White). Daarna hoef je toch alleen maar te checken op alive, dus de FillRectangle op regel 10, 12 en 14 vervallen. Zou wel wat moeten schelen.
Ik neem aan dat in een later stadium de verschillende CellStates ook verschillende kleuren krijgen (groen = alive, rood = dead, grijs = overcrowed, etc). En dan moet je dus wel de verschillende kleuren kunnen tekenen

If it isn't broken, fix it until it is..


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 30-11 11:35

Janoz

Moderator Devschuur®

!litemod

Ik ben niet heel bekend met GDI, maar dit soort snelheden zijn belachelijk traag. De enige manier waarop ik dit kan verklaren is doordat de graphics een redraw triggered van het scherm bij elke fillRect. Zelfs Windows 3.1 op een 486 kan sneller tekenen dan dit.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

En daar zou Janoz best eens gelijk in kunnen hebben. :) Ik heb ook eens Conway's Game of Life gemaakt, met de visualisatie door middel van GDI+. Het is weliswaar in C#, maar als je de laatste versie (met behoorlijke snelheidsverbeteringen) tegenover de eerste versie zet en de source vergelijkt kan je misschien nog wat inspiratie opdoen.

Sole survivor of the Chicxulub asteroid impact.


  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

Janoz schreef op donderdag 06 september 2007 @ 12:23:
Ik ben niet heel bekend met GDI, maar dit soort snelheden zijn belachelijk traag. De enige manier waarop ik dit kan verklaren is doordat de graphics een redraw triggered van het scherm bij elke fillRect. Zelfs Windows 3.1 op een 486 kan sneller tekenen dan dit.
Ik mis i.d.d. een invalidateRect call :)
Verder kun je je afvragen of het zinvol is om een vierkant te tekenen, een vierkant leegmaken is volgens mij een stuk sneller.

God, root, what is difference? | Talga Vassternich | IBM zuigt


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 13-10 22:03

MrSleeves

You'll thank me later.

Wat ik me ook nog afvraag. Wat doe je met de Bitmap die al in Form1.PictureBox1.Image staat?

In weze zou een Invalidate niet uit moeten maken, omdat er op een Bitmap getekend wordt en niet rechtstreeks in een Control (maar dan teken je in het Paint-event en heb je dat probleem ook niet).

[ Voor 51% gewijzigd door MrSleeves op 06-09-2007 12:45 ]

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • ? ?
  • Registratie: Mei 2007
  • Niet online
Met setpixel ging het nog te traag naar mijn zin na een snelle test gisteren.
Normaal is er geen redraw na elke wijziging aangezien de bitmap pas op het einde op een picturebox gedrawt wordt.

Ik ga het vanavond/morgen eens met lockbits doen.
Ter referentie: met mijn webcam van 240*320 (?) kan ik een goeie 30 keer per seconde een beeld volledig pixel per pixel overlopen/veranderen d.m.v. de raw bytes. Vandaar mijn verbijstering dat dit zo slow was !
WPF (.NET3 bedoel je?) heb ik nog niet geinstalleerd

  • Serpie
  • Registratie: Maart 2005
  • Laatst online: 01-07-2023
Wellicht een aantal al genoemd, maar voor de volledigheid:
  • In plaats van tekenen in een nieuwe bitmap en die plaatsen in een picturebox, zou ik kiezen voor een eigen control en daar de OnPaint methode in te overriden.
  • Zet de DoubleBuffered Property van het control op True, voor een soepelere overgang van de tekeningen
  • Gebruik voor de eerste Fillrectange de clear methode ipv de fill.
  • Bouw eerst een array van rectangles op en gebruik FillRectangles ipv elke keer een rectangle te tekenen met FillRectangle (veel sneller)
  • Is het niet veel efficienter om te loopen met Step 3, ipv steeds te vermenigvuldigen?

[ Voor 9% gewijzigd door Serpie op 06-09-2007 15:41 ]

Pagina: 1