Direct Draw und Surface drehen!!!



  • Hi,

    wie vielleicht schon einige der Überschrift entnehmen konnten suche ich eine möglichkeit eine sekundäre oberfläche gedreht auf die primäre zu blitten!!!....
    ich dachte zunächste dies wäre mit der "dwRotationAngel" funktion von DDBLTFX dazu dienen würde, aber der erfolg bleibt aus!.....kann es sein, dass ich beim fastblitten ein RECT angeben muss das gedreht ist?

    vielen dank im voraus!!

    tobi



  • Hi,

    meiner Erfahrung nach funktioniert dieses Rotieren über DDraw auf kaum einer Grafikkarte.

    Du könntest entweder noch Direct3D dazunehmen und deine Bilder aus zwei Dreiecken zusammensetzen oder du nimmst eine der neueren DX Versionen.
    Da nimmst du dann die D3DX die auch Sprites anbieten.
    (Die dann aber intern wieder als 2 Dreicke berechnet werden).



  • oder du drehst die surface per hand (langsam) und blittest dann ganz normal



  • dank schon für eure antworten, aber was heißt denn das mit von hand drehen?? erklär bitte mal!

    tobi



  • damit meint er, das bild in software pixel für pixel zu drehen...



  • aso... *hehe*, nee das is nischt für mich, dazu bin ich zu faul...dennoch thx!!



  • zu faul? Programmiertechnisch ist das imho noch die einfachste lösung.. 😕



  • ehrlich gesagt weiß ich ganich genau, wie das geht...könntest du das mal genauer erläutern, am besten mit code-beispielen!!!.. 🙄

    DANKE!!
    tobi



  • hm. hatte sowas mal gemacht.. Ist aber schon älter und bissel häßlich :>

    void surfaceVerwalter::rotateSurface(LPDIRECTDRAW7 &lpDirectDraw, LPDIRECTDRAWSURFACE7 &sourcesurface, DDSURFACEDESC2 &sourcesurfacedesc, LPDIRECTDRAWSURFACE7 &targetsurface, DDSURFACEDESC2 &targetsurfacedesc, RECT olddrawRect, RECT &newdrawRect, float winkel)
    {
    
        int x,y;
        WORD *lpSourcePixel;
        WORD *lpTargetPixel;
    
        float cosine = (float)cos(winkel);
        float sine = (float)sin(winkel);
        //die 3 ecken bestimmen 
        int x1 = (int)(((float)(sourcesurfacedesc.dwHeight)*(-1)) * sine);
        int y1 = (int)(sourcesurfacedesc.dwHeight * cosine);
        int x2 = (int)(sourcesurfacedesc.dwWidth * cosine - sourcesurfacedesc.dwHeight * sine);
        int y2 = (int)(sourcesurfacedesc.dwHeight * cosine + sourcesurfacedesc.dwWidth * sine);
        int x3 = (int)(sourcesurfacedesc.dwWidth * cosine);
        int y3 = (int)(sourcesurfacedesc.dwWidth * sine);
    
        int minx = min(0,min(x1, min(x2,x3)));
        int miny = min(0,min(y1, min(y2,y3)));
        int maxx = max(x1, max(x2,max(x3,0)));
        int maxy = max(y1, max(y2,max(y3,0)));
    
        int w = maxx - minx;
        int h = maxy - miny;
    
       //neues Rechteck bestimmen:
    
       //Zunächst berechnen um wieviel das alte Rect größer oder kleiner war als das Bild
       float sizeModifierX = (float)(olddrawRect.right-olddrawRect.left)/(float)sourcesurfacedesc.dwWidth;
       float sizeModifierY = (float)(olddrawRect.bottom-olddrawRect.top)/(float)sourcesurfacedesc.dwHeight;
    
       if(sizeModifierX != sizeModifierY)
       {
         cout << "Fehler in rotateSurface()! Das übergebene Rechteck verzerrt das Bild! Die Weite des Bildes ist: " << sourcesurfacedesc.dwWidth << ". Und die Höhe ist: "<< sourcesurfacedesc.dwHeight << ". Bitte Rechteckwerte entsprechend ändern \n";
       }
    
       //Dann berechnen um wieviel das Rechteck größer werden muss
       int vergroesserungX = (w-sourcesurfacedesc.dwWidth);
       int vergroesserungY = (h-sourcesurfacedesc.dwHeight);
    
       //Nun kann ich das neue Rect berechnen
       newdrawRect.left = olddrawRect.left - vergroesserungX/2.0*sizeModifierX; //durch 2, damit es sich um die Mitte dreht und nicht um die linke, obere Ecke
       newdrawRect.right = olddrawRect.right + vergroesserungX/2.0*sizeModifierX;
       newdrawRect.top = olddrawRect.top - vergroesserungY/2.0*sizeModifierY;
       newdrawRect.bottom =olddrawRect.bottom + vergroesserungY/2.0*sizeModifierY;
    
      //targetsurface auf richtige Höhe und Weite bringen.
       targetsurfacedesc.dwSize = sizeof(DDSURFACEDESC2);
       targetsurfacedesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
       targetsurfacedesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
       targetsurfacedesc.ddsCaps.dwCaps2 = 0;
       targetsurfacedesc.dwWidth  = w;
       targetsurfacedesc.dwHeight  = h;
       if (lpDirectDraw->CreateSurface(&targetsurfacedesc, &targetsurface, NULL) != DD_OK)
          {
                  cout << "Erzeugen der Bildzeichenfläche fehlgeschlagen!rotate\n";
                 // MessageBox(NULL, "Erzeugen der Bildzeichenfläche fehlgeschlagen!", NULL, MB_OK);
    
          }
        if ((*targetsurface).GetSurfaceDesc(&targetsurfacedesc) != DD_OK)
          {
                  MessageBox(NULL, "Konnte komplette Bildsurfacebeschreibung nicht hohlen", NULL, MB_OK);
    
          }
    //Nun kopieren
       if( targetsurface->Lock(NULL, &targetsurfacedesc, DDLOCK_WAIT, NULL)== DD_OK && sourcesurface->Lock(NULL, &sourcesurfacedesc, DDLOCK_WAIT, NULL) == DD_OK)
       {
         int sourcepitch = sourcesurfacedesc.lPitch;
         int targetpitch = targetsurfacedesc.lPitch;
         int sourcex;
         int sourcey;
         lpSourcePixel = (WORD*)sourcesurfacedesc.lpSurface;
         lpTargetPixel = (WORD*)targetsurfacedesc.lpSurface;
    
          //drehen
          for( y = 0; y < h; y++ )
            {
                    for( x = 0; x < targetpitch/2; x++)
                    {
                            sourcex = (int)((x+minx)*cosine + (y+miny)*sine);
                            sourcey = (int)((y+miny)*cosine - (x+minx)*sine);
    
                            if( sourcex >= 0 && sourcex < sourcesurfacedesc.dwWidth && sourcey >= 0 && sourcey < sourcesurfacedesc.dwHeight )
                               {
                                lpTargetPixel +=(int) (x+y*targetpitch/2);
                                lpSourcePixel +=(int) (sourcex)+sourcey*sourcepitch/2;
    
                                *lpTargetPixel = *lpSourcePixel;//Byte kopieren
    
                                lpTargetPixel -= (int)(x+y*targetpitch/2);
                                lpSourcePixel -= (int)(sourcex)+sourcey*sourcepitch/2;
    
                               }
                    }
    
            }
    
            sourcesurface->Unlock( NULL);
            targetsurface->Unlock( NULL);
       }
    
    }
    


  • schankedöN!!!!


Anmelden zum Antworten