Sign in to follow this  
ZeuC

OpenGL I got this nasty problem with OpenGL Picking (i've read a few tutorials, but...)

Recommended Posts

I've been trying to get the OpenGL selection procedure to work, but i haven't got lucky so far ... I've read quite a few tutorials (including nehe's 32 and one from lighthouse3d.com and i've even found a couple more on some coding sites which i may add were "clones" of nehe's code ...) I know i'm doing a really stupid mistake and i was wondering if you could take a look and hopefully help me sort it out ...
#include <windows.h>
#include <stdio.h>
#include <gl/gl.h>
#include <gl/glu.h>
typedef struct
{
    GLfloat r,g,b;
}rgb;

rgb color1,color2;

/**************************
 * Function Declarations
 *
 **************************/

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 glzResizeWindow(int width, int height);
void selectObjects(double mouse_x,double mouse_y,HWND hWnd);
void DrawCards();
//           x   y    z     W    H
float z_init = -10.0f;
/**************************
 * WinMain
 *
 **************************/

int WINAPI WinMain (HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,
                    int iCmdShow)
{
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;        
    MSG msg;
    BOOL bQuit = FALSE;

    /* register window class */
    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 = "GLSample";
    RegisterClass (&wc);

    /* create main window */
    hWnd = CreateWindow (
      "GLSample", "OpenGL Sample", 
      WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
      0, 0, 512, 512,
      NULL, NULL, hInstance, NULL);

    /* enable OpenGL for the window */
    
    EnableOpenGL (hWnd, &hDC, &hRC);
    glzResizeWindow(512,512);
    color1.r = 1.0f;
    color1.g = 0.0f;
    color1.b = 0.0f;

    color2.g = 1.0f;
    color2.r = 0.0f;
    color2.b = 0.0f;
    
    /* program main loop */
    while (!bQuit)
    {
        /* check for messages */
        if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }
        }
        else
        {
            /* OpenGL animation code goes here */
            glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear Screen And Depth Buffer
        	glLoadIdentity();											// Reset The Modelview Matrix           glLoadIdentity();
      		glPushMatrix();	
            glTranslatef(+0.5/z_init,0.0f,z_init+0.23f*z_init);
            DrawCards();
            glPopMatrix();
            glFlush();
            SwapBuffers (hDC);
            Sleep (1);
        }
    }

    /* shutdown OpenGL */
    DisableOpenGL (hWnd, hDC, hRC);

    /* destroy the window explicitly */
    DestroyWindow (hWnd);

    return msg.wParam;
}


/********************
 * Window Procedure
 *
 ********************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
                          WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage (0);
        return 0;

    case WM_DESTROY:
        return 0;
    case WM_SIZE:
        {
            RECT window;
            GetWindowRect(hWnd,&window);
            glzResizeWindow(window.right - window.left - 7,window.bottom - window.top - 34);
        }
        break;
    case WM_LBUTTONDOWN:
        {
        selectObjects(LOWORD(lParam),HIWORD(lParam),hWnd);
        }
        break;
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;
        }
        return 0;

    default:
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
}


/*******************
 * Enable OpenGL
 *
 *******************/

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{

    RECT windowRect;
    GetWindowRect(hWnd,&windowRect);
    AdjustWindowRect (&windowRect, WS_POPUP, 0);
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    /* get the device context (DC) */
    *hDC = GetDC (hWnd);

    /* set the pixel format for the DC */
    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 = 24;
    pfd.cDepthBits = 16;
    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 );
    
    glEnable(GL_TEXTURE_2D);							// Enable Texture Mapping
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
    glEnable( GL_LINE_SMOOTH );
	glHint( GL_LINE_SMOOTH_HINT,GL_NICEST );

}


/******************
 * Disable OpenGL
 *
 ******************/

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent (NULL, NULL);
    wglDeleteContext (hRC);
    ReleaseDC (hWnd, hDC);
}

void glzResizeWindow(int width, int height)
{
    if(height == 0)
        height =1;
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f,(GLfloat)(width/height),0.1f,100.f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void DrawCards()
{   
    glLoadName(1);
    glTranslatef(-1.0f,0.0f,0.0f);
    glColor3f(color1.r,color1.g,color1.b);
    glBegin(GL_QUADS);

    glVertex3f(0.0f  ,0.0f  ,0.0f);
    glVertex3f(1.0f ,0.0f  ,0.0f);
    glVertex3f(1.0f ,2.0f,0.0f);
    glVertex3f(0.0f  ,2.0f,0.0f);

    glEnd();
}
void selectObjects(double mouse_x,double mouse_y,HWND hWnd)
{
    GLuint selectBuf[512];
	GLint viewport[4];
	float ratio;

	glSelectBuffer(512,selectBuf);

	glGetIntegerv(GL_VIEWPORT,viewport);

	glRenderMode(GL_SELECT);

	glInitNames();
    glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	gluPickMatrix(mouse_x,viewport[3]-mouse_y,1,1,viewport);
	ratio = (viewport[2]+0.0) / viewport[3];
	gluPerspective(45,ratio,0.1,100);
	glMatrixMode(GL_MODELVIEW);
	DrawCards();
    glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glFlush();
	int hits = glRenderMode(GL_RENDER);
    if(hits)
        color1 = color2;
    char temp[30];
    sprintf(temp,"%d",hits);
    SetWindowText(hWnd,temp);
    
} 

P.S Thank you for your time ... [Edited by - ZeuC on October 23, 2006 5:46:27 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
well it's supposed to print "1" in the window title when you press the red square and then turn the square green ... but it's not..I think that the problem is in the DrawCards() and selectObjects() bit of the code ...

i could really really use your help ...
-ZeuC

Share this post


Link to post
Share on other sites
You're glTranslate-ing before you render the card in your message loop, but you're not doing the same translation in selectObjects.


//... in WinMain
glTranslatef(+0.5/z_init,0.0f,z_init+0.23f*z_init);
DrawCards();

//... in selectObjects
glMatrixMode(GL_MODELVIEW);
// missing glLoadIdentity();
// missing glTranslate(/* blah with z_init */);
DrawCards();



You may think the MODELVIEW matrix will still be okay to draw the card, but don't forget: inside of DrawCards, you're also glTranslate-ing...pushing it further into the scene, or out of, or however. ^_^

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this