Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: OGL kysymyksiä

Sivun loppuun

vehkis91 [20.01.2009 19:44:31]

#

Ongelma on, että jostain syystä opengl piirtää vain yhden monista asioista mitä pääloopissa pitäisi piirtää...

Jos kommentoin ton ukko.draw()-funktion pois niin piirtää taustan, jos taas en niin piirtää pelkän ukon, eikä taustaa ollenkaan. :O

while(!quit)
{
   tausta.draw();

   ukko.draw();

   SDL_GL_SwapBuffers();
}

Spongi [20.01.2009 19:56:55]

#

Missä sun glClear() on? Luultavasti noiden olioiden draw-funktioissa vai?

vehkis91 [20.01.2009 19:58:39]

#

glClear(GL_COLOR_BUFFER_BIT);

tollanen löytyy jokaisen piirtofunktion alusta.

Metabolix [20.01.2009 20:05:08]

#

Ota sitten järki käteen ja korjaa asia.

vehkis91 [20.01.2009 20:08:55]

#

No kato, olinpas taas tyhmä. :S:( Tuohan tietenkin poisti aina edelliset jutut näytöltä... :D

vehkis91 [26.01.2009 09:24:55]

#

Kaks kyssäriä:

1. Miten saan parannettua kuvanlaatua, ku nyt näyttää todella sumealta.

2. Miten saan alpha blendauksen toimimaan, olen lukenut netistä monesta paikasta, mutta en vain saa toimiin. Kuvat ovat .png muodossa ja niihin on tallennettu alphakanava.

kayttaja-3842 [26.01.2009 10:06:59]

#

Kannattaa lukea noita SuomiOppaan artikkeleita.

http://www.suomipelit.com/index.php?c­=naytaartikkeli&id=59&s=2

vehkis91 [26.01.2009 10:20:19]

#

Pitääpä vilkaista...

vehkis91 [26.01.2009 12:00:39]

#

EN vaan saa toimimaan, vaikka yrittäisin mitä... :(

Blaze [26.01.2009 12:53:54]

#

vehkis91 kirjoitti:

1. Miten saan parannettua kuvanlaatua, ku nyt näyttää todella sumealta.

Väännä tekstuureiltais bilinear filtering pois päältä.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Alle pasteamani latausfunkkari tekee tuon.

vehkis91 kirjoitti:

2. Miten saan alpha blendauksen toimimaan, olen lukenut netistä monesta paikasta, mutta en vain saa toimiin. Kuvat ovat .png muodossa ja niihin on tallennettu alphakanava.

En nyt äkkiseltään muista, että piirron puolelle tarvittais sen ihmeempää kuin

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Hankalampaa on ladata tekstuuri niin, että siinä säilyy se alfakanava. Mulla on tarkotukseen tollaset funkkarit:

/* Loads given image file
 * @param name filename, relative to images-directory
 * @return pointer to loaded image surface
 */
SDL_Surface *graphics_load_image(const char *name) {
    SDL_Surface *temp = NULL;
    SDL_Surface *s = NULL;
    char subpath[] = "images/";
    char *pathname = (char*)malloc((strlen(game->datadir) + strlen(subpath)
                + strlen(name) + 1) * sizeof(char));
    sprintf(pathname, "%s%s%s", game->datadir, subpath, name);
    temp = IMG_Load(pathname);
    if(temp == NULL) {
        fprintf(stderr, "Could not load file: %s\n", IMG_GetError());
    } else {
        s = SDL_DisplayFormatAlpha(temp);

        SDL_FreeSurface(temp);
    }
    free(pathname);
    return s;
}

/* Converts given SDL_Surface to OpenGL texture
 * @param surface surface to convert from
 * @param texcoord coordinates of actual image inside texture
 * @return OpenGL texture index
 */
/* (adapted from SDL testgl.c) */
GLuint graphics_surface_to_texture(SDL_Surface *surface, GLfloat *texcoord) {
    GLuint texture;
    int w, h;
    SDL_Surface *image;
    SDL_Rect area;
    Uint32 saved_flags;
    Uint8 saved_alpha;

    /* Use the surface width and height expanded to powers of 2 */
    w = power_of_two(surface->w);
    h = power_of_two(surface->h);
    /* I think I'm not gonna need this info every time */
    if(texcoord != NULL) {
        texcoord[0] = 0.0f;         /* Min X */
        texcoord[1] = 0.0f;         /* Min Y */
        texcoord[2] = (GLfloat)surface->w / w;     /* Max X */
        texcoord[3] = (GLfloat)surface->h / h;     /* Max Y */
    }

    image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32
#if SDL_BYTEORDER == SDL_LIL_ENDIAN     /* OpenGL RGBA masks */
            0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
            0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
    );
    if(image == NULL)
        return 0;

    /* Save the alpha blending attributes */
    saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
    saved_alpha = surface->format->alpha;
    if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
        SDL_SetAlpha(surface, 0, 0);

    /* Copy the surface into the GL texture image */
    area.x = area.y = 0;
    area.w = surface->w;
    area.h = surface->h;
    SDL_BlitSurface(surface, &area, image, &area);

    /* Restore the alpha blending attributes */
    if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
        SDL_SetAlpha(surface, saved_flags, saved_alpha);

    /* Create an OpenGL texture for the image */
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
            GL_UNSIGNED_BYTE, image->pixels);
    SDL_FreeSurface(image);     /* No longer needed */

    return texture;
}

vehkis91 [26.01.2009 18:41:55]

#

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Tämä aiheuttaa sen, että piirrettävä kuva häviää kokonaan, eikä vain sen tausta. :S Kokeilin silleen, että alpha-kanava oli käytössä ja silleen, ettei sitä ollut.
Piirto funkkarin lopussa on

glDisable(GL_BLEND);

EDIT2:

Laitoin näin sinne mun latausfunkkariin:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Niin kuvanlaatu huononi entisestään. :S

User137 [26.01.2009 20:27:35]

#

Kuvakaappausta? Miten kuva huononee tai sumenee?

Spongi [27.01.2009 13:54:23]

#

Minkä kokosia teksuuris on? Seki voi vaikuttaa niiden laatuun. Tässä ois vielä mainio tutoriaali tähän liittyen, http://gpwiki.org/index.php/OpenGL_Tutorial_Framework:Ortho_and_Alpha

User137 [27.01.2009 14:48:22]

#

Sitten voisi katsella mitä näiden sisältä löytyisi?
tausta.draw();
ukko.draw();

Esim glBegin glEnd parien välissä ei saa vaihtaa tekstuureja tai tehdä juuri mitään ylimääräistä... glPushMatrix, glPopMatrix pitää myös kutsua yhtä monta kertaa. Kääntäjä ei noista herjaa eikä välttämättä ohjelmakaan.

vehkis91 [27.01.2009 15:22:14]

#

void player::Draw()
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    if(state==false)
    {
        glLoadIdentity();
        glBindTexture(GL_TEXTURE_2D, this->Kuvat[1]);

        glPushMatrix();

        glTranslatef(this->x, this->y, 0.0f);
        glRotatef(-(this->suunta), 0.0f, 0.0f, 1.0f );

        glBegin( GL_QUADS );

            glTexCoord2f(0.0f,0.0f);glVertex2f(-16, -16);
            glTexCoord2f(1.0f,0.0f);glVertex2f( 16, -16);
            glTexCoord2f(1.0f,1.0f);glVertex2f( 16, 16 );
            glTexCoord2f(0.0f,1.0f);glVertex2f( -16, 16);

        glEnd();

        glPopMatrix();
    }

    else
    {
        glLoadIdentity();

        glBindTexture(GL_TEXTURE_2D, this->Kuvat[0]);

        glPushMatrix();

        glTranslatef(this->x, this->y, 0.0f);
        glRotatef(-(this->suunta), 0.0f, 0.0f, 1.0f );

        glBegin( GL_QUADS );

            glTexCoord2f(0.0f,0.0f);glVertex2f(-16, -16);
            glTexCoord2f(1.0f,0.0f);glVertex2f( 16, -16);
            glTexCoord2f(1.0f,1.0f);glVertex2f( 16, 16 );
            glTexCoord2f(0.0f,1.0f);glVertex2f( -16, 16);

        glEnd();



        glPopMatrix();
    }

    glDisable(GL_BLEND);
}

