Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: gluOrtho2D, koordinaatit pikselin pielessä

Sivun loppuun

Tumpelo [17.09.2008 17:47:10]

#

Käytän OpenGL:ää eräissä projekteissani kaksiulotteisen grafiikan piirtämiseen, ja sinänsä homma kyllä toimii, pienen bugin säestämänä. Kun luon ikkunan ja asetan OpenGL:n projektiot, niin (0, 0) ja (ikkunan_leveys, ikkunan_korkeus) koordinaatit heittävät yhdellä pikselillä. Eli jos piirrän kohtaan (0, 0) punaisen pikselin, se ei näy vaan on siirtynyt yhden pikselin verran ylöspäin, pois näytöstä, eli jos piirrän sen kohtaan (0, 1) niin se näkyy (ei siis virhettä vaakakoordinaatissa). Jos haluan (ikkunan_leveys, ikkunan_korkeus) kohtaan pikselin, sekään ei näy vaan nyt täytyy x-koordinaatista vähentää yksi pikseli. Mielelläni haluaisin että koko näytön alueella olisi täsmällinen pikselitarkkuus ja alkukohta olisi (0, 0) jne.

Tässä vähän koodia:

glfwInit(); // Alustetaan GLFW
glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 0); // Ei reunanpehmennystä
glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE); // Ikkunan kokoa ei voi muuttaa

if (!glfwOpenWindow(WIDTH, HEIGHT, 8, 8, 8, 0, 0, 0, GLFW_FULLSCREEN)) // Onnistuuko ikkunan luonti
{
	glfwTerminate();
	exit(EXIT_FAILURE);
}

...

glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, WIDTH, HEIGHT, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

EDIT: Seuraan huvittuneena minkä otsikon moderaattori päättää jättää lopulliseksi. Ei kai siinä, omani kieltämättä oli huono.

Metabolix [17.09.2008 17:58:45]

#

Nyt kannattaa muistaa tällainen mielenkiintoinen asia, että OpenGL:n koordinaatisto on tosiaan matemaattinen eikä pikselipohjainen. Jos siis ikkunan vasen alakulma on kohdassa (0, 0), tämä tosiaan tarkoittaa vasemman alakulman pikselin vasenta alakulmaa. Pikselin keskikohta sen sijaan on kohdassa (0,5, 0,5), jos koordinaatiston yksikkö vastaa pikseliä. Olet poistanut antialiasoinnin käytöstä, joten OpenGL arpoo jollakin sumealla logiikalla (luultavasti sen mukaan, miten nyt liukuluku sattuu pyöristymään) jonkin pyydettyä koordinaattia ympäröivistä neljästä pikseleistä, sinun huonoksi onneksesi ilmeisesti sen ruudun ulkopuolelle jäävän.

Ohjelma ehkä toimii haluamallasi tavalla, jos vähennät kaikista glOrthon koordinaateista puolikkaan, jolloin koordinaatit (0, 0) ja (W-1, H-1) osuvat vastaavien kulmapikselien keskelle. En kuitenkaan mene asiasta takuuseen, sen verran vähän olen asiaan perehtynyt. :)

Tumpelo [17.09.2008 18:07:32]

#

Tämä tosiaankin on ollut tiedossa, mutta kuvittelisin että pikselitarkkuuteen olisi silti jotenkin mahdollista päästä. Kokeilin tuon puolikkaan vähentämistä, mutta siltikään pikselit eivät mene aivan täysin oikein. Onko OpenGL:ssä joitain funktioita joilla voitaisiin muuttaa sen suhtautumista pikselin valintaan?

EDIT: Ei, kyllä se silti näyttäisi toimivan, unohdin vähentää puolikkaan myös right ja bottom parametreista. Nyt näyttää siis tältä ja ainakin pikaisella testauksella toimii pikselintarkasti:

gluOrtho2D(-0.5, WIDTH-0.5, HEIGHT-0.5, -0.5);

kpzpt [18.09.2008 11:51:16]

#

Hei!

Eikös gl myöskin pitänyt vastaavan käskyn.
mitäs eroa on käyttää glu taikka gl orthoa ??

siis muuta kuin että toinen on gl ja toinen glu ;)

onko toiminnallisia eroja ??

gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrtho( -(width/2),width/2,-(height/2),height/2,20f,-20f );
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();

vain syvyys ??

minä elän käsityksessä, että, jos ei tarvitse glulookat() käskyä.
niin käytän aina tuota gl orthoa. ei tarvitse new glu() käskyä pienissä projekteissani.

( en tosin tunnekkaan kaikki glu ominaisuuksia, käytän sitä siis vain glulookat() kanssa )

//----

kiitos,,

Metabolix [18.09.2008 12:09:06]

#

OpenGL manual kirjoitti:

gluOrtho2D sets up a two-dimensional orthographic viewing region. This is equivalent to calling glOrtho with near=-1 and far=1.

Voisit ehkä ottaa asioista itsekin selvää, ennen kuin lähettelet aiheeseen liittymättömiä viestejä, vai mitä?

pieslice [19.09.2008 00:24:25]

#

Pistän tämän pätkän jällen kerran näkyville.
Eli pikselintarkka 2d opengl:ssä

    const int width     = ruudun_leveys_x;
    const int height    = ruudun_leveys_y;

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    gluOrtho2D( 0, width, height, 0 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0.375, 0.375, 0.0 );

Miksi toimii?
viimeinen glTranslatef() siirtää koordinaatteja sen verran että koordinaatiston pisteet siirtyvät ikään kuin "pikselien keskelle" ja rasteroituvat pikselin tarkkuudella.

Tuo perus-modelview-matriisi (missä pikseleitä offsetattu tuo 0.375 yksikköä) pitää sitten muistaa säilyttää koko 2d-rasteroinnin ajan, eli jos teet jotain muita matriisioperaatioita modelview-matriisilla muista tallettaa tuo perusmodelview glPushMatrix() ja palauttaa glPopMatrix() kutsuilla.

Tumpelo [19.09.2008 10:49:44]

#

Onko sillä väliä siirtääkö modelview matriisia tuon 0.375 vai asettaako orthoon nuo edellämainitut arvot (vai pitäisikö laittaa sinnekin 0.375? Mistä se tulee)?

Metabolix [19.09.2008 12:13:32]

#

Ei ole tietääkseni mitään (ainakaan speksiin tai muuhun selvään auktoriteettiin nojautuvaa) perustetta, miksi juuri 0.375 pitäisi asettaa. Sen sijaan tietääkseni on hyviä perusteita, miksi juuri 0.5 on oikein (kuten selitin). Lopputulos on kuitenkin näennäisesti sama kokonaisluvuilla pelattaessa, koska kummassakin saatu liukuluku osuu oikean pikselin alueelle. Minusta on myös järkevämpää ja loogisempaa asettaa tuo suoraan perspektiiviin, koska sitähän sillä on tarkoitus säätää eikä tarvitse huolehtia matriisin tallentamisesta ja palauttamisesta. Heppoisia perusteita pieslicen tavalle (glTranslate) löytyy, jos samaan kuvaan on tarkoitus piirtää myös muuta kuin pikseligrafiikkaa.

Toki saa valaista asiaa, jos tuossa on jotain aivan erityisen hienoa ja oikeaa. ^^

User137 [19.09.2008 18:54:07]

#

Onko varmaa että 0.5 pitäisi vähentää? Yläkulman pikselin jos piirtää quadina niin se olisi 0,0 - 1,1. Olen olettanut että 0,0 tarkoittaa sen kulmapikselin nurkkaa. Mutta se vaihtelee näytönohjaimittain hieman, ainakin vanhoissa.

Tietty kun ikkunan kanssa on tekemisissä niin on otettava huomioon mitä leveys/korkeus muuttujia käyttää. Ikkunan leveys ja korkeus muuttujat saattaa kattaa reunat ja otsikkorivin.

pieslice [19.09.2008 19:08:59]

#

Tumpelo kirjoitti:

Onko sillä väliä siirtääkö modelview matriisia tuon 0.375 vai asettaako orthoon nuo edellämainitut arvot (vai pitäisikö laittaa sinnekin 0.375? Mistä se tulee)?

Tuo 0.375 oli mainittu jossain opengl-tutoriaalissa vuonna kivi, se on sellainen "tried and true"-arvo. Eli siirtää juuri sen verran että se virtuaalirasteroija menee "pikselin keskelle". Joissain tapauksissa tuo 0.5 saattaa pyöristyä yli "pikselin keskeltä" ja rasteroiutua yhden pikselin vinoon.

Hankala kuvailla.


Sivun alkuun

Vastaus

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

Tietoa sivustosta