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(); }
Missä sun glClear() on? Luultavasti noiden olioiden draw-funktioissa vai?
glClear(GL_COLOR_BUFFER_BIT);
tollanen löytyy jokaisen piirtofunktion alusta.
Ota sitten järki käteen ja korjaa asia.
No kato, olinpas taas tyhmä. :S:( Tuohan tietenkin poisti aina edelliset jutut näytöltä... :D
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.
Kannattaa lukea noita SuomiOppaan artikkeleita.
http://www.suomipelit.com/index.php?c=naytaartikkeli&id=59&s=2
Pitääpä vilkaista...
EN vaan saa toimimaan, vaikka yrittäisin mitä... :(
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; }
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
Kuvakaappausta? Miten kuva huononee tai sumenee?
Minkä kokosia teksuuris on? Seki voi vaikuttaa niiden laatuun. Tässä ois vielä mainio tutoriaali tähän liittyen, http://gpwiki.org/index.php/
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.
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); }
glAlphaFunc(GL_GREATER,0.1f); glEnable(GL_ALPHA_TEST);
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ä?
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);
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); }
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ää.
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.
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.
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. :)
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...
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.