Hi all, having a bit of trouble with getting OpenGL picking to work in Win32. Note that pretty much the exact code works in GLUT, though i suspect that the reason i cant get it to work in Win32 is that it is not clear exactly how GLUT handles windowing related functions. Having said this, i have checked the code with NeHe lesson 32 and other OpenGL picking examples and i still can't find out what's wrong.
Would be grateful for some help
Here's the code - apologies for length but i think in this case you really need to see the whole lot.
/* main.c
Texture movie demo for Quex (Ges Moody) using keyframes to replicate rotation of object.
Admin..
5+ spaces for textures
video is default scene
when mouse clicked, text appears - like VM example
it appears that mouse function calls the picking routine
Am testing the opengl red book example here to see if it does actually work here
*/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <stdlib.h>
HWND hWnd;
HDC hDC;
HGLRC hRC;
int mouseX, mouseY;
char strTitle[128];
int width = 800;
int height = 600;
LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);
void BuildFont();
void DrawScene();
void OpenGLSetup();
void PerspView(int width, int height);
void Movie();
void Select();
void Pick(GLuint hit, GLuint buff[]);
float rot;
void glPrint(const char *fmt, ...);
BOOL OpenGLWindow(char* titleName, int height, int width);
//keypressing
BOOL Press[256];
GLuint base;
GLuint id, object;
int HIT, NAME;
char cMessage[128];
BOOL scene, infotext; //scene for video, infotext for text
BOOL rightmouse, leftmouse; //leftm and right mouse buttons
GLfloat GUIalpha, GUIselect;
GLfloat textureUpdate; //updating texture obviously
GLuint hits;
GLuint *ptr, names;
int textureupdate = 0;
/**************************
* WinMain
*
**************************/
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
MSG msg;
BOOL bQuit = FALSE;
if(!OpenGLWindow("Hello",width,height))
{
PostQuitMessage(0);
}
SetWindowText(hWnd, strTitle);
EnableOpenGL (hWnd, &hDC, &hRC);
PerspView(width, height);
OpenGLSetup();
/* program main loop */
while (!bQuit)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
else
{
DrawScene();
SwapBuffers (hDC);
Sleep (1);
}
}
/* shutdown OpenGL */
DisableOpenGL (hWnd, hDC, hRC);
/* destroy the window explicitly */
DestroyWindow (hWnd);
return msg.wParam;
}
BOOL OpenGLWindow(char *titleName, int width, int height)
{
WNDCLASS wc;
HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "VM - Virtual Museum";
RegisterClass (&wc);
hWnd = CreateWindowEx (0, wc.lpszClassName, "",
WS_OVERLAPPEDWINDOW|WS_CAPTION|WS_VISIBLE| WS_CLIPSIBLINGS|WS_CLIPCHILDREN,0, 0, 800,
600,NULL, NULL, hInstance, NULL);
ShowWindow (hWnd, SW_SHOW);
UpdateWindow(hWnd);
//SetFocus(hWnd);
return TRUE;
}
void PerspView(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 16.0, 0.0, 16.0, -2.0, 2.5);
//gluPerspective(80.00, (GLfloat) 800 / (GLfloat) 600, 1.0, 300.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void OpenGLSetup() //ok
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_FLAT);
//BuildFont();
}
void DrawScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
if(scene)
{
Select();
}
Movie();
}
void Movie()
{
glLoadName(1);
glPushMatrix();
glTranslatef(8, 6, 0);
glBegin(GL_QUADS);
glColor3f(0.2, 0.5, 0.6);
glTexCoord2i(0, 0); glVertex3f(-1, -1.4, 0);
glTexCoord2i(0, 1); glVertex3f(-1, -1.2, 0);
glTexCoord2i(1, 1); glVertex3f(-0.5, -1.2, 0);
glTexCoord2i(1, 0);glVertex3f(-0.5, -1.4, 0);
glEnd();
glPopMatrix();
glLoadName(2);
glPushMatrix();
glTranslatef(8, 6, 0);
glBegin(GL_QUADS);
glColor3f(0.8, 0.2, 0.1);
glTexCoord2i(0, 0); glVertex3f(-0.5, -1.4, 0);
glTexCoord2i(0, 1); glVertex3f(-0.5, -1.2, 0);
glTexCoord2i(1, 1); glVertex3f(0.0, -1.2, 0);
glTexCoord2i(1, 0);glVertex3f(0.0, -1.4, 0);
glEnd();
glPopMatrix();
glLoadName(3);
glPushMatrix();
glTranslatef(8, 6, 0);
glBegin(GL_QUADS);
glColor3f(0.4, 0.2, 0.8);
glTexCoord2i(0, 0); glVertex3f(0.0, -1.4, 0);
glTexCoord2i(0, 1); glVertex3f(0.0, -1.2, 0);
glTexCoord2i(1, 1);glVertex3f(0.5, -1.2, 0);
glTexCoord2i(1, 0);glVertex3f(0.5, -1.4, 0);
glEnd();
glPopMatrix();
glLoadName(4);
glPushMatrix();
glTranslatef(8, 6, 0);
glBegin(GL_QUADS);
glColor3f(0.8, 0.7, 0.2);
glTexCoord2i(0, 0); glVertex3f(0.5, -1.4, 0);
glTexCoord2i(0, 1);glVertex3f(0.5, -1.2, 0);
glTexCoord2i(1, 1);glVertex3f(1.0, -1.2, 0);
glTexCoord2i(1, 0);glVertex3f(1.0, -1.4, 0);
glEnd();
glPopMatrix();
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_KEYUP:
Press[wParam] = FALSE;
break;
case WM_KEYDOWN:
Press[wParam] = TRUE;
break;
case WM_MOUSEMOVE:
{
mouseX = LOWORD(lParam);
mouseY = HIWORD(lParam);
}
break;
case WM_LBUTTONDOWN:
{
mouseX = LOWORD(lParam);
mouseY = HIWORD(lParam);
scene = TRUE;
}
break;
case WM_LBUTTONUP:
{
mouseX = LOWORD(lParam);
mouseY = HIWORD(lParam);
scene = FALSE;
}
break;
case WM_CLOSE:
PostQuitMessage (0);
return 0;
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
return 0;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
}
void Select()
{
GLuint buffer[512];
GLuint hits;
int i;
unsigned int j;
GLuint names, *ptr;
GLuint view[4];
glGetIntegerv(GL_VIEWPORT, view);
glSelectBuffer(512, buffer);
(void) glRenderMode(GL_SELECT); //SELECT MODE
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble) mouseX, (GLdouble) (view[3]-mouseY), 5.0, 5.0, view);
glOrtho(0.0, 16.0, 0.0, 16.0, -2.0, 2.5);
//gluPerspective(80.00, (GLfloat) (view[2]-view[0]) / (GLfloat) (view[3]-view[1]), 1.0, 300.0);
glMatrixMode(GL_MODELVIEW);
Movie();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
hits=glRenderMode(GL_RENDER);
//Pick(hits, buffer);
//}
//void Pick(GLuint hit, GLuint buff[])
//{
ptr = (GLuint *) buffer;
for (i = 0; i < hits; i++) { /* for each hit */
names = *ptr;
// printf(" number of names for hit = %d\n", names);
ptr++;
// printf(" z1 is %g;", (float) *ptr/0xffffffff);
ptr++;
// printf(" z2 is %g\n", (float) *ptr/0xffffffff);
ptr++;
switch(*ptr)
{
case 1:
//strcpy(strTitle,"hello");
sprintf(strTitle, "%s\n", "one");
textureupdate++;
if(textureupdate == 1)
strcpy(cMessage,"1");
if(textureupdate == 2)
strcpy(cMessage,"2");
if(textureupdate == 3)
strcpy(cMessage,"3");
if(textureupdate == 4)
strcpy(cMessage,"4");
if(textureupdate >= 4)
textureupdate = 0;
break;
case 2:
sprintf(strTitle, "%s\n", "two");
break;
case 3:
sprintf(strTitle, "%s\n", "two");
break;
case 4:
sprintf(strTitle, "%s\n", "two");
break;
}
}
}
/*******************
* Enable OpenGL
*
*******************/
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
*hDC = GetDC (hWnd);
ZeroMemory (&pfd, sizeof (pfd));
pfd.nSize = sizeof (pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat (*hDC, &pfd);
SetPixelFormat (*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );
}
/******************
* Disable OpenGL
*
******************/
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hRC);
ReleaseDC (hWnd, hDC);
}