...PixelFast auf TextureBuffer
Übersicht

![]() |
hecticSieger des IS Talentwettbewerb 2006Betreff: ...PixelFast auf TextureBuffer |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die letzten Tage habe ich an der Entwiklung der V.3.1 meiner Draw3D gearbeitet. In der neuen Version gibt es u.a. jetzt auch Set/Get-Pixel3D-Befehle, womit man eben auf einer Textur zeichnen oder aus dieser eben lesen kann. Mir fiel dabei ein Bug (oder ein Feature?) von Blitz3D auf. Wenn man eine geladene Textur einmal per LockBuffer lockt und gleich wieder per UnlockBuffer auslockt, dann kann man anschliessend immer schön weiter ReadPixelFast oder WritePixelFast -Befehle mit voller Speedunterstützung nutzen. Dabei ist es egal, wenn Renderworld dazwischen kommt oder nicht. Das gleiche funktioniert allerdings nicht mit Texturen die per CreateTexture erstellt wurden, da muss man schön brav vor jeden ...PixelFast -Befehl den Buffer locken und vor Renderworld wieder 'aus'locken.
Nun meine Fragen: - Wie kann ich Blitz3D das gleiche Fealing bei selbst erstellten Texturen geben, wie sie auch bei LoadTexture vorkommen? - Warum sind Pixeloperationen auf selbst erstellten Texturen gleicher größe schneller als auf geladenen Texturen, selbst mit gleichen Flags? Code: [AUSKLAPPEN] Graphics3D 512,512,0,2
SetBuffer BackBuffer() Local Camera=CreateCamera() PositionEntity Camera,0,0,-1 CameraClsColor Camera,64,64,64 Local Mesh%=CreateMesh() Local Face%=CreateSurface(Mesh) ;Local Texture%=CreateTexture(256,256,2) Local Texture%=LoadTexture("schall2.png",2) Local X%,Y%,ARGB% EntityTexture Mesh,Texture EntityFX Mesh,1+2+8+16 Local V0=AddVertex(Face,-1,+1,0 ,0,0) Local V1=AddVertex(Face,+1,+1,0 ,1,0) Local V2=AddVertex(Face,+1,-1,0 ,1,1) Local V3=AddVertex(Face,-1,-1,0 ,0,1) AddTriangle Face,V0,V1,V2 AddTriangle Face,V2,V3,V0 ;Wenn die Variable 'Texture' per LoadTexture erstellt wurde, ;dann reichen einmal die zwei Codezeilen aus, um im späteren ;Programmablauf auf Un/lockBuffer verzichten zu können. ;Das heisst, es funktionieren die PixelFast-Befehle ;auch ohne den Buffer zu 'locken' mit mehr Speed. LockBuffer TextureBuffer(Texture) UnlockBuffer TextureBuffer(Texture) ;Das gleiche gilt aber leider nicht mit CreateTexture, ;obwohl die gleiche Flags und weitere Angaben identisch ;sind. Wie lässt sich dieses nun am besten 'faken'? While Not KeyHit(1) ; LockBuffer TextureBuffer(Texture) For Y=0 To 255 Step 1 For X=0 To 255 Step 2 WritePixelFast X,Y,$FF000000+Rand(0,255)*$10000,TextureBuffer(Texture) Next Next ; UnlockBuffer TextureBuffer(Texture) RenderWorld Text 20,20,fps:msc=MilliSecs() If msc>mts Then mts=msc+1001:fps=frm:frm=0 Else frm=frm+1 Flip 0 Wend End Mir ist bewusst, dass es sich hierbei um ein Schlupfloch handelt welcher beim nächsten Update von Blitz3D wieder geschlossen sein kann. Aber bei einzelnen Pixeloperationen ist der Geschwindigkeitszuwachs gegenüber dem ständigem Buffer-ein/aus-locken mehr als man es vernachlässigen könnte. Wer Bedenken über ''sauberes Programmieren'' hat, sollte wissen dass er Recht hat, dieses Verhalten aber schon seit über 4 Jahren besteht. Mir ist auch bewusst, dass so ein Vorgehen auf endlos vielen Rechner getestet werden muss, bevor man sowas der Menschheit loslässt. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wer weiss, vielleicht ist dieses "Schlupfloch" mitschuld an den neuerlichen Problemen von Create und LoadTexture, dass die zwei befehle inkonsistente Resultate liefern ...
Mir persönlich würds sorgen machen, dass es auch ohne unlock weiterhin möglich ist ... weil das würde heissen, dass ein dublikat der textur erzeugt wurde auf dem rumoperiert wird oder die textur direkt voll dynamisch ist. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm, wie nun intern Texturen gehandhabt werden, weiß ich nicht. Dublikate könnte man aber mithilfe externer Programm austesten, indem man große Texturen läd und dann den Grafikspeicherverbrauch vergleicht... Dass Blitz3D aber seine eigenarten hat kann ich bestätigen. Zum Beispiel lässt sich nicht eine und die selbe Bilddatei zweimal auf unterschiedliche Variablen laden. Das ist dann nervig, wenn man mehrere Kacheln in einer Textur hat, aber diese mit unterschiedlichen Flags benötigt. Blitz3D verlinkt dann die zweite Bilddatei mit der ersten. Ist für absolute Noobs *Ich lade meine Textur in der Hauptschleife jede Schleife neu* eventuell vom Vorteil, aber nicht für mich. Grad bei der Draw3D wird es problematisch, den Leuten sowas zu erklären, dass sie pro Bilddatei nur einmal laden können. Also keine Tricks.
Bei dem ...PixelFast -Problem könnte man natürlich jedesmal eine Datei laden, welche man als Create ausgibt. Auch nicht so wirklich toll. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
ChristianK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
So spontan sind mir zwei Dinge eingefallen:
1. Bei LoadTexture wird der Buffer auch bei einem Aufruf von UnlockBuffer nicht entsperrt ( unwahrscheinlich, weil geladene und erstelle Texturen ja letztendlich gleich sind und DirectX in diesem Fall wohl einen Fehler melden würde ). 2. Mit LoadTexture geladene Texturen reagieren nicht auf Lock-/UnlockBuffer, sondern werden in Write-/ReadPixelFast automatisch gesperrt ( auch unwahrscheinlich, weil es ja sonst das gleiche ist wie Read-/WritePixel ). Wie sind denn die Geschwindigkeits-Unterschiede zwischen Create-/LoadTexture? |
||
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
hectic: Dass jede textur nur 1x geladen wird ist defakto für dich noch viel wichtiger als für bloody noobs. Denn es ist der grund warum Blitz3D so schnell ist trotz seiner DX7 Nutzung: Es kann die textur in einem go rendern. wenn du auch noch mehrere versionen davon hast würd das die verwaltung weiter erschweren, mehr texturbinds erfordern und performance kosten.
wenn du mehrere flags willst, würd ich jetz einfach ma so sagen, klingt das nach brush ... |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ChristianK, in meinem oben geposteten Code hat die Datei ''schall2.png'' die Abmessung 256x256, wie auch Createtexture 256x256. Beide werden mit Flag 2 geladen bzw. erstellt.
Pixeloperationen sind auf CreateTexture schneller wenn man, wie im Beispiel, viele pro Schleife macht, da das locken und unlocken auch Zeit benötigt. Wogegen bei LoadTexture die Pixeloperationen langsamer sind (egal ob lockbuffer und unlockbuffer benutzt wird). Wird aber zum Beispiel immer nur ein Pixel pro Schleifendurchlauf geändert, so ist LoadTexture schneller, weil man hier auf das locken verzichten kann. Der Geschwindigkeitsunterschied ist da so stark, dass man dann auch gleich ohne Fast Operationen durchführen kann, da es dann vergleichbar ist. @Dreamora, es geht mir nicht darum ob im Hintergrund ein Ablauf getätigt wird, der vom Vorteil ist. Sondern dass einfach so in die Programmstruktur eingegriffen wird, wo man es nicht erwarten würde. Wenn ich Variable = LoadTexture ("Texture", 2) mache, dann erwarte ich dieses auch, und nicht ein Link von wo anders. Das mit Brush ist so eine Sache. Ich bin extra vom Brush runter, weil ich mir per Texture mehr kompatibilität und mehr Speed erhoffte. Damit habe ich mir auch nicht unwesentlich mehr Arbeit im Bezug UV-Mapping gemacht. Das mit doppelt laden ist eben so eine Sache. Es kommt mal vor, dass man mal eine Kachel einer Textur in einem anderem Flag benötigt, während gleichzeitig andere Kacheln in anderer Flag benötigt werden. Dann läd man mal eben ein und die selbe Datei doppelt. Geht aber nicht. Warum soll dies aber schneller sein? Wenn ich nun eine Kopie meiner Textur mache und sie dann unter anderen Namen lade, bleibt doch gleich. Der einzige Geschwindigkeitsvorteil denn ich sehe ist, dass man dann eher auf kleinere Texturen mit kleinerer Kantenlänge kommen kann, was eben schneller bearbeitet werden kann. Auch dann wenn der ausgelesene UV-Bereich gleich groß sein sollte (kleine Texturen sind eben schneller). |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das System wurde, finde ich zumindest, aus zwei relativ simplen und einleuchtenden Gründen so gemacht:
1. Man braucht nix in Texturen zu speichern was man nicht braucht. Heisst man speicher net alpha rein um die textur dann mal mit und mal ohne Alpha zu laden, so als blödes beispiel. 2. Das wird von den meisten komischerweise DURCHGEHEND vergessen: Texturefilter Denn damit kann man seine Texturen entsprechend ihrer späteren Nutzung schon im Namen flaggen! Alpha Texture -> a_ vorne im namen Masked Texture -> m_ vorne im namen VRAM Texture -> v_ vorne im namen und kombinationen davon danach musst du garnimmer an den flags rumspielen und es wirkt sich auch gleich noch auf texturen aus die auf modellen sind so das du potentiell ohne modifikation von B3D Material Flags solche Dinge verändern kannst. Der Befehl ist gleichzeitig auch der Grund warum es nicht möglich ist 1 Texturname und 2 Filter settings zu haben, behaupte ich zumindest einfach mal so. Denn wenn die Textur einem filter entsprechen würde wäre sie automatisch immer das, egal mit was du sie nochma versuchen würdest zu laden -> massiver konflikt Aber es gibt da ja nen billigen Workaround: Temporäre kopie, laden, temporäre kopie wieder löschen ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group