Einen fixierten Type-Eintrag auslesen

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

hectic

Sieger des IS Talentwettbewerb 2006

Betreff: Einen fixierten Type-Eintrag auslesen

BeitragMi, Aug 11, 2010 0:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie kann ich bei BlitzMax auf EINEN BESTIMMTEN Type-Eintrag zugreifen? Bei Blitz3D hatte man dafür das Object/Handle zur Verfügung. Bei BlitzMax gibt es das anscheinend nicht mehr. Oder gibt es dafür eine bessere Alternative?

BlitzMax: [AUSKLAPPEN]
Type TNeu
Field Wert1:Int
Field Wert2:Int
End Type

Local T1=Rein(1,6)
Local T2=Rein(4,6)
Local T3=Rein(9,6)

Mach(T1)
Mach(T2)
Mach(T3)

WaitKey




Function Rein(FZahl1,FZahl2)

Local IT:TNeu=New TNeu
IT.Wert1=FZahl1
IT.Wert2=FZahl2
Return Handle

End Function


Function Mach(Handle)

Local IT.TNeu=Object.TNeu(Handle)
Print "TEST: "+IT.Wert1+" "+IT.Wert2

End Function

Alternativ, falls es nicht gehen sollte, wie kann man in eine Bank einen Wert für TPixmap der von ConvertPixmap(LoadPixmap("image.png"),PF_RGBA8888) zurück gegeben wird speichern? Als Integer geht es schon mal nicht.

Danke im Voraus.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Xeres

Moderator

BeitragMi, Aug 11, 2010 0:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Gewöhne dich dran, Objekte als solche zu verwenden - und Funktionen und Metoden für die Types zu benutzen Wink
Ich würde das wohl so schreiben:

BlitzMax: [AUSKLAPPEN]
SuperStrict

Type TNeu
Field Wert1:Int
Field Wert2:Int

Function Rein:TNeu(FZahl1:Int, FZahl2:Int)

Local IT:TNeu=New TNeu
IT.Wert1=FZahl1
IT.Wert2=FZahl2
Return IT

End Function


Method Mach()

Print "TEST: " + Self.Wert1 + " " + Self.Wert2

End Method

End Type

Local T1:TNeu = TNeu.Rein(1, 6)
Local T2:TNeu = TNeu.Rein(4, 6)
Local T3:TNeu = TNeu.Rein(9, 6)

T1.Mach()
T2.Mach()
T3.Mach()
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Aug 11, 2010 1:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich will das ganze Syntax-Zeug da weg haben. Höchstens mit einem alá :TImage bin ich einverstanden.

Angenommen, ich schreibe eine Grafikbibliothek die sich Draw3D2Max nennt, und will nun ein Bild laden das ''auto.png'' heisst.

Statt zu schreiben Code: [AUSKLAPPEN]
Local Auto:TImage=LoadImage3D("auto.png",2,2)

kommt stattdessen Code: [AUSKLAPPEN]
Local Auto:TDraw3D2Max=TDraw3D2Max.LoadImage3D("auto.png",2,2)

Lässt sich das bewerkstelligen indem man die Funktionen wieder auslagert? Die ersten Versuche haben nicht geklappt.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Xeres

Moderator

BeitragMi, Aug 11, 2010 2:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Bild lädst du in ein Timage oder TPixmap, und dieses wiederrum in ein TDraw3D2Max Objekt. Oder du erweiterst Timage; was dir sinniger erscheint bzw. je nach dem viel OOP du benutzen möchtest.
BlitzMax: [AUSKLAPPEN]
SuperStrict

Type TDraw3D2Max
Field img:TImage
'[...]

Function LoadImage3D:TDraw3D2Max(_pfad:String)

Local obj:TDraw3D2Max = New TDraw3D2Max
obj.img = LoadImage(_pfad)
Return obj

End Function


End Type

Local Auto:TDraw3D2Max = TDraw3D2Max.LoadImage3D("auto.png")
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Thunder

BeitragMi, Aug 11, 2010 2:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Zur 1. Frage: Soweit ich weiß erzeugt BlitzBasic für einen Type gleich eine LinkedList. Das musst du in BlitzMax von Hand machen:

BlitzMax: [AUSKLAPPEN]
SuperStrict
Framework brl.standardio
Import brl.linkedlist

Type blub
Field x%,y%
Function Create:blub(x%,y%)
Local instanz:blub=New blub
instanz.x=x
instanz.y=y
Return instanz
EndFunction
EndType

Local blublist:TList=CreateList()
blublist.addLast( blub.Create(1,1) ) 'ein blub mit X=1, Y=1 erstellen und ans Ende der Liste anfügen
blublist.addLast( blub.Create(2,3) )
blublist.addLast( blub.Create(5,8) )
'jetzt sind 3 Elemente in der Liste. Die lassen sich mit EachIn ansprechen:
For Local b:blub=EachIn blublist
Print "X: "+b.x+" Y: "+b.y
Next

