LockRect -> invalid call
-
So, ich habe es erstmal mit deinem flag versucht, das klappt aber nicht. Immer noch der gleiche Fehler und mein struct wird einfach nicht gefüllt, ergo erhalte ich werde nen pitch noch pixeldaten. Ich werde morgen mal schauen, dass ich die meine Version mit dem zusätzlichen buffer versuche, allerdings finde ich das reichlich umständlich. Ich kann mir nicht vorstellen, das ein Buch derartig falsche Informationen vermittelt. Allerdings bin ich mir wirklich sicher, dass der backbuffer richtig ermittelt wurde und sonst kann von meiner Seite aus, mal abgesehen von dem Flag, mit dem es allerdings auch nicht klappt, nichts verkehrt gelaufen sein. Wenn noch jemand ne idee hat würde ich mir die gerne durchlesen^^
Bis bald euer shane
-
Ich seh grad, dass der Invalid Call Error weg ist. Das ist en riesen fortschritt, allerdings habe ich scheinbar keine zugriffsrechte auf den buffer speicher. Ist LockRect zufällig defaultmäßig ReadOnly geflaggt?
-
Was genau heißt du hast keine Zugriffsrechte?
-
shane_da_progga schrieb:
@dot: vielen dank, also habe ich hustbaer unrecht getan, sry deswegen.
wo?
hab nix davon bemerkt.und meine aussage war eh topfen. es geht ja wohl doch, mit diesem flag eben.
sorry BTW fürs unsinn posten.
-
Naja deine Aussage war vielleicht nicht ganz korrekt weil es doch einen Weg gibt, aber ohne das Flag gehts nicht und abgesehen davon will man den Backbuffer sowieso nie locken weil das nie ne gute Idee ist
-
Hab drüber geschlafen und mir klar gemacht, dass es echt keine gute idee ist den backbuffer zu locken
Allerdings finde ich es ein wenig enttäuschend, dass dieses Buch, welches immerhin von Markt+Technik ist, so nen unsinn macht, zumal nicht auf den zusätzlichen Flag eingegangen wird, aber da ich die cd nicht mehr finde, kann ich nicht sagen, ob der quellcode auf eben dieser nicht vielleicht doch korrekt ist.
Also der Backbuffer wird gelockt und Pitch sowie Pixelfeldzeiger gesetzt, aber sobalb ich ein Pixel verändern will krieg ich nen Zugriff verweigert, wenn ich das richtig verstehe von VC++, aber ich poste die Zeile einfach mal:
Eine Ausnahme (erste Chance) bei 0x00c92187 in HalloWindows.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x01de8a90.
Unbehandelte Ausnahme bei 0x00c92187 in HalloWindows.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x01de8a90.Etwas suspekt. Ich habe mich jetzt gegen die backbuffer variante entschieden und werde stattdessen eine PlainSurface erzeugen, darauf meine Pixeldaten setzen und die PlainSurface dann auf meinen backbuffer kopieren, oder ich versuche es mit der PointList Methode, welche sich auch sehr interessant anhört, zumal mir da, soweit ich richtig liege, ne zusätzliche PlainSurface erspart bleibt.
Thx so far
euer Shane
-
Langsam bin ich etwas genervt
Jetzt habe ich nen OffscreenPlainSurface erzeugt, versuche darauf zu malen, aber auch da bekomme ich die selbe Fehlermeldung.
Wenn ich keinen Zugriff auf den BackBuffer hab, ok, kann ich auch drauf verzichten da direkt Pixelarbeiten zu erledigen, aber zumindest auf nem OffscreenPlainSurface sollte es doch möglich sein.
Wenn einer ne Idee hat was mir den Zugriff versaut, dann wär ich um jeden Ratschlag froh^^
Thx so far
euer Shane
-
Ich werd mal Ausführlicher, vielleicht hilft das ja.
Als erstes das Device anlegen://Direct3D-Gerät anlegen HRESULT hr; if(FAILED(hr = m_lpD3D->CreateDevice( D3DADAPTER_DEFAULT, //verwende die primäre Grafikkarte D3DDEVTYPE_HAL, //verwende Hardwareunterstützung hWnd, //Fensterhandle D3DCREATE_SOFTWARE_VERTEXPROCESSING, //Softwareemulierte Vertexberechnung &PParams, //Backbuffereigenschaften &m_lpD3DDevice))) //Struktur zum ablegen der Deviceinformationen { //Fehler, kann Gerät nicht anlegen const char *Err = DXGetErrorDescription(hr); DXTRACE_MSG(Err); return FALSE; }
PParams ist wie folgt festgelegt:
//Parameter für den Modus festlegen D3DPRESENT_PARAMETERS PParams; //Struktur zum festlegen der Backbuffereigenschaften ZeroMemory(&PParams, sizeof(PParams)); //Allokiert Speicher für das obige Struct PParams.SwapEffect = D3DSWAPEFFECT_DISCARD; //Backbuffer auf schnellst mögliche Art anzeigen PParams.hDeviceWindow = hWnd; //Fensterhandle PParams.Windowed = bWindowed; //Vollbild = FALSE, Fenster = TRUE PParams.BackBufferWidth = SCR_WIDTH; //horizontale Auflösung PParams.BackBufferHeight = SCR_HEIGHT; //vertikale Auflösung PParams.BackBufferFormat = D3DFMT_A8R8G8B8; //Farbtiefe bestimmen, hier 32bit (8bit alpha, 8bit rot, 8bit grün, 8bit blau)
So, jetzt den OffscreenPlainSurface:
//OffscreenPlainSurface erzeugen if(FAILED(hr = m_lpD3DDevice->CreateOffscreenPlainSurface( SCR_WIDTH, SCR_HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_lpOffscreenPlainSurface, 0))) { const char *Err = DXGetErrorDescription(hr); DXTRACE_MSG(Err); return FALSE; }
SCR_WIDTH und SCRHEIGHT sind Makros für die Auflösung. in meinem fall 800x600@32bit, (@32bit)wie man den Flags entnehmen kann.
Jetzt versuch ich den OffscreenPlainSurface zu Locken:
D3DLOCKED_RECT LockedRect = {0}; //Oberfläche für direkten Zugriff sperren HRESULT hr; if(FAILED(hr = lpSurface->LockRect(&LockedRect, 0, 0))) { const char *Err = DXGetErrorDescription(hr); DXTRACE_MSG(Err); }
Es wird kein Fehler ausgegeben, ergo hat das locken geklappt.
dann pitch berechnen und drauf zeichnen:int Pitch = LockedRect.Pitch / 4; D3DCOLOR* Pixels = (D3DCOLOR*)LockedRect.pBits; ... //Position für den Stern berechnen int index = ((int)m_y * Pitch + (int)m_x); //Länge berücksichtigen und Farbe wählen for(int i=0; i<m_Length; i++) { Pixels[index + i * Pitch] = StarColors[i]; }
So, hier ist Zeile 10 das Problem.
Sobald ich hier in das Pixelfeld schreiben will krieg ich die folgende Fehlermeldung:Eine Ausnahme (erste Chance) bei 0x00dd2207 in HalloWindows.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x04de8a90.
Unbehandelte Ausnahme bei 0x00dd2207 in HalloWindows.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x04de8a90.Die Adressen sind naürlich immer andere, aber immer relativ zum Adressraum des Pixelfeldes.
Vielleicht hilft euch das ja mir zu Helfen^^
Weiß echt nicht, wo ich noch einfluss auf Zugriffsrechte habe, die werden doch eigentlich drch das Betriebssystem gesetzt. In meinem Fall Vista. IDE ist Visual C++ 2008 Express Edition. DirectX ist June 2010.thx so far
euer Shane
-
Hab grad noch den Versuch unternommen, das ganze im Vollbildmodus laufen zu lassen, weil im Fenstermodus evtl. irgendwelche rechte nicht gegeben waren, aber da funktioniert es auch nicht. Im nachhinein auch logisch, aber ein versuch war es mir wert. Im Vollbildmodus schmiert auch vc++ irgendwie ab und man kann nicht mal mehr zwischen den Fenstern hin und her schalten. das einzige was da funktioniert hat war das ausführen des Taskmanagers via STRG+ALT+ENTF. Glaub ich ein fehler von VC++ 2008.
thx so far
euer Shane
-
Was mir beim schnellen Überfliegen mal auffällt: Der Pitch ist die Anzahl der Bytes pro Zeile, nicht der Pixel...
-
richtig, deswegen teile ich ihn durch die Farbtiefe, um ihn auf die anzahl der Pixel pro Zeile zu bringen, da 32bit farbtiefe = 4 byte, ist pitch / 4 = anzahl der pixel in jeder zeile.
-
Hm ok übersehen sry. Ich würd mich aber nicht drauf verlassen dass der Pitch immer ein vielfaches von 4 ist...
Wo machst du eigentlich dein UnlockRect()?
-
der pitch ist doch abhängig von der Farbtiefe, die ich im falle meines programmes auf 32bit festgelegt habe. sowohl der backbuffer als auch mein offscreenplainsurface haben 32bit.
UnlockRect habe ich hier nur nicht mit aufgeführt. im programm stehts, aber da kommt der nie hin, weil er beim schreiben der pixeldaten hängen bleibt.
-
Der Pitch hängt natürlich mit der Farbtiefe zusammen er ist aber nicht notwendigerweise einfach Breite * sizeof(Pixel), dann bräuchte man ja keinen extra Pitch oder?
. Je nachdem wie die Graka das Ding im Speicher alignen will etc. kann der Pitch einfach irgendwas sein...
Wegen dem UnlockRect(): Wollte nur sichergehen dass es auch nach dem Schreiben steht und nicht davor...
-
Das UnlockRect kommt auch definitiv nach dem Schreiben.
Hm, wegen dem Pitch. Soweit ich weiß gibt es den, weil noch additionale informationen zu den Pixeln gespeichert werden. Demnach gibt der Pitch die Zeilen Länge inclusive der additionalen infos in byte an.
Ist meine berechnung bezüglich des Pitch und die anschließende adressierung mit dem neuen pitch verkehrt?
-
shane_da_progga schrieb:
Ist meine berechnung bezüglich des Pitch und die anschließende adressierung mit dem neuen pitch verkehrt?
Sie basiert auf der nicht notwendigerweise korrekten Annahme dass der Pitch ein Vielfaches von 4 ist. Aber naja, üblicherweise ist das der Fall, also wird er Fehler eher nicht dort zu suchen sein...
-
Nun, ich habe mir selber nicht besonders viele gedanken zu dem Pitch gemacht, da ich der annamhme war, wdas dieser im Buch korrekt berechnet wird.
Aber mal angenommen er ist falsch berechnet, wie berechne ich den Pitch dann so, dass ich in als offset in meiner adressierung benutzen kann? Ich meine, wie finde ich raus, inwieweit er nun von meiner farbtiefe abhängig ist oder nicht.
Da ich im prinzip nichs anderes falsch machen kann, ist das meine einzige hoffnung^^
es sei denn, dass irgendwelche flags gesetzt werden müssen, auf die das buch, aus gründen der nicht-kompetenz, nicht eingegangen ist.
Ich finds echt schade, dass der code aus dem buch fehlerhaft ist.
-
Wo liegt das Problem? Der Pitch ist die Anzahl an Bytes die eine Zeile belegt. Das ist alles. Um zur nächsten Zeile zu gelangen spul einfach um Pitch Bytes vor und nicht Pitch / 4 DWORDs...
-
um einzelne pixel zu adressieren ist es notwendig das entsprechende byte in der zeile zu ermitteln, da muss ich den pitch früher oder später teilen.
-
Nein musst du nicht. Einzelne Pixel adressierst du mit x und y Koordinaten. Die y Koordinate entspricht der Zeile. y * Pitch gibt dir damit den Byteoffset von pBits zum Zeilenanfang. Und von dort gehst du dann x * sizeof(Pixel) (in deinem Fall also x DWORDs) weiter um zu deinem Pixel zu gelangen. An deiner Stelle würd ich sowieso mal diese ganze komische Indexberechnung da überprüfen, höchstwahrscheinlich liegt der Fehler eh dort. Check mal ob das was du da ausrechnest überhaupt noch in der Surface drinnen liegt...