Spongi [27.01.2009 15:35:45]

#

glAlphaFunc(GL_GREATER,0.1f);
glEnable(GL_ALPHA_TEST);

vehkis91 [31.01.2009 00:37:32]

#

Tuossa tapahtuu sillen, että jos kuvassa on valmiina alpha-kanava, niin se häipyy kokonaan ja jos alpha-kanavaa ei oo määritelty niin ei mitään taas häviä. :/

EDIT: Olisko mahdollista sellainen, että voisi vaan laittaa yhden värin läpinäkyväksi samalla tyylillä kuin sdl:ssä?

User137 [31.01.2009 15:18:09]

#

Edelleen hankala sanoa noilla tiedoilla missä ongelma on. Piirtofunktio oli ok ainakin jos se toimi ilman alphaa? Huomaan että käytit ortho tilaa (?), syvyystarkistus pitää olla sillon pois päältä.

glDisable(GL_DEPTH_TEST);

vehkis91 [01.02.2009 00:21:41]

#

Tällaiselta näyttää alustus:

//OpenGL-asetukset
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, SCREEN_BPP);

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

//Asetetaan näyttö: 800x600x32
naytto=SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_REAL_HEIGHT, SCREEN_BPP, SDL_OPENGL );//| SDL_HWSURFACE | SDL_DOUBLEBUF);
if (!naytto) //virhe
{
    fprintf(stderr, "Resoluution vaihto ei onnistunut: %s\n", SDL_GetError());
    SDL_Quit();
    return EXIT_SUCCESS;
}

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, SCREEN_WIDTH, SCREEN_REAL_HEIGHT);
glOrtho(0.0f, SCREEN_WIDTH, SCREEN_REAL_HEIGHT, 0.0f, -1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDisable(GL_DEPTH_TEST);

Ja tässä vielä se piirtofunkkari:

void player::Draw()
{
    glAlphaFunc(GL_GREATER,0.1f);
    glEnable(GL_ALPHA_TEST);

    if(state==false)
    {
        glLoadIdentity();
        glBindTexture(GL_TEXTURE_2D, this->Kuvat[1]);

        glPushMatrix();

        glTranslatef(this->x, this->y, 0.0f);
        glRotatef(-(this->suunta), 0.0f, 0.0f, 1.0f );

        glBegin( GL_QUADS );

            glTexCoord2f(0.0f,0.0f);glVertex2f(-16, -16);
            glTexCoord2f(1.0f,0.0f);glVertex2f( 16, -16);
            glTexCoord2f(1.0f,1.0f);glVertex2f( 16, 16 );
            glTexCoord2f(0.0f,1.0f);glVertex2f( -16, 16);

        glEnd();

        glPopMatrix();
    }

    else
    {
        glLoadIdentity();

        glBindTexture(GL_TEXTURE_2D, this->Kuvat[0]);

        glPushMatrix();

        glTranslatef(this->x, this->y, 0.0f);
        glRotatef(-(this->suunta), 0.0f, 0.0f, 1.0f );

        glBegin( GL_QUADS );

            glTexCoord2f(0.0f,0.0f);glVertex2f(-16, -16);
            glTexCoord2f(1.0f,0.0f);glVertex2f( 16, -16);
            glTexCoord2f(1.0f,1.0f);glVertex2f( 16, 16 );
            glTexCoord2f(0.0f,1.0f);glVertex2f( -16, 16);

        glEnd();



        glPopMatrix();
    }

    glDisable(GL_ALPHA_TEST);
}

User137 [01.02.2009 10:17:32]

#

Tällaset on itellä vielä alustuksen mukana (GL_ALPHA_TEST ei itseasiassa tee mitään erikoista ellet käytä syvyyttä, nopeampi? Ei tietoa):

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

edit: Blaze nuo jo mainitsikin. Pidä ne vaan mukana, jos ei toimi niin muualla mättää.

Metabolix [02.02.2009 22:25:18]

#

Tarkista tosiaan, ettet kutsu vääriä funktioita väärässä paikassa, esimerkiksi glEnablea kesken piirron (glBegin-glEnd). Lisäksi olen hieman skeptinen tuon graphics_surface_to_texture-funktion suhteen, koska itse en ainakaan saanut SDL-funktioilla kopioitua pintaa toiselle niin, että alfakanavakin olisi siirtynyt. Se ainakin on melko varmaa, että SDL_BlitSurface ei sitä kopioi. Kaikkea muutakin kokeilin, ja mikään kirjaston funktioista ei oikein osannut käsitellä alfakanavaa järkevästi.

GL:n puolesta voit testata toiminnan tekemällä perinteisen xor-tekstuurin:

GLuint xor_texture() {
  GLuint texture;
  char xor_map[256 * 256 * 4];
  for (int i = 0; i < 256; ++i) {
    for (int j = 0; j < 256; ++j) {
      for (int k = 0; k < 4; ++k) {
        xor_map[(i * 256 + j) * 4 + k] = i ^ j;
      }
    }
  }
  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_2D, texture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, xor_map);
  return texture;
}