'Ansprechen kann man sie aber auch über Integer und ich glaube das wolltest du:
For Local i%=0 To blublist.count()-1
Print "X: "+blub( blublist.ValueAtIndex(i) ).x+" Y: "+blub( blublist.ValueAtIndex(i) ).y
'blublist.ValueAtIndex(i) gibt das Objekt am Index i zurück
'das muss man noch zu einem blub-Objekt casten
Next

End


Das ist die einzige Methode die mir dazu einfällt.


mfg Thunder
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMi, Aug 11, 2010 3:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Nagut, eigentlich wollte ich nur den Aufruf etwas verkürzen. OOP ist zwar eine tolle Sache, aber meiner Meinung muss man es nicht überall anwenden wo es überhaupt keinen Vorteil bringt. Und um Bilder in den Speicher zu laden sind Baumstrukturen nicht notwendig.

OOP kommt mir schon langsam wie eine Sekte vor, wo noch so große Nachteile einfach hingenommen werden, und noch so kleine Vorteile in den Himmel gelobt werden. Shocked

Aber gut. Ich übertreib mal:

Ich möchte lieber folgendes schreiben können:

Code: [AUSKLAPPEN]
Local I=LoadImage("jeah.png")


Statt eine ganze Geschichte wie folgende schreiben zu müssen:

Code: [AUSKLAPPEN]
Local I:TGeileOOPListenstruktur=TGeileOOPListenstruktur.LoadImage("oh-no.png")


Und jetzt mal ehrlich. OOP braucht man hier absolut nicht. Selbst die Samples von BlitzMax haben einfachen Aufruf für Bilder (und keiner beschwert sich dabei). Nämlich ein alleiniges:

Code: [AUSKLAPPEN]
Local I:TImage=LoadImage("noch-ok.png")


Damit könnte ich mich noch anfreunden. Aber es muss doch nicht alles doppelt und dreifach sein. Und nochmal... Um Bilder zu laden braucht man keine Baumstrukturen. Ich bin also auf der Suche: Banken, Types oder irgend einen anderen Mehrfach-Wertespeicher zu suchen, der mir so einen einfachen Aufruf ermöglicht. Eine Bank wäre sogar ideal, nur hab ich noch keinen Weg gefunden, ein Objekt mit dem Rückgabewert von ConvertPixmap(LoadPixmap("bild.png"),PF_RGBA8888) zu speichern.

Aber anscheinend wird das alles wohl nicht möglich sein. Crying or Very sad

Dennoch haben mir Eure Beispiele andere Anwendungsmöglichkeiten eröffnet. Ich bin immer noch interessiert auf weitere Lösungsvorschläge.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

n-Halbleiter

BeitragMi, Aug 11, 2010 3:30
Antworten mit Zitat
Benutzer-Profile anzeigen
ConvertPixmap gibt eine TPixmap zurück, wo liegt also das Problem?^^
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit
Ploing!
Blog

"Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935)

Thunder

BeitragMi, Aug 11, 2010 3:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe hier einen kleinen Code geschrieben der einen Speicherblock reserviert. Darin die Pixeldaten speichert und sie als Pixmap lädt:
BlitzMax: [AUSKLAPPEN]
SuperStrict
Graphics 400,300
Const width%=150,height%=150
Local mem:Byte Ptr=MemAlloc(width*height*4)
Local r:Byte,g:Byte,b:Byte
For Local i%=0 To width*height*4 Step 4
r:+3
g:+7
b:+11
mem[i]=0'alpha
mem[i+1]=r
mem[i+2]=g
mem[i+3]=b
Next
Local p:TPixmap
p=CreateStaticPixmap(mem,width,height,width,PF_RGBA8888)
Local img:TImage=LoadImage(p)
Repeat
Cls
DrawImage img,MouseX()-width/2,MouseY()-height/2
Flip
Until AppTerminate()
MemFree mem
End


Das ganze geht auch mit Banks, aber das ist etwas komplizierter.

Code: [AUSKLAPPEN]

BlitzMax       ANSI-C-LIB
MemAlloc ... malloc
MemFree ... free
MemExtend ... realloc
...


Zeiger dereferenziert man in BlitzMax wie Arrays.


mfg Thunder
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

Xeres

Moderator

BeitragMi, Aug 11, 2010 4:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Bis auf die Länge deiner beiden Beispielzeilen, sehe ich ehrlich gesagt kaum einen Unterschied, hectic. Das "I" ohne Angabe des Typs funktioniert sowieso nur im non-Strict Modus. Und so sollte man wirklich nicht arbeiten - es ist langsamer und fehleranfälliger. Bei der Funktion als teil des Types ist alles hübsch gekapselt...
Ich weiß auch nicht, was du hier für eine Baumstruktur siehst?!

Wenn du - wie auch immer - Handle verwenden willst, dann mittels HandleFromObject, HandleToObject, Release.
BlitzMax: [AUSKLAPPEN]
SuperStrict

