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
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void CSprite::PutPixel (SDL_Surface *pImageIn,int x, int y,Uint32 pixel) { Uint32 *ptr = (Uint32 *) pImageIn->pixels; int lineoffset = y * (pImageIn->pitch) / 4; int pixelpos = (lineoffset + x/2) ; ptr[pixelpos] = pixel; } Uint32 CSprite::GetPixel (SDL_Surface *pImageIn,int x, int y) { Uint32 *ptr = (Uint32 *) pImageIn->pixels; int lineoffset = y * (pImageIn->pitch) / 4; int pixelpos = lineoffset + x/2 ; return ptr[pixelpos]; } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
SDL_Surface *CSprite::Rotate (SDL_Surface *pImageIn,float fWinkel) { SDL_Surface *pImageOut; pImageOut=NULL; Uint32 pix; Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif if (m_pRotated!=NULL) { SDL_FreeSurface(m_pRotated); pImageIn=m_pImage; m_pRotated=NULL; pImageOut=NULL; } int x2,y2; double h=(pImageIn->h); double w=(pImageIn->w); double width=(sqrtf((pImageIn->h * pImageIn->h+pImageIn->w * pImageIn->w))); double height=width; SDL_Surface *temp; //cout << height << "\t" << width << endl; temp = SDL_CreateRGBSurface(SDL_HWSURFACE,width, height, 32, rmask, gmask, bmask, amask); pImageOut=SDL_DisplayFormat(temp); SDL_FreeSurface(temp); SDL_FillRect(pImageOut,NULL,SDL_MapRGB (m_pScreen->format, 255, 0, 255)); if(pImageOut == NULL) { fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError()); return NULL; } if ( SDL_MUSTLOCK(pImageIn) ) { if ( SDL_LockSurface(pImageIn) < 0 ) { fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); return NULL; } } if ( SDL_MUSTLOCK(pImageOut) ) { if ( SDL_LockSurface(pImageOut) < 0 ) { fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); return NULL; } } // Berechnung der neuen Koordinaten für die gedrehte Bitmap und //kopieren der Pixelinformation for (int y1=0;y1<h;y1++) { for (int x1=0;x1<w;x1++) { x2=static_cast<int> ((x1-(w/2))*cos(fWinkel)-(y1-(h/2))*sin(fWinkel)+(width/2)); y2=static_cast<int> ((x1-(w/2))*sin(fWinkel)+(y1-(h/2))*cos(fWinkel)+(height/2)); if (x2>0&&x2<width&&y2>0&&y2<height) { pix=GetPixel(pImageIn,x1,y1); } else { pix=SDL_MapRGB (m_pScreen->format, 0, 0, 0); } PutPixel(pImageOut,x2,y2,pix); } } if ( SDL_MUSTLOCK(pImageOut) ) { SDL_UnlockSurface(pImageOut); } if ( SDL_MUSTLOCK(pImageIn) ) { SDL_UnlockSurface(pImageIn); } SDL_SetColorKey (pImageOut, SDL_SRCCOLORKEY, SDL_MapRGB (pImageOut->format, 255, 0, 255) ); return pImageOut; } |
Zitat von »"Gotbread"«
ich würde zumindestens im dehungscode mit double-werten arbeiten.
Zitat
außerdem ware das programm um einiges schneller, wenn du die sinus
und kosinuswerte einmal zu beginn berechnest statt immer in der schleife.
Zitat
desweiteren wäre es besser, einen zeiger auf die pixeldaten zu bekommen
statt die pixel einzeln abzuholen.
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
void CSprite::SetTransparency(SDL_Surface *surface,Uint8 R,Uint8 G,Uint8 B) { Uint8 r,g,b,a; SDL_LockSurface(surface); Uint32 *ptr = (Uint32 *) surface->pixels; int iMax=(surface->w*surface->h); for (int i=0; i<iMax;i++) { SDL_GetRGBA(ptr[i],surface->format,&r,&g,&b,&a); if (r==R&&g==G&&b==B) a=0; else a=255; ptr[i]=SDL_MapRGBA(surface->format,r,g,b,a); } SDL_UnlockSurface(surface); } void CSprite::SetTransparency(SDL_Surface *surface,Uint32 color) { SDL_LockSurface(surface); Uint32 *ptr=(Uint32 *) surface->pixels; int iMax=surface->w*surface->h; for (int i=0; i<iMax;i++) { ptr[i]=ptr[i] | (0xFF000000); if (ptr[i]==(color)) ptr[i]=color & (0x00FFFFFF); } SDL_UnlockSurface(surface); } |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
SDL_Surface *CSprite::Rotate (SDL_Surface *pImageIn,double dAngle) { SDL_Surface *pImageOut; pImageOut=NULL; Uint32 pix; Uint32 rmask, gmask, bmask, amask; /* SDL interprets each pixel as a 32-bit number, so our masks must depend on the endianness (byte order) of the machine */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif if (m_pRotated!=NULL) { SDL_FreeSurface(m_pRotated); pImageIn=m_pImage; m_pRotated=NULL; pImageOut=NULL; } int x2,y2; double dHIn=pImageIn->h; double dWIn=pImageIn->w; double dWOut=sqrtf(dHIn*dHIn+dWIn*dWIn); double dHOut=dWOut; // calculate cos and sin ex for-loop to preserve some time double dCosAngle=cos(dAngle); double dSinAngle=sin(dAngle); SDL_Surface *temp; temp = SDL_CreateRGBSurface(SDL_HWSURFACE,static_cast<int>(dWOut), static_cast<int>(dHOut), 32, rmask, gmask, bmask, amask); pImageOut=SDL_DisplayFormatAlpha(temp); SDL_FreeSurface(temp); SDL_FillRect(pImageOut,NULL,SDL_MapRGB (m_pScreen->format, 255, 0, 255)); if(pImageOut == NULL) { fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError()); return NULL; } if ( SDL_MUSTLOCK(pImageIn) ) { if ( SDL_LockSurface(pImageIn) < 0 ) { fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); return NULL; } } if ( SDL_MUSTLOCK(pImageOut) ) { if ( SDL_LockSurface(pImageOut) < 0 ) { fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); return NULL; } } // loop for rotation-transformation and color picking for (double y1=0;y1<dHIn;y1++) { for (double x1=0;x1<dWIn;x1++) { x2=static_cast<int> ((x1-dWIn/2)*dCosAngle-(y1-dHIn/2)*dSinAngle + dHOut/2); y2=static_cast<int> ((x1-dWIn/2)*dSinAngle+(y1-dHIn/2)*dCosAngle + dWOut/2); if (x2>=0&&x2<=dWOut&&y2>=0&&y2<=dHOut) { pix=GetPixel(pImageIn,x1,y1); } else { pix=SDL_MapRGB (m_pScreen->format, 0, 0, 0); } PutPixel(pImageOut,x2,y2,pix); } } if ( SDL_MUSTLOCK(pImageOut) ) { SDL_UnlockSurface(pImageOut); } if ( SDL_MUSTLOCK(pImageIn) ) { SDL_UnlockSurface(pImageIn); } SetTransparency(pImageOut,0xFFFF00FF); return pImageOut; } |
Werbeanzeige