Juu, elikkä OpenGL:n koordinaatiojärjestelmä sopii kyllä hienosti 3D peleihin, mutta entäs kun haluan saada tehtyä esim pelin valikot OpenGL:llä, ja vielä niin että ne näkyvät samalla tavalla eri resoluutioilla. Nythän käy niin että jos vaikka 800*600 resolla kohta 1.0, 1.0 on pikseli vasemmassa yläkulmassa, niin jollain toisella resolla se ei olekaan siinä. Saako tuota koordinaatiosysteemiä muutettua mitenkään niin että resoluutiosta huolimatta tietty piste olisi aina tietyssä kohtaa?
Kyllä se on kaikilla resoluutioilla siinä. Olet nyt tehnyt jonkin kriittisen mokan (ehkäpä glViewport-funktion kanssa?) Laitapa hieman alustuskoodia juuri mainitun funktion seutuvilta ja glMatrixMode-juttujen ympäristöstä, niin katsotaan.
Joo no minulla on varmaan tämä kohta koodissa päin seiniä:
glViewport(0,0,System.GetXRes(),System.GetYRes()); glEnable(GL_TEXTURE_2D); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glDisable(GL_DEPTH_TEST); glOrtho(-1, 1, -1, 1, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
Kuinkas tuo tehdään oikein?
EDIT: Ja voisitko selittää mitä nuo Viewport, MatrixMode ja LoadIdentity funktiot tekevät? En ole oikein ottanut selvää niistä vaikka jotain englannin kielisiä tutoja olen lukenut.
glViewport määrää OpenGL:n koordinaattien muunnoksen pikseleiksi (ja samalla myös sen, mitä aluetta ikkunasta OpenGL käyttää). Siksi se on nollasta ikkunan mittoihin: (-1,-1) asetetaan pikseliin (0,0) ja (1,1) ikkunan oikeaan yläkulmaan.
glMatrixMode valitsee OpenGL:n sisäisistä matriiseista yhden muokattavaksi. Tämän jälkeen kaikki matriisioperaatiot muuttavat juuri kyseistä matriisia. (Matriisioperaatioita ovat esimerkiksi glFrustum, glOrtho, glTranslate, glRotate yms.) Tämän ymmärtämiseksi on syytä tutustua hieman OpenGL:n rakenteeseen.
glLoadIdentity lataa valittuun matriisiin identiteettimatriisin, jonka merkittävä ominaisuus on se, että se ei muuta annettua pikseliä mitenkään. Esimerkiksi projektiomatriisi ei tällöin aiheuta lainkaan syvyysvaikutelmaa, koska pisteen z-koordinaatti ei vaikuta mitenkään muihin.
glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Projektio pitää määrittää tässä vaiheessa (vaikkapa glFrustum-funktiolla). glOrthon merkitys on se, että ikkunan saa skaalattua muulle välille kuin (-1,-1) - (1,1) glMatrixMode(GL_MODELVIEW); glLoadIdentity();
Kaikkia ominaisuuksia voit testailla etsimällä tilanteen, jossa ne toimivat, ja muuttamalla sitten arvoja vähitellen (mielellään ihan ajon aikana, niin näet parhaiten).
Okei, muutin koodin tällaiseksi:
glViewport(0,0,System.GetXRes(),System.GetYRes()); glEnable(GL_TEXTURE_2D); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1, 1, -1, 1, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
Ja nyt tuntuu toimivan. Kiitoksia avusta.
tällä taas saa pixel-precise tarkkuuden, eli 1 koordinaattiyksikkö on 1 pikseli. systeemi toimii mutta y-koordinaatti on flipattu eli 0 = alareuna joten käsittele se rasterointifunktioissasi siten etta y = ruudun_korkeus - y;
const int width = screen_x_resolution; const int height = screen_y_resolution; glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluOrtho2D( 0, width, 0, height ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.375, 0.375, 0.0 );
Aihe on jo aika vanha, joten et voi enää vastata siihen.