Surface als Textur



  • Hallo, ich muss im laufenden Programm son bisschen in einer Surface rummalen und diese dann als Textur auf ne Fläche legen. Ich hab die, weil die so einfach ist fix als VertexArray implemtentiert und dann mit lpD3DDevice->DrawPrimitiveUP(); Vorher muss ich dann halt noch mit lpD3DDevice->SetTexture() irgendwie meine Surface anwenden, wie mach ich das??? Wie mach ich aus ner Surface ne Textur, Koordinaten und so alles klar, ne Bitmap krich ich auch als Textur hin, aber mit der Surface steh ich voll aufm Schlauch, is aber wichtig... 🙂

    Danke im voraus,
    D1B



  • Also ich geh mal davon aus Du benutzt DX8. Dann lädst Du die Textur normal mit

    D3DXCreateTextureFromFileA( g_lpD3DDevice, datei, ppTex );
    

    Wenn Du die Textur jetzt ändern willst dann geht das so:

    D3DLOCKED_RECT rcLock;
    DWORD* pData;  // Zeiger auf anfang von Bild
    DWORD* pPixel; // Zeiger auf einen 32 BitPixel
    
    // Locken
    lpTextur->LockRect( 0, &rcLock, NULL, 0 );
    pData = (DWORD*)rcLock.pBits;
    
    // jetzt kannst Du einzelne Pixel verändern, zB:
    
    WORD x = 100;
    WORD y = 150;
    
    pPixel = &pData[ (y*rcLock.Pitch>>2) + x ];
    
    pPixel = 0x00ff0000;// Pixel = rot
    
    // am ende noch:
    lpTextur->UnlockRect(0);
    

    Alles nur für 32Bit Texturen.
    Der Code ist leider nicht optimiert und bestimmt auch nicht fehlerfrei, aber das kriegst hin 😉

    [ Dieser Beitrag wurde am 05.01.2003 um 14:59 Uhr von 0x00000001 editiert. ]



  • Danke für deine Mühe, aber ich weiß, wie man ne BitMap bearbeiten kann. Vielleicht willst du mir damit ja abstrakterweise meines Problems Lösung zeigen, aber die hab ich leider nicht gefunden...

    Also nochmal: Ich will ne Surface als Textur eines Modells (wenn auch ne ne Fläche) benutzen. Was ich gestern noch in den Backbuffer geschrieben habe, muss ich heute auf ne Fläche mappen. Stell dir also vor, du hast ne OffscreenSurface und malst darin rum um sie daraufhin als Textur zu verwenden.

    Aber Moment, genau das meintest du, oder? Ich sollte ne Instanz von ner BitMap nehmen und auf die schreiben, anstelle einer Surface, die ich schon vorher als Textur definiert habe?? Okay, ich nehme alles zurück und werds gleich ma versuchen, danke nochma... 🙄

    mfG D1B

    PS: Der Pixel wär bei mir nicht rot, ich benutze nur 16bit :p



  • Meinst du vielleicht dass du in eine Textur reinrendern möchtest ?
    Dann guck dir mal die Funktion SetRenderTarget an 🙂



  • Nein, das kenn ich eigentlich auch... 🙂 Aber das Problem ist, dass ich die Größe der Surface/Textur recht variabel brauch, zumindest zur Initialisierung. Kann ich von ner DIRECT3DTEXTURE8 nachträglich oder schon während der Initialisierung die Größe, also Höhe und Breite einstellen? Denn sonst müsste ich ja vorher n Bild in nen Ordner packen, was totale Speicherverschwendung wäre, da ich ja nichts laden, sondern selbst malen will. Wär doch blöd, dafür ne riesige leere Bitmap zu laden. Geht das nich ohne???

    mfG D1B

    EDIT: hab da was gefunden: D3DXCreateTextureFromFileExA, werd das ma ausprobieren, da gibts mehr Parameter, u.a. Höhe und Breite... 😃

    [ Dieser Beitrag wurde am 05.01.2003 um 19:25 Uhr von D1BAKEL editiert. ]



  • Original erstellt von D1BAKEL:
    Nein, das kenn ich eigentlich auch... 🙂 Aber das Problem ist, dass ich die Größe der Surface/Textur recht variabel brauch [...]

    Denk aber dran :
    Texturgröße am besten Quadratisch und ^2 !
    Maximal am besten nur 256 (alte Voodookarten können net mehr)

    [ Dieser Beitrag wurde am 05.01.2003 um 19:46 Uhr von Headhunter editiert. ]



  • Ach du Güte, das passt mir gar nicht. Naja, muss ichs halt größer machen, hilft nix! 😞 Ich habs jetzt ma probiert, klappt aber nicht. Ich hab hier ma bisschen Code:

    LPDIRECT3DTEXTURE8 Texture;
    
    BOOL D3DInit(void *Parameterliste)
    {
        //...
        // richtig initialisiert?
        D3DXCreateTextureFromFileExA(lpD3DDevice, "white.bmp", 800, 600, 0, 0,
                    D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, 0, 0, 0, 0, 0, &Texture);
        //...
        return TRUE;
    }
    
    void EinmalProFrameBearbeiten()
    {
        //...
        D3DLOCKED_RECT Rect;
    
        Texture->LockRect(0, &Rect, NULL, 0);
    
        USHORT *Vram = (USHORT *)Rect.pBits;
        int lPitch   = Rect.Pitch >> 1;
    
        // was das folgende macht is nich so wichtig, die Textur wird halt bearbeitet... =)
        for(int x = 0; x < SCREEN_WIDTH; x++)
            for(int y = 0; y < SCREEN_HEIGHT; y++)
                if(ColorMap[x + y * SCREEN_WIDTH] != -1)
                    Vram[x + y * lPitch] = Color[ColorMap[x + y * SCREEN_WIDTH]]; 
    
        Texture->UnlockRect(0);
        //...
    }
    
    void HierWirdsGerendert()
    {
        // Ne VertexListe basteln
        D3DVERTEX TriangleList[6];
    
        TriangleList[0].x = 0.0f;
        TriangleList[0].y = 0.0f;
        TriangleList[0].z = 0.0f;
        TriangleList[0].tu = 0.0f; // Texturkoordinaten zwischen 0.0f und 1.0f
        TriangleList[0].tv = 0.0f;
    
        TriangleList[1].x = 0.0f;
        TriangleList[1].y = 0.0f;
        TriangleList[1].z = float(SCREEN_HEIGHT);
        TriangleList[1].tu = 0.0f;
        TriangleList[1].tv = 1.0f;
        // usw...
    
        // Rotationen und Verschiebungen mit Matrizen
        D3DMATERIAL8 material;
    
        // hab ich hier vielleicht was übersehen?
        material.Ambient.r = 0.5f;
        material.Ambient.g = 0.5f;
        material.Ambient.b = 0.5f;
        material.Diffuse.r = 0.0f;
        material.Diffuse.g = 0.0f;
        material.Diffuse.b = 0.0f;
        material.Emissive.r = 0.2f;
        material.Emissive.g = 0.2f;
        material.Emissive.b = 0.2f;
        material.Specular.r = 0.0f;
        material.Specular.g = 0.0f;
        material.Specular.b = 0.0f;
    
        // alles schön einstellen
        lpD3DDevice->SetTransform(D3DTS_WORLD, &matWelt);
        lpD3DDevice->SetMaterial(&material);
        lpD3DDevice->SetTexture(0, Texture);
    
        // ...und rendern
        lpD3DDevice->BeginScene();
    
        lpD3DDevice->DrawPrimitiveUP(
                        D3DPT_TRIANGLELIST,
                        2,
                        &TriangleList[0],
                        sizeof(D3DVERTEX));
    
        lpD3DDevice->EndScene();
    
    }
    

    So, ich hoffe das reicht an Code... Isses echt so schlimm, dass die Textur diese Größe hat und nich 2^n und quadratisch? Schlägt die SetTexture fehl? Ich werd ma ne Fehlerbehandlung einbauen, vielleicht (hoffentlich) habt ihr da noch Ideen...

    mfG D1B

    EDIT: Habs ma ausprobiert, gibt keine Fehlermeldung, SetTexture() schein zu funktionieren... Ich weiß auch nich mehr... 😕

    [ Dieser Beitrag wurde am 05.01.2003 um 21:06 Uhr von D1BAKEL editiert. ]



  • Kann sich das mal jemand durchlesen und mir helfen? 😞



  • Was klappt denn an deinem Code nich ?

    So, ich hoffe das reicht an Code... Isses echt so schlimm, dass die Textur diese >>Größe hat und nich 2^n und quadratisch?

    Wenn du Pech hast skaliert dir die Graka dein Image auf Quadratgröße 😉



  • @D1ibakel: Ich glaube dass D3DXCreateTexture() das ist, was Du suchst.

    Ich habe aber mal gelesen dass bie manchen Grafikkarten/Chips die Breite und Höhe eine gerade Zahl sein muss, sonst wird wie Headhunter gesagt hat skaliert. Das merkt man aber eh nicht wenn man das Bild als Textur rendern lässt.


Anmelden zum Antworten