[Monkey] HTML5 + Anglefont = zu langsam?

Übersicht Andere Programmiersprachen Beginners-Corner

Neue Antwort erstellen

C--

Betreff: HTML5 + Anglefont = zu langsam?

BeitragSa, Nov 09, 2013 20:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Nabend,
ich arbeite mich derzeit in Monkey ein und bin eigentlich ganz angetan. Jedoch habe ich ein kleines Problem. Ich habe meinen kleinen flüssig spielbaren Pac Man Klon etwas modifiziert und seitdem ist die FPS ins unspielbare gerutscht. Modifizierte wurde die Levelgröße (verdoppelt). Ferner ist eine einfache GameState Klasse eingebaut worden sowie das Anglefont Modul. Ich vermute, dass letzeres der Kern allen Übels ist, da die Demo auch nicht sonderlich flüssig läuft. Meine Frage: Habt ihr ähnliche Erfahrungen gemacht mit HTML5 und Anglefont. Oder liegt es an zuvielen Aufrufen von DrawImage?
Mfg
C--
PS: Verwendeter Browser ist Iron unter Win7

Midimaster

BeitragSa, Nov 09, 2013 21:26
Antworten mit Zitat
Benutzer-Profile anzeigen
um festzustellen, ob es AngelFont ist, könntest Du in AngelFont.monkey die DrawText "ausschalten"

BlitzMax: [AUSKLAPPEN]
Method DrawText:Void(txt:String, x:Int, y:Int)
Return
...


AngelFont verbrät tatsächlich viel Performance. Aber es ist nicht so, dass das Spiel dadurch unspielbar würde. Vielleicht handelt es sich bei Dir dann doch um eine zweite Ursache.

Ich habe mir für Text eine Funktion geschrieben, die den String in ein Image wandelt und den stattdessen anzeigt.

Alle Wörter, die sich im Spiel gar nicht ändern, solltest Du sowieso lieber gleich als Images laden.

Hat die Verdoppelung der Levelgröße auch zu einer Verdoppelung der Bildschirmgröße geführt?
Oder nur "logische Spielfläche verdoppelt? und scrollt jetzt mehr? Sowas wirkt sich kaum aus!




Ist deine Verdoppelung vielleicht sogar eine Vervierfachung? x*2 und y*2 wäre ja dann schon eine 4x so große Fläche! Ab 1000x1500pix rucket Html5 bei mir auch
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

PhillipK

BeitragSa, Nov 09, 2013 21:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn du mit veropplung der fläche meinst, das du zb 100x100 tiles statt 50x50 anzeigst, dann könnte hier ein hund begraben liegen.
Wird der gleiche ausschnitt wie vorher angezeigt, aber es gibt mehr "leveldaten", stelle sicher das nur das gezeichnet wird, was sichtbar ist.
Man mag es kaum glauben, aber wenn du alles zeichnest kann es gut sein, das es hier derben overkill gibt. Auch wenn man logischerweise nicht sehen kann, was ausserhalb der sichtbaren fläche liegt, kann es dennoch enorm leistung fressen, jeder kachel (o.ä) ein drawaufruf zu verpassen.

Ich habe keine ahnung, was anglefont genau ist. Aber die nativen text-renderfunktionen sind ziemlich hungrig.
Allerdings vermute ich, das anglefont wenn überhaupt eine art ImageText modul ist, dh die schriftart ist als image hinterlegt und die buchstaben stellen frames dar.
Hier kommt es nun darauf an, von wieviel text du redest. Sinds ein paar hundert zeichen, sollte das kein akt sein. Sind es ganze texte oder ähnliches, solltest du dir überlegen vllt deine eigene version eines Textrenderers zu bauen, in dem stil wie midimaster es vorschlug: Größere ansammlungen buchstaben, welche sich nicht ändern, in eine grafik packen und diese stattdessen rendern.

Meines wissens gibt es hierfür auch eine GrabImage abart in monkey, habe ich allerdings nur einmal ausgetestet und naja.. sie war sau lahm. Bzw einfach mal überhauptnicht echtzeit tauglich Smile
Heißt: Wenn überhaupt, bei programmstart die texte initialisieren und als grafiken "grabben"


(da fällt mir grade ein: Vielleicht macht anglefont etwas ähnliches? Dh statische texte erkennen und als image abpacken? Schau doch mal im source, ob du etwas dergleichen findest, eine art grab!)

C--

