Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

17.05.2012, 16:47

[DirectX 9] Sprites verschmieren - falsch skaliert?

Hallo Leute,

ich bin leider auf ein Problem gestoßen, das mich gerade etwas verzweifeln lässt. Ich möchte ein Bild in einer bestimmten Größe auf dem Bildschirm mittels eines Sprites darstellen.

Ich habe dazu eine Bilddatei in eine Textur (vom Typ LPDIRECT3DTEXTURE9) geladen und in der Render-Funktion meiner für das Sprite verantwortlichen Klasse sieht das Ganze dann so aus (Ich habe nicht die Code-Tags verwendet, die führten bei mir zu Darstellungsfehlern):

// get description of texture
D3DSURFACE_DESC desc;
texture->GetLevelDesc(0, &desc);

// apply scaling
D3DXMATRIX matScaling;
D3DXMatrixScaling(&matScaling, (double)this->rect.right / (double)desc.Width, (double)this->rect.bottom / (double)desc.Height, 0.0);

// render sprite
this->lpSprite->Begin(D3DXSPRITE_ALPHABLEND);
this->lpSprite->SetTransform(&matScaling);
this->lpSprite->Draw(
texture , &this->rect, NULL, NULL, D3DCOLOR_RGBA(255, 255, 255, 255));
this->lpSprite->End();

texture ist die LPDIRECT3DTEXTURE9, rect enthält die Größe des Sprites in Pixeln, bei einer Breite von 300px wäre rect.left = 0 und rect.right = 300. Was ich mache, ist, die Größe der Textur auslesen und dann entsprechend zu skalieren, indem ich das Verhältnis von der gewünschten und tatsächlichen Größe nehme. Anschließend zeichne ist das Sprite mit der passenden Transformation.


Das funktioniert auch. Mein Problem: wie auf dem Beispielbild unten zu sehen, verschmiert das Ganze fürchterlich nach rechts und unten und leider weiß ich nicht, was diesen Effekt verursacht. Hat jemand von euch den rettenden Tipp? :) Ich hätte erwartet, dass der Hintergrund komplett schwarz ist.


(Link)

FSA

Community-Fossil

  • Private Nachricht senden

2

17.05.2012, 17:23

BackBuffer gelöscht?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

3

17.05.2012, 17:37

Ich lösche den Target- und Z-Buffer, damit sollte der Back Buffer gelöscht sein.

Meine Render-Funktion (Auszug):


// Clear window and z-buffer to a given color
lpD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
lpD3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

// Begins the 3D scene (lock video memory)
lpD3DDevice->BeginScene();

// set the view transform
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, Cam->GetEye(), Cam->GetCenter(), Cam->GetUp());
lpD3DDevice->SetTransform(D3DTS_VIEW, &matView);

// set the projection transform
D3DXMATRIX matProjection; // the projection transform matrix
D3DXMatrixPerspectiveFovLH(&matProjection, D3DXToRadian(45), (FLOAT)ScreenWidth / (FLOAT)ScreenHeight, 1.0f, 10000.0f);
lpD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection);

// Ends the 3D scene (unlock video memory)
lpD3DDevice->EndScene();

// Displays the created frame
lpD3DDevice->Present(NULL, NULL, NULL, NULL);

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

17.05.2012, 19:06

Hinweis:
"Clear" kann in einem Rutsch sowohl Back-Buffer als auch Z-Buffer leeren.
Einfach D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER übergeben.

Sieht das sofort so aus oder bewegt sich da irgendwas?
Sieht aus als ob die Texturkoordinaten aus dem Sprite herausgehen und der "Clamp"-Modus für die Texeladressierung aktiviert ist.
Sagt dir das irgendwas?

5

17.05.2012, 19:14

Das sieht sofort so aus. Ich habe auch testweise ein Bild über den ganzen Bildschirm zeichnen lassen und danach eins über einen Teil des Bildschirms. Das Resultat war, dass das Bild, das eigentlich nur einen Teil des Bildschirms füllen sollte, den ganzen Bildschirm gefüllt hat - so, wie auf dem Bild in meinem Ausgangspost.

Das letztere sagt mir leider nichts, bedaure.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

17.05.2012, 19:15

Sieht mir aus als ob da die Texcoords geclamped werden...
Wie lädst du die Textur und welche Abmessungen hat das Bild in der Datei und die Surface und wie groß ist das Rect das du dem Sprite gibst?

7

17.05.2012, 19:59

Laden der Texturen:


void HUD::AddTexture(LPDIRECT3DDEVICE9 Device, std::wstring FileName)
{
LPDIRECT3DTEXTURE9 lpTexture = NULL;
D3DXCreateTextureFromFile(Device, FileName.c_str(), &lpTexture);

this->lpTextures.push_back(lpTexture);
}


Größe der Original-Bilddatei: 665 x 375 px

Zielgröße: 1380 x 750 px

Das Problem trat auch bei anderen Bildern mit verschiedener Original- und Zielgröße aus. Es war immer mindestens ein einer der beiden Dimensionen verzerrt.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

17.05.2012, 20:56

Antworte mal auf meine Frage.

9

18.05.2012, 07:36

Das habe ich doch?!? Ich habe geschrieben, dass das bereits zu Beginn so aussieht und mir das mit dem Clampen nichts sagt.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

10

18.05.2012, 09:48

Sorry, hatte nur den unteren Post gelesen. :wacko:

Kannst du das Problem in einem möglichst kurzen Programm reproduzieren?
Schmeiß mal Schritt für Schritt alles andere raus, bis du am Ende nur noch ein paar Zeilen hast, die das Problem zeigen.

Werbeanzeige