JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=36a11128562c9dc11ae3db847a24941fMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

[DirectX] Sprites werden ungewollt skaliert

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Fragen, Antworten und Kritik
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
piv0
Mini JLI'ler



Anmeldedatum: 04.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 12:52    Titel: [DirectX] Sprites werden ungewollt skaliert Antworten mit Zitat

Hallo miteinander,

Ich habe mir neulich das Buch "Jetzt lerne ich DirectX 9 und Visual C++ gekauft, bin eigentlich auch recht zufrieden damit. Jedoch habe ich ein Problem. Ich habe es bereits in einem anderen Forum gepostet
( http://www.c-plusplus.de/forum/viewtopic-var-t-is-163506-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html ), jedoch konnte mir dort nicht geholfen werden.

Nämlich werden meine Sprites in meinem Programm skaliert, ohne dass ich das möchte bzw. obwohl ein Skalierungsfaktor von 1.0 angegeben ist.
Ich habe dazu ein kleines gif erstellt, welches mein Problem verdeutlicht. Zu sehen ist mein entstehendes Schachspiel. Ein Frame zeigt das tatsächliche Erscheinungsbild (das mit den Figuren und dem 'Hallo'), das andere ist ein (mit Bildbearbeitung) erstelltes Bild 'so wie es sein soll'.
Das Hellblau ist die ClearColor.
http://mitglied.lycos.de/krazzomat/schach.gif

In meinem Büchlein steht geschrieben, dass so etwas (ähnliches?) passiert wenn man eine Textur mit Kantenlänge ungleich einer 2er Potenz wählt.. Nungut, dann habe ich eben meine Schachbretttextur auf die Größe von 512x512 Px vergrößert. Jedoch mit dem gleichen Ergebnis. (siehe gif)

Außerdem ist mir aufgefallen, dass wenn ich bei einem Beispielprogramm aus dem Buch, die anwendung von Fullscreen auf ein Fenster umstelle, dass dann ebenfalls die Texturen gestaucht werden und verschwimmen.

Mein Verdacht: es muss irgendwas mit dem Fenster(modus?) zu tun haben, oder irgendwelche Eigenschaften des Fensters betreffen.

Ich hoffe ihr könnt mir weiterhelfen und freue mich auf Antworten.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
KI
JLI Master


Alter: 39
Anmeldedatum: 04.07.2003
Beiträge: 965
Wohnort: Aachen
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 13:29    Titel: Antworten mit Zitat

Bei den Beispielen im Buch könnte ich mir vorstellen, dass die Client-Area des Fensters (der Bereich auf dem gezeichnet wird) zu klein ist. (Also kleiner als die Auflösung des Backbuffers)

Zu deinem Problem. Ich wüsste es jetzt auch nicht. Kannst du mal ein Minimalbeispiel mit deinem Problem machen und zum Download anbieten?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
piv0
Mini JLI'ler



Anmeldedatum: 04.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 13:36    Titel: Antworten mit Zitat

Naja mein Programm basiert ja auf einem Beispielprogramm Smile

Ehrlichgesagt weiß ich noch nicht recht wie ich mein "Spiel" zu einer finalen Version kompiliere in der alle Dateien (Quellen, Header etc) drinstecken. Wenn ich das mit Visual C++ Authoren Version kompiliere kommt eine .exe und jede Menge Dateien raus, wie .obj uvm..

Ich werde jetzt mal den Code durchsehen ob ich mit deinem Tipp mit der Client-Area was anfangen kann.

Danke für deine Mühe
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
KI
JLI Master


Alter: 39
Anmeldedatum: 04.07.2003
Beiträge: 965
Wohnort: Aachen
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 13:56    Titel: Antworten mit Zitat

Die Größe der Client-Area kannst du am besten per Screenshot und Augenmaß herausfinden.

Wenn du nämlich ein Fenster mit der Größe 800 * 600 erstellst, ist der Client-Bereich etwas kleiner, weil in den Bereich von 800*600Pixeln auch noch Fensterrahmen und Titelleiste Platz finden müssen.

Um so etwas zu vermeiden und den Client-Bereich so groß zu bekommen, wie den Backbuffer muss man also das Fenster etwas größer machen.
AdjustWindowRectEx hilft einem dabei wieviel größer.

Beispielcode:
CPP:
   // Fensterklasse registrieren und Hauptfenster erstellen
   LPCSTR pWndClass = "WindowClass";

   WNDCLASSEX wcex;

   wcex.cbSize        = sizeof(WNDCLASSEX);
   wcex.style         = CS_HREDRAW | CS_VREDRAW;
   wcex.lpfnWndProc   = (WNDPROC)MessageHandler;
   wcex.cbClsExtra    = 0;
   wcex.cbWndExtra    = 0;
   wcex.hInstance     = hInstance;
   wcex.hIcon         = LoadIcon(/*hInstance*/NULL, (LPCSTR)IDI_WINLOGO);
   wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
   wcex.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_APPWORKSPACE);
   wcex.lpszMenuName  = NULL;
   wcex.lpszClassName = pWndClass;
   wcex.hIconSm       = NULL;

   if(!RegisterClassEx(&wcex))
   {
      MessageBox(NULL, "Konnte Fensterklasse nicht registrieren!", "Allgemeiner Programminitialisierungsfehler", MB_ICONERROR);

      return 0;
   }

   HWND hWnd;

   RECT rc;
   rc.left = 0;
   rc.top = 0;
   rc.right =uWidth; // uWidth ist die Breite des Backbuffers
   rc.bottom =uHeight; // hier die Höhe
   AdjustWindowRectEx(&rc,WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_BORDER|WS_MINIMIZEBOX,FALSE,0);

   hWnd = CreateWindow(
      pWndClass,
      "Fenstertitel",
      WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_BORDER|WS_MINIMIZEBOX,
      CW_USEDEFAULT,
      0,
      (rc.right - rc.left),
      (rc.bottom - rc.top),
      NULL,
      NULL,
      hInstance,
      NULL);
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
piv0
Mini JLI'ler



Anmeldedatum: 04.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 14:18    Titel: Antworten mit Zitat

Ja okay, also ich hab mein Fenster mit Pixelzählen aufm Screenshot so groß gemacht, dass genau ein 512² Bild reinpasst.
Muss ich das dann auch noch machen, mit dem rc.top und so, ich meine das ist eleganter als meine Pixelzählmethode, klar, aber mir geht es jetzt eigentlich nur im mein Problem..

Zu dem BackPuffer; meiner ist auf die Fenstergröße ausgelegt:
CPP:
// Direct3D initialisieren
BOOL CDirect3D::Init(HWND hWnd, BOOL bWindowed)
{
    // Direct3D-Objekt erzeugen
    m_lpD3D = Direct3DCreate9(D3D_SDK_VERSION);

    if(NULL == m_lpD3D)
    {
        // Fehler, D3D-Objekt wurde nicht erzeugt
        return FALSE;
    }

    // Parameter für den Modus festlegen
    D3DPRESENT_PARAMETERS PParams;
    ZeroMemory(&PParams,sizeof(PParams));

    PParams.SwapEffect       = D3DSWAPEFFECT_DISCARD;
    PParams.hDeviceWindow    = hWnd;
    PParams.Windowed         = bWindowed;

    PParams.BackBufferWidth  = SCR_WIDTH;
    PParams.BackBufferHeight = SCR_HEIGHT;
    PParams.BackBufferFormat = D3DFMT_A8R8G8B8;

    HRESULT hr;
.
.
.

und eben mit SCR_WIDTH und SCR_HEIGHT, so wie ich es brauche um ein 512x512 Bild darin unterzubringen (siehe auch das gif im ersten Post..)

Also sind Backpuffer und Client Area doch gleich, oder?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 18:52    Titel: Antworten mit Zitat

Jo, normalerweise schon.
Am einfachsten wäre es, du benutzt einfach Vollbildmodus.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
piv0
Mini JLI'ler



Anmeldedatum: 04.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 22:41    Titel: Antworten mit Zitat

Noch einfacher wäre es wenn ich das Buch in die Ecke schmeiße ebenso wie mein Spiel.. Smile

Nunja, Vollbildmodus finde ich einfach unangebracht für so ein kleines Spielchen; das soll nebenbei gespielt werden (wenn überhaupt, wie ihr merkt geht es mir eigentlich ums Prinzip, ich will eben auch Fenster machen können..)

Ich glaube das ganze ist ein ganz kleiner Fehler.. aber irgendwie will das einfach nicht so funktionieren wie ich das möchte..
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 23:17    Titel: Antworten mit Zitat

Ist das Problem den so schlimm?

Also an sich ist die Sache ja klar:
Du sagst DX meinetwegen, es soll auf einer Größe von 640x480 Pixeln arbeiten.
Du sagst DX, es solle dein Windows fenster benutezn.
DX verändert die Windowsfenstergröße nicht.
DX benutzt nicht das ganze Fenster, sondern den Teil der von Rand und Titelleiste noch frei bleibt.

Jetzt haste aber einen konflikt, da du DX gesagt hast, es solle 640x480 Pixel große Oberfläche haben, du aber meinetwegen eine 520x400 große Oberfläche gegeben hast.

Das resultat ist einfach, das DX dann alles so umrechnet, das es auf diese Größe passt. Ist das Anwendungsfenster also kleiner, wird auch deine komplette Ausgabe kleiner.
Umgekehrt wird sie eben größer.

Eigentlich ganz logisch.

So, um das zu umgehen, musst du an DX die Größe des beschreibbaren Bereichs übergeben.

Dazu gabs mal ne Windowsfunktion, weiß die aber nicht mehr.

Auf jeden Fall, solltest du deswegen nciht aufgeben.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
KI
JLI Master


Alter: 39
Anmeldedatum: 04.07.2003
Beiträge: 965
Wohnort: Aachen
Medaillen: Keine

BeitragVerfasst am: 04.11.2006, 23:19    Titel: Antworten mit Zitat

Ich schlage weiterhin vor, du stellst ein Beispielprojekt zur Verfügung. Dann können wir am schnellsten feststellen was schief läuft.

Meinetwegen auch ein Beispiel aus dem Buch, wenn dort der gleiche Fehler zu sehen ist.

Ansonsten kommst du vielleicht auch selbst auf die Lösug, während du das Beispiel machst...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
piv0
Mini JLI'ler



Anmeldedatum: 04.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 05.11.2006, 00:11    Titel: Antworten mit Zitat

Jonathan_Klein hat Folgendes geschrieben:
Auf jeden Fall, solltest du deswegen nciht aufgeben.


Aufgeben werde ich aus diesem Grund natürlich nicht.

Jedoch bin ich (leider?) immer recht penibel, bei allem was ich tue muss alles perfekt sein Smile
Außerdem möchte ich ja dazulernen und wissen woran das liegen mag..


Nunja ich habe nun ein Beispielprojekt erstellt und aufs nötigste reduziert. Es ist hier zu finden.

Ich möchte mich recht herzlich für euere Bemühungen bedanken, das freut mich wirklich.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 05.11.2006, 00:29    Titel: Antworten mit Zitat

Ich denke dein Backbuffer sowie deine ClientArea werden mit der Grösse 512x512 erstellt, das stimmt aber nicht bei dir.

Ich habe die Client Size mal getestet:

512x505

Und dein Backbuffer wird mit folgenden defines erstellt:

#define SCR_WIDTH 518
#define SCR_HEIGHT 537

also:

518x537

ändere

#define SCR_WIDTH 518
#define SCR_HEIGHT 537

zu

#define SCR_WIDTH 512
#define SCR_HEIGHT 512

und dein Problem ist gelöst.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
piv0
Mini JLI'ler



Anmeldedatum: 04.11.2006
Beiträge: 8

Medaillen: Keine

BeitragVerfasst am: 05.11.2006, 11:39    Titel: Antworten mit Zitat

Okay, ich habe nun 2 neue Variablen eingeführt, die die Größe des Backbuffers definieren; diese habe ich dann wie du sagtest auf 512x512 gestellt und siehe da:
ES GEHT Smile

Ich danke euch vielmals für eure Mühe mir zu helfen!

Und nun habe ich auch wieder etwas gelernt: Der Backbuffer wird von der Größe her in die des Fensters reingequetscht und darf nicht über die Ränder des Fensters hinausgehen Smile

Moral gelernt, Fabel vorbei, vielen Dank nochmals
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
AFE-GmdG
JLI MVP
JLI MVP


Alter: 45
Anmeldedatum: 19.07.2002
Beiträge: 1374
Wohnort: Irgendwo im Universum...
Medaillen: Keine

BeitragVerfasst am: 06.11.2006, 08:01    Titel: Antworten mit Zitat

Du kannst auch Das Fenster so erstellen, dass der Clientbereich so gross ist wie du es haben willst.
Dafür musst du dein Fenster erstellen (muss dabei nicht angezeigt werden), dann nimmst du die Fenstergröße und die Clientgröße, rechnest den Fehlbetrag aus und vergrößerst dein Fenster so, dass der Clientbereich die gewünschte Größe hat.
Es geht auch irgendwie, indem man die Systemmetrics für Rahmen, Titelleiste usw. abfragt - aber ich habs bisher immer so gemacht wie oben beschrieben...
_________________
CPP:
float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
KI
JLI Master


Alter: 39
Anmeldedatum: 04.07.2003
Beiträge: 965
Wohnort: Aachen
Medaillen: Keine

BeitragVerfasst am: 06.11.2006, 08:31    Titel: Antworten mit Zitat

@AFE-GmdG
Es geht ganz einfach. Siehe 4. Beitrag von oben.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Fragen, Antworten und Kritik Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum