简体   繁体   中英

Zoom OpenGL scene using mouse selection

I'm trying to implement zoom of opengl scene according to selected area on screen with a mouse.

My goal is to make so that user is able to zoom whichever part of a 2D opengl world using a mouse. Also he should ne able to zoom several times.

Having hard time trying to achieve this.

Drawing is perfromed with:

    glViewport(fullscreen)
    gluOrtho2D()
    ...drawing...

Tried to change world coords in gluOrtho2D, but it seems to be impossible to zoom several times then...

So I'm trying to figure numbers for glScalef and glTranslatef...

Maybe any1 has tried to do something like this and could help with some advice?

How about you use glLoadIdentity to reset the matrix to a sane value. Everytime you call one of OpenGL's matrix manipulation functions it does an in-place multiplication onto the top of the currently active matrix stack.

Your typical display function should look like this (pseudocode)

display:
    glClear(…)

    # just to illustrate that you can mix multiple projection
    # setups throughout rendering a single frame
    foreach l in layers:
        glViewport(l→viewport)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        l→setup_projection() # for example glOrtho

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        l→setup_view() # for example gluLookAt

        foreach m in models:
            glMatrixMode(GL_MODELVIEW)
            # make a copy of the current modelview so that we can
            # restore it after the model has been drawn, by pushing onto the stack
            glPushMatrix()

            setup_model_transformation()
            draw_model()

            glMatrixMode(GL_MODELVIEW)
            # restore to the previous matrix by poping it from the stack
            glPopMatrix()

Note that this uses the deprecated (ie old and removed from modern OpenGL) matrix stack. Modern OpenGL programs do their own matrix math and just load the relevant, effective matrices into so called shader uniforms for each model drawn.

Made some progress...

    displayedMapCoords[0] = mapCenterPoint[0] - sceneSize * aspectRatio;
    displayedMapCoords[1] = mapCenterPoint[0] + sceneSize * aspectRatio;
    displayedMapCoords[2] = mapCenterPoint[1] - sceneSize;
    displayedMapCoords[3] = mapCenterPoint[1] + sceneSize;
    ...
    gluOrtho2D( displayedMapCoords[0], displayedMapCoords[1],
                displayedMapCoords[2], displayedMapCoords[3] ); 
    glScalef(mapScale, mapScale, 0);
    ...

When selected a rect with mouse, I calculate scale factor and new center point:

    mapScale = (float) CfgManager::Instance()->getScreenHeight() / selectedAreaSize;
    mapCenterPoint[0] = -(float) mapScale * (CfgManager::Instance()->getScreenWidth()/2 - zoomArea[0] - selectedAreaSize / 2) * sceneSize / CfgManager::Instance()->getScreenHeight();
    mapCenterPoint[1] = (float) mapScale * (CfgManager::Instance()->getScreenHeight()/2 - zoomArea[1] - selectedAreaSize / 2) * sceneSize / CfgManager::Instance()->getScreenHeight();

This code works just fine... but only once. I'd like to be able to select another area after I've zoomed already. Calculating scale factor is not an issue here, but calculate new center point position is not so easy :/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM