Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Mai 15, 2024 17:33

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Aspect ratio
BeitragVerfasst: Fr Mai 18, 2012 12:55 
Offline
DGL Member

Registriert: Mi Nov 18, 2009 10:55
Beiträge: 20
Programmiersprache: C++
Hallo.

Ich habe mich leider erst nach einer viel zu langen Pause wieder mit OpenGL beschäftigt und naja, wie auch immer.
Mein Problem ist, dass ich beim Zeichnen eines Quads und Fensteränderungen eine Verzerrung dieses Quads erhalte. :(

Displayliste für alle 2D-GUI-Elemente
Code:
  1.  
  2.    void cGUIManager::generateQuad(float zFar)
  3.    {
  4.       if(generated)
  5.          return;
  6.       float Breite=1, Laenge=1, Tiefe=zFar*-1;
  7.       Quad = glGenLists(1);
  8.       glNewList(Quad,GL_COMPILE);
  9.          glBegin(GL_TRIANGLE_STRIP);
  10.             glVertex3f(-Breite, Laenge,Tiefe);
  11.             glVertex3f(-Breite, -Laenge,Tiefe);
  12.             glVertex3f(Breite, Laenge,Tiefe);
  13.             glVertex3f(Breite, -Laenge,Tiefe);
  14.          glEnd();
  15.       glEndList();
  16.       generated=true;
  17.    }


Berechnung der orth. Proj.-Matrix
Code:
  1.  
  2.             // Ergibt ein Seiterverhältnis von 16:9
  3.             const unsigned short cGraphicengine::DigWndW=640;
  4.             const unsigned short cGraphicengine::DigWndH=360;
  5.             const unsigned short cGraphicengine::DigZFar=100;
  6.             inline void SetToProMa()
  7.             {
  8.                glMatrixMode(GL_PROJECTION);
  9.                glLoadIdentity();
  10.             }
  11.  
  12.             inline void SetToMoMa()
  13.             {
  14.                glMatrixMode(GL_MODELVIEW);
  15.                glLoadIdentity();
  16.             }
  17.  
  18.             inline void RendMo2D()
  19.             {
  20.                if(!RenderMode2D)
  21.                {
  22.                   SetToProMa();
  23.                   glViewport(0,0,Wnd.GetWidth(),Wnd.GetHeight());
  24.                   glMatrixMode(GL_PROJECTION);
  25.                   glLoadIdentity();
  26.                   if(Wnd.GetHeight()>0.0f)
  27.                      AspectRatio=Wnd.GetWidth()/Wnd.GetHeight();
  28.                   else
  29.                      AspectRatio=1;
  30.                   glOrtho(0, DigWndW*AspectRatio, 0, DigWndH*AspectRatio, -1, 1);
  31.                   //glOrtho(0,DigWndW,0,DigWndH,0,DigZFar-1);
  32.                   SetToMoMa();
  33.                   RenderMode2D=true;
  34.                }
  35.             }


Zeichnungsvorgang
Code:
  1. void gameloop() // So nicht im Programmcode, sondern aus den aufgerufenen Funktionen für euch zusammengesetzt.
  2. {
  3.    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  4.    RendMo2D();
  5.    glTranslated(100,200,0);
  6.    glScalef(100,100,0);
  7.    glCallList(cGUIManager::Quad);
  8.    glLoadIdentity();
  9. }


Beispielbilder sind abgehängt. Ich verstehe nicht, was ich beim Seitenverhältnis falsch mache. :(


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Aspect ratio
BeitragVerfasst: Fr Mai 18, 2012 13:15 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

du musst die Größe des Bereichs, den du mit glOrtho abdecken willst von der Höhe abhängig machen:
Code:
  1. ViewportBreite / ViewportHöhe = SzenenBreite / SzenenHöhe
  2. AspectRation = ViewportBreite / ViewportHöhe
  3. daraus folgt:
  4. SzenenBreite = AspectRation * SzenenHöhe;

Jetzt musst du nur noch festlegen wie hoch dein Bereich sein soll und dann sollte das funktionieren:
Code:
  1. glOrtho(0, DigWndW*AspectRatio, 0, DigWndH, -1, 1); //wenn DigWndH deine Höhe des Breichs ist...

MfG Bergmann

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Aspect ratio
BeitragVerfasst: Fr Mai 18, 2012 15:04 
Offline
DGL Member

Registriert: Mi Nov 18, 2009 10:55
Beiträge: 20
Programmiersprache: C++
Also DigWndH/DigWndW sind Werte für eine virtuelle Auflösung (aus dem Tutorial über 2D entnommen), die eigentlich dafür sorgen sollten, dass ich wenig mit Auflösungsrumrechnerei zu tun habe. Oder habe ich das jetzt total in den falschen Hals bekommen?

Also AspectRatio(n) war also vollkommen richtig eingestellt, ja?
Aber dann verstehe ich (immernoch) nicht, was schief läuft.

Wenn ich das ganze Funktionsgedöns mal entschlacke, sieht mein code so aus:
Initialisierung von OpenGL und dem Fenster + Displayliste anlegen
Code:
  1.    // OpenGL initialisieren
  2.    glClearDepth(1.f);
  3.    glClearColor(Black.R, Black.G, Black.B, 0.f);
  4.    glEnable(GL_DEPTH_TEST);
  5.    glDepthMask(GL_TRUE);
  6.    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  7.    glMatrixMode(GL_PROJECTION);
  8.    glLoadIdentity();
  9.    glViewport(0,0,Window.GetWidth(),Window.GetHeight());
  10.    glOrtho(0,DigWndW,0,DigWndH,0,DigZFar-1);
  11.    glMatrixMode(GL_MODELVIEW);
  12.    glLoadIdentity();
  13.    glEnable(GL_CULL_FACE);
  14.    glEnable(GL_TEXTURE_2D);
  15.    glEnable(GL_ALPHA_TEST);
  16.    glAlphaFunc(GL_GREATER, 0.1);
  17.  
  18.    // Das Fenster erzeugen und zentrieren
  19.    Window.Create(Window.GetDesktopMode(),"Mein Fenster");
  20.    Window.SetPosition((Window.GetDesktopMode().Width-Window.GetWidth())/2, (Window.GetDesktopMode().Height-Window.GetHeight())/2);
  21.  
  22.    bool RenderMode2D=false;
  23.    float Size[2]={Window.GetWidth(),Window.GetHeight()};
  24.    if (Size[1]!=0.0f)
  25.       AspectRatio=Size[0]/Size[1];
  26.    else
  27.       AspectRatio=Size[0];
  28.  
  29.       if(!RenderMode2D)
  30.       {
  31.             glMatrixMode(GL_PROJECTION);
  32.             glLoadIdentity();
  33.             glViewport(0,0,Window.GetWidth(),Window.GetHeight());
  34.             glMatrixMode(GL_PROJECTION);
  35.             glLoadIdentity();
  36.             if(Window.GetHeight()>0.0f)
  37.                   AspectRatio=Window.GetWidth()/Window.GetHeight();
  38.             else
  39.                   AspectRatio=1;
  40.             glOrtho(0, DigWndW*AspectRatio, 0, DigWndH, -1, DigZFar-1);
  41.             glMatrixMode(GL_MODELVIEW);
  42.             glLoadIdentity();
  43.             RenderMode2D=true;
  44.       }
  45.  
  46.    GLuint Quad = glGenLists(1);
  47.    float Breite=1, Laenge=1, Tiefe=zFar*-1;
  48.    glNewList(Quad,GL_COMPILE);//GL_COMPILE_AND_EXECUTE
  49.       glBegin(GL_TRIANGLE_STRIP);
  50.          glVertex3f(-Breite, Laenge,Tiefe);
  51.          glVertex3f(-Breite, -Laenge,Tiefe);
  52.          glVertex3f(Breite, Laenge,Tiefe);
  53.          glVertex3f(Breite, -Laenge,Tiefe);
  54.       glEnd();
  55.    glEndList();


Rendervorgang
Code:
  1.  
  2. sf::Event Evt;
  3. while(Window.IsOpened())
  4. {
  5.    while(Window.GetEvent(Evt))
  6.    {
  7.       switch (Evt.Type)
  8.       {
  9.          // Wennn das Fenster in der Größe verändert wurde, dem Grafikmanager die neuen Werte übergeben und das Fenster zentrieren.
  10.          case sf::Event::Resized:
  11.             Size[0]=Window.GetWidth();
  12.             Size[1]=Window.GetHeight();
  13.             if (Size[1]!=0.0f)
  14.                AspectRatio=Size[0]/Size[1];
  15.             else
  16.                AspectRatio=Size[0];
  17.  
  18.                if(!RenderMode2D)
  19.                {
  20.                   glMatrixMode(GL_PROJECTION);
  21.                   glLoadIdentity();
  22.                   glViewport(0,0,Size[0],Size[1]);
  23.                   glMatrixMode(GL_PROJECTION);
  24.                   glLoadIdentity();
  25.                   if(Size[1]>0.0f)
  26.                      AspectRatio=Size[0]/Size[1];
  27.                   else
  28.                      AspectRatio=1;
  29.                   glOrtho(0, DigWndW*AspectRatio, 0, DigWndH, -1, DigZFar-1);
  30.                   glMatrixMode(GL_MODELVIEW);
  31.                   glLoadIdentity();
  32.                   RenderMode2D=true;
  33.                }
  34.             Window.SetPosition((Window.GetDesktopMode().Size[0])/2, (Window.GetDesktopMode().Height-Size[1])/2);
  35.             break;
  36.          case sf::Event::KeyPressed:
  37.             if(Evt.Key.Code == sf::Key::Escape)
  38.                Window.Close();
  39.             break;
  40.       }
  41.    }
  42.    
  43.    //Hier wird der Rendervorgang abgewickelt.
  44.    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  45.  
  46.    if(!RenderMode2D)
  47.    {
  48.       glMatrixMode(GL_PROJECTION);
  49.       glLoadIdentity();
  50.       glViewport(0,0,Size[0],Size[1]);
  51.       glMatrixMode(GL_PROJECTION);
  52.       glLoadIdentity();
  53.       if(Size[1]>0.0f)
  54.          AspectRatio=Size[0]/Size[1];
  55.       else
  56.          AspectRatio=1;
  57.       glOrtho(0, DigWndW*AspectRatio, 0, DigWndH, -1, DigZFar-1);
  58.       glMatrixMode(GL_MODELVIEW);
  59.       glLoadIdentity();
  60.       RenderMode2D=true;
  61.    }
  62.    
  63.    // Es wird eine grüne Farbe zum Zeichnen des Quads benutzt.
  64.    glColor3f(SeaGreen.R,SeaGreen.G,SeaGreen.B);
  65.    EglTranslated(100,200,0);
  66.    glScalef(100,100,0);
  67.    glCallList(Quad);
  68.    glLoadIdentity();
  69.  
  70.    //RendMo3D();
  71. }
  72.  

Die letzte auskommentierte Zeile enthält den untenstehenden Code. ViewAngle ist dabei immer 65. Wenn ich es so (auskommentiert) kompiliere, ist das Quad nicht zu sehen, ansonsten ja, wird auch richtig verzerrt, verschwindet aber, wenn das Fenster eine gewisse Breite unterschreitet.
Code:
  1.  
  2.    if(RenderMode2D)
  3.    {
  4.       glMatrixMode(GL_PROJECTION);
  5.       glLoadIdentity();
  6.       gluPerspective(ViewAngle, AspectRatio, zNear, zFar);
  7.       SetToMoMa();
  8.       RenderMode2D=false;
  9.    }
  10.  


Das Verschwinden ist unabhängig von der (skalierten) Größe des Quads.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Aspect ratio
BeitragVerfasst: Fr Mai 18, 2012 15:47 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

die virtuelle Auflösung die du einstellst bezieht sich immer auf den Viewport. Mal angenommen zu zeichnest ein 100*100 Quad mit einem 640*480 Viewport und einer virtuellen Auflösung von 640*480. Dann ist das Quad auf dem Monitor auch genau 100*100. Wenn der Viewport doppelt so groß ist, dann wird auch das Quad doppelt so Groß, weil deine Virtuelle Auflösung einfach nur auf einem Größeren Viewport angezeigt wird. Wenn du die virtuelle Auflösung verdoppelst, dann zeichnest du einen Größeren Ausschnitt deiner Szene und deshalb wird das Quad kleiner.
Damit dein Quad immer genau das gleiche Seitenverhältniss hat und sich nur in der Größe ändert musst die virtuelle Auflösung ein Vielfaches der Viewportauflösung sein. Also AspectRatio muss bei Viewport und virtueller Auflösung gleich sein.
AspectRatioViewport = ViewportWidth/VieportHeight;
AspectRationResolution = DigWndW/DigWndH;
AspectRatioViewport = AspectRationResolution;
ViewportWidth/VieportHeight = DigWndW/DigWndH;
um diese Gleichung zu Lösen musst du mindestens eine Unbekannte haben. Normalerweiße nimmt man da die Breite der virtuellen Auflösung. Sprich wenn du die Breite vom Viewport veränderst, dann bleibt dein Quad gleich groß. Wenn du die Höhe vom Viewport veränderst soll das Quad kleiner oder größer werden. Also setzen wir DigWndW = x weil es unbekannt ist und erst berechnet werden muss:
ViewportWidth/VieportHeight = x/DigWndH;
ViewportWidth/VieportHeight * DigWndH = x;
Die Werte kannst du jetzt an OpenGL übergeben. Hier ma ein kleines Bsp. Das ein 100*100 Quad in der Mitte des Viewport zeichnet:
Code:
  1. glViewport(0, 0, ViewportWidth, VieportHeight);
  2. glMatrixMode(GL_PROJECTION);
  3. glLoadIdentity;
  4. DigWndW := ViewportWidth/VieportHeight * DigWndH;
  5. glOrtho(0, DigWndW, DigWndH, 0, -10, 10);
  6. glMatrixMode(GL_MODELVIEW);
  7. glLoadIdentity;
  8.  
  9. glClearColor(0,0,0,0);
  10. glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  11.  
  12. glTranslatef(DigWndW/2, DigWndH/2, 0); //in die Mitte der Szene verschieben
  13. glColor4f(1, 1, 1, 1);
  14. glDisable(GL_DEPTH_TEST);
  15. glDisable(GL_CULL_FACE);
  16. glBegin(GL_QUADS);
  17.   glVertex2f(-100, -100);
  18.   glVertex2f(-100,  100);
  19.   glVertex2f( 100,  100);
  20.   glVertex2f( 100, -100);
  21. glEnd;


Bei dir kann ich zur Zeit nur einen Fehler sehen. Und zwar im ersten Codefenster Z.40 und im zweiten Z.29. Die Breite DigWndW berechnet sich aus DigWndH*AspectRatio! Wenn du nicht weiter weißt, dann kannst du auch erstmal alles unwichtige auskommentieren oder dir ne kleine Testanwendung schreiben. Das Bsp. oben ist voll funktionsfähig (bis auf die Initialisierung von OpenGL).

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Aspect ratio
BeitragVerfasst: Di Apr 30, 2013 13:50 
Offline
DGL Member

Registriert: Do Mär 21, 2013 14:57
Beiträge: 51
Programmiersprache: C#,C++
Kann man das auch so auf eine perpective - Projektion anwenden? Denn bei mir sieht das wie folgt aus,
und der Körper wird ebenfalls in die Breite und Höhe gezogen beim Resizen, was ich nicht möchte. Außer-
dem wird dieser komischer Weise verschoben.

Code:
  1.  
  2.         public void setUpViewPort(ref GLControl glControl1)
  3.         {
  4.             // Compute the size of the glControl1.
  5.             int width = glControl1.Width;
  6.             int height = glControl1.Height;
  7.            
  8.             // Tell OpenGL how to compute pixels to coordinates.
  9.             GL.Viewport(0, 0, width, height);
  10.  
  11.             // Choose Matrix.
  12.             GL.MatrixMode(MatrixMode.Projection);
  13.  
  14.             // Reset camera.
  15.             GL.LoadIdentity();
  16.            
  17.             // Generating a perspective matrix.
  18.             //Matrix4d perspective = Matrix4d.Perspective(((Math.PI / 180) * 45.0), (width / height), 0.0, 1000.0);
  19.             Matrix4d frustrum = Matrix4d.Frustum(0, width, 0, height, 0.0, 100.0);
  20.  
  21.             // Multiplying the projection matrix with the perspective one.
  22.             //GL.LoadMatrix(ref perspective);
  23.             GL.LoadMatrix(ref frustrum);
  24.         }
  25.  
  26.         private void computeCamPos(Point mouse_current, Point mouse_previous)
  27.         {
  28.             // Compute moving distance depending on mouse speed.
  29.             double dx = mouse_current.X - mouse_previous.X;
  30.             dx *= mouse_speed;
  31.             double dy = mouse_current.Y - mouse_previous.Y;
  32.             dy *= mouse_speed;
  33.  
  34.             // Get angle in rad.
  35.             this.theta += dx * Math.PI / 180.0;
  36.             this.phi += dy * Math.PI / 180.0;
  37.  
  38.             // Set borders from 0 to 360°.
  39.             if (this.theta > 2 * Math.PI)
  40.                 this.theta -= 2 * Math.PI;
  41.             if (this.theta < 0)
  42.                 this.theta += 2 * Math.PI;
  43.  
  44.             // Set borders from 90 to -90°
  45.             if (this.phi > Math.PI / 2)
  46.                 this.phi = Math.PI / 2;
  47.             if (this.phi < -Math.PI / 2)
  48.                 this.phi = -Math.PI / 2;
  49.            
  50.             // Normalize target vector.
  51.             double x = Math.Sin(this.theta) * Math.Cos(this.phi);
  52.             double y = -Math.Sin(this.phi);
  53.             double z = Math.Cos(this.theta) * Math.Cos(this.phi);
  54.  
  55.             double length = Math.Sqrt((x*x) + (y*y) + (z*z));
  56.  
  57.             double norm_x = x;
  58.             double norm_y = y;
  59.             double norm_z = z;
  60.  
  61.             if (length != 0)
  62.             {
  63.                 norm_x = x / length;
  64.                 norm_y = y / length;
  65.                 norm_z = z / length;
  66.             }
  67.  
  68.             // Compute position vector.
  69.             forward = new Vector3d()
  70.             {
  71.                 X = norm_x,
  72.                 Y = norm_y,
  73.                 Z = norm_z
  74.             };
  75.         }
  76.  
  77.         public void setCamPos(double zoom, Point mouse_current, Point mouse_previous, ref GLControl glControl1)
  78.         {
  79.             Point mouseCurrent = mouse_current;
  80.             Point mousePrevious = mouse_previous;
  81.  
  82.             this.computeCamPos(mouseCurrent, mousePrevious);
  83.  
  84.             this.setUpViewPort(ref glControl1);
  85.  
  86.             // Switch do model matrix.
  87.             GL.MatrixMode(MatrixMode.Modelview);
  88.  
  89.             GL.LoadIdentity();
  90.  
  91.             Vector3d.Zero.Normalize();
  92.             Vector3d.UnitY.Normalize();
  93.  
  94.             // Compute new modelview matrix.
  95.             Matrix4d modelview = Matrix4d.LookAt(Vector3d.Zero + this.forward * 0.1, Vector3d.Zero, Vector3d.UnitY);
  96.  
  97.             // Set new modelview matrix.
  98.             GL.LoadMatrix(ref modelview);
  99.         }
  100.  

_________________
_______________________________________
Lets move over mountains and through valleys:
GL.Map2(,,,,,,,,,)
GL.MapGrid2(,,,,,,,,,)
GL.EvalMesh2(,,,,,,,,,)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.014s | 14 Queries | GZIP : On ]