/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
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);



Søg
Reklame
Statistik
Spørgsmål : 177577
Tips : 31968
Nyheder : 719565
Indlæg : 6409071
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste