Pixelzugriff DDraw
-
Hallo,
also ich befasse mich seit kurzem mit DirectDraw (ja gut, ich weiß, dass Direct3d eigentlich viel besser wäre, aber für mich reicht erstmal DD).
Da gibt es ja beim C++ Builder einige Beispiele, mit denen ich auch schon andere Sachen zurecht gebastelt habe.
Also im Grunde funktioniert alles, Bild laden, Linien zeichnen etc. kein Problem.
Allerdings bereitet mit das Kopieren von Pixeln noch einige Kopfschmerzen, da die Funktionen GetPixel() und SetPixel() einfach mal viel zu langsam sind (ähnlich wie Canvas->Pixels[x][y]), da ich hab eine Funktion zum Drehen von Grafiken brauch, möchte ich gern wissen, wie solch ein Zugriff schneller zu realisieren ist.Bei folgendem Code erhalte ich immer einen Zugriffsverletzungsfehler (bei data[]...):
LPDIRECTDRAWSURFACE lpDDSBack; [...] //DDraw-Initilisierung etc. [...] ::DDSURFACEDESC bb; lpDDSBack->GetSurfaceDesc(&bb); unsigned long pitch = bb.lPitch; unsigned short* data = reinterpret_cast<unsigned short*>(bb.lpSurface); lpDDSBack->Lock(NULL,&bb,DDLOCK_WAIT,NULL); for(int y=0; y<300; y++) { for(int x=0; x<300; x++) { data[x + y*pitch] = RGB(255,0,0); } } lpDDSBack->Unlock(NULL);Ist denn der Ansatz überhaupt richtig?
-
Meine DDraw Erfahrungen liegen schon lange zurück. Aber vertausche mal Zeile 10 und 11. Was liefert die Lock Methode zurück?
-
Also vertauschen ändert nix.
Und Lock() liefert true zurück.
-
Dieser Thread wurde von Moderator/in Jansen aus dem Forum VCL/CLX (Borland C++ Builder) in das Forum Spiele-/Grafikprogrammierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Ich habe mal etwas in meinem Archiv gekramt und folgendes gefunden:
//Speicherzugriff DDSURFACEDESC2 Des; Des.dwSize=sizeof(Des); SystemAnzeige->Surface_SystemMenue->Lock(NULL,&Des,DDLOCK_WAIT,NULL); BYTE *Line; WORD *Dest; Line=(BYTE*)Des.lpSurface; for(int y=600; y < 700; y++) { Dest=(WORD*)Line; for(int x=600; x < 700; x++) { *Dest = (rand()%100 + 50) << 10; *Dest++; } Line+=Des.lPitch; } SystemAnzeige->Surface_SystemMenue->Unlock(NULL);Wenn ich die zugehörige Anwendung starte, dann ist links oben ein rauschendes Rechteck von ca. 100x100 Pixeln zu sehen. Frag aber nicht, warum oben x und y von 600 bis 700 laufen.
Sehr viel anders habe ich es vom Prinzip aber scheinbar auch nicht gemacht. Evtl. kannst du es ja mal 1:1 zum testen übertragen.
Ich kann das Projekt leider nicht neu übersetzten, da Bibliotheken fehlen ...Viel Erfolg
-
Super, danke, die Lösung funktioniert!
Das einzige, was aber daran noch komisch ist, ich erhalte, wenn ich beispielsweise x von 0 bis 200 durchlaufen lasse, nur ein 100Pixel breites Bild...
aber gut, Hauptsache, es klappt! danke nochmal!
-
Das ist nicht komisch. In dem Programm wird davon ausgegangen, dass ein Pixel 16 Bits braucht. Wenn er aber 32 Bits braucht, wird pro Durchlauf nur ein "halber Pixel" (R und G) bearbeitet.
-
Jut danke, sowas in der Art dachte ich mir schon. Stellt ja euch kein Problem dar.
-
BTW: das RGB() Makro kannst du nur verwenden wenn das Pixelformat genau passt. Bei 16 Bit oder "verdrehtem" 32 Bit kannst du das Makro so nicht verwenden. Da musst du erst selbst in das entsprechende Farbformat der Surface konvertieren.