BeitragSa, Nov 09, 2013 22:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielen Dank für die schnellen Antworten. Die Verdoppelung der Levelgröße hat nicht zu einer Verdoppelung des Bildbereiches geführt. Soweit ich das sehe kann man native in Monkey die Größe des Bildbereiches gar nicht einstellen. Was mich sehr wundert. Verdoppelt habe ich eigentlich nur die Leveldaten, d.h. meine Tiles sind von 32px auf 16px Seitenlänge geschrumpft. Viel Text wird außerdem nicht gerendert. Ein einfaches "Lives" sollte nicht soviel verlangt sein. Klar kann ich jeweils immer Bilder für meinen Text erstellen, aber ich wollte das so allgemein/flexibel wie möglich halten. Es muss doch irgendwie einen Weg geben Schrift ruckelfrei mit Monkey darstellen zu können.

Auf die Idee mit den Ausschalten von anglefont bin ich nicht gekommen *facepalm*, danke dafür!

Btw. anglefont ist ein example aus den monkey bananas Very Happy
 

PhillipK

BeitragSa, Nov 09, 2013 23:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay.. das bedeutet, du hast doppeltsoviele leveldaten die halb so groß dargestellt werden. Das wiederrum bedeutet, das du mehr tiles (undzwar das vierfache) renderst.

Was ich festgestellt habe, ist das Alpha und / oder lightblend sehr an der leistung ziehen. So sehr, das ich mir WebGl zugelegt habe (ein "patch" für html5, welcher nach dem builden eingefügt wird. Es bildet die nativen renderings in OpenGL ab und rennt verblüffend gut.)

Verwendest du SetAlpha / SetColor / SetBlend häufig? Ich konnte bei fuzzleball bereits bei etwa 30 aufrufen pro frame an SetAlpha und / oder SetBlend(Lightblend) eine verschlechterung von heroischem ausmaße feststellen.

Midimaster

BeitragSo, Nov 10, 2013 3:36
Antworten mit Zitat
Benutzer-Profile anzeigen
@PhillipK

"Ich habe keine ahnung, was anglefont genau ist. ... Allerdings vermute ich, ..."
genau!

Die von dir zitierten "paar hundert Zeichen" von denen Du sagst sie wären "kein Act"... sind(!) der Overkill via Angelfont. Und ein einmaliges GrabImage die einzig sinnvolle Lösung. Nur so erreicht du wieder Performance, wenn Du Echtzeit und Texte benötigst!!!

@C--

Texte mit AngelFont sind kritisch. Ein einfaches "Lives" sind nur 5 Zeichen und zerstören keine Echtzeit. Wieviele Buchstaben hast du den im Durchschnitt gleichzeitig auf dem Bildschirm?

AngelFont malt pro Buchstabe ein Image auf den Screen (ImageFont). Ab ca. 100 Buchstaben wirds dann bemerkbar. So richtig ausgebremst wird es erst dan, wenn man die Buchstabe in Farbe möchte, also z.b. mit einem vorangestellten SetColor 255,0,0. Das verlangsamt die Darstellung um 500%. Also immer auf SetColor 255,255,255. Brauchst du Farbe, färbst du schon vorher den Zeichenvorrat "MeinFont.png" mit einem Malprogramm ein und malst dann alles in SetColor 255,255,255

Flexible Texte und Performance erreichst Du nur mit "Vorrendern" via GrabImage.


4x so viele Tiles können auch ein Problem werden. Da kommt es jetzt darauf an, wie Du die organisiert hast. Die beste Performance erzielst du, wenn alle Tile-Vorlagen auf einem gemeinsamen Riesenbild liegen und von dort aus mit DrawImageRect() auf den Screen gezeichnet werden. Worst Case wäre dass alle Tiles als einzel-Images geladen wurden.

So jetzt noch ein Code, der zeigt, wie das GrabImage in Monkey ausschaut:

BlitzMax: [AUSKLAPPEN]
	Function ScreenGrab:Image(X%,Y%,Width%,Height%)
Local ScreenShot:Image
ScreenShot = CreateImage(Width,Height)
Local pixels:Int[] =New Int[Width*Height]
ReadPixels(pixels, X, Y, Width,Height)
ScreenShot.WritePixels(pixels, 0, 0, Width,Height)
Return ScreenShot
End



Mess doch mal die Performance! Dann siehst Du doch, wo der Einbruch stattfindet.

BlitzMax: [AUSKLAPPEN]
Method OnRender%()
Cls
Local Zeit%=MilliSecs()
.....
Print "Zeit MessPunkt A=" + (MilliSecs()-Zeit)=
.....
Print "Zeit MessPunkt B=" + (MilliSecs()-Zeit)=
.....
.....
Print "Zeit Komplett=" + (MilliSecs()-Zeit)=
Return 0
End


Versuche bitte mal testhalber auch FireFox als Browser.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

C--

Betreff: Lösung

BeitragSo, Nov 10, 2013 21:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay ich denke ich habe das Problem mit eurer Hilfe gelöst. Das komplette entfernen von Anglefont hat mir gerade mal 1FPS gebracht. Mehr hatte ich auch nicht erwartet, da stets nur 5 Buchstaben gezeichnet wurden. Nachdem ich die Tile Anzahl geviertelt habe von 40*26 auf 20*13 (alles 16x16 Tiles) ist die FPS von 1,33 auf 20 explodiert. GrabImage nutze ich schon intensiv. Jeweils einmal für meine Playertiles, Gegnertiles und die Leveltiles. Das werde ich dann auch noch in ein Bild packen. Aber ich habe bis jetzt mir jeweils drei Imageatlanten (nennt man glaube ich so, wenn nicht steinigt mich Smile) definierte und male daraus.

Code: [AUSKLAPPEN]

Field tilesimg:Image[5]
...
Local tilesimgatlas:Image = LoadImage("tiles.png")
For Local i:Int = 0 Until 5
     tilesimg[i] = tilesimgatlas.GrabImage(i*16,0,16,16)
End
...
DrawImage(tilesimg[l.data[x][y]],16*x,64+16*y)


So dürften das doch richtig sein. Obwohl die 20fps noch ein wenig enttäuschend sind. Kleine Frage am Rande: Sind die FPS auf anderen Targets deutlich höher? Bzw. ist Anglefont auf anderen Target auch im größeren Maßstab nutzbar? Ich kann das derzeit noch nicht testen, da meine Kaufentscheidung davon abhängt Smile.

PS: Ich denke nicht, das Firefox das flüssiger erledigt, da Firefox noch einiges weiter im HTML5 Test zurück liegt.

DAK

BeitragSo, Nov 10, 2013 22:59
Antworten mit Zitat
Benutzer-Profile anzeigen
HTML5 ist generell wohl das langsamste Medium auf das Monkey kompiliert. Da ich kein Monkey habe, kann ich dir nicht sagen, um wie viel die anderen Targets dann wirklich schneller sind, aber ich programmiere viel mit Java und weiß, dass das schon deutlich schneller ist als HTML5. Auch die Plattformen der anderen Targets sind deutlich schneller als HTML5.
Gewinner der 6. und der 68. BlitzCodeCompo
 

PhillipK

BeitragSo, Nov 10, 2013 23:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Einspruch: Flash ist deutlich langsamer.

@Midimaster: Mh, ist mein system so gut? Mad Wenn ich mein imagefont modul nutze, sind ein paar hundert zeichen "kein akt" Mad
Wobei ich hier auch den grund bei opengl vermute, wo ich recht früh drauf umgestiegen bin. Das gute: Einfach ein neues target für html5 anlegen (template kopieren und verändern, sodass der "patch" mit übernommen wird) und man hat nie wieder streß.

@C-- :
Definiere das "intensive nutzen" von Grabimage.
Einmal pro frame oder alle 2-3 frame sist schon zuviel. das zeug ist so langsam, das es fast schon sinnvoller ist (manchmal) einfach per hand bilder zusammenzuschustern.
Ist es allerdings nur beim laden von einem level o.ä. sollte das okay sein.

Kannst du im groben auflisten, welche funktionen du in einem renderschritt aufrufst? Bedenke: SetColor, SetBlend, SetAlpha.. alles overkill für html5 in purer form. Erpropterweise Mad
Ps: Bitte definiere mal das vierteln.. wie kann das zu fps explosionen führen? Renderst du einfach weniger pixel?

Geschwindigkeit:
Meinen tests nach ist html5 auf jedenfall schneller als flash. Glfw / Android rennen wie sau, das ist allerdings systemabhängig (Getestet auf einem Samsung Galaxy II plus sowie meinem desktop pc)
Die gepatchte html5 version hat grade im bereich SetAlpha die performance von 20fps auf 60fps hochgebracht, wobei 60fps irgendwo gecappt wird (nicht von mir, sondern entweder monkey oder browser / javascript part). Die tatsächliche performance kann also deutlich höher liegen.
Iphone / Win8 konnte ich nicht testen, c++ auch nicht.

DAK

BeitragMo, Nov 11, 2013 1:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Stimmt, Flash hatte ich vergessen^^
Gewinner der 6. und der 68. BlitzCodeCompo

Midimaster

BeitragMo, Nov 11, 2013 10:58
Antworten mit Zitat
Benutzer-Profile anzeigen
einen Geschwindigkeitsvorteil wirst Du nur haben, wenn du eben nicht die Einzelbilder verwaltest, wie du das in deinem Beispiel "GrabImage" zeigst, sondern mit dem Gesamtbild und DrawImageRect() arbeitest.

Aber So wie das bei Dir aussieht, wäre sogar das Frame-ImageDraw möglich:

BlitzBasic: [AUSKLAPPEN]
Local tilesimgatlas:Image = LoadImage("tiles.png",5)
...
DrawImage tilesimgatlas, 16*x, 64+16*y, l.Data[x][y]

