2010-12-02 4 views
3

J'ai une application Windows (XP) qui doit afficher un rectangle bidimensionnel dans une fenêtre. Le rectangle ne doit pas être découpé (c'est-à-dire doit toujours se trouver complètement dans la fenêtre d'affichage) et doit conserver son format d'image lors du redimensionnement. Actuellement, la méthode qui gère la disposition déforme le rapport d'aspect du rectangle pour correspondre à la fenêtre. Je veux que le rectangle soit à l'échelle de la fenêtre et soit centré dans la fenêtre (encore une fois, sans écrêtage). La méthode telle qu'elle se présente est ci-dessous. lWinDist et lMaxDepth sont la largeur et la hauteur du rectangle à afficher (en 48ths de pouce, si elle importe):Conserver le format de l'objet 2D sur le redimensionnement de la fenêtre

void CRoRRecView::RedoLayout(long lWinDist, long lMaxDepth) 
{ 
    CDC* pDC = GetDC() ; 

    if (pDC != NULL) 
    { 
     m_lWinDist = lWinDist; 
     GetClientRect(m_rectClient) ; 
     int nClientWidth = m_rectClient.Width(); 
     int nClientHeight = m_rectClient.Height(); 
     glViewport(0, 0, nClientWidth, nClientHeight); 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 

     m_fWinXDist = (float) lWinDist ; 
     m_fWinYDist = lMaxDepth ; 
     m_fAspectRatio = m_fWinXDist/m_fWinYDist; 

     glOrtho(0.0, m_fWinXDist, 0.0, m_fWinYDist, -1, 1) ; 

     glRotatef(180.0, 0,1,0); 
     glTranslatef((float)(-1 * lWinDist),0,0); // Translate across the x axis 

     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 

     ReleaseDC(pDC) ; 
    } 
} 

Répondre

3

Celui-ci devrait échelle comme prévu:

// g++ main.cpp -lglut -lGL 
#include <GL/glut.h> 

void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    double w = glutGet(GLUT_WINDOW_WIDTH); 
    double h = glutGet(GLUT_WINDOW_HEIGHT); 
    double ar = w/h; 
    glOrtho(-2 * ar, 2 * ar, -2, 2, -1, 1); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glColor3ub(255, 0, 0); 
    glBegin(GL_QUADS); 
    glVertex2i(-1, -1); 
    glVertex2i( 1, -1); 
    glVertex2i( 1, 1); 
    glVertex2i(-1, 1); 
    glEnd(); 

    glutSwapBuffers(); 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); 
    glutInitWindowSize(640, 480); 
    glutCreateWindow("Aspect Ratio"); 
    glutDisplayFunc(display); 
    glutMainLoop(); 
    return 0; 
} 
+0

Merci. Oui, ça balance bien. Malheureusement, toute la question est devenue discutable de mon côté; les pouvoirs en place ont déclaré que le rapport d'aspect doit être fixé. Je vais garder ça dans ma poche arrière de toute façon. – PSU

0

Essayez ceci:

#include <GL/glut.h> 

size_t win_w = 0; 
size_t win_h = 0; 

void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0, win_w, 0, win_h, -1, 1); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glColor3ub(255,0,0); 
    glPushMatrix(); 
     glTranslatef(win_w/2,win_h/2,0); 
     glScalef(50,50,50); 
     glBegin(GL_QUADS); 
      glVertex2f(-1,-1); 
      glVertex2f(1,-1); 
      glVertex2f(1,1); 
      glVertex2f(-1,1); 
     glEnd(); 
    glPopMatrix(); 

    glFlush(); 
    glutSwapBuffers(); 
} 

void reshape(int w, int h) 
{ 
    win_w = w; 
    win_h = h; 
    glViewport(0, 0, w, h); 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); 

    glutInitWindowSize(800,600); 
    glutCreateWindow("Aspect Ratio"); 

    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutMainLoop(); 
    return 0; 
} 
+1

Merci. Cependant, bien que le rapport d'aspect et le centrage de l'objet soient conservés, il n'est pas redimensionné lorsque la fenêtre est redimensionnée. C'est-à-dire que si l'objet commence par occuper, disons, les 3/4 de la hauteur de la fenêtre, il occupera toujours les 3/4 de la hauteur de la fenêtre après redimensionnement. – PSU

+0

@PSU: Oui, vous avez raison. J'ai eu une version légèrement différente qui a fait la bonne chose, je vais voir si je peux le tirer vers le haut. – genpfault

1

Essayez cette fonction de réorganisation. Il conservera votre rapport d'aspect, redimensionnera l'objet et rendra la fenêtre à centraliser.

// initial window screen size 
int WIDTH = 400; 
int HEIGHT = 300; 

// reshape function, call with glutReshapeFunc(reshape) in yout main function 
void reshape(int width, int height) { 
    const float ar_origin = (float) WIDTH/(float) HEIGHT; 
    const float ar_new = (float) width/(float) height; 

    float scale_w = (float) width/(float) WIDTH; 
    float scale_h = (float) height/(float) HEIGHT; 
    if (ar_new > ar_origin) { 
     scale_w = scale_h; 
    } else { 
     scale_h = scale_w; 
    } 

    float margin_x = (width - WIDTH * scale_w)/2; 
    float margin_y = (height - HEIGHT * scale_h)/2; 

    glViewport(margin_x, margin_y, WIDTH * scale_w, HEIGHT * scale_h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0, WIDTH/ar_origin, 0, HEIGHT/ar_origin, 0, 1.0); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity() ; 
} 
0

Je pense que vous devriez regarder cela pour obtenir les bons chiffres:

self.hOffset = (self.wOffset/(16.0/9.0)); 
self.xOffset = ((int)ceil((_backingWidth/2.0) - ((_backingWidth + self.wOffset)/2.0))); 
self.yOffset = ((int)ceil((_backingHeight/2.0) - ((_backingHeight + self.hOffset)/2.0))); 

glViewport(self.xOffset, self.yOffset, _backingWidth + self.wOffset, _backingHeight + self.hOffset); 

Dans le code ci-dessus, wOffset, qui est la largeur de l'image, donner ou prendre sa valeur modifiée par un curseur La première ligne augmente la hauteur car la largeur est augmentée au bon ratio, ce qui se passe à 16: 9 (il ne fonctionne pas bien pour diviser la largeur par la hauteur pour obtenir le ratio, en spécifiant explicitement le meilleur). Les deux lignes suivantes ajustent les coordonnées x, y de l'image, de sorte que, lorsqu'elle augmente ou diminue en taille, elle reste toujours centrée.

C'est de loin une approche plus simple et plus simple sur le GPU. S'il y a des raisons pour lesquelles l'approche du méga-codage que je vois ici est meilleure, je ne peux pas le comprendre. Bonne chance.

Questions connexes