Moi. Olen etsimässä nopeaa putpixel-toimintoa C+SDL -yhdistelmälle. Useimmat erillisessä funktiossa olevat ovat todella hitaita koko ruudun täyttämiseen. Onko teillä suoria ehdotuksia? Muistan joskus lukeneeni memset-tyylisestä putpixelistä, mutta en enää muista sen toimintaa.
Kiitos :-)
-Burton
Tällä koodilla saa kaikki bytet samoiksi (= vain harmaasävy)
// Näyttö lukkoon jos tarvitsee memset(naytto->pixels, /* arvo väliltä 0-255 (0 = musta, 255 valkoinen) */ 0, naytto->w * naytto->h * naytto->format>BytesPerPixel); // Pois lukosta
EDIT: Niin tietysti tällä saa täytettyä koko ruudun mihin väriin tahansa
// R B G SDL_FillRect(naytto, NULL, SDL_MapRGB(naytto->format, 0, 0, 255));
Mutta ajatuksena oli, että pystyisi piirtämään vaikka koko ruudun täyteen spritejä putpixelin avulla. Olen huomannut, että tämä on todella hidasta ja siksi joudun käyttämään SDL:n valmiita funktioita ja sijoittamaan kuvia ruudulle.
Inline-funktiolla tuo onnistuu juuri niin nopeasti kuin funktiolla yleensä on mahdollista. Putpixel ei tosiaan ole oikea väline koko ruudun piirtämiseen uusiksi, jos resoluutio on vähänkään isompi. Yksi mahdollisesti jopa melkein merkittävä nopeutuskonsti on se, että varmistat pinnan olevan tietyssä formaatissa, jolloin voit optimoida koodin juuri sille formaatille. Myös sopivassa paikassa olevat const-määreet ja vastaavat kikat voivat nopeuttaa ihmeesti, kuten myös turhien muistiosoitusten karsiminen. Muistathan optimointilipun -O2.
Mitä tämä -O2 -lippu tekee? Olen kyllä käyttänyt gcc:llä kääntäessäni lippua -O1, mutta luulin tämän vain pienentävän ulos tulevan tiedoston kokoa.
edit. tämä koodi:
#include <SDL/SDL.h> #define PITCH naytto->pitch SDL_Surface *naytto; int main(int aaaaa,char *bbbbb[]) { SDL_Init(SDL_INIT_VIDEO); naytto = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE); Uint8 *p = (Uint8 *)naytto->pixels; int y , x, b; long hidastea = SDL_GetTicks(); fprintf(stderr, "%i\n", hidastea); for (b = 0; b < 1000; b = b + 1) { for (y = 0; y < 600; y = y + 1) { for (x = 0; x < 800; x = x + 1) { *(Uint32 *)(p + y * PITCH + (x << 2)) = 255; } } SDL_UpdateRect(naytto, 0, 0, 800, 600); } hidastea=SDL_GetTicks(); fprintf(stderr,"%i\n",hidastea); SDL_Quit(); return 0; }
suoriutui 7432 millisekunnissa. Eli minusta se on aika nopea, jos kerran tuhat kertaa täytetään 800*600 -kokoinen näyttö.
O1 pienentää binäärin kokoa ja O2 lisää nopeutta.
Voiko niitä käyttää yhdessä? GCC tekee hirveän isoja tiedostoja muuten...
Lahha kirjoitti:
O1 pienentää binäärin kokoa ja O2 lisää nopeutta.
No ei nyt aivan noinkaan. O1 optimoi vähän, O2 optimoi enemmän. Os panostaa kokoon. Vain yhtä tällaista optimointilippua voi käyttää kerralla. O2 sisältää myös kaikki O1:n optimoinnit. Koon pienentyminen tulee perusoptimoinnissa kaupan päälle, kun turhaa koodia poistetaan ja asiat tehdään tehokkaammin. Kokoon auttaa vielä paljon enemmän -s (pienellä, ei isolla).
Onko sitten olemassa O3-lipuke?
Toki, mutta se ei läheskään aina ole kakkosta parempi (joskus jopa huomattavasti huonompikin) ja se voi jo joissakin tapauksissa merkittävästi suurentaa binaaria. Sitä isompia ei sitten olekaan.
Tein koodin:
#include <SDL/SDL.h> #define PITCH naytto->pitch SDL_Surface *naytto; int main(int aaaa,char *bbbb[]) { if (SDL_Init(SDL_INIT_VIDEO)<0) { fprintf(stderr,"SDL-Virhe: %s\n",SDL_GetError()); exit(1); } naytto = SDL_SetVideoMode(320, 200, 32, SDL_SWSURFACE|SDL_FULLSCREEN ); SDL_Event t; Uint8 *p = (Uint8 *)naytto->pixels; while (1) { SDL_PollEvent(&t); if (t.type == SDL_QUIT) break; else if (t.type == SDL_KEYDOWN) if (t.key.keysym.sym == SDLK_ESCAPE) break; *(Uint32 *)(p + 100 * PITCH + (100 << 2))= 255; SDL_UpdateRect(naytto, 0, 0, 320, 200); SDL_Delay(1) } SDL_Quit(); return 0; }
Ja tuo ei toiminut, mutta jos jätän SDL_FULLSCREEN:n pois koodi toimii!
Koodin pitäisi tulostaa ruudulle pikseli.
Pitääköhän pinta lukita SDL_LockSurfacella ennen pixelien käpälöintiä, ja vapauttaa sen jälkeen SDL_UnlockSurfacella. SDL:n dokumenteissa on lisää aiheesta.
Aihe on jo aika vanha, joten et voi enää vastata siihen.