Polys und Quads bei BlitzMax

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

hectic

Sieger des IS Talentwettbewerb 2006

Betreff: Polys und Quads bei BlitzMax

BeitragSo, Aug 08, 2010 11:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich experimentiere seit gestern etwas mit BlitzMax rum und bin nun froh, überhaupt ein texturiertes Quad darstellen zu können. Ich wollte versuchen zumindest das DrawImage3D aus der Draw3D2 nachzuahmen. Das ganze mache ich über GLGraphics. Doch ein Speedtest ergab, das es gerade mal 1% schneller ist als Blitz3D, und immer noch langsamer (100:130) gegenüber Graphics / SetRotation / DrawImage bei gleicher Bilddatei, gleicher größe, gleiche Menge ist.

Nun die Frage. Gibt es vielleicht etwas was ich komplett übersehen habe. Also Variablen, Pixmap-Alternative oder anderes bei BlitzMax?

Mein Code: [AUSKLAPPEN]
Strict

GLGraphics 800,600

Local   Angle%
Local   X%
Local   Y%
Local   FPS
Local   MSC
Local   MTS
Local   FRM


glMatrixMode(GL_PROJECTION)
gluPerspective(80,4.0/3.0,0,200)
glMatrixMode(GL_MODELVIEW)


glEnable GL_TEXTURE_2D
glBindTexture GL_TEXTURE_2D,1

glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR

Local pixmap:TPixmap=LoadPixmap("_.png")
glTexImage2D GL_TEXTURE_2D,0,GL_RGBA8,pixmap.width,pixmap.height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels

glEnable GL_BLEND
glBlendFunc GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA




While Not KeyHit(KEY_ESCAPE)
   
   
   Angle:+1
   
   glBegin GL_QUADS
   
   For y=-12 To 12
      For x=-16 To 16
         DrawImage3D(pixmap,x*20,y*20,0,x*45+y*45+Angle,1,0)
      Next
   Next
   
   glEnd
   
   
   'FPS>>>>>>>>
   GLDrawText FPS,20,20
   MSC=MilliSecs()
   If MSC>MTS Then
      MTS=MTS+1000; FPS=FRM; FRM=1
      If MSC>MTS+2000 Then MTS=MSC
   Else; FRM=FRM+1; End If
   'FPS<<<<<<<<<<<<<<<<<
   
   
   Flip 0
   Clear3D()
   
   
Wend




