Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Viivan piirto

crafn [28.09.2005 16:12:26]

#

Minulla on ongelma... :D
Tein funktion joka piirtää viivan mutta se ei toimi kunnolla:

 #include <SDL/SDL.h>

#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "SDL.lib")

void DrawPixel(SDL_Surface *Surface, int x, int y,Uint8 R, Uint8 G,Uint8 B)
{
        Uint32 color = SDL_MapRGB(Surface->format, R, G, B);
        Uint8 *  bufp= (Uint8 *)Surface->pixels + y*Surface->pitch + x*Surface->format->BytesPerPixel;
        switch (Surface->format->BytesPerPixel) {
                case 4:
                        bufp[3] = color >> 24;
                case 3:
                        bufp[2] = color >> 16;
                case 2:
                        bufp[1] = color >> 8;
                case 1:
                        bufp[0] = color;
        }
        return;
}
void LineTo(SDL_Surface *Surface, int alkux, int alkuy, int loppux, int loppuy)
{
     long x=alkux, y=alkuy;
     long lisax=0, lisay=0;

     lisax = loppux/loppuy;
     lisay = loppuy/loppux;

     if(lisax > 1) lisax = 1;
     if(lisay > 1) lisay = 1;

     while(1) {

     SDL_LockSurface(Surface);
     DrawPixel(Surface, x, y, 255, 255, 255);
     SDL_UnlockSurface(Surface);

     x += lisax;
     y += lisay;

     if(x >= loppux && y >= loppuy) {

     break;
     }
     }
}
void DrawImage(SDL_Surface *kuva, SDL_Surface *naytto, int kuvax, int kuvay, int leveys, int korkeus, int nayttox, int nayttoy)
{
    SDL_Rect kuvaalue;
    kuvaalue.x = kuvax;
    kuvaalue.y = kuvay;
    kuvaalue.h = korkeus;
    kuvaalue.w = leveys;

    SDL_Rect nayttoalue;
    nayttoalue.x = nayttox;
    nayttoalue.y = nayttoy;

    SDL_SetColorKey(kuva, SDL_SRCCOLORKEY, SDL_MapRGB(kuva->format,0,255,0));
    SDL_BlitSurface(kuva, &kuvaalue, naytto, &nayttoalue);
}

int main(int argc, char *argv[]) {



    if( SDL_Init(SDL_INIT_VIDEO) < 0 )
    {
        fprintf(stderr, "SDL:n alustus ei onnistunut: %s\n", SDL_GetError());
        return 0;
    }

    SDL_Surface * screen;

    screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);

    int mx, my, mouse;

    while (1)
    {
    SDL_Event tapahtuma;
    SDL_PollEvent(&tapahtuma);

    Uint32 color;

    color = SDL_MapRGB (screen->format, 0, 0, 0);
    SDL_FillRect (screen, NULL, color);

    mouse=SDL_GetMouseState(&mx, &my);

    Uint8* keyboard;
    keyboard=SDL_GetKeyState(NULL);

    LineTo(screen, 0, 0, 10, 20);


    if(keyboard[SDLK_ESCAPE])  break;

    SDL_Delay(1);
    SDL_Flip(screen);
    }
    SDL_Quit();
    return 0;
}

Kun käynnistän ohjelman, eikä loppux ja loppuy ole samoja niin ohjelma sammuu heti.
Miten asian voi korjata??

Mazuli [29.09.2005 09:42:30]

#

kokeile muttaa rivit

long x=alkux, y=alkuy;
long lisax=0, lisay=0;

lisax = loppux/loppuy;
lisay = loppuy/loppux;

muotoon

int x=alkux, y=alkuy;
int lisax=0, lisay=0;

lisax = (int)(loppux/loppuy);
lisay = (int)(loppuy/loppux);

muistaakseni SDL syö vain kokonaislukuja

CyberianRat [29.09.2005 13:20:06]

#

Viivapiirtofunktiosi on erheellinen. Silmiinpistävin virhe on, että yrität ratkaista lisä-x:n pelkän loppu-x:n ja loppu-y:n suhteen avulla, kun tulisi käyttää koordinaattien erotuksien suhdetta, siis tyyliin:

(loppuy-alkuy)/(loppux-alkux)

Valitettavasti tälläkin tavalla pääset vain alkuun, vielä pitää ottaa useita asioita lukuun, kuten mahdolliset nollalla jakamiset sekä se, liikutaanko viivaa piirrettäessä x-akselia vai y-akselia pitkin. Jos haluat tehdä tällä tavalla oman viivapiirtoalgoritmisi, on se ihan hyvä harjoitus, googlelta saat lisää apua esim. hakusanoilla 'line drawing algorithms'.

Osoittautuu kuitenkin, että on olemassa tehokkaampikin tapa piirtää viivoja, sitä kutsutaan Bresenhamin viivapiirtoalgoritmiksi, google auttaa jälleen.

Vaan sittenkin tehokkuuteen jää lähestymistavassasi vielä paljon toivomisen varaa, sillä kutsut LockSurfacea, DrawPixeliä ja UnlockSurfacea kerran jok'ikiselle pikselille, jonka piirrät. Tämä ei ole yleensä hyväksyttävää overheadia. Esim. värin laskeminen, joka tapahtuu DrawPixel-funktiossa tarvitsisi suorittaa vain kerran per viiva.

Jos siis haluat tehdä viivapiirtofunktion, varaa aikaa vähintään muutama tunti ja ryhdy ensin lukemaan ja sitten koodaamaan. Jos taas haluat vain piirtää viivoja, käytä jotain SDL:n lisäkirjastoa, jossa on valmiit funktiot grafiikkaprimitiivien piirtämiseen.

Toivottavasti tästä oli apua :)

crafn [29.09.2005 15:49:51]

#

kiitos vastauksista vaan :D

hunajavohveli [29.09.2005 16:09:09]

#

Jotenkin ikävästi näyttää siltä, että tuossa on käytetty valmiita funktioita pikselien piirtoon eikä ole koodattu itse (Pyydän anteeksi, jos erehdyn). Kannattaa ensin opetella ymmärtämään kunnolla, miten ne pikselinpiirtofunktiot toimivat, ja sitten niiden tietojen pohjalta tehdä oma funktio, josta jätetään pois kaikki tarpeettomat ominaisuudet.

Edit: Monissa tapauksissa pikselin piirtämiseen ei kannata tehdä erillistä funktiota ollenkaan.

Vastaus

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

Tietoa sivustosta