Jos tämä toimii, vika on luultavasti juuri tuossa, missä arvelin. Voit joko tallentaa PNG-kuvat valmiiksi RGBA-formaatissa ja jättää funktiossa tehtävän muunnoksen (SDL_BlitSurface ja image-pinta) pois tai käyttää glpng-kirjastoa. Lataussivut ovat näköjään hävinneet, vain uutiset ovat jäljellä. Pidän siitä itse saatavilla tiedostoja ja esimerkkiä, kun aiemmilla kysyjillä oli niin paljon vaikeuksia sen kanssa.

Blaze [02.02.2009 23:43:17]

#

Metabolix kirjoitti:

Lisäksi olen hieman skeptinen tuon graphics_surface_to_texture-funktion suhteen, koska itse en ainakaan saanut SDL-funktioilla kopioitua pintaa toiselle niin, että alfakanavakin olisi siirtynyt.

En nyt muista, oisko se taika tuossa save & restore alpha blending attributes -kommenttien alla, mut tuo koodi on toimivasta softanpätkästä kopioitu sellaisenaan, ja siitä menen takuuseen.

Alphablittailu pelkällä SDL:llä on sitten oma taiteenlajinsa: viimeksi kun googletin, paras tapa oli varastaa pygamen toteutus.

Metabolix [03.02.2009 00:22:39]

#

Blaze kirjoitti:

En nyt muista, oisko se taika tuossa save & restore alpha blending attributes -kommenttien alla,

Aivan, jostain syystä en ole huomannut tuota kokeilla. Dokumentaatio tosiaan sanookin, että RGBA->RGBA ilman SRCALPHA-lippua kopioi sen datan suoraan. Olen kuitenkin yrittänyt SDL_GetRGBA-funktiollakin, ja sekään ei jostain syystä toiminut odotetusti. Kiitokset tästä.

Koodin toimivuudesta kuitenkin sen verran, että tuolta esikääntäjäpätkää edeltävältä riviltä (SDL_CreateRGBSurface) puuttuu pilkku. pwned. :)

vehkis91 [03.02.2009 08:58:55]

#

En kylläkään ole vielä testannut tuota Blazen pätkää, koska ajattelin, että olisi mahdollista vaan tehdä jokin väri läpinäkyväksi tyyliin:

SDL_SetColorKey()...

Mut pitää kokeilla jos saisin pelaan...

Metabolix [03.02.2009 11:04:02]

#

SetColorKey ei vaikuta pinnan sisältämään pikselidataan millään tavalla, vaan se kertoo SDL:n funktioille, että kyseisen värinen pikseli pitää hypätä yli SDL_BlitSurface-funktiossa.

Tuollaisenkin pinnan voit Blazen funktiolla kopioida tyhjälle (mustalle ja läpinäkyvälle) pohjalle, jolloin lopputulos on haluamasi.


Sivun alkuun

Vastaus

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

Tietoa sivustosta