2006. 06. 01. (keresztféléves vizsga!)

A VIK Wikiből

Ez az oldal a korábbi SCH wikiről lett áthozva.

Ha úgy érzed, hogy bármilyen formázási vagy tartalmi probléma van vele, akkor, kérlek, javíts rajta egy rövid szerkesztéssel!

Ha nem tudod, hogyan indulj el, olvasd el a migrálási útmutatót.


infosite alapján

1.)

Phong árnyalás (vigyázat, nem Phong BRDF modell)

  • elv
  • mi a különbség a Gouranud árnyaláshoz képest?
  • milyen koordinátarendszerben vannak a pontok és vektorok
  • az openGL-ben hogyan lehet bekapcsolni?

Megoldás 1.)

  • elv és különbség a Gouraud-hoz képest: sünis könyv 209-210 oldalon <br
Phong-árnyalás Gouraud-árnyalás
Az árnyalási egyenletben szereplő, a fényforrás és a kamera irányába mutató egységvektorokat, illetve a normálvektort interpolálja a háromszög csúcspontjaiban érvényes adatokból, az árnyalási egyenletet minden pixelre külön értékeli ki. A műveleteket ezen vektorok világ-koordinátarendszerbeli koordinátáin kell végrehajtani. A háromszögek csúcspontjaiban értékeli ki a fényforásból odajutó fény visszaverődést. Az illuminációs képlet alkalmazásánál az eredeti felület normálvektorával dolgozik, azaz a tesszeláció során kiadott pontokban a normálvektort is meg kell határozni. A háromszög belső pontjainak színét a csúcspontok színéből lineárisan interpolálja
  • Világkoordinátarendszer
  • nem lehet (csak GL_FLAT (konstan árnyalás) és GL_SMOOTH (Gouraud árnyalás) van )

2.)

A z=0 síkon egy r sugarú, textúrázott golyó gurul az x tengely mentén v sebességgel. A t=0 időpillanatban éppen az origó felett van, a textúra kép felső része a gömb tetéjen z=2r, az alsó rész a gömb alján van z=0. Írjon egy c függvényt, mely az openGL-lel kirajzoltatja a golyót a saját színével (azaz illumináció nélkül) a t időpillanatban GL_QUADS primitívek felhasználásával. A golyó textúráját már átadtuk az openGL-nek a ==text== textúra azonosítóra hivatkozva. A kamera az 1 0 0 pontban van, mindig a gömb közepére néz, függőleges iránya 0 0 1 látószöge 90 fok, az ablak szélesség/magasság aránya 1, az első vágósík távolsaga 0.1, a hátsóé 1000. A következő függvények használata javasolt: ==glLoadIdentity, glRotatef, ...==
(A golyó mozgásállapotának meghatározása 1p, a gömb tesszellációja 5p transzformációk beállítása 4p)

Megoldás 2.)

Vö.:

  • kamerabeállítás - Render() süni 23-25. oldal
  • gomb animáció - Animate() süni 324. oldal
  • gömb explicit egyenlete - getX(),getY(), getZ() süni 71. oldal.
  • paraméteres felületek tesszellációja - Drawit() süni 101-102 oldal
class Gomb {

float x0, y0, z0; // kezdeti poz
float x, y, z;	 // aktual poz
float R;			 // gomb sugar 

public:
	Gomb (float x00,float y00,float z00,float vx0,float vy0,float R0){
			x0=x00; y0=y00; z0=z00; 
			vx=vx0; vy=vy0;
			R=R0;
			}

	float getX(int u, int v){
		return x0+R*cos(2*PI*u)*sin(PI*v);
	}

	float getY(int u, int v){
		return y0+R*sin(2*PI*u)*sin(PI*v);
	}

	float getZ(int u, int v){
		return z0+R*cos(PI*v);
	}

	void Animate(float t){
			x=x0+vx*t;
			y=y0+vy*t;
			z=R;  
			}
	void Drawit(int M, // u felosztások száma
					int N){ // v felosztások száma

		for (int i=0; i<M; i++){
				for (int j=0; j<N; j++){
		//az i,j négyzet négy csúcsa
		glBegin(GL_QUADS);

		//normálvektor kiszámítása
		float nx=getX((i+0.5)/M,(j+0.5)/N)-x0;
		float ny=getY((i+0.5)/M, (j+0.5)/N)-y0;
		float nz=getZ((i+0.5)/M,(j+0.5)/N)-z0;		
		float sum=sqrt(nx*nx+ny*ny+nz*nz);
		
		glNormal3f(nx/sum, ny/sum, nz/sum);

		glTexCoord2f( i/M,	 j/N);	 glVertex3fv(getX( i/M,		j/N),	 getY( i/M,	  j/N),	  getZ( i/M,	  j/N));
		glTexCoord2f((i+1)/M, j/N);	 glVertex3fv(getX((i+1)/M,	j/N),	 getY((i+1)/M,  j/N),	  getZ((i+1)/M,  j/N));
		glTexCoord2f( i/M,	(j+1)/N); glVertex3fv(getX( i/M,	  (j+1)/N), getY( i/M,	 (j+1)/N),  getZ( i/M,	 (j+1)/N));
		glTexCoord2f((i+1)/M, j+/N);	glVertex3fv(getX((i+1)/M,  (j+1)/N), getY((i+1)/M, (j+1)/N),  getZ((i+1)/M, (j+1)/N));
		glEnd();
			}

		}
	}
};

class Gombablak : public Application {

Gomb * gomb
float time;

public: 
	 Gombablak() : application ("gomboc rajzolo moka", 300, 300) {time=0;}
	 void Init();
	 void Render()
			{
			 glClearColor(0,0,0,0);									 // képernyő törlése
			 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
			 glDrawBuffer(GL_BACK);									 // hátsó buffer használata
			 glMatrixMode(GL_PROJECTION);							 //projekciós mátrix mód
			 glLoadIdentity();
			 gluPerspective(90,1, 1, 1000)							// látószög, ablak arány , első vágósík , hátsó vágósík.
			 glMatrixMode(GL_MODELVIEW);							  // modell-nézeti mátrix
			 glLoadIdentity();
			 gluLookAt(1.0, 0.0, 0.0 ,								 // szem pozició  
						  gomb.x, gomb.y, gomb.z,					  // mindig a labda közepét nézzük
						  0.0, 0.0, 1.0)								  // függőleges irány
						  
			 gomb.Drawit(100,100);									  // mondvacsinált paraméterek az M és N-re	
			 SwapBuffers(wglGetCurrentDC());						 //duplabuffer csere
			 wglMakeCurrent(NULL,NULL);

			}

	 Do_a_Step(float dt){
			time+=dt;
			labda(Animate(time);
			Render();
			}

};


3.)

Adott a következő csúcspont árnyaló (Vertex Shader) és pixel árnyaló (pixel Shader)

struct inputs{
	float4 pos:POSITION;
	float3 normal:NORMAL;
	float2 uv:TEXCOORD;
}
struct outputs{
	float4 hpos:POSITION;
float4 color:COLOR0;
}

float 4 main(in float3 color:COLOR0):COLOR
{
	 float 4 c;
	c.xyz=color.xyz;
	c.w=1;
	return c;
}

outputs main(inputs IN)
{
	output OUT;
	OUT.hpos.x=IN.uv.x*IN.Pos.z;
	OUT.hpos.y=IN.uv.y*IN.Pos.z;
	OUT.hpos.z=IN.normal.z;
	OUT.hpos.w=IN.Pos.z;
	OUT.color=normalize(IN.normal);
	return OUT;
}


Mit rajzol fel az ilyen árnyalók mellett a következő openGL program:

GlMatrixMode(GL_MODELVIEW);
GlloadIdentity();
GlLookAt(100, 200, 300,  0,0,0,  0,1,0);
GlMatrixMode(GL_PROJECTION);
GlLoadIdentity();
GluPerspective(90, 1, 0.1, 100);
GlNormal3d(2,0,0);
GlBegin(GL_QUADS);
GlTexCoord2f(0,0);	glVertex3f(100,100,100);
GlTexCoord2f(0,1);	glVertex3f(-20, 30, 150);
GlTexCoord2f(1,1);	glVertex3f(220, -30, -110);
GlTexCoord2f(1,0);	glVertex3f(-30, 100, -150);
GlEnd();


Válasz a kérdésre, rövid indoklással 5p

Megoldás 3.)

A PixelShader semmit nem csinál, csak beállítja az átlátszatlanságot 1-re:

	c.xyz=color.xyz;
	c.w=1;

A VertexShader megváltoztatja a csúcspont koordinátait :

	OUT.hpos.x=IN.uv.x*IN.Pos.z;
	OUT.hpos.y=IN.uv.y*IN.Pos.z;	
	OUT.hpos.z=IN.normal.z;		  //3.koord. = normál vektor 3. koordinátája
	OUT.hpos.w=IN.Pos.z;			  

és a színét is

OUT.color=normalize(IN.normal); //látjuk, hogy a szín csak normálvektortól függ

A program négyszöget rajzol, és közös normálvektor (2,0,0) van. Ennek normalizáltja (1,0,0) tehát négyszög csúcsa piros szín lesz.

A csúcs koordináta számítás:

Pl első csúcsra:

  GlTexCoord2f(0,0);	glVertex3f(100,100,100); //(u,v)=(0,0) 

OUT.hpos.x=IN.uv.x*IN.Pos.z = 0*100=0
OUT.hpos.y=IN.uv.y*IN.Pos.z = 0*100=0
OUT.hpos.z=IN.normal.z = 0
OUT.hpos.w=IN.Pos.z = 100

Ebből az első csúcs: (0,0,0,100) -> (0,0,0)

A többi hasonlóan kiszámíható: (0,1,0) (1,1,0) és (1,0,0)

-- NandorG - 2006.12.31.
-- nam - 2007.01.06.
-- adamo - 2007.05.28.