Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: OpenGL takana olevat polygonit vilkkuvat päälle

Sivun loppuun

Kray [23.03.2008 20:33:17]

#

En millään käsitä syytä, kun takana olevat polygonit näkyvät päällä, vaikka GL_CULL_FACE on päällä. :( Sama ongelma ollut useammankin kerran.

Metabolix [23.03.2008 20:36:31]

#

Tuo vaikuttaa vain siihen, piirretäänkö polygonit, joita katsotaan takapuolelta. Eri kohdissa olevia polygoneja varten sen sijaan on syvyyspuskuri.
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

Kray [23.03.2008 20:37:53]

#

Tuo oli päällä...
Edit: DEPTH_BUFFER_BIT siivotaan moneen kertaan...
Edit2: Eli ei auttanut...

crafn [24.03.2008 13:22:15]

#

Sit ois hyvä nähä sitä sun koodia. Yleensä syvyyspuskuri kannattaa tyhjentää ainoastaan juuri ennen piirtoa.

Kray [24.03.2008 13:36:01]

#

Tässä kaikki piirtoon vaikuttavat pätkät (en siivonnut yhtään, copy+paste vain):

init:
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   	GLfloat mat_shininess[] = { 50.0 };
   	GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
   	glShadeModel (GL_SMOOTH);
   	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
   	//glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glViewport(0, 0, uti.width, uti.height);

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);
	glEnable(GL_COLOR_MATERIAL);
	//glEnable(GL_NORMALIZE);
	glEnable(GL_CULL_FACE);
	//glColorMaterial(GL_FRONT, GL_DIFFUSE);
	glPolygonMode(GL_FRONT,GL_DIFFUSE);

piirtolooppi:
glClearColor(0.6f, 0.95f, 1.0f, 1);
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		glMatrixMode (GL_MODELVIEW);
		glLoadIdentity ();
		glClear (GL_DEPTH_BUFFER_BIT);
		glViewport(0, 0, uti.width, uti.height);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(40, ((double)uti.width)/(uti.height), 0, 500);
		glMatrixMode (GL_MODELVIEW);
		glLoadIdentity ();
		glClear (GL_DEPTH_BUFFER_BIT);

		glColor3f(0.5,0.1,0.1);


   cam.settolook();

   model.Draw();

User137 [24.03.2008 20:26:14]

#

[Viilaus]
Miksi kutsut glClear() 3 kertaa, ja glLoadIdentity() 2 kertaa peräkkäin? Toisekseen GL_PROJECTION ei tarvitse määrätä kuin ikkunan luodessa ja kokoa muutettaessa, ja sama ViewPort:lle. Ellet käytä kahdenlaista projektiota, esim ortho-moodilla piirtää tekstiä 3d:n päälle tms.
[/Viilaus]

model.Draw(); on kuitenkin tässä ongelmassa varmaankin se ratkaisun sisältävä käädipätkä.

pieslice [25.03.2008 00:30:24]

#

Jos GL_CULL_FACE on oikeasti päällä ja asetettu oikein, mutta backfacet silti näkyvät, on modelissasi jotain häikkää. OpenGL:hän tietää polygonin suunnan vain ja ainoastaan verteksien järjestyksestä. Se, että kumpi puoli onkaan backface määritellään glCullFace( GLenum mode ) funktiolla joka syö mode parametrikseen GL_FRONT, GL_BACK (oletus, tätä useimmiten käytetään) tai GL_FRONT_AND_BACK. Jälkimmäistä ei kannata laittaa parametriksi :)

Kyse voi olla myös z-fightista, eli z-bufferin tarkkuus ei riitä erottelemaan kahta toisiaan lähellä olevaa polygonia jolloin ne piirtyvät 'ristiin'. Lopputulos on usein juuri vilkkumista.

Asiaan ei tällöin usein auta muu kuin z-bufferin tarkkuuden nosto (nykyään luulisi z-bufferin automaattisesti olevan 32-bittinen) tai modelin viilaus siten että z-fightia ei pääse syntymään, mutta joissain tapauksissa z-fightia voi vähentää glDepthFunc modea säätämällä.

Metabolix [25.03.2008 02:12:19]

#

Tietyt mallin virheet (väärään suuntaan kiertävät polygonit) voit huomata ottamalla GL_CULL_FACEn pois käytöstä, jolloin polygoineista piirretään molemmat puolet ja näkyvä osa ratkeaa vain syvyyspuskurin avulla.

Kray [25.03.2008 15:00:05]

#

Aha... Olin tehnyt sen wings3d:llä ja konvertoinut sen... Kiitos kuitenkin.
Edit: Mitä laitan siihen glDepthFunc:iin

pieslice [26.03.2008 00:00:21]

#

kray kirjoitti:

Mitä laitan siihen glDepthFunc:iin

Googleta.
Eka osuma vie opengl:n dokumentaatioon.

Kray [26.03.2008 07:33:58]

#

Kyllä minä sen löysin, kysyin minkä niistä parametreista laitan siihen.

Metabolix [26.03.2008 21:27:17]

#

Sen, joka sopii tarkoituksiisi. Jos et tiedä asiasta, niin älä koske; oletusasetus (GL_LESS) on luultavasti juuri se, mitä kaipaatkin, ja vika on mitä todennäköisimmin jossain muualla.

Kun nyt toivottavasti käytät SDL:ää tai muuta käytännöllistä kirjastoa OpenGL:n alla, voisit kysäistä siltä, onko syvyyspuskuri varmasti käytössä. Oletko myös nyt aivan varma, että tiedät, mikä oikeastaan on ongelma? Mitä tapahtuu, jos piirrät piirtokoodissa keskelle ruutua osittain päällekkäin eri syvyyksille kaksi erilaista kolmiota? Kumpi näkyy, vaikuttaako piirtojärjestys asiaan jne?

User137 [27.03.2008 03:05:59]

#

Muistin juuri erään pikkuseikan joka tuollakin huomautetaan:
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/perspective.html

"Because r approaches infinity as zNear approaches 0, zNear must never be set to 0."

Toisinsanoen kokeile tämän tilalle:
gluPerspective(40, ((double)uti.width)/(uti.height), 0, 500);

vaikka:
gluPerspective(40, ((double)uti.width)/(uti.height), 0.1, 500);

Jos tuo ei auta niin käytä pienempää objektin skaalausta, esim ihmisen korkeus voisi suhteellisesti OpenGL koordinaateissa olla 0-1, eikä 0-180 tai suurempaa. Näillä asioilla on merkitystä siihen miten syvyyspuskuri käyttäytyy pintojen leikatessa toisiaan, ja käytännössä aiheuttaa välkkymistä.

Tai jos piirrät 2 pintaa täsmälleen samoilla koordinaateilla päällekkäin, ne välkkyvät takuuvarmasti asetuksista huolimatta.


Sivun alkuun

Vastaus

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

Tietoa sivustosta