| 
					
							
        
    
        
						
			 | 
			
			
					    
					
        
         
          
         
	
            | OpenGL - forklaring på Viewport (omregning~ Fra : Doe | 
  Dato :  13-08-06 23:48 |  
  |  
 
            width = 640;
 height = 480;
 Hvis jeg har følgende opsat i min OpenGL skærm og rendering kode:
 ResizeGLScene:
 glViewport(0, 0, width, height);
 gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 100.0f);
 RenderScene:
 glBegin(GL_POINTS);
 glVertex3f(0.0f, 0.0f, 0.0f);
 glEnd();
 Punktet 0,0,0 er jo ret nem at finde (det er midten), men hvordan finder jeg 
 ud af mine yderste X og Y koordinater i de 4 hjørner!? Det afhænger jo meget 
 af min Z-værdi og hvis jeg f.eks. ændre Z med:
 glTranslatef(0.0f, 0.0f, -10.0f);
 .... bliver X og Y jo noget helt andet. Så meget forstår jeg, men jeg forstår 
 ikke omregningen eller hvordan jeg finder X,Y?    Er der nogen der kan 
 hjælpe med at få mig til at forstå det?
            
              |   |   
            
        
 
            
         
           Bent Frøslev (14-08-2006) 
         
	
            | Kommentar Fra : Bent Frøslev | 
  Dato :  14-08-06 12:19 |  
  |  
 
            > width = 640;
 > height = 480;
 >
 > Hvis jeg har følgende opsat i min OpenGL skærm og rendering kode:
 >
 > ResizeGLScene:
 > glViewport(0, 0, width, height);
 > gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 100.0f);
 >
 > RenderScene:
 > glBegin(GL_POINTS);
 > glVertex3f(0.0f, 0.0f, 0.0f);
 > glEnd();
 >
 > Punktet 0,0,0 er jo ret nem at finde (det er midten), men hvordan finder 
 > jeg ud af mine yderste X og Y koordinater i de 4 hjørner!? Det afhænger jo 
 > meget af min Z-værdi og hvis jeg f.eks. ændre Z med:
 >
 > glTranslatef(0.0f, 0.0f, -10.0f);
 >
 > ... bliver X og Y jo noget helt andet. Så meget forstår jeg, men jeg 
 > forstår ikke omregningen eller hvordan jeg finder X,Y?    Er der nogen 
 > der kan hjælpe med at få mig til at forstå det?
 >
 >
 Betragt det som du står i spidsen af en ligebenet trekant, hvor vinklen i 
 dit tilfælde er 45 grader. Trekanten ligger i yz-planet. Trekanten angiver 
 grænsen for den synlige del af din model/verden. Jo længere du bevæger dig 
 væk i z-retningen (væk fra spidsen af trekanten), jo "mere" kan man se. Det 
 er helt analogt til den måde dine øjne eller et kamera ser verden på.
 Så højden af "den synlige verden" er så naturligvis en funktion af z: y = 
 z/sin(fovy). Dvs. for din near/far planer er y: y_near = 1/sin(45) = 1,4 og 
 y_far = 100/sin(45) = 141,4.
 Har du overvejet om det du vil modellere egner sig bedre til til 2D end 3D? 
 I såfald kan du bruge gluOrtho2D. Hvilket kan gør det hele noget lettere 
 hvis du alligevel ikke bruger dybden (z) til noget.
 /b 
            
              |   |   
            
        
 
            
         
           Doe (14-08-2006) 
         
	
            | Kommentar Fra : Doe | 
  Dato :  14-08-06 13:24 |  
  |   
            > Betragt det som du står i spidsen af en ligebenet trekant, hvor vinklen i 
 > dit tilfælde er 45 grader. Trekanten ligger i yz-planet. Trekanten angiver 
 > grænsen for den synlige del af din model/verden. Jo længere du bevæger dig 
 > væk i z-retningen (væk fra spidsen af trekanten), jo "mere" kan man se. 
 > Det er helt analogt til den måde dine øjne eller et kamera ser verden på.
 >
 > Så højden af "den synlige verden" er så naturligvis en funktion af z: y = 
 > z/sin(fovy). Dvs. for din near/far planer er y: y_near = 1/sin(45) = 1,4 
 > og y_far = 100/sin(45) = 141,4.
 
 Hmmm.. jeg er ikke helt med, for hvis jeg med mine tidligere tal ser på max 
 Y værdien, når glTranslatef står til -1 i z:
 glTranslatef(0.0f, 0.0f, -1.0f);
 
 så er dette det øverste Y jeg kan tegne:
 glVertex3f(0.0f, 0.41f, 0.0f);
 
 Er det fordi jeg skal trække 1 fra eller er det tilfældigt, at 0,41 er 1 fra 
 1,41?
 
 > Har du overvejet om det du vil modellere egner sig bedre til til 2D end 
 > 3D? I såfald kan du bruge gluOrtho2D. Hvilket kan gør det hele noget 
 > lettere hvis du alligevel ikke bruger dybden (z) til noget.
 
 Njoo, jeg har overvejet det men meningen er også netop at forstå 3D 
 principperne således, at jeg sidenhen kan smide noget 3D grafik i det.
 
 
  
            
             |   |   
            
        
 
            
         
            Bent Frøslev (14-08-2006) 
         
	
            | Kommentar Fra : Bent Frøslev | 
  Dato :  14-08-06 20:05 |  
  |   
            >> Så højden af "den synlige verden" er så naturligvis en funktion af z: y = 
 >> z/sin(fovy). Dvs. for din near/far planer er y: y_near = 1/sin(45) = 1,4 
 >> og y_far = 100/sin(45) = 141,4.
 
 Trekants beregninger ligger vist lige lidt længere væk end jeg troede. 
 Formlen er y = z*tan(fovy/2). Den halve vinkel fordi vi kun ser på afstanden 
 fra centerlinien gennem 0,0 og op til maks. y.
 
 Resultatet bliver så
 y_near  = 1*tan(45/2) = 0,414
 y_far = 100*tan(45/2) = 41,42
 
 > Hmmm.. jeg er ikke helt med, for hvis jeg med mine tidligere tal ser på 
 > max Y værdien, når glTranslatef står til -1 i z:
 > glTranslatef(0.0f, 0.0f, -1.0f);
 >
 > så er dette det øverste Y jeg kan tegne:
 > glVertex3f(0.0f, 0.41f, 0.0f);
 
 Ja, det lyder rigtigt.
 
 > Njoo, jeg har overvejet det men meningen er også netop at forstå 3D 
 > principperne således, at jeg sidenhen kan smide noget 3D grafik i det.
 >
 okay.
 
 /b 
 
 
  
            
             |   |   
            
        
 
            
         
             Doe (14-08-2006) 
         
	
            | Kommentar Fra : Doe | 
  Dato :  14-08-06 22:57 |  
  |   
            > Trekants beregninger ligger vist lige lidt længere væk end jeg troede. 
 > Formlen er y = z*tan(fovy/2). Den halve vinkel fordi vi kun ser på 
 > afstanden fra centerlinien gennem 0,0 og op til maks. y.
 >
 > Resultatet bliver så
 > y_near  = 1*tan(45/2) = 0,414
 > y_far = 100*tan(45/2) = 41,42
 
 Det får jeg fint til at passe, men kun på Y-aksen. Hvad med X-aksen, for det 
 kan ikke regnes ud på samme måde, da det ikke er et kvadrat (x=640, y=480 
 pixels).
 
 Man kunne dividere X med Y men er det måden?
 
 x_near  = 1*tan(45/2) * (x/y) = 0,552
 x_far = 100*tan(45/2) * (x/y) = 55,213
 
 
  
            
             |   |   
            
        
 
            
         
             Doe (14-08-2006) 
         
	
            | Kommentar Fra : Doe | 
  Dato :  14-08-06 23:31 |  
  |   
            > Resultatet bliver så
 > y_near  = 1*tan(45/2) = 0,414
 > y_far = 100*tan(45/2) = 41,42
 
 Hmm.. hvis jeg har denne linie i Visual C++
 
 float MAX_Y = 1*tan(45/2);
 
 ... får jeg resultatet 0.557851. På min lommeregner får jeg 0,414!?
 Jeg har prøvet at inkludere både math.h og cmath.
 
 float MAX_Y = tan((double)2);
 
 ... giver -2.185039 men 0,035 på min lommeregner!? Det ser helt forkert ud. 
 Bruger jeg den forkerte funktion?
 
 
  
            
             |   |   
            
        
 
            
         
              Bertel Brander (14-08-2006) 
         
	
            | Kommentar Fra : Bertel Brander | 
  Dato :  14-08-06 23:53 |  
  |  
 
            Doe wrote:
 >> Resultatet bliver så
 >> y_near  = 1*tan(45/2) = 0,414
 >> y_far = 100*tan(45/2) = 41,42
 > 
 > Hmm.. hvis jeg har denne linie i Visual C++
 > 
 > float MAX_Y = 1*tan(45/2);
 > 
 > .. får jeg resultatet 0.557851. På min lommeregner får jeg 0,414!?
 > Jeg har prøvet at inkludere både math.h og cmath.
 Dette giver 0.414214:
     MAX_Y = 1*tan((M_PI/4)/2);
     std::cout << MAX_Y << std::endl;
 Der er i øvrigt næsten aldrig nogen grund til at
 bruge float, brug double.
 -- 
 Absolutely not the best homepage on the net:
 http://home20.inet.tele.dk/midgaard
