[DirectX] Sprites werden ungewollt skaliert



  • Hallo miteinander,

    Ich hatte mal die Lust verspürt mich am Spieleprogrammieren zu versuchen und so sitze ich gerade mit meinem Buch ("Jetzt lerne ich DirectX 9 und Visual C++") an meinem ersten Spielchen (es soll ein 2D-Schachspiel werden).

    Mein Problem besteht nun darin: Meine Sprites (bzw die Texturen) werden gestaucht und verschwimmen dadurch, was zum einen doof aussieht und zum anderen ich nicht mehr so einfach mit den Mauskoordinaten zurecht komme..

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

    Ich habe festgestellt, dass das Sprite (ich befinde mich in einem Fenster) automatisch skaliert wird wenn ich das Fenster größer und kleiner mache (also während das Programm läuft). Ich nehme an damit kann das zusammen hängen; ich will eigentlich eine feste Fenstergröße vorgeben, was ich auch schon realisiert habe (mit Fensterstilen WS_*) aber irgendwie scheint es mir als würde das immernoch mein Sprite beeinflussen.

    Ich habe mir Mühe gegeben alles so genau wie möglich zu beschreiben und hoffe es ist ausführlich genug. Ich hoffe weiterhin, dass ihr mir helfen könnt und freue mich auf Antworten.

    Gruß



  • also dass dein sprite skaliert wird, wenn du das fenster vergrößerst/verkleinerst is normal. Kann man so nichts gegen machen, außer man fängt WM_SIZE ab und skaliert dann das sprite neu, damit es wieder so aussieht wie vorher. Is aber shwachsinn.

    Wie malst du dein Sprite? zeig mal den Lade code und den zeichencode



  • Danke für die Hilfe.
    Also wenn du sagst, dass mit WM_SIZE is Schwachsinn dann frag ich erst gar nicht was das ist bzw. wie das geht..

    Zum Laden des Sprites (eben das erwähnte Schachbrett, jedoch ist bei den Figuren das gleiche Problem..)

    Brett.Create(Direct3D.GetDevice(),BRETT);

    mit

    // Sprite kreiern
    void CSprite::Create(LPDIRECT3DDEVICE9 lpDevice, LPCSTR lpFileName)
    {
        m_lpDevice  = lpDevice;
    
        // Sprite anlegen
        D3DXCreateSprite(m_lpDevice,&m_lpSprite);
    
        // Inforationen über die Textur holen
        D3DXIMAGE_INFO ImgInfo;
        D3DXGetImageInfoFromFile(lpFileName,&ImgInfo);
    
        // Textur anlegen
        D3DXCreateTextureFromFileEx(m_lpDevice,
                                    lpFileName,
                                    ImgInfo.Width,
                                    ImgInfo.Height,
                                    1,0,
                                    D3DFMT_UNKNOWN,
                                    D3DPOOL_MANAGED,
                                    D3DX_FILTER_NONE,
                                    D3DX_FILTER_NONE,
                                    RGB(0,255,0),            //Grün wird Transparent
    								0,0,
                                    &m_lpTexture);
    
        // Breite und Höhe speichern
        m_Width  = ImgInfo.Width;
        m_Height = ImgInfo.Height;
    
    }
    

    Zum Zeichnen:

    Brett.Draw();

    mit:

    // Sprite zeichnen
    void CSprite::Draw(void)
    {
        m_lpSprite->Draw(m_lpTexture,
                         0,
                         &vScaling,		//Scale
                         0,				//Rotationszentrum
                         0,				//Rotation
                         &m_vPosition,
                         0xFFFFFFFF);
    }
    

    *Edit*

    Hätte ich doch glatt vergessen:

    //Sprite soll nicht skaliert werden
    D3DXVECTOR2 vScaling(1.0f, 1.0f);
    


  • hm... also ich glaub ich versteh nich genau was den problem is. Der code sieht ganz gut aus.

    Wenn deine Textur 512*512 Pixel groß ist, dann wird die eigentlich auch in der Größe dargestellt. versuch mal dein Fenster auch in der Größe 512*512 zu erstellen. Dann müsste das sprite das Fenster füllen. Wenn nciht, läuft (meiner meinung nach was schief)



  • Ich habe mein Problem mal dokumentiert, habe eine kleine Gif-Datei erstellt.
    Der Frame vom Gif mit der Schrift 'Hallo' und den Figuren (deplatziert? joa..) ist das was mir das Programm zeigt, der andere Frame auf dem nur das Brett zu sehen ist ist die original Textur (mit Bildbearbeitung drübergelegt; also so sollte es aussehen..) Hellblau ist die ClearColor von DX; man sieht also, dass der Sprite tatsächlich gestaucht wird.
    Das Fenster ist so angepasst, dass die 512x512 Textur gerade reinpasst (sogar mit Rändern und Balken angerechnet etc..).

    Hier mal das Gif:
    http://mitglied.lycos.de/krazzomat/schach.gif

    Wahrscheinlich steckt ein winziger Fehler dahinter, aber ich komm beim besten Willen nicht drauf..



  • muss man beim zeichnen nicht ein D3DXSPrite::Begin() und End() machen? fällt mir grad ein.
    welches sdk verwendest du? in der sdk-doku zu dx9c hat Draw auch nur 5 Parameter.

    und versuch mal vor dem malen sowas:

    D3DXMaxtrix id;
    D3DXMatrixIdentity(&id);
    sprite->SetTransform(id);
    
    sprite->Draw()
    


  • Ich benutze DX 9.0 SDK..

    Maxi schrieb:

    muss man beim zeichnen nicht ein D3DXSPrite::Begin() und End() machen? fällt mir grad ein.

    Hmm, ich weiß nicht ob du das meinst, ich benutze:

    //Start/Beenden der Szene 
    void CDirect3D::BeginScene(void)
    {
        m_lpD3DDevice->Clear(0,0,D3DCLEAR_TARGET,m_ClearColor,0,0);
    
        m_lpD3DDevice->BeginScene();
    }
    
    void CDirect3D::EndScene(void)
    {
        m_lpD3DDevice->EndScene();
    
        m_lpD3DDevice->Present(0,0,0,0);
    }
    

    Deinen Code, konnte ich leider nicht wirklich einbauen. D3DXMatrix nimmt er irgendwie nicht an.



  • du musst die header für d3dx einbinden.

    also #include <d3dx9.h>

    ich meine sowas:

    sprite->Begin();
    sprite->Draw(...)
    sprite->End()

    Leider kenn ich mich aber auch nich sehr gut mit id3dxsprite aus



  • Der Typ heißt D3DXMATRIX, nicht D3DXMatrix.



  • Danke für eure Hilfe..

    Also das mit der Matrix funktioniert nicht ganz, nämlich wird der Befehl SetTransform nicht erkannt.

    'SetTransform' : Ist kein Element von 'ID3DXSprite'
    c:\dxsdk\include\d3dx9core.h(213) : Siehe Deklaration von 'ID3DXSprite'



  • du hastn anderes sdk als das in der msdn-online-doku. sorry, kann ich dir dann auch ncih helfen 😞



  • Schade..

    Nunja also ich habe mal ein Beispielprogramm von der CD meines Lernbuches ausprobiert.. Das Programm lief im Fullscreen und als ich es in ein Fenster umgewandelt habe (so wie ich das mache, vielleicht mache ich dabei ja etwas falsch oder vergesse, dass man dazu noch etwas umstellen muss..) trat das gleiche Problem auf: Das Sprite war verschwommen und nicht in originaler Größe.

    Nun, was habe ich zum Einstellen von Vollbild -> Fenster gemacht:

    // Direct3D initialisieren
        if(!Direct3D.Init(hWnd,TRUE))        // TRUE = bWindowed: Fenster
        {                                    // Davor stand hier FALSE für Vollbild
            return -1;
        }
    

    Direct3D ist eine Instanz von CDirect3D.. Init siehe hier:

    // 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;     //Also steht hier TRUE für mein Fenster
    
        PParams.BackBufferWidth  = SCR_WIDTH;
        PParams.BackBufferHeight = SCR_HEIGHT;
        PParams.BackBufferFormat = D3DFMT_A8R8G8B8;
    
        HRESULT hr;
    
        // Direct3D-Gerät anlegen
        if(FAILED(hr = m_lpD3D->CreateDevice(
                                     D3DADAPTER_DEFAULT,
                                     D3DDEVTYPE_HAL,
                                     hWnd,
                                     D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                     &PParams,
                                     &m_lpD3DDevice)))
        {
            // Fehler, Gerät kann nicht angelegt werden
            const char* Err = DXGetErrorDescription9(hr);
    
            DXTRACE_MSG(Err);
    
            return FALSE;
        }
    ..
    
    }
    

    Dies wollte ich noch los werden, wohl als letzte Chance mein Problem zu lösen.. Vielleicht kann ja jemand was damit anfangen und mir helfen.
    Danke nochmal für eure Mühe!



  • Also irgendwie seh ich kein Problem. f'`8k

    Gruß, TGGC (\-/ has leading)


Anmelden zum Antworten