Local pm:TPixmap = CreatePixmap(16, 16, PF_RGBA8888)
Local bank:TBank = CreateBank(4)

PokeInt(bank, 0, HandleFromObject(pm))

Local pm2:TPixmap = TPixmap(HandleToObject(PeekInt(bank, 0)))

If pm = pm2 Then Print("Tataa!")
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

das wurgel

BeitragMi, Aug 11, 2010 12:22
Antworten mit Zitat
Benutzer-Profile anzeigen
hectic hat Folgendes geschrieben:
Statt zu schreiben
Code: [AUSKLAPPEN]
Local Auto:TImage=LoadImage3D("auto.png",2,2)

kommt stattdessen
Code: [AUSKLAPPEN]
Local Auto:TDraw3D2Max=TDraw3D2Max.LoadImage3D("auto.png",2,2)


Mach einfach in die Hauptdatei deiner Lib ne Funktion die so aussieht:
Code: [AUSKLAPPEN]
Function LoadImage3D(url:Object, a, b)
 Return TDraw3D2Max.LoadImage3D(url,a,b)
End Function


So macht es BRL auch.
1 ist ungefähr 3

Noobody

BeitragMi, Aug 11, 2010 20:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Du musst hier ein wenig aufpassen, dass du nicht in gewissen Programmierstrukturen erstarrst, nur weil du dir sie dir gewohnt bist. OOP ist keine 'Sekte' - sieh es als führende Wissenschaft, während Prozedurales Programmieren okkulten Druidenritualen gleicht, bei denen man in dunklen Kellern giftige Hexensüppchen kocht Razz (um hier gleich mal giftige Kommentare abzuwenden: Das war natürlich ein überspitztes Beispiel. Prozedurale Programmiersprachen haben auch heute noch Anwendungszwecke).
Ich lehnte früher Javas Klassensystem vehement ab, bis ich mal gezwungen war, es ernsthaft zu benutzen. Wenn sogar ich die Vorteile an Java erkennen kann, würde ich auch BMax mal eine Chance geben. OOP wirst du nicht mehr missen mögen.

In deinem Fall scheinst du wohl noch sehr den Handles nachzuhängen. Es ist zwar wahr, dass man ein LoadImage so furchtbar kurz hinbekommt, aber andererseits sind Handles auch sehr gefährlich - ich kann damit rumrechnen, wie ich lustig bin, da es nur ein Int ist. Auch kann ich nie wissen, ob das Objekt, zu dem das Handle ursprünglich gehörte, noch da ist oder nicht - ich verwende einfach frischfröhlich irgendeine Zahl und hoffe, dass nirgends unerwartet das zugehörige Objekt gelöscht wird.

Da ist eine echte Referenz natürlich viel toller. Entweder, die Referenz ist Null und zeigt auf gar nichts, oder sie ist nicht Null und zeigt dann auf ein garantiert existierendes Objekt - Ende mit russischem Roulette. Ja, ich muss ein :TImage hinten an die Variablendeklaration anhängen, aber das sollte nun keinen User von der Verwendung der Lib abhalten. In SuperStrict (der Modus, der von jedem nicht masochistischem Entwickler verwendet wird) müsstest du für ein Handle sowieso noch ein :Int hinschreiben, da ist es nicht mehr weit bis :TImage.

Ob man nun die Ladefunktion in den Type steckt oder nicht, scheint Geschmackssache zu sein. BMax selbst bietet zwar eigenständige Funktionen an, jedoch liegt das schlicht daran, dass BMax sowieso noch auf Rückwärtskompatibilität zu BB getrimmt ist. In den Funktionen selbst wird aber einfach die Funktion im Type aufgerufen, scheint also eine rein kosmetische Angelegenheit zu sein. Die OOP-igere Variante wäre auf jeden Fall, die Ladefunktion in den Type selbst zu stecken.
Der Hintergrundgedanke dabei ist, dass eine Klasse gekapselt sein muss. Im Idealfall kopiert man eine Klasse aus ihrer Originaldatei in ein anderes Projekt hinein und kann sie gleich verwenden, ohne dass man noch alle fünfhundert Funktionen zusammensuchen muss, die irgendwas mit der Klasse zu tun haben.
Wenn man eine Lib einbindet, erwartet man eine Handvoll Klassen, die jede ihre eigenen Funktionen mitbringen, die genau auf sie zugeschnitten sind. Alle Funktionen, die für die Verwendung eines Types nötig sind, stecken in besagtem Type drin. Man muss nicht mehr wild in der Dokumentation oder gar im Source wühlen, um herauszufinden, zu welchen Types nun diese verflixte Funktion gehört und was für Handles man da genau angeben muss, sondern es ist immer klar, dass eine Methode auf dem Type ausgeführt wird, zu dem sie gehört.

Wenn dir nun ein TImage3D.LoadImage3D zu lange ist, dann überleg mal, was an dem Aufruf zu viel ist. Du weisst ja schon, dass du es mit einem TImage3D zu tun hast - wofür also nochmal im Funktionsnamen verwenden? BlitzMax: [AUSKLAPPEN]
Local I:TImage3D=TImage3D.Load("i'm-okay-with-this.png")
'Im Vergleich
Local I:TImage3D=LoadImage3D("ewwww-no-way.bmp")


Ich denke, dass man genau dieselbe Diskussion früher bei Types vs. Arrays oder gar Funktionen vs. GoTos hatte - trotzdem würde heute niemand mehr ernsthaft die letzteren Alternativen verwenden Wink
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

BeitragMi, Aug 11, 2010 22:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich will jetzt keine VS.-Diskussion lostreten. Mir fällt nur auf, dass egal was für Argumente man findet, von den OOP-Jüngern ausgelacht wird. Egal ob berechtigt oder nicht.

Wenn man beim prozeduralem programmieren einen Fehler verursacht der mit OOP nicht passiert wäre und deswegen 10min länger braucht um das zu debuggen, wird man schnell ausgelacht. Dabei ist es egal ob man mit OOP für das gleiche Problem insgesamt 60min länger am coden ist, nur um sich die ganzen Unterklassen im Internet oder anderen Quellen zusammen zu suchen. Hier stehen +10min vs. +60min, dennoch wird der der schneller voran kommt ausgelacht. Und genau das ist einfach nur dumm. Genau wie der Typ, der eine 2D-Map mit Types realisiert hat. Hauptsache es geht.

Noobody hat Folgendes geschrieben:
...dieselbe Diskussion früher bei Types vs. Arrays...

Man muss einfach einsehen, dass Types als auch Array jeweils ihre Daseinsberechtigung haben. Genauso auch Gosub (lassen wir mal Goto bitte weg, sonst können wir gleich noch mit Lochkarten anfangen).

Der ganze OOP-Wahn geht bereits so weit, statt einfach eine Variable die für die Positionssteuerung einer Spielfigur (KEIN Multiplayer) dient, nicht als Global deklariert wird, sondern einzig für XPos und YPos mal eine Typeliste erstellt wird. Rolling Eyes Oje oje oje

Ich versuche wirklich nur einen gesunden Mittelweg zu finden. Dieser die Vorteile von prozeduralem als auch die des OOP zusammen führt. Ich will mich nicht auf OOP aufgeilen, sondern deren Vorteile nutzen wenn welche da sind.

Aber genug geredet, hier meine bisherige Arbeiten:



- - -



Mein aktueller Stand (damit daddel ich grad noch rum, funktioniert schon und zeigt Quads an):

BlitzMax: [AUSKLAPPEN]
SuperStrict

GLGraphics 800,600
glMatrixMode(GL_PROJECTION)
glScalef(1.0,1.0, 1)
gluPerspective(90, 800/600, -1,+1)
glMatrixMode(GL_MODELVIEW)
Global Matrix:Double[4,4]

glLoadIdentity()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
gluLookAt(0,0,300,0,0,0, 0,1,0)
glGetDoubleV(GL_MODELVIEW_MATRIX,Matrix)


Type TDraw3D2Max


Field TDraw3D2PM:TPixmap
Field TDraw3D2U1:Float
Field TDraw3D2V1:Float
Field TDraw3D2U2:Float
Field TDraw3D2V2:Float


Function LoadImage3D:TDraw3D2Max(FDraw3D2Name:String)




Local IDraw3D2New:TDraw3D2Max=New TDraw3D2Max

If FileType(FDraw3D2Name)=0 Then RuntimeError("LoadImage3D <"+FDraw3D2Name+"> not found!")

IDraw3D2New.TDraw3D2PM:TPixmap=ConvertPixmap(LoadPixmap(FDraw3D2Name),PF_RGBA8888)
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D,0,4, IDraw3D2New.TDraw3D2PM.Width,IDraw3D2New.TDraw3D2PM.Height, 0,GL_RGBA,GL_UNSIGNED_BYTE,IDraw3D2New.TDraw3D2PM.Pixels)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)

IDraw3D2New.TDraw3D2U1:Float=0
IDraw3D2New.TDraw3D2V1:Float=0
IDraw3D2New.TDraw3D2U2:Float=IDraw3D2New.TDraw3D2PM.Width
IDraw3D2New.TDraw3D2V2:Float=IDraw3D2New.TDraw3D2PM.Height

Return IDraw3D2New




End Function


Function GrabImage3D:TDraw3D2Max(FDraw3D2U1:Float,FDraw3D2V1:Float,FDraw3D2U2:Float,FDraw3D2V2:Float)




Local IDraw3D2New:TDraw3D2Max=New TDraw3D2Max

IDraw3D2New.TDraw3D2U1:Float=FDraw3D2U1
IDraw3D2New.TDraw3D2V1:Float=FDraw3D2V1
IDraw3D2New.TDraw3D2U2:Float=FDraw3D2U2
IDraw3D2New.TDraw3D2V2:Float=FDraw3D2V2

Return IDraw3D2New




End Function


Method DrawImage3D(FDraw3D2XP:Int,FDraw3D2YP:Int,FDraw3D2RP:Int=0,FDraw3D2SC:Float=1)




GLDrawText "TEST",Self.TDraw3D2U1+FDraw3D2XP,Self.TDraw3D2V1+FDraw3D2YP
Print FDraw3D2XP+" "+FDraw3D2YP+" / "+Int(Self.TDraw3D2U1)+" "+Int(Self.TDraw3D2V1)+" "+Int(Self.TDraw3D2U2)+" "+Int(Self.TDraw3D2V2)


'VARIABLENDEKLARATIONEN
Local LDrawXRan:Float=32*FDraw3D2SC
Local LDrawYRan:Float=32*FDraw3D2SC
Local IDrawTCos:Float
Local IDrawTSin:Float
Local IDrawXPos1:Float
Local IDrawYPos1:Float
Local IDrawXPos2:Float
Local IDrawYPos2:Float

'EXTRA/WINKELBERECHNUNG
If FDraw3D2RP<>0 Then

'UMRECHNUNG/VON: 'aMul'
IDrawTCos=Cos(FDraw3D2RP)
IDrawTSin=Sin(FDraw3D2RP)
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 FDraw3D2XP-IDrawXPos1,FDraw3D2YP+IDrawYPos1
glTexCoord2f 1,0; glVertex2f FDraw3D2XP+IDrawXPos2,FDraw3D2YP+IDrawYPos2
glTexCoord2f 1,1; glVertex2f FDraw3D2XP+IDrawXPos1,FDraw3D2YP-IDrawYPos1
glTexCoord2f 0,1; glVertex2f FDraw3D2XP-IDrawXPos2,FDraw3D2YP-IDrawYPos2
glEnd




End Method
End Type


Local T1:TDraw3D2Max=TDraw3D2Max.LoadImage3D("_.png")
Local T2:TDraw3D2Max=TDraw3D2Max.LoadImage3D("_A.png")
Local T3:TDraw3D2Max=TDraw3D2Max.LoadImage3D("_C.png")
Local T4:TDraw3D2Max=TDraw3D2Max.GrabImage3D(10,10,80,80)


'Local Auto:TDraw3D2Max=TDraw3D2Max.LoadImage3D("auto.png",2,2)


T1.DrawImage3D(100,100)
T2.DrawImage3D(200,100)
T3.DrawImage3D(200,200)
T4.DrawImage3D(200,275,45,0.5)


Flip



Print "ENDE"
Delay 2000


- Bei mir waren selbst berechnete Sin/Cos-Werte für die Bilddrehung schneller, als glRotatef(). Nur falls einer wieder kommt. Wink

- Mir gefällt das letzte Beispiel von das wurgel sehr gut und werde versuchen diese Funktionen als Zusatz nachzuliefern. Dann kann jeder selbst entscheiden, ob er den Zusatz mit einbindet, oder lieber darauf verzichtet.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Xeres

Moderator

BeitragMi, Aug 11, 2010 22:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Sin/Cos kannst du noch einen Tick schneller machen, wenn du die Werte im Vorhinein berechnest:
BlitzMax: [AUSKLAPPEN]
Global Cos_:Float[360], Sin_:Float[360]
For Local i:Int = 0 Until 360
Cos_[i] = Cos(i)
Sin_[i] = Sin(i)
Next
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

BladeRunner

Moderator

BeitragDo, Aug 12, 2010 9:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Der ganze OOP-Wahn geht bereits so weit, statt einfach eine Variable die für die Positionssteuerung einer Spielfigur (KEIN Multiplayer) dient, nicht als Global deklariert wird, sondern einzig für XPos und YPos mal eine Typeliste erstellt wird.

Ich würde in der Tat einen Type dafür anlegen, um es sauberer zu kapseln, eine Liste hingegen nicht. Types und Listen sind ja nicht miteinander verbunden. Der Mehraufwand beträgt dabei das tippen des jeweiligen scopes (Player.posx statt posx), der Nutzen ist dass ich jederzeit weiß welche x-Position denn gemeint ist. Alle Daten die eine einzelne Struktur meines Spieles betreffen sind an einer Stelle gebündelt, und das finde ich ungemein praktisch.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Noobody

BeitragDo, Aug 12, 2010 20:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe dir mal das ganze so umgeschrieben, wie es aussehen könnte. Das umfasst zum einen Vorschläge, wie man es in OOP-Manier umsetzen könnte, als auch Verbesserungen am OpenGL-Part. Der Code ist hoffentlich genügend kommentiert. BlitzMax: [AUSKLAPPEN]
SuperStrict

TDraw3D2.Graphics( 800, 600 ) 'Alternativ auch Graphics3D( .... )

Local Timer:TTimer = CreateTimer( 60 )

Local T1:TImage3D = TImage3D.Load("_.png")
Local T2:TImage3D = TImage3D.Load("_A.png")
Local T3:TImage3D = TImage3D.Load("_C.png")

T1.Scale( 0.5, 0.5 ) 'Skalierung setzen - wird nur einmal gebraucht und nicht bei jedem Zeichenaufruf
T2.Scale( 0.5, 0.1 )
T3.Scale( 0.1, 0.9 )

While Not ( KeyHit( KEY_ESCAPE ) Or AppTerminate() )
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) 'Ersetzt Cls

T1.Draw( 200, 300 ) 'Einzeichnen
T2.Draw( 400, 100 )
T3.Draw( 400, 200 )

T1.Turn( 1.0 ) 'Im Uhrzeigersinn drehen. Auch hier muss es nicht jedesmal beim Zeichnen angegeben werden.

Flip 0
WaitTimer Timer
Wend

End

Type TDraw3D2 'Die Draw3D als eigener Type. Macht jetzt natürlich noch nicht wahnsinnig Sinn mit nur einer Funktion, aber wenn du später
'zwei dutzend Funktionen hast, bleibt es übersichtlich
Function Graphics( Width:Int, Height:Int )
GLGraphics Width, Height

glMatrixMode( GL_PROJECTION )
glOrtho( 0, Width, Height, 0, -1.0, 1.0 ) 'gluPerspective ist in 2D nicht gebraucht

glMatrixMode( GL_MODELVIEW )
glLoadIdentity()

glEnable( GL_TEXTURE_2D ) 'Textur und Blendmodi müssen nur einmal gesetzt werden und nicht beim Laden jedes Bildes
glEnable( GL_BLEND )

glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )
End Function
End Type

Type TImage3D
Field TDraw3D2PM:TPixmap
Field TDraw3D2U1:Float
Field TDraw3D2V1:Float
Field TDraw3D2U2:Float
Field TDraw3D2V2:Float

Field Matrix:Float[] 'Enthält die OGL-Matrix
Field TextureHandle:Int

Function Load:TImage3D(FDraw3D2Name:String)
Local IDraw3D2New:TImage3D=New TImage3D

If FileType(FDraw3D2Name)=0 Then RuntimeError("Load <"+FDraw3D2Name+"> not found!")

IDraw3D2New.TDraw3D2PM:TPixmap=ConvertPixmap(LoadPixmap(FDraw3D2Name),PF_RGBA8888)

'GLTexFromPixmap ist sehr praktisch, wenn man ohne viel Aufwand eine Pixmap in OGL reinladen will
IDraw3D2New.TextureHandle = GLTexFromPixmap( IDraw3D2New.TDraw3D2PM, False )

'Textur an den 2D-Slot binden, um die Parameter setzen zu können
glBindTexture( GL_TEXTURE_2D, IDraw3D2New.TextureHandle )

'Texturfilter
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR )
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR )

'Da keine Mipmaps generiert wurden, braucht es diesen kleinen Trick, damit er nicht versucht, nicht existierende
'Mipmaps einzuzeichnen
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0 )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0 )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0 )

IDraw3D2New.TDraw3D2U1:Float=0
IDraw3D2New.TDraw3D2V1:Float=0
IDraw3D2New.TDraw3D2U2:Float=IDraw3D2New.TDraw3D2PM.Width
IDraw3D2New.TDraw3D2V2:Float=IDraw3D2New.TDraw3D2PM.Height

'Einheitsmatrix setzen. Die eigenartige Formatierung ist darum so gewählt, damit die Matrizenstruktur gut erkennbar ist
IDraw3D2New.Matrix = ..
[ 1.0, 0.0, 0.0, 0.0, ..
0.0, 1.0, 0.0, 0.0, ..
0.0, 0.0, 1.0, 0.0, ..
0.0, 0.0, 0.0, 1.0 ]

Return IDraw3D2New
End Function

Method Scale( ScaleX:Float, ScaleY:Float ) 'Skaliert ein Bild.
'Wichtig: Die Skalierung multipliziert sich über die alte Skalierung drüber, ist also relativ.
'Für eine absolute Skalierung müsste man hier noch einiges umschreiben, habe ich aber der Einfachheit
'halber weggelassen

'Bisherige MAtrix auf den Stack retten
glPushMatrix()

'Unsere Matrix nach OGL holen
glLoadMatrixf( Matrix )

'Skalierung anwenden
glScalef( ScaleX, ScaleY, 0.0 )

'Zurückholen
glGetFloatV( GL_MODELVIEW_MATRIX, Matrix )

'Alte Matrix wieder vom Stack poppen
glPopMatrix()
End Method

Method Turn( Angle:Float )
'Genau gleich wie bei Scale(....)

glPushMatrix()
glLoadMatrixf( Matrix )

glRotatef( Angle, 0.0, 0.0, 1.0 )

glGetFloatV( GL_MODELVIEW_MATRIX, Matrix )
glPopMatrix()
End Method

Function Grab:TImage3D(FDraw3D2U1:Float,FDraw3D2V1:Float,FDraw3D2U2:Float,FDraw3D2V2:Float)
Local IDraw3D2New:TImage3D=New TImage3D

IDraw3D2New.TDraw3D2U1:Float=FDraw3D2U1
IDraw3D2New.TDraw3D2V1:Float=FDraw3D2V1
IDraw3D2New.TDraw3D2U2:Float=FDraw3D2U2
IDraw3D2New.TDraw3D2V2:Float=FDraw3D2V2

Return IDraw3D2New
End Function


Method Draw(FDraw3D2XP:Int,FDraw3D2YP:Int)
'Textur binden. Das wurde bei deiner Version gar nicht gemacht, weswegen auch immer nur dasselbe Bild eingezeichnet wurde-
glBindTexture( GL_TEXTURE_2D, TextureHandle )

glMatrixMode( GL_MODELVIEW )

'Bisherige Matrix retten
glPushMatrix()

'Verschiebung setzen
glTranslatef( FDraw3D2XP, FDraw3D2YP, 0.0 )

'Unsere Bildmatrix drübermultiplizieren
glMultMatrixf( Matrix )

'Zeug zeichnen
glBegin GL_QUADS
glTexCoord2f 0,0; glVertex2f TDraw3D2U1, TDraw3D2V1
glTexCoord2f 1,0; glVertex2f TDraw3D2U2, TDraw3D2V1
glTexCoord2f 1,1; glVertex2f TDraw3D2U2, TDraw3D2V2
glTexCoord2f 0,1; glVertex2f TDraw3D2U1, TDraw3D2V2
glEnd

'Alte Matrix wieder vom Stack poppen
glPopMatrix()
End Method
End Type

Zur ganzen OOP-Diskussion möchte ich eigentlich nichts mehr anfügen. Du hast klar gemacht, dass du relativ wenig davon hältst und dich auch nicht weiter darauf einlassen willst. Das ist zwar schade, aber deine Entscheidung Razz
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

BeitragDo, Aug 12, 2010 22:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Ne, vergiss das mal mit der Diskussion. Smile

Vielen Dank für den lehrreichen Code. Wird mir die nächsten Tage sicherlich viel Spielerei ermöglichen. Hoffentlich ist nun die BMax-Variante schneller, als die bisherige Blitz3D/Draw3D2 nachdem die Mipmaps-Funktionen erstmal weg fallen.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Aug 15, 2010 19:12
Antworten mit Zitat
Benutzer-Profile anzeigen
So, hab mich schon bei einigen Dingen durchgeschlagen.

Graphics3D
LoadImage3D
DrawImage3D
DrawLine3D
DrawQuad3D
DrawRect3D


sind soweit aus der Blitz3D Draw3D2 funktionstüchtig portiert. Ich hänge nun bei folgendem Code:

BlitzMax: [AUSKLAPPEN]
Local L1:TDraw3D=TDraw3D.LoadImage3D("__.png")
Local G1:TDraw3D=TDraw3D.GrabImage3D(L1,16,16,32,32)


Type TDraw3D
Field TDrawPM:TPixmap
Field TDrawTH:Int 'TEXTURE
Field TDrawU1:Float 'U1/MAPPING
Field TDrawV1:Float 'V1/MAPPING
Field TDrawU2:Float 'U2/MAPPING
Field TDrawV2:Float 'V2/MAPPING
Field TDrawXS:Int 'X/DIMENS
Field TDrawYS:Int 'Y/DIMENS
Field TMatrix:Float[]


Function LoadImage3D:TDraw3D(FDrawName:String)


Local IDrawNew:TDraw3D=New TDraw3D

If FileType(FDrawName)=0 Then RuntimeError("LoadImage3D: <"+FDrawName+"> not found!")

IDrawNew.TDrawPM:TPixmap=ConvertPixmap(LoadPixmap(FDrawName),PF_RGBA8888)

IDrawNew.TDrawTH=GLTexFromPixmap(IDrawNew.TDrawPM,False)

glBindTexture(GL_TEXTURE_2D,IDrawNew.TDrawTH)

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_LOD,0)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LOD,0)

IDrawNew.TDrawU1=0
IDrawNew.TDrawV1=0
IDrawNew.TDrawU2=1
IDrawNew.TDrawV2=1

IDrawNew.TDrawXS=IDrawNew.TDrawPM.Width/2
IDrawNew.TDrawYS=IDrawNew.TDrawPM.Height/2

IDrawNew.TMatrix=[ ..
1.0,0.0,0.0,0.0, ..
0.0,1.0,0.0,0.0, ..
0.0,0.0,1.0,0.0, ..
0.0,0.0,0.0,1.0 ..
]

Return IDrawNew


End Function
Function GrabImage3D:TDraw3D(FDrawHD:TDraw3D,FDrawU1:Float,FDrawV1:Float,FDrawU2:Float,FDrawV2:Float)


Local IDrawNew:TDraw3D=New TDraw3D

' IDrawNew.TDrawPM':TPixmap
IDrawNew.TDrawTH=TDraw3D.FDrawHD
' IDrawNew.TDrawU1=FDrawU1/IDrawNew.TDrawPM.Width
' IDrawNew.TDrawV1=FDrawV1/IDrawNew.TDrawPM.Height
' IDrawNew.TDrawU2=FDrawU2/IDrawNew.TDrawPM.Width
' IDrawNew.TDrawV2=FDrawV2/IDrawNew.TDrawPM.Height
' IDrawNew.TDrawXS=IDrawNew.TDrawPM.Width/2
' IDrawNew.TDrawYS=IDrawNew.TDrawPM.Height/2
'
' IDrawNew.TMatrix=[ ..
' 1.0,0.0,0.0,0.0, ..
' 0.0,1.0,0.0,0.0, ..
' 0.0,0.0,1.0,0.0, ..
' 0.0,0.0,0.0,1.0 ..
' ]

Return IDrawNew


End Function
End Type

Ich möchte nun ein geladenes Bild dessen UV/Werte neu setzen und in ein eigenem Handle abspeichern. Das Referenzbild soll dabei das selbe bleiben.

Local L1:TDraw3D=TDraw3D.LoadImage3D("__.png")
Local G1:TDraw3D=TDraw3D.GrabImage3D(L1,16,16,32,32)


Aber irgendwie bekomme ich das Handle L1 nicht in GrabImage3D so rein, das ich damit weiter arbeiten kann. Also auf die Typeeinträge aus L1 in G1 übertragen kann.

Edit1:

Und eines wäre sehr hilfreich, wenn man Texturen skalieren könnte. Also das Pendant zu ScaleTexture wäre toll. Gibt es so einen Befehl bei OpenGL/BlitzMax?

mpmxyz

BeitragSo, Aug 15, 2010 20:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Du möchtest eine Pixmap skalieren?
Dann solltest du ResizePixmap nehmen.
Ist dein vorheriges Problem jetzt geklärt oder sehe ich das Problem nicht?
Edit: Mit "FDrawHD.TDrawPM" greift man z.B. auf auf die Pixmap des Originalobjektes zu. (Warum haben alle deine Objektvariablen ein T am Anfang und sind so aufgebläht?)
mfG
mpmxyz
PS: GrabImage3D wäre etwas angenehmer zu nutzen, wenn es eine Methode ist. ("TDraw3D" und ein Komma verschwinden.)
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

hectic

Sieger des IS Talentwettbewerb 2006

BeitragSo, Aug 15, 2010 20:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich will aber nicht ein bestehendes geladenes Bild zuschneiden, sondern einen eigenen Handle zu einem bestehendem Bild hinzu haben.

A=LoadImage3D( "Bild.png" )
B=GrabImage3D( A, 10, 10, 30, 30)
...
A.DrawImage3D( X1, Y1 )
B.DrawImage3D( X2, Y2 )


Aufgebläht sind die Variablennamen, weil ich zu jeder Art einen Bezeichner vergebe. Dann Draw, damit es zu keinen Kollisionen kommt. Auch wenn es hier zu keinen kommen kann. Ist wohl eine alte Angewohnheit.

- - -

Wie ziehe ich denn nun die Werte - also das Handle und die Pixmap - zu einem neuem Handle, damit das geladene Bild unberührt bleibt, das gegrabbte Bild auf die Oberreferenz zugreift?

Edit1:

ResizePixmap hab ich eben ausprobiert. Es ändert die Auflösung des Bildes. Ich möchte aber ein Pendant zu ScaleTexture haben. Das ändert die UV/Skalierung. Das heißt, man hat einen einfachen Weg statt von 0,0 -> 1,1 ein Bild über UV einzugrenzen, sondern von 0,0 -> Width,Height. Das macht restliche Berechnungen einfacher. Man dann auch komplett auf Integer umsteigen und muss nicht ständig mit 1/Usereingaben rumrechnen.

mpmxyz

BeitragSo, Aug 15, 2010 21:01
Antworten mit Zitat
Benutzer-Profile anzeigen
So würde ich eine Kopiermethode schreiben:
BlitzMax: [AUSKLAPPEN]
Method CopyImage:TDraw3D()
Local newImg:TDraw3D=New TDraw3D
newImg.TDrawPM=Self.TDrawPM 'CopyPixmap sollte hier genutzt werden, wenn sich Modifikationen an dem Originalbild nicht am neuen Bild bemerkbar machen sollen
newImg.TDrawTH=Self.TDrawTH 'Wenn oben CopyPixmap genutzt wurde, sollte hier auch ein neues OpenGL-Handle hin.
newImg.TDrawU1=Self.TDrawU1
'[...]
newImg.TMatrix=Self.TMatrix[..] 'array[..] kopiert das Array (ein Nebeneffekt von "Array Slicing")
Return newImg
EndMethod

Ob du nun eine Methode oder eine Funktion mit einem zusätzlichen Parameter schreibst, ist von der Funktionsweise gesehen ziemlich egal. (Self habe ich nur der Deutlichkeit halber genutzt und könnte weggelassen werden.)
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group