PDA

View Full Version : A square does not display as a square



Barbara
04-16-2010, 12:45 PM
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);
}


::DescribePixelFormat(*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);

dorbie
04-16-2010, 03:39 PM
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.

Barbara
04-17-2010, 12:07 PM
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.