Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Yksi vaivainen pikseli

Sivun loppuun

verho88 [08.09.2005 09:41:34]

#

Olen hankkinut ohjelman DEV-C++ ja haluaisin opetella hieman grafiikkaa piirtämään.. Osaan hieman jo alkeita C kielestä, mutta QBasicilla olen tähän asti koodannut..

Eli ohjelmalla pitäisi saada yksi pikseli piirrettyä kokonäytön kattavalle 640x480 kokoiselle ja 256 väriä omaavalle "ohjelmalle"..(vai kuinka se pitäisi sanoa?)
Koko koodi olisi mukava saada joltakin etevämmältä koodaajalta.

-Kiitos

Gwaur [08.09.2005 09:53:13]

#

https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=sdl1

Heikki [08.09.2005 10:24:13]

#

Jos perustiedot kielestä eivät ole kunnossa, voi grafiikkaohjelmoinnin kanssa mennä helposti sormi suuhun. Jos C:llä ohjelmoi, kannattaa ainakin varmistaa, että Antin C-opassarjan asiat ovat hallussa. Tämän jälkeen SDL:llä pitäisi saada mukavasti grafiikkaa aikaan.

Toisaalta yksittäisen pisteen piirto ei SDL:llä ole mitenkään erityisen helppoa, mutta bittikartan (.bmp-tiedosto) saa ruudulle sitäkin helpommin :)

hunajavohveli [08.09.2005 15:15:22]

#

Tuohon oppaaseen voisi kyllä lisätä jonkin selostuksen pikseleiden piirrosta pointtereiden avulla. Itse olen havainnut sen melko käteväksi keinoksi.

Meitsi [08.09.2005 15:28:55]

#

hunajavohveli kirjoitti:

Tuohon oppaaseen voisi kyllä lisätä jonkin selostuksen pikseleiden piirrosta pointtereiden avulla. Itse olen havainnut sen melko käteväksi keinoksi.

Kannatetaan.

Juice [08.09.2005 18:41:12]

#

SDL_gfx:ssä on helppo funktio pixelColor, jolla pikselin piirtäminen onnistuu

int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y,
			      Uint32 color);

dst SDL_Surface, jolle piirretään
x x-koordinaatti
y y-koordinaatti
color väri muodossa 0xRRGGBB, eli esim. 0x00FF00

Tämä on helpoin tapa.

Tai sitten voit tehdä kaiken itse:

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    if ( SDL_MUSTLOCK(surface) ) {
        if ( SDL_LockSurface(surface) < 0 ) {
            return;
        }
    }
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *p = pixel;
        break;

    case 2:
        *(Uint16 *)p = pixel;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            p[0] = (pixel >> 16) & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = pixel & 0xff;
        } else {
            p[0] = pixel & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = (pixel >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)p = pixel;
        break;
    }

    if ( SDL_MUSTLOCK(surface) ) {
        SDL_UnlockSurface(surface);
    }
}

(Koodin palaset kopsailtu ei lähteistä, ei välttämättä toimi).

hunajavohveli [08.09.2005 19:25:06]

#

Tuossa on tosiaan perusidea siitä, miten pikseli voidaan piirtää pointterin avulla. Tuollaisenaan funktio on kuitenkin melko hidas, kun otetaan huomioon, että useimmissa tapauksissa monet sen ominaisuuksista on täysin turhia.

Esim. Jos Surface or varmasti lukittu, sitä koskevan tarkistuksen voi poistaa. Samaten BytesPerPixel pitäisi olla aina tiedossa, ennen kuin funktiota kutsutaan, joten senkin tilalle voi laittaa tilanteesta riippuen vakion, ja heivata loput vaihtoehdot pois. Jos piirrettävät pikselit ovat peräkkäin tai muuten loogisessa järjestyksessä, ei funktiota välttämättä kannata käyttää ollenkaan, vaan yksinkertaisesti luupissa kasvattaa pointteria tietyn verran, ja sitten plotata pikseli sen osoittamaan muistiosoitteeseen.

Edit: Tässä esimerkki, joka piirtää laatikon annetujen koordinaattien ja värin mukaan 8-bittisessä eli 256 värin tilassa. Repäisin suoraan yhdestä pelistäni. Pitäisi toimia, mutta saatoin unohtaa kopioida jotain. :)

void Box(int x1, int y1, int x2, int y2, int c) {
unsigned char *p;
int x,y,i;
  p=SURFACE_NAME->pixels;
  p+=y1*SCREEN_WIDTH+x1;
  for(y=y1;y<=y2;y++){
  for(x=x1;x<=x2;x++){
    *p=c;
    p++;
    }
  p-=(x2-x1+1);
  p+=SCREEN_WIDTH;
  }
}

aWW [09.09.2005 10:27:50]

#

hunajavohveli kirjoitti:

Tässä esimerkki, joka piirtää laatikon annetujen koordinaattien ja värin mukaan 8-bittisessä eli 256 värin tilassa.

void Box(int x1, int y1, int x2, int y2, int c) {
unsigned char *p;
int x,y,i;
  p=SURFACE_NAME->pixels;
  p+=y1*SCREEN_WIDTH+x1;
  for(y=y1;y<=y2;y++){
  for(x=x1;x<=x2;x++){
    *p=c;
    p++;
    }
  p-=(x2-x1+1);
  p+=SCREEN_WIDTH;
  }
}

Onko järkeä kirjoittaa itse tuollainen funktio, jos käyttää jotain korkean tason rajapintaa? (esim SDL)

SDL_Fill()-funktio on helpompi aloittelijalle.

hunajavohveli [09.09.2005 13:30:49]

#

Tarkoitus oli nyt siis havainnollistaa pointtereiden käyttöä, eikä esitellä nopeinta mahdollista tapaa piirtää tietyn värinen laatikko.

Edit: Ja jos nyt siis jäit ihmettelemään, miksi tuollainen koodi on pelissäni, niin ei se ihan täsmälleen tuollaisena olekaan. Väriparametrin tilalla on taulukosta kohdalta (x,y) haettava väriarvo.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta