LockRect -> invalid call
-
ich MUSS nicht unbedingt im backbuffer malen, aber im buch ist es so beschrieben, weshalb ich es erstmal so machen wollte. Aber ich habe grad ne andere idee gepostet. Ich weiß allerdings nicht, was du mit nem overhead meinst, kannst du mir das noch erklären? hab grad erst mit grafik programmierung angefangen. Habe aber solide c/c++ kenntnisse, sowie noch kenntnisse in diversen anderen sprachen.
-
DX SDK Doku schrieb:
Set this flag if the application requires the ability to lock the back buffer directly. Note that back buffers are not lockable unless the application specifies D3DPRESENTFLAG_LOCKABLE_BACKBUFFER when calling IDirect3D9::CreateDevice or IDirect3DDevice9::Reset. Lockable back buffers incur a performance cost on some graphics hardware configurations. Performing a lock operation (or using IDirect3DDevice9::UpdateSurface to write) on the lockable back buffer decreases performance on many cards. In this case, consider using textured triangles to move data to the back buffer.
-
BTW, das Programm lautet Sternenfeld. Einfach schwarzer hintergrund und ein paar sterne die von oben runter fallen. Also in jedem frame backbuffer locken sterne zeichnen backbuffer freigeben, fertig. so die theorie^^
-
Warum die Sterne nicht als Pointlist malen?
-
@dot: vielen dank, also habe ich hustbaer unrecht getan, sry deswegen. kann es sein, dass mein buch trotz guter referenzen schlecht ist? ist nicht die erste inkonsistenz die ich entdecke.
-
weil es mir jetzt noch nur darum geht die funktionen von directX kennen zu lernen. Das ergebnis bzw die effizienz des lösungsweges ist mir noch nicht so wichtig^^ aber pointlists hören sich nach nem netten lösungsansatz an.
Hab soweit ne liste von sternen, die sich quasi selbst in den buffer zeichnen sollen. wenn alle sterne sich reingezeichnet haben, soll der buffer wieder freigegeben werden.
-
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...