Hierbei wird schon beim Laden festgelegt, dass es sich um einen ImageStrip mit 5 bildern handelt.Welches Frame dann jeweils gezeichnet werden soll, legt ein weiterer Parameter bei DrawImage fest.

Außerdem könntest Du den gesamte Bildschirm, wenn mal alle Tiles stehen in ein neues Bilder grabben und das ergibt dann in der folgenden OnRender() nur noch einen Aufruf statt 40x26=1004 Aufrufe.

Ich bin weiterhin überzeugt, dass Dein Problem aber wo anders liegt. Aber wenn du nicht bereit bist mehr Messpunkte einzufügen und die Ergebnisse zu nennen, kann man Dir da kaum weiterhelfen.

20fps wären akzeptabel, aber es geht sicher auch flüssiger. Wenn es bei 40x26 nur noch 1-2fps waren, ist dies genau die Stelle, wo du mit Verbesserungen einsetzen musst. Alleine Die Anzahl der Tiles wieder runterzusetzen ist keine "Verbesserung".

Ich habe gleich mal ein Testprogramm geschrieben. Da benötigt das Zeichnen der 1004 Tiles 7msec. Das entspräche theoretischen 140fps. Daraus folgt: die Zahl der Tiles ist nicht Dein Problem!

BlitzMax: [AUSKLAPPEN]
Strict
Import mojo


Class Game Extends App

Field Bild:Image, FirstTime%

Method OnCreate%()
SetUpdateRate 60
Return 0
End

Method OnUpdate%()
If KeyHit(KEY_ESCAPE) OnBack
Return 0
End

Method OnRender%()
If FirstTime=0
FirstRender
Return 0
EndIf
Local Zeit%=MilliSecs()
Seed=12345678
For Local i%=0 To 39
For Local j%=0 To 20
Local Tile%=Int(Rnd(5))*20
DrawImageRect Bild,i*20,j*20,Tile,0,20,20
Next
Next
Print "Zeit=" + (MilliSecs()-Zeit)
Return 0
End



Method FirstRender:Void()
FirstTime=1
For Local i%=0 To 4
SetColor i*50+50,250-i*50,Rnd(255)
DrawRect i*20,0,20,20
Next
Bild=ScreenGrab(0,0,300,300)
Cls
SetColor 255,255,255
End


Method OnBack%()
EndApp()
Return 0
End
End

Function Main%()
New Game
Return 0
End



Function ScreenGrab:Image(X%,Y%,Width%,Height%)
Local ScreenShot:Image
ScreenShot = CreateImage(Width,Height)
Local pixels:Int[] =New Int[Width*Height]
ReadPixels(pixels, X, Y, Width,Height)
ScreenShot.WritePixels(pixels, 0, 0, Width,Height)
Return ScreenShot
End


Auch seltsam, dass Du fragst, ob AngelFont Dir auf den anderen Targets die gleichen Probleme bereitet, wo du doch jetzt festgestellt hast, dass es nicht an AngelFont gelegen haben kann.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

C--

Betreff: Die Lösung

BeitragMo, Nov 11, 2013 13:04
Antworten mit Zitat
Benutzer-Profile anzeigen
@DAK & PhillipK: Danke. Die Kaufentscheidung ist gefallen Wink

@Midimaster: Firefox habe ich jetzt am unveränderten Programm getestet und hat nur 5FPS geliefert. Sehr erstaunlich, das FF nicht soweit hinter Chrome im HTML5 Test liegt. Ferner habe ich mich wohl etwas unpräzise ausgedrückt. Bis jetzt ist nur das Levelladen und zeichnen implementiert (Anglefont hatte ich ja rausgeworfen) und da gäbe es nicht viel mehr zu messen als das Laden, zeichnen. Und GrabImage verwende ich auch nur einmal bei Programmstart um die Bilder zu laden, also konnte es daran nicht liegen. Aber du hast Recht. Es kann nicht an der Anzahl der Tiles liegen. Mein Fehler ist mir fast schon peinlich: Ich habe beim Entfernen von Anglefont aus dem Programm einen SetColor Befehl übersehen, welcher zwischen Cls und dem Zeichnen der Tiles stand. Merke: SetColor ist Böse. Die Idee das ganze Level zu grabben ist genial, da wäre ich allein nicht drauf gekommen.
Nach Anglefont habe ich aus Neugier gefragt, da - wie schon oben erwähnt - das Beispiel aus den Bananas unter HTML5 ja sehr langsam läuft und es bspw. unter win deutlich schneller sein könnte(?). Aber das werde ich bald selbst Testen können.

@all: Danke für die Geduld und schnelle Hilfe.

Neue Antwort erstellen


Übersicht Andere Programmiersprachen Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group