Function DrawImage3D(FDrawHandle:TPixmap,FDrawX#,FDrawY#,FDrawButton%=0,FDrawAngle#=0,FDrawScale#=1,FDrawFrame%=0)
   
   
   Local LDrawXRan#=32*FDrawScale
   Local LDrawYRan#=32*FDrawScale
   Local IDrawTCos#
   Local IDrawTSin#
   Local IDrawXPos1#
   Local IDrawYPos1#
   Local IDrawXPos2#
   Local IDrawYPos2#
   
   'EXTRA/WINKELBERECHNUNG
   If FDrawAngle<>0 Then
      
      'SCHNELLE/UMRECHNUNG/VON: 'aMul'
      IDrawTCos=Cos(FDrawAngle)
      IDrawTSin=Sin(FDrawAngle)
      IDrawXPos1=LDrawXRan*IDrawTCos-LDrawYRan*IDrawTSin
      IDrawYPos1=LDrawYRan*IDrawTCos+LDrawXRan*IDrawTSin
      IDrawXPos2=LDrawXRan*IDrawTCos+LDrawYRan*IDrawTSin
      IDrawYPos2=LDrawYRan*IDrawTCos-LDrawXRan*IDrawTSin
   Else
      
      'DIREKTE/DARSTELLUNG
      IDrawXPos1=LDrawXRan
      IDrawYPos1=LDrawYRan
      IDrawXPos2=LDrawXRan
      IDrawYPos2=LDrawYRan
   End If
   
   'QUAD/ZEICHNEN
'   glBegin GL_QUADS
   glTexCoord2f 0,0; glVertex2f FDrawX-IDrawXPos1,FDrawY+IDrawYPos1
   glTexCoord2f 1,0; glVertex2f FDrawX+IDrawXPos2,FDrawY+IDrawYPos2
   glTexCoord2f 1,1; glVertex2f FDrawX+IDrawXPos1,FDrawY-IDrawYPos1
   glTexCoord2f 0,1; glVertex2f FDrawX-IDrawXPos2,FDrawY-IDrawYPos2
'   glEnd
   
   
EndFunction

Function Clear3D()
   
   
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
   glLoadIdentity()
   gluLookAt(0,0,360, 0,0,0, 0,1,0)
   
   
EndFunction
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

Matthias

Betreff: glNewList

BeitragSo, Aug 08, 2010 12:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Hay. Vieleicht hilft dir dieser Befehl im bereich der Geschwindigkeitsoptiemierung weiter.
Bei mir wars jedenfalls so.

http://wiki.delphigl.com/index.php/glNewList
Viel Spass mit OpenGL. Laughing

Edit:
Voher müstest du aber erst diese Displayliste mit glGenLists anlegen.

Mit glCallList kannst du dann die Displayliste anzeigen.
Und wenn du alle Quads drehen willst brauchst du vor glCallLists nur glRotatef benutzen und alle Quads in der Displayliste werden gedreht.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Aug 08, 2010 13:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Info. So wie ich das sehe sind diese Listen aber nur für statische Sachen. Das entspräche etwas dem Draw3D-Befehl ClearOff3D, welcher auch sehr wichtig ist und auch beachtet werden sollte. Falls ich es für realistisch halte die Draw3D2 zu portieren.

Gibt es vielleicht noch andere OGL-Treiber die vielleicht schneller sind? Oder eine andere Vorgehensweise?

Dein Link ist übrigens super. Finde viele Sachen die für mich wichtig sind oder noch sein könnten. Very Happy
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

Matthias

BeitragSo, Aug 08, 2010 13:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Naja es gibt dann noch diese VBOs. Die sind eigentlich für Echtzeitveränderungen gedacht bzw ausgelegt.

Doch ich habe sie selbst noch nicht zum laufen bekommen. Crying or Very sad
Vieleicht hast du da mehr Glück.

http://wiki.delphigl.com/index...fferobject
Ich denke nicht das es am Treiber liegt. Ob OpenGL schnell ist oder langsamm ist.
Es ist die Technick die mann anwendet sowie die Grafikkarte.

Bei meinem momentanen Projekt. 3DTerrainEditor in BMax+OpenGL.
Habe ich auf einem Kern von 2. 100% CPU Auslastung.

Bei einem bekannten der hat 4Kerne und eine sehr neue GrafikKarte.
Werden alle Kerne benutzt und er hat geade mal eine auslastung von 7%.
Was mich echt wundert. Twisted Evil

mpmxyz

BeitragSo, Aug 08, 2010 16:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Bremse liegt in dieser Zeile:
BlitzMax: [AUSKLAPPEN]
   gluLookAt(0,0,360, 0,0,0, 0,1,0) 

Wenn man diesen Funktionsaufruf auskommentiert, hat man mehr als das dreifache an fps. (etwa doppelt so schnell wie GLMax2D)
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Aug 08, 2010 17:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Info. Bringt zwar auf meinem Rechner 0% mehr Leistung, ist aber dennoch gut zu wissen da ja nicht jeder mein System hat. Und es soll ja schließlich möglichst überall schnell laufen.

Hab noch etwas rumexperimentiert und bin darauf gestoßen, dass meine Funktion durchaus deutlich schneller sein kann, als die von BlitzMax eigene 2D DrawImage-Funktion. Hängt alles von der Fillrate ab.

Bei gleicher Anzahl Bilder die sich jedoch gegenseitig überlappen (hohe Fillrate) ist meine Funktion langsamer (100:130). Doch bei gleicher Anzahl Bilder, nur das diese auf 0.3 skaliert sind (wenig bis keine Überlappung), ist meine Funktion gleich viel schneller (150:100).

Dann mach ich mal fröhlich weiter, und schaue, ob ich ein Equivalent zu der älteren Draw3D V.3.2 schaffen kann. Zumindest schnelle Kreise-Auf-Linen-Kolisionen (2D-Physik-Engine) werden noch eine Hürde für mich sein.

- - -

Frage:

In der Draw3D wird alles über Handles erledigt. So läft man zum Beispiel eine Textur über Handle = LoadImage3D(...). Nun ist es hier aber so, dass man statt Handle= ein blödes Handle:TPixmap= schreiben müsste. Finde ich nicht so toll.

Wie kann man es ab besten schaffen, dass jedes 'Handle' seinen eigenen Variablenkreis hat, der aber auch direkt angesprochen werden kann? Bei der Draw3D hab ich das über Banken erledigt. Gibt es unter BlitzMax eine bessere Möglichkeit? Ich habe schon öfters gesehen, dass bei BlitzMax in den Typelisten auch Methoden drin stecken. Könnte man diese für solche Zwecke nutzen?

Edit1:

Matthias

kann es sein, dass diese VBOs veraltet sind? Habe im englischem Forum irgendwo gelesen, dass eine ganze Befehlsreihe raus gefallen ist, und stattdessen neue gekommen sind. Die neuen sind all diejenige, die ich auch benutze.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

mpmxyz

BeitragSo, Aug 08, 2010 17:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein Integer-Handle?
->Nutze Arrays geschickt! Die sind in BM viel flexibler als in B3D. (geschickt=wachsendes Array+Liste der leeren Einträge)
Sonstige Handles?
->TMap-Objekte nutzen (Damit kann man Schlüsseln Werte zuordnen.)
Die beste Lösung:
Schreibe dir eine eigene Klasse. (z.B. ein eigenes "TImage")
Man muss zwar ":TImage" dann bei den Deklarationen schreiben, aber man kann die Bilder dann direkt ansprechen, braucht keine Löschfunktion zu verwenden, da die Objekte vom Garbage Collector automatisch freigegeben werden, und kann die Objekte auch in Listen/Maps verwenden. (Man muss bei der automatischen Freigabe aber noch die Texturennamen von OpenGL freigeben. -> "Delete"-Methode)
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Noobody

BeitragSo, Aug 08, 2010 19:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Handles sind ein eher unschönes Konstrukt aus B3D-Zeiten. In BMax sollte man auf jeden Fall dafür einen Type, z.B. TImage3D, benutzen. Statt Funktionen verwendet man dann Methoden, beispielsweise TollesBild.Draw( X, Y ).
BMax hat zwar noch Unterstützung für Integer-Handles aus Gründen der Rückwärtskompatibilität, aber solche Konstrukte passen einfach nicht mehr in eine OOP-Sprache wie BMax, zumal es ja auch den Garbage Collector umgeht und manuelles Löschen erfordert.

Was dein Geschwindigkeitsproblem angeht, so gäbe es dafür mehrere Tipps. Das eine wäre, wie schon erwähnt, das Verwenden eines VBOs statt des Immediate Modes. Der Immediate Mode (der glBegin/glEnd-Block) ist an sich nur für kleine Programme gedacht, bei denen man nur mal schnell etwas ausprobieren will und das Anlegen eines VBOs ein Overkill wäre, aber für den normalen Anwendungszweck ist dieser Modus langsam und veraltet.

Statt die ganzen Rotations/Handle/Was-auch-immer-Berechnungen von Hand auszuführen, würde ich eher die OGL-Funktionen glRotate, glScale usw. verwenden. Diese sollten im Regelfall schneller sein, wenn man sich die Matrix nach der Berechnung speichert und beim nächsten Zeichnen wieder verwendet kann, um sich das ständige Neuberechnen zu sparen.
Überhaupt würde ich das Konzept überarbeiten, dass man bei der Zeichenfunktion die Parameter wie Rotation und Skalierung angibt. Normalerweise ändern sich diese Argumente für ein Bild nicht bei jedem neuen Zeichenaufruf, daher ist es auch fraglich, ob man denn bei jedem Zeichnen die Eckpunkte komplett neu berechnen muss. Stattdessen würde ich es, ähnlich wie bei Max2D, über ein SetRotation, SetScale etc. erledigen, dass man für jedes Bild einzeln setzen kann. So kommst du dem Modell von OpenGL als State Machine einiges näher und sparst unnötiges Neuberechnen von Werten, die sich gar nicht änderten.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Aug 08, 2010 20:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bin dir für deine Tipps wiklich dankbar. Aber mir stellt sich die Frage, wieviel Sinn das alles hat? Statische Objekte nutzt kaum einer. Selbst die Draw3D konnte mit ClearOff3D ein ganzes Surface feststellen. Dadurch wurde das Objekt nicht mehr jedes Frame neu berechnet, sondern nur von der Grafikkarte gezeichnet. Hatte sogar eine einfache Steuerung einer Anzeigepriorität, und dennoch war es den meisten zuviel, eine Zeile Code am Anfang und eine Am Ende einer Hauptschleife zu schreiben. Warum sollte es nun bei BlitzMax anders sein?

Außerdem bietet sich einfach zu selten die Gelegenheit statische Sachen überhaupt anzeigen zu können. Sinnvoll wäre es erst bei einem größerem Objekt, das aus mehreren Teilbildern besteht (sonst lohnt sich das ganze nicht). Wie einer Tilemap zum Beispiel. Doch hier kann man auch diese nicht unendlich groß machen, da bereits das Maximum bei 64x63 Tiles liegt. Das reicht nicht mal für eine Minimap, und schon ist die Anzahl Vertices am Limit.

Als blutiger Anfänger bei BlitzMax werde ich so schnell keine erstzunehmende Konkurenz zur Avas-Grafikengine oder der miniB3D sein. Also versuche ich einen guten Umstieg für die Leute zu schaffen, die aufgrund immer mangelnder Funktionalität neuerer Betriebssysteme zu Blitz3D-Dx7, gezwungen sind demnächst ihr Projekt aus diesem Grund aufzugeben. Hier könnte man einfach den Code auf BlitzMax ziehen, zwei Replaces durchführen (';'>''' & ':'>';'), und einmal kurz den Header ändern, und schon kann man weiter machen. Nicht perfekt OOP, dafür glücklich.

Sinnvoll?

- - -

Garbage Collector ist so eine Sache. Die Draw3D verwaltet ihre Banken auch automatisch. So ähnlich könnte man es sicherlich auch auf BlitzMax umsetzen.

glRotate, glScale, glTranslate... Kennt mein BlitzMax nicht. Weiß einer wie ich dazu die Abhilfe schaffe?

Zitat:
...Stattdessen würde ich es, ähnlich wie bei Max2D, über ein SetRotation, SetScale etc. erledigen, dass man für jedes Bild einzeln setzen kann...

JEDES Bild einzelnd, oder gilt es einmal eingestellt für ALLE Bilder die danach gezeichnet werden, bis es wieder geändert wird?
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Noobody

BeitragSo, Aug 08, 2010 20:46
Antworten mit Zitat
Benutzer-Profile anzeigen
hectic hat Folgendes geschrieben:
Aber mir stellt sich die Frage, wieviel Sinn das alles hat? Statische Objekte nutzt kaum einer.

Statische Objekte? Davon war eigentlich nie die Rede Razz Die Position, Rotation und Skalierung kann man ja weiterhin beliebig festsetzen, sonst wäre es ja nicht sinnvoll. Die Grundidee ist aber, dass man, wenn sich die Position des Bildes ändert, nicht auch noch die Berechnungen für Rotation, Skalierung und Animation ausführen muss. Daher speichert man die Matrix einmal und ändert sie nur, wenn sich irgendwas ändert.

hectic hat Folgendes geschrieben:
Also versuche ich einen guten Umstieg für die Leute zu schaffen, die aufgrund immer mangelnder Funktionalität neuerer Betriebssysteme zu Blitz3D-Dx7, gezwungen sind demnächst ihr Projekt aus diesem Grund aufzugeben.

Wenn du einfach eine 1:1 Übersetzung der Draw3D nach BMax willst, dann vergiss alles, was ich sagte. Ich finde es einfach schade, dass man bei einer Lib für BMax noch die ganzen Altlasten aus B3D mitschleppt, nur damit andere einen leichteren Einstieg haben. Dieselbe Mentalität bei Mark war wohl einer der Gründe, warum BMax einige sehr fragwürdige und unschöne Features besitzt.

hectic hat Folgendes geschrieben:
glRotate, glScale, glTranslate... Kennt mein BlitzMax nicht. Weiß einer wie ich dazu die Abhilfe schaffe?

OpenGL-Befehle haben immer einen Postfix, der die Parametertypen spezifiziert. Das siehst du z.B. bei Vertex2f, der zwei Floats entgegennimmt. Dasselbe gilt für diese Befehle, die z.B. glRotatef und glRotated für die Float und Double-Version heissen.

hectic hat Folgendes geschrieben:
JEDES Bild einzelnd, oder gilt es einmal eingestellt für ALLE Bilder die danach gezeichnet werden, bis es wieder geändert wird?

In der Max2D gilt es für alle Bilder. Wie du es umsetzt, ist komplett dir überlassen - in deinem Fall würde ich es wohl eher für jedes Bild einzeln festlegen.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Aug 08, 2010 23:32
Antworten mit Zitat
Benutzer-Profile anzeigen
So, hat wunderbar geklappt mit glRotate, glScale und glTranslate. Ist im Grunde nichts anderes, als würde man mit Pivots arbeiten. Ändert man die Matrix, so kann man ausgehend der aktuellen Stellung zeichnen.

Nur etwas nervig das alles relativ angegeben wird. So lässt sich glRotate nicht auf einen bestimmten Wert festlegen (zum Beispiel = Nullstellung), sondern arbeitet immer relativ zur letzten Position.

Wie kann man denn am besten die Matrix auf Null stellen? Gibt es da kein ''Reset'' oder sowas? Oder muss ich gleich am Anfang eine Nuller-Matix speichern, die ich dann später lade? Wenn ja, hat da einer ein Beispielcodezeilen zu?
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

The Shark

BeitragSo, Aug 08, 2010 23:42
Antworten mit Zitat
Benutzer-Profile anzeigen
In dem Zusammenhang kann ich nur dieses Tutorial empfehlen. Dort geht es genau um diese Problematik.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Aug 09, 2010 0:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Edit1: Hab's geschafft.

Einmalig Code: [AUSKLAPPEN]
Global TempMatrix:Float[16]

Beim rendern Code: [AUSKLAPPEN]
GLGetFloatv(GL_MODELVIEW_MATRIX,TempMatrix)

Beim Reset Code: [AUSKLAPPEN]
glLoadMatrixf(TempMatrix)
 

undefined

BeitragMo, Aug 09, 2010 0:56
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax: [AUSKLAPPEN]
Matrix:Double [ 4, 4 ]

glGetDoubleV ( GL_MODELVIEW_MATRIX, Matrix )

glLoadMatrixd ( Matrix )


glLoadMatrix ersetzt immer die aktive OpenGL Matrix (glMatrixMode).

mpmxyz

BeitragMo, Aug 09, 2010 12:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Ähm, stand da nichts von "glLoadIdentity()"? Dabei wird die Matix aber nicht auf 0 sondern auf die Einheitsmatrix gestellt. (Sonst würde man nichts sehen können. Razz)
glLoadIdentity wird sogar schneller als jede andere Lösung sein.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Aug 09, 2010 12:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit glLoadIdentity werde ich es erneut ausprobieren sobald ich von der Arbeit zurück bin. Bisherige Versuche schlugen mit glLoadIdentity jedoch fehl.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Noobody

BeitragMo, Aug 09, 2010 18:05
Antworten mit Zitat
Benutzer-Profile anzeigen
An sich sollte glLoadIdentity genau das sein, was du suchst. Eine Nuller-Matrix führt eigentlich nur dazu, dass deine Vertices sich alle bei 0|0|0 zusammenklumpen.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Aug 09, 2010 18:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Gut, hab mich falsch ausgedrückt. Sollte klar sein, dass eine 0,0,0 Matrix keine Dimensionen mehr hat, von dennen man weitere Berechnungen durchführen kann. Ich probier das noch aus, sobald ich Zuhause bin.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group