But it's mine - Bertel
            
              |   |   
            
        
 
            
         
               Doe (15-08-2006) 
         
	
            | Kommentar Fra : Doe | 
  Dato :  15-08-06 00:20 |  
  |  
 
            > Dette giver 0.414214:
 >    MAX_Y = 1*tan((M_PI/4)/2);
 >    std::cout << MAX_Y << std::endl;
 Dette afføder blot et par nye spørgsmål:
 1) Det giver kun 0,007 på min lommeregner.
 2) VC++ kan ikke kompile det med M_PI, da det er en ukendt konstant. Jeg har 
 ellers inkluderet:
 #define _USE_MATH_DEFINES
 Det ser ud til, at der findes en M_PI_4 men den kan heller ikke genkendes 
 som konstant.
 Mangler jeg noget opsætning i min kompiler, at den skal godtage globale 
 konstanter eller hvorfor vil den ikke kendes ved dem?
 3) Det er sikkert logisk for nogen, men hvorfor skal pi nu lige pludselig 
 blandes ind i det?    Hvis jeg skal kunne regne max og min Y ud og jeg har 
 sat FOW til f.eks. 45, bliver jeg jo nødt til at inkludere de 45 på én eller 
 anden måde i formlen - ellers kan jeg ikke regne det ud?
 > Der er i øvrigt næsten aldrig nogen grund til at
 > bruge float, brug double.
 Ok, tak.
            
              |   |   
            
        
 
            
         
                Bertel Brander (15-08-2006) 
         
	
            | Kommentar Fra : Bertel Brander | 
  Dato :  15-08-06 00:34 |  
  |  
 
            Doe wrote:
 >> Dette giver 0.414214:
 >>    MAX_Y = 1*tan((M_PI/4)/2);
 >>    std::cout << MAX_Y << std::endl;
 > 
 > Dette afføder blot et par nye spørgsmål:
 > 
 > 1) Det giver kun 0,007 på min lommeregner.
 I C++ er der 2*Pi radianer i en cirkel, på nogle lommeregnere er
 der 360 grader.
 > 2) VC++ kan ikke kompile det med M_PI, da det er en ukendt konstant. Jeg har 
 > ellers inkluderet:
 > #define _USE_MATH_DEFINES
 > Det ser ud til, at der findes en M_PI_4 men den kan heller ikke genkendes 
 > som konstant.
 > Mangler jeg noget opsætning i min kompiler, at den skal godtage globale 
 > konstanter eller hvorfor vil den ikke kendes ved dem?
 M_PI er tilsyneladende ikke standard.
 MinGW definerer den med:
 #define M_PI      3.14159265358979323846
 -- 
 Absolutely not the best homepage on the net:
 http://home20.inet.tele.dk/midgaard
But it's mine - Bertel
            
              |   |   
            
        
 
            
         
                Doe (15-08-2006) 
         
	
            | Kommentar Fra : Doe | 
  Dato :  15-08-06 00:35 |  
  |   
            > 2) VC++ kan ikke kompile det med M_PI, da det er en ukendt konstant. Jeg 
 > har ellers inkluderet:
 > #define _USE_MATH_DEFINES
 > Det ser ud til, at der findes en M_PI_4 men den kan heller ikke genkendes 
 > som konstant.
 > Mangler jeg noget opsætning i min kompiler, at den skal godtage globale 
 > konstanter eller hvorfor vil den ikke kendes ved dem?
 
 Foreløbigt løst med:
 const double M_PI = 2.0 * asin(1.0);
 
 
  
            
             |   |   
            
        
 
    
 
					
					 
			 | 
			
				
        
			 |