Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: A square does not display as a square

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2010
    Posts
    2

    A square does not display as a square

    The following code was put in an OnDraw() function in an MFC project to display a square. If you measure each side with a ruler it is not square. What am I doing wrong? I need a square to look like a square not a rectangle.

    PIXELFORMATDESCRIPTOR pfd;
    HGLRC hrc;

    int nFlags = PFD_DRAW_TO_WINDOW | // Support drawing to window.
    PFD_SUPPORT_OPENGL |
    PFD_DOUBLEBUFFER |
    PFD_GENERIC_ACCELERATED |
    PFD_SWAP_COPY;

    ::ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion = 1 ; // Version number
    pfd.dwFlags = nFlags ;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 32 ; // 32-bit depth buffer
    pfd.iLayerType = PFD_MAIN_PLANE ; // Layer type

    int nPixelFormat;
    if((nPixelFormat = ChoosePixelFormat(*pDC, &pfd)) == 0)
    {
    TRACE(_T("ChoosePixelFormat() failed.\n"));

    }

    if(!SetPixelFormat(*pDC, nPixelFormat, &pfd))
    {
    int nError = ::GetLastError();
    TRACE(_T("SetPixelFormat() failed. OpenGL error #: %d"), nError);
    }


    :escribePixelFormat(*pDC,
    ::GetPixelFormat(*pDC),
    sizeof(pfd),
    &pfd);

    // Create a rendering context and make it current.
    hrc = wglCreateContext(*pDC);

    if (!wglMakeCurrent(*pDC, hrc))
    {
    TRACE(_T("wglMakeCurrent() failed.\n"));
    }

    glEnable(GL_DEPTH_TEST); // Depth test for hidden surface removal.
    glDepthFunc(GL_LEQUAL); // Depth function. Note: Default is GL_LESS.

    // --- end section to initialize opengl

    // Set the viewport
    CRect cr;
    GetClientRect(&cr);
    glViewport(0, 0, (GLdouble)cr.Width(), (GLdouble)cr.Height());

    double m_fUserRectLeft = 8845;
    double m_fUserRectRight = 9429;
    double m_fUserRectBottom = 8819;
    double m_fUserRectTop = 9298;

    double rdx, rdy, ratio;
    rdx = m_fUserRectRight - m_fUserRectLeft;
    rdy = m_fUserRectTop - m_fUserRectBottom;
    ratio = (double)cr.Height() / (double)cr.Width();
    if(rdy < ratio * rdx)
    {
    m_fUserRectTop = m_fUserRectTop + (rdx * ratio - rdy) / 2.;
    m_fUserRectBottom = m_fUserRectBottom - (rdx * ratio - rdy) / 2.;
    }
    else if(rdy > ratio * rdx)
    {
    m_fUserRectRight = m_fUserRectRight + (rdy / ratio - rdx) / 2.;
    m_fUserRectLeft = m_fUserRectLeft - (rdy / ratio - rdx) / 2.;
    }
    double fWidth = m_fUserRectRight - m_fUserRectLeft;
    double fHeight = m_fUserRectTop - m_fUserRectBottom;

    // Note, after executing the next line the value of ratio and fAspectRatioOfUserRect
    // will be the same, so the problem is not with the aspect ratio
    double fAspectRatioOfUserRect = fHeight / fWidth;

    double m_fCameraPos[3];
    double m_fLookAt[3];
    double m_fUpDirection[3];
    m_fCameraPos[0] = 9137.;
    m_fCameraPos[1] = 505.;
    m_fCameraPos[2] = -9058.;

    // Set the glOrtho() params.
    double m_fOrthoLeft = -fWidth/2.;
    double m_fOrthoRight = fWidth/2.;
    double m_fOrthoBottom = -fHeight/2;
    double m_fOrthoTop = fHeight/2;
    double m_fOrthoNear = -1.;
    double m_fOrthoFar = m_fCameraPos[1] + 25.;

    // Set ortho projection.
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(m_fOrthoLeft, m_fOrthoRight, m_fOrthoBottom, m_fOrthoTop, m_fOrthoNear, m_fOrthoFar);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    m_fLookAt[0] = m_fCameraPos[0];
    m_fLookAt[1] = 1.;
    m_fLookAt[2] = m_fCameraPos[2];

    // Set up direction to -Z.
    m_fUpDirection[0] = 0.;
    m_fUpDirection[1] = 0.;
    m_fUpDirection[2] = -1.;
    gluLookAt(m_fCameraPos[0], m_fCameraPos[1], m_fCameraPos[2],
    m_fLookAt[0], m_fLookAt[1], m_fLookAt[2],
    m_fUpDirection[0], m_fUpDirection[1], m_fUpDirection[2]);



    double x = 9177.;
    double y = 9058.;
    double rad = 100.;
    glColor3ub(150, 20, 168);

    // Draw a square where each side of the square is rad units
    glBegin (GL_QUADS);
    glVertex3f (x, 0., -y);
    glVertex3f (x + rad, 0., -y);
    glVertex3f (x + rad, 0., -(y + rad));
    glVertex3f (x, 0., -(y + rad));
    glEnd ();

    SwapBuffers(*pDC);

  2. #2
    Super Moderator OpenGL Guru dorbie's Avatar
    Join Date
    Jul 2000
    Location
    Bay Area, CA, USA
    Posts
    3,941

    Re: A square does not display as a square

    Your ortho dimensions need to be adjusted based on cr.Width() cr.Height(), right now you use user rect values which are hardcoded.

    At the very least you need to adjust the user rect width or hight to be proportional to width and height.

    This is teh purpose of computing aspect ratio. It helps you calculate one from the other.

    You cannot have a window of arbitrary proportions and then draw to an ortho of different proportions if you want to preserve aspect ratio.

  3. #3
    Junior Member Newbie
    Join Date
    Apr 2010
    Posts
    2

    Re: A square does not display as a square

    The code gets the clientrect in variable "cr" and computes the aspect ratio of the window in variable "ratio". It then adjusts the users coords to have the same aspect ratio as the window. After the adjustment "fAspectRatioOfUserRect" is the same as "ratio" which I checked in the debugger. So the proportions are the same when "fWidth" and "fHeight" are computed which are what the params passed to glOrtho are based on.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •