I set gluPerspective(45.0f, 3.0f/ 2.0f, 0.1f, 400.0f), glViewport(0, 0, 1024, 768), gluLookAt(0.0f, 0.0f, 2.1f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f), the third parameter of gluUnProject is 0.5f. I think the objZ should have been -198f, but it was 1.9f. Could anyone tell me the reason?
Maybe it was my fault.
#include <windows.h>
#include <cstdio>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
const int width = 1024;
const int height = 768;
const int bits = 32;
HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance = NULL;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void ReleaseWindow();
bool keys[256];
GLuint g_FontListID;
HFONT hOldFont;
const int FONTHEIGHT = 32;
GLUquadricObj *sphere;
GLdouble x, y, z;
int x1, y1;
GLuint CreateGLFont(PSTR fontName, int height)
{
GLuint fontListID;
HFONT hFont;
fontListID = glGenLists(256);
hFont = CreateFont(height,
0,
0,
0,
FW_BOLD,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_TT_PRECIS,
CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
DEFAULT_PITCH | FF_DONTCARE,
fontName);
hOldFont = (HFONT)SelectObject(hDC, hFont);
wglUseFontBitmaps(hDC, 0, 255, fontListID);
return fontListID;
}
void PositionText(int x, int y)
{
glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
y = height - FONTHEIGHT - y;
glViewport(x - 1, y - 1, 0, 0);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glRasterPos4f(0.0f, 0.0f, 0.0f, 1.0f);
glPopAttrib();
}
void printText(int x, int y, const char *str, ...)
{
if (!str)
return;
char temp[1024];
va_list argument;
va_start(argument, str);
vsprintf(temp, str, argument);
va_end(argument);
PositionText(x, y);
glPushAttrib(GL_LIST_BIT);
glListBase(g_FontListID);
glCallLists(strlen(temp), GL_UNSIGNED_BYTE, temp);
glPopAttrib();
}
void returnPos(int wx, int wy)
{
GLdouble mvmatrix[16], projmatrix[16];
GLint viewport[4];
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
glGetIntegerv(GL_VIEWPORT, viewport);
wy = viewport[3] - (GLint)wy - 1;
gluUnProject((GLdouble)wx, (GLdouble)wy, 0.5f, mvmatrix, projmatrix, viewport, &x, &y, &z);
}
void InitLight()
{
GLfloat light_pos[] = { 0.0f, 0.0f, 1.0f, 1.0f };
GLfloat light_ambient[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
//glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
//glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
//glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
GLfloat mat_ambient[] = { 0.8f, 0.2f, 0.5f, 1.0f };
GLfloat mat_diffuse[] = { 0.6f, 0.2f, 0.3f, 1.0f };
GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat mat_shininess[] = { 5.0f };
GLfloat mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
//glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glEnable(GL_LIGHT0);
//glEnable(GL_LIGHTING);
}
bool InitGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glDepthRange(0.0f, 1.0f);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLdouble)width / (GLdouble)height, 0.1f, 400.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
InitLight();
sphere = gluNewQuadric();
g_FontListID = CreateGLFont("Arial", FONTHEIGHT);
return true;
}
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 2.1f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glEnable(GL_LIGHTING);
gluSphere(sphere, 0.5f, 30, 30 );
glDisable(GL_LIGHTING);
glColor3f(1.0f, 1.0f, 1.0f);
printText(0, 0, "x = %.2f, y = %.2f, z = %.2f.", x, y, z);
printText(0, FONTHEIGHT, "WX = %d, WY = %d", x1, y1);
}
void SetupPixelFormat()
{
int pixel;
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(pfd),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
bits,
0, 0, 0, 0, 0, 0, 0, 0,
32,
8, 8, 8, 8,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
hDC = GetDC(hWnd);
pixel = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pixel, &pfd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
}
void FullScreen()
{
DEVMODE dm;
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmPelsWidth = width;
dm.dmPelsHeight = height;
dm.dmBitsPerPel = bits;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
//ShowCursor(FALSE);
}
bool CreateGLWindow()
{
WNDCLASS wc;
RECT rect;
SetRect(&rect, 0, 0, width, height);
hInstance = GetModuleHandle(NULL);
wc.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
if (!RegisterClass(&wc))
{
return false;
}
AdjustWindowRectEx(&rect, WS_POPUP, FALSE, WS_EX_APPWINDOW);
hWnd = CreateWindowEx(WS_EX_APPWINDOW,
"OpenGL",
"",
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0,
rect.right - rect.left, rect.bottom - rect.top,
NULL,
NULL,
hInstance, NULL);
if (!hWnd)
{
return false;
}
SetupPixelFormat();
FullScreen();
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
if (!InitGL())
{
ReleaseWindow();
return false;
}
return true;
}
void ReleaseWindow()
{
ChangeDisplaySettings(NULL, 0);
ShowCursor(TRUE);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd);
UnregisterClass("OpenGL", hInstance);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance,
PSTR lpCmdLine, int nCmdShow)
{
bool done = false;
MSG msg;
if (!CreateGLWindow())
{
return 0;
}
while (!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
DrawGLScene();
SwapBuffers(hDC);
if (keys[VK_ESCAPE])
{
done = true;
}
}
}
glDeleteLists(g_FontListID, 256);
ReleaseWindow();
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_MONITORPOWER:
case SC_SCREENSAVE:
{
return 0;
}
}
break;
}
case WM_KEYDOWN:
{
keys[wParam] = true;
return 0;
}
case WM_KEYUP:
{
keys[wParam] = false;
return 0;
}
case WM_MOUSEMOVE:
{
x1 = (int)LOWORD(lParam);
y1 = (int)HIWORD(lParam);
returnPos(x1, y1);
return 0;
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}