| |
|
|
Sven Bader | cela jongler avec Datentypen peux im Alltag nerven. Zum besseren Verständnis pour mich selbst habe je quelque chose avec Rückgabewerten de OpenGL herumgespielt. Dankenswerterweise peux on là toujours entre Float, Double et Integer choisir. avec 32-Bit Floats peut ältere XProfan Versionen seulement einmal rien anfangen mais aussi cela bekommt on hin!
Im Beispiel frage je qui maximale Taille pour une gezeichneten Punkt ab. Zurück venez qui Adresse eines Arrays avec deux Werten, mich intéressé jeweils qui 2. Wert. chez meiner Grafikkarte incidemment 189.875
j'ai Procs et Assembler Funktionen geschrieben, um cela interne Float() et Long() trop ersetzen. Letztendlich tue je m piège de Float 7x cela gleiche sur unterschiedlichen à cause de.
c'est mon erster excursion trop Assembler, weshalb qui Kommentare am Code et avec ca maladroit sommes. Letztendlich ist es oui c'est ca pour solche grenier-Schubsereien ideal. Schneller comme ses Vorbilder long() et float() sommes qui Funktionen NICHT geworden.
Fazit: Über den Lerneffekt hinaus sommes folgende Wege qui einfachsten et pas langsamer comme qui ASM Code:
Verarbeitung eines 32-Bit Floats aus einem externe Aufruf mithilfe de long et double: float! = double(integer&) bzw. comme Bereich float! = double(long(bereich#,0)) Alternativ ab XProfan X2, avec dem Datentyp Single travailler.
Verarbeitung eines 64-Bit Floats (Double) aus einem externe Aufruf: direct, sans Konvertierung bzw. comme Bereich float! = float(bereich#,0)
Verarbeitung eines 32-Bit Integers aus einem externe Aufruf: direct, sans Konvertierung bzw. comme Bereich integer& = long(bereich#,0)
chacun Variable et Arrays peut comment un Bereich verwendet volonté avec Addr(): long(Addr(integer&[0],4) ist cela gleiche comment integer&[1], alors un Integer chez Adresse des ersten Array-Elements + 4 Byte.
avec Speicheradressen (Bereichsvariablen # et addr()) peux gerechnet volonté: long(bereich#,4) ist cela gleiche comment long(bereich# + 4,0)
Beim Herumspielen avec Speicheradressen muss on bien sûr aufpassen, là on einerseits vite sur deklarierte Bereiche hinausschießt ou bien sogar Werte avec Speicheradressen verwechelt et irgendwo im grenier landet.
Cls
Déclarer sizeRangeFloat#, sizeRangeInteger#, float!,sizeRangeArray![2],integerArray&[2]
Déclarer single singleArray[2]' cela allez seulement depuis X2
Faible sizeRangeFloat#, 16'2 Werte je 8 Byte
Faible sizeRangeInteger#, 8'2 Werte je 4 Byte
oGL("Init", %hWnd, 1,1,1,1)
oGL("glGetDoublev", ~GL_POINT_SIZE_RANGE, Addr(sizeRangeArray![0]))
oGL("glGetDoublev", ~GL_POINT_SIZE_RANGE, sizeRangeFloat#)
oGL("glGetFloatv", ~GL_POINT_SIZE_RANGE, Addr(singleArray[0]))'cela allez seulement depuis X2
oGL("glGetFloatv", ~GL_POINT_SIZE_RANGE, Addr(integerArray&[0]))'Trick pour ältere Profan-Versionen, es folgt double()
oGL("glGetIntegerv", ~GL_POINT_SIZE_RANGE, sizeRangeInteger#)
oGL("Done")
Proc procLong
Paramètres a#, shift&
'dans Tests pas toujours korrekt
Retour ( (Byte(a#+shift&,3) << 24) | (Byte(a#+shift&,2) << 16) | (Byte(a#+shift&,1) << 8) | (Byte(a#+shift&,0)) )
ENDPROC
ASM "asmFloat2", 3
mov ecx, par1'par1 pour ecx
mov ebx, par2'par2 pour ebx
mov eax, [ebx]'par2 pour eax
mov [ecx], eax' eax pour par1
add ecx, 4' par1 Adresse + 4
mov edx, par3' par2 pour edx
mov eax, [edx]' par3 pour eax
mov [ecx], eax' eax pour par1
ENDASM
ASM "asmFloat", 2
mov eax, par2'par2 pour eax
mov edx, [eax]'4-Byte par2 (offset 0) pour edx schieben
mov eax, par1'par1 pour eax (Speicheradresse qui but Float-Variable)
mov [eax], edx
mov eax, par2'par2 pour eax
add eax, 4'Adresse + 4
mov edx, [eax]
mov eax, par1
add eax, 4'Adresse + 4
mov [eax], edx' eax (maintenant+4) dans par1 Sauver
ENDASM
'cet Funktion tut eigentlich rien:
'vous gibt cela heraus, quoi on hineingeworfen hat
ASM "asmLong", 1
mov ecx, par1'par 1 pour ecx
mov eax, [ecx]'et inchangé ausgeben
ENDASM
'cet Funktion tut eigentlich rien:
'vous gibt cela heraus, quoi on hineingeworfen hat
ASM "asmLong2", 2
mov ecx, par1'par 1 pour ecx
mov ebx, par2'par 2 pour ebx
add ecx, par2'par 1 (ecx) et par2 addieren
mov eax, [ecx]'ausgeben
ENDASM
Def MoveMemory(3) !"kernel32.dll","RtlMoveMemory"
Proc procFloatMoveMemory
Paramètres dest!, source#
MoveMemory(addr(dest!),source#,8)
Retour dest!
ENDPROC
Proc procFloatLongLong
Paramètres dest!, source#
Long addr(dest!),0 = long(source#,8),long(source#,12)
ENDPROC
Imprimer "\nFloats:"
'Offset jeweils chez Byte 8, c'est qui zweite Array-Wert
'Float() Assembler-variante
asmFloat(addr(float!), sizeRangeFloat# + 8)'directe Zuweisung allez malheureusement Aufgrund de 32-Bit Paremetern pas
Imprimer float!
'Float() comme interne XProfan-Funktion
Imprimer Float(sizeRangeFloat#,8)
'Float() comme Proc avec deux long()
procFloatLongLong(float!,sizeRangeFloat#+8)'directe Rückgabe pas possible, sauf avec float() et cela sollte oui plan ersetzt volonté ;-)
imprimer str$(float!)
'Float() comme Proc avec MoveMemory
Imprimer procFloatMoveMemory(float!, sizeRangeFloat#+8)'Zuweisung possible mais qui Variable im 1. Paremeter wird dans chaque le cas aussi beschrieben
'Wert aus Array (1 = zweiter Wert, là es de 0 startet)
Imprimer sizeRangeArray![1]'Zuweisung possible mais qui Variable im 1. Paremeter wird dans chaque le cas aussi beschrieben
'Wert aus Single-Array (32-Bit), Datentyp ab X2 disponible
Imprimer singleArray[1]
'Wert aus Integer-Array (32-Bit) comme Double intepretiert. cela allez aussi avec älteren Profan Versionen
Imprimer double(integerArray&[1])
Imprimer "\nIntegers:"
'Long() comme Proc
Imprimer procLong(sizeRangeInteger#,4)'pas toujours korrekt...
'Long() comme interne XProfan-Funktion
Imprimer Long(sizeRangeInteger#,4)
'Long() Assembler-variante dans einem paramètre (Adress-Offset muss selbst addiert volonté)
Imprimer asmLong(sizeRangeInteger# + 4)
'Long() Assembler-variante avec 2 Parametern, Offset peux comment dans qui originalen Funktion transfert volonté
Imprimer asmLong2(sizeRangeInteger#, 4)
Dispose sizeRangeFloat#
Dispose sizeRangeInteger#
WaitKey
Fin
|
|
|
| |
|
|