Skip to main content
GameDev.net gamedev.net
🔒 Locked

Opengl Selection with Ortho Mode

Started by Xiachunyi Dec 24, 2005 at 10:30 AM 2 replies 2.7k views
Original Post
Xiachunyi
Xiachunyi
Hello, I am currently making a programming that finally has a GUI in ortho mode, but the problem with this is that my selection code does not work. The selection code is shown below:

int Select(int x, int y)
{
    int objectsFound = 0;
    int viewportCoords[4] = {0};
    unsigned int selectBuffer[128] = {0};

    glSelectBuffer(128, selectBuffer);
    glGetIntegerv(GL_VIEWPORT, viewportCoords);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
        glRenderMode(GL_SELECT);
        glLoadIdentity();
        gluPickMatrix(x, viewportCoords[3] - y, 1, 1, viewportCoords);
        gluPerspective(45.0f, (float)g_rRect.right / (float)g_rRect.bottom, 0.1f, 150.0f);
        glMatrixMode(GL_MODELVIEW);
            DrawScene();
            objectsFound = glRenderMode(GL_RENDER);
        glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);

    if(objectsFound > 0)
    {
        unsigned int lowestDepth = selectBuffer[1];
        int selectedObject = selectBuffer[3];

        for(int i = 1; i < objectsFound; i++)
        {
            if(selectBuffer[(i * 4) + 1] < lowestDepth)
            {
                lowestDepth = selectBuffer[(i * 4) + 1];
                selectedObject = selectBuffer[(i * 4) + 3];
            }
        }

        return selectedObject;
    }
    return 0;
}

This code does work for objects that are only drawn in projection mode but not in ortho. I have tried searching for a solutions on the internet and in the forums but have either arrived at a dead end or the replies involved utilizing another method such as ray tracing or the back buffer (colors). My scene involves objects drawn in both orthographic and projection views. The objects drawn in projection are simply given an ID that is regarded as being nothing while the objects drawn in ortho are given various IDs to distinguish one from another. Thank you.
Xiachunyi
Xiachunyi
Upon trying to figure out what is wrong, I find that rendering just the area around my mouse produces only the objects that are drawn in the projection mode. The objects, my buttons, that are drawn in the orthographic mode are skipped and never even displayed.

There must be something wrong with my orthographic setup but I am unsure.
//Sets the Matrix Mode into Orthographic View - Thanks to "Dwarf with Axe" from www.gamedev.netvoid SetOrtho(){    int iViewPort[4];    glGetIntegerv(GL_VIEWPORT, iViewPort);    glMatrixMode(GL_PROJECTION);    glPushMatrix();    glLoadIdentity();    //glOrtho(0, iViewPort[2], 0, iViewPort[3], -1, 1);    glOrtho(-ASPECT_X / 2, ASPECT_X / 2, -ASPECT_Y /2, ASPECT_Y / 2, -1, 1);    glMatrixMode(GL_MODELVIEW);    glPushMatrix();    glLoadIdentity();}//Sets the Matrix Mode into Projection View - Thanks to "Dwarf with Axe" from www.gamedev.netvoid SetProjection(){    glMatrixMode(GL_PROJECTION);    glPopMatrix();    glMatrixMode(GL_MODELVIEW);    glPopMatrix();}


Anyone have a clue as to why objects drawn in ortho are not drawn for the selection routine?
LilBudyWizer
LilBudyWizer
If I had to guess it would be that DrawScene just draws the objects and a differant routine draws the GUI. Particularly since you have that gluPerspective before calling it. So my guess would be you need to set the projection/camera for the GUI, draw the GUI then call glRenderMode.
Keys to success: Ability, ambition and opportunity.
Skeleton_V@T
Skeleton_V@T
You don't really need to switch to Ortho mode when drawing 2D objects. Normally a GUI object is drawn using a Quad or two triangle strips, you can draw these 2D quad directly onto the screen without having to switch to other mode. The code will look like this:
//Assume the quad has dimensions of (2, 2)	glBegin(GL_QUADS);	// Draw A Quad		glVertex3f(-1.0f, 1.0f, 0.0f);		glVertex3f( 1.0f, 1.0f, 0.0f);		glVertex3f( 1.0f,-1.0f, 0.0f);		glVertex3f(-1.0f,-1.0f, 0.0f);	glEnd();


If we are standing at (0.0f, 0.0f, -1.0f) and draw this quad, it will cover the screen entirely. So before drawing the quad, we should translate back an amount of
glTranslatef (0.0f, 0.0f, -ScreenWidth)


By moving back an amount of -ScreenWidth along z axis, the object will be drawn exactly in it's original dimensions (meaning (2, 2) with the above quad). So no state changes are required, we just have to make sure to disable DepthBuffer before drawing and it will be on top of all other objects.

You may refer to this snippet, it will draw a quad at a particular absolute position:
//pPos is a 2D vector with X and Y components//ListID is an ID of a created display list of a quad//Setup OpenGL states    glDisable (GL_DEPTH_TEST) ;//Setup matrices    //Model View matrix	glPushMatrix () ;	glLoadIdentity () ; //These two lines make sure the object will be draw in it's original dimensions	glTranslatef (pPos -> X, pPos -> Y, static_cast<float> (-GW_WIDTH)) ;//Draw the object    glCallLists (1, GL_UNSIGNED_BYTE, ListID) ;//Restore matrices    //Model View matrix	glPopMatrix () ;//Restore OpenGL states    glEnable (GL_DEPTH_TEST) ;


While my solution maybe different from your design, it requires a little amount of work to draw a 2D object (it is actually a 3D object), this probably worths a looking at. :)
--> The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones <--

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.