Eli mulla on tällainen ongelma, jota en saanut ratkaistua vaikka kuinka googletin. Tarkoituksena on käyttää käyttää SDL:ää ja OpenGl:ää pelimoottorissa, mutta en saa SDL:llä ladattua kuvaa käytettyä OpenGL-tekstuurina. Laitan tähän osan koodeista, jos joku tietäväisempi kertoisi missä vika.
Image.cpp
#include <iostream> #include <string> #include "SDL.h" #include "SDL_image.h" #include "SDL_opengl.h" #include "Image.h" Image::Image(std::string imagefile) { sdlTexture = IMG_Load( imagefile.c_str() ); if(!sdlTexture) { SDL_Quit(); exit(1); } height = sdlTexture->h; width = sdlTexture->w; 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_3D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, sdlTexture->pixels); SDL_FreeSurface(sdlTexture); } void Image::Draw() { //Draw SQUARE glTranslatef(x,y,0); glBindTexture(GL_TEXTURE_2D, texture); glBegin( GL_QUADS ); glTexCoord2d(0.0,0.0); glVertex2d(0,0); glTexCoord2d(1.0,0.0); glVertex2d(width,0); glTexCoord2d(1.0,1.0); glVertex2d(width,height); glTexCoord2d(0.0,1.0); glVertex2d(0,height); glEnd(); glLoadIdentity(); }
Image.h
#include <iostream> #include <string> #include "SDL.h" #include "SDL_image.h" #include "SDL_opengl.h" #ifndef IMAGE_H #define IMAGE_H class Image { public: float x; float y; int width; int height; Image(std::string imagefile); void Draw(); private: SDL_Surface* sdlTexture; GLuint texture; }; #endif
main.cpp - Initialize OpenGL
//Initialize OpenGL bool init_GL() { //Clear Color glClearColor(0,0,0,0); //Stuff glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); //Projection glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho(0,SCREEN_WIDTH,SCREEN_HEIGHT,0,-1,1); //Initialize MODELVIEW MATRIX glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); //Error Check if( glGetError() != GL_NO_ERROR ) { return false; } return true; }
main.cpp - SDL ikkunan luonti
if( SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL ) == NULL ) { return false; }
main.cpp - Piirto
glClear( GL_COLOR_BUFFER_BIT ); kuva.Draw(); SDL_GL_SwapBuffers();
Kääntäjä ei anna minkäänlaista erroria, mutta ohjelma ei pysty piirtämään tekstuuria. Näkyviin tulee ainoastaan haluttuun kohtaan kuvatiedoston kokoinen valkeaalue, mutta kuva informaatio puuttuu. Oisko jossain noissa OpenGL-asetuksissa vika?
Kiitos vastauksista jo näin etukäteen.
Tsekkaa putkassa oleva opas aiheeseen liittyen. Toinen mikä tulee mieleen on tuossa Image::Image(std::string imagefile) metodissa mieleen on, että et alusta texture muuttujaa mitenkään, mutta käytät siitä ensinnäkin viitettä ja toisaalta muuttujaa. En osaa suoraan sanoa kuuluuko noiden funktioiden toimiakin noin, mutta muuttujaan tulisi kaiketi alustaa jokin arvo.
Itse ongelma: glTexImage2D-kutsuun on lipsahtanut GL_TEXTURE_3D eikä 2D.
Lisäksi voi olla, että kuvasi formaatti on väärä eli pikselit eivät ole muistissa GL_RGBA:lle sopivassa muodossa. Jos muunnos on tarpeen, voit ottaa mallia koodivinkistäni. Käyttämällä sopivaa muunnosfunktiota säästät ehkä tilaa ja vaivaa, kun ei tarvitse erikseen tarkkailla, että kaikki kuvat on tallennettu 32-bittisinä RGBA-kuvina.
Käsittääkseni tuo glGenTextures() laittaa siihen jonkin generoidun arvon. Korjasin tuon GL_TEXTURE_3D:n GL_TEXTURE_2D:ksi, mutta sama ongelma jatkuu. Kuvat on .png-tiedostoja, joten käsittääkseni niissä pitäisi olla tuo alpha-kanavakin, jos nyt käsitin oikein tuon Metabolixin vinkin. Täytynee vielä noita vinkkejä tutkia, jos niistä saisin jotain irti.
Kokeile, auttaako vinkkifunktioni käyttö glTexImage2D:n paikalla. Turvallisinta tässä tapauksessa on kopioida funktio ensin sellaisenaan.
Käsittääkseni glTexParameteri-funktiot tulisi laittaa glTexImage2D-funktion jälkeen, en nyt jaksa testata tuota.
Ei ole mikään näistä vielä pelittänyt. Kokeilin tuota Metabolixin MySDL_glTexImage2D-funktiota. Laittoin sen Tuonne Image-luokan sisään omaksi funktioksi ja korvasin siitä Image-luokan luontifunktiosta sen glTexImage2D-funktion sillä, mutta sain kääntäessä errorin tuosta MySDL_glTexImage2D-funktion lopussa olevasta glTexImage2D_f()-funktiosta. Eli en saanu testattua sen toimivuuttaa, koska kääntäjä ilmoitti siinä olevasta viasta.
Oma vanha OpenGL+SDL räpellykseni lataa muuten samaan tyylin kuin tuo koodivinkin funktio (oikeastaan kopioin vinkin toimintaperiaatteen, koodi oli vain omaa), mutta minulla glTexImage2D_f() funktion tilalla on glTexImage2D()
Parametritkin olivat jopa samat
En kylläkään tiedä mitä tuo _f tekee. Minullakin kääntäjä herjaa siitä (ei ole olemassa)
Ethän luo/lataa tekstuuria ennen ikkunan luontia, sillä opengl funktiot ovat käytössä vasta, kun ikkuna on luotu.
Kiitos Markus! Ongelma oli aika pitkälti tuossa, että latasin kuvaan tiedot ennen ikkunan luontia. Hieno säädin koodia sen verran, että korvastin GL_TEXTURE_2D kohdat GL_TEXTURE_RECTANGLE_NV:llä, jolloin textuurin cordinaatteina voidaan käyttää pixeliarvoja kuvan korkeudesta ja leveydestä. Alpha kanavan kanssa oli ongelmia vielä, mutta pitänee tutkia tuota Metabolixin koodivinkkiä ja kirjoittaa jonkin sortin funktio, jolla saisin sen alpha-kanavan toimimaan.
Kiitos kaikille avun antajille. Pitäisiköhän tuo lopullinen koodilaittaa tänne malliksi, kunhan sen nyt saan valmiiksi, muiden saman ongelman parissa tappelevien avuksi? Jos nyt täällä sivuilla edes on muita, jotka sellaista tarvitsee :D:D
Kahtelin noita Metabolixin vinkkejä, mutta en niillä saa tuota alphaa toimimaan... valittaa kääntäessä jostain ihmeellisyyksistä. Kokeilin vaihtaa tuon glTexImage2D_f()-funktion ihan glTexImage2D():ksi, mutta sitten se herjasi lisää. Oiskohan jotain vikkelää tapaa saada tuo alphataso aktiiviseksi? Vähän niinkuin SDL:n DisplayFormatAlpha.
Kuvauksesi perusteella minulla on joskus ollut samantyylinen ongelma, tässä on viesti ketju, https://www.ohjelmointiputka.net/keskustelu/
Toivottavasti on apua.
Juuh oli ihan suhteellisen hyödyllistä luettavaa tuo vehkis91:sen laittamat linkki ym. sen takaa löytyvät linkit. En mitään sairaallisen sekavia funktioita kirjoittanut, mutta rupesi toimimaan kuin taika iskusta. Tähän johtaneita toimen pitäitä oli seuraavat:
- Asetin piirrettävän polygonin väriksi
glColor4f(1.0,1.0,1.0,1.0);
- ja lisäsin OpenGL:n alustukseen
glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ja sen lisäksi piirto-ohjelmassa lähdin työstämään tekstuuria läpinäkyvälle pohjalle. Kun aloitti läpinäkyvällä pohjalla, niin pystyin värjäämään kaikki kuvan pixelit myöhemmin vaikka täysin punaisiksi ja toimi moitteettomasti. Jos aloitti vaikka valkealla pohjalla, niin ohjelma ei tajunnut kuvaa oikein hyvin.
Toivottavasti tämä nyt ei ollut aivan älyttömän sekavasti selitetty. Pitänee jatkaa muihin pelimoottorin osiin tästä.
Suunnattomat kiitokset kaikille apua tarjonneille.
Aihe on jo aika vanha, joten et voi enää vastata siihen.