Zooming

Hello everyone,

I am currently working on a zoom feature for my program. Basically, when you spin the mouse wheel, the window will zoom in/out depending on the direction of the wheel spun. I figured that glScale function would be apprioate for something like this. However, I seem to be having a difficult time implementing it. I started from one of the tutorials on lazy foo site and I am expanding to feature the zoom.

When I zoom out, I can see all four squares (one of them is white, I was experimenting with a few things) so this works normally. However, when I press one of the keys on the keyboard to translate the matrix, the camera zooms back to where it was before I zoomed out. I am very new to openGL and I am hoping someone can send some light. On a slight note, I also noticed that when I zoom in, it is just a white screen but I think that i do not have enough code for it to properly zoom in. Ideally, I would like to zoom in where the mouse pointer is pointing at. But I think that I need to expand on the code a but more. Any help would be greatly appreciated.

Also, I am developing in wxwidgets which is a cross platform UI library. So when you see the function Refresh(), this will force an event to paint the canvas to be thrown. Below is the code that I am currently working with:



void geometryEditorCanvas::onKeyDown(wxKeyEvent &event)
{
    if(event.GetKeyCode() == LETTER_W || event.GetKeyCode() == LETTER_w)
    {
        cameraY -= 16.0f;
    }
	else if(event.GetKeyCode() == LETTER_S || event.GetKeyCode() == LETTER_s)
	{
		cameraY += 16.0f;
	}	
	else if(event.GetKeyCode() == LETTER_A || event.GetKeyCode() == LETTER_a)
	{
		cameraX -= 16.0f;
	}
	else if(event.GetKeyCode() == LETTER_d || event.GetKeyCode() == LETTER_D)
	{	
		cameraX += 16.0f;
	}
    
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glLoadIdentity();
	
	glTranslated(cameraX, cameraY, 0.0f);
	glPushMatrix();
	
    this->Refresh();// This will force the canvas to experience a redraw event
}



void geometryEditorCanvas::onMouseWheel(wxMouseEvent &event)
{
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glLoadIdentity();
	
	if(event.GetWheelRotation() > 0)
	{
		glScaled(zoomFactor, zoomFactor, 0.0d);
		totalZoom *= zoomFactor;
	}
	else if(event.GetWheelRotation() < 0)
	{
		glScaled(1.0d / zoomFactor, 1.0d / zoomFactor, 0.0d);
		totalZoom /= zoomFactor;
	}
	
	glPushMatrix();
	
    this->Refresh();// This will force the canvas to experience a redraw event
}



void geometryEditorCanvas::onGeometryPaint(wxPaintEvent &event)
{
	wxGLCanvas::SetCurrent(*geometryContext);// This will make sure the the openGL commands are routed to the wxGLCanvas object
	wxPaintDC dc(this);// This is required for drawing
	
	render();
	
	SwapBuffers();// Display the output
}



void geometryEditorCanvas::render()
{
	// Clears the color buffer
	glClear(GL_COLOR_BUFFER_BIT);
	
	//Reset to modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	
    glPushMatrix();
	
	glTranslatef(canvasWidth / 2.0f, canvasHeight / 2.0f, 0.0f);
	
    //Red quad
    glBegin( GL_QUADS );
        glColor3f( 1.f, 1.f, 1.f );
        glVertex2f( -canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f,  canvasHeight / 4.f );
        glVertex2f( -canvasWidth / 4.f,  canvasHeight / 4.f );
    glEnd();

    //Move to the right of the screen
    glTranslatef( canvasWidth, 0.f, 0.f );

    //Green quad
    glBegin( GL_QUADS );
        glColor3f( 0.f, 1.f, 0.f );
        glVertex2f( -canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f,  canvasHeight / 4.f );
        glVertex2f( -canvasWidth / 4.f,  canvasHeight / 4.f );
    glEnd();

    //Move to the lower right of the screen
    glTranslatef( 0.f, canvasHeight, 0.f );

    //Blue quad
    glBegin( GL_QUADS );
        glColor3f( 0.f, 0.f, 1.f );
        glVertex2f( -canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f,  canvasHeight / 4.f );
        glVertex2f( -canvasWidth / 4.f,  canvasHeight / 4.f );
    glEnd();

    //Move below the screen
    glTranslatef( -canvasWidth, 0.f, 0.f );

    //Yellow quad
    glBegin( GL_QUADS );
        glColor3f( 1.f, 1.f, 0.f );
        glVertex2f( -canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f, -canvasHeight / 4.f );
        glVertex2f(  canvasWidth / 4.f,  canvasHeight / 4.f );
        glVertex2f( -canvasWidth / 4.f,  canvasHeight / 4.f );
    glEnd();
    
}




Anyone? Please, if you need more information, let me know.

In a 3D perspective scene, you could lower the FOV. In a 2D scene, decrease the ortho compared to your viewport I think(less certain than 3D on this one). For example, on a 800x600 window, keep that your viewport, but perhaps set Ortho to 400x300 for a 2x zoom.

EDIT: With the ortho solution, make sure you apply that centered, it increase right, bottom by 100, and decrease left, top for 100. Otherwise, you’ll zoom to a corner.

[QUOTE=javaprophet;1282100]In a 3D perspective scene, you could lower the FOV. In a 2D scene, decrease the ortho compared to your viewport I think(less certain than 3D on this one). For example, on a 800x600 window, keep that your viewport, but perhaps set Ortho to 400x300 for a 2x zoom.

EDIT: With the ortho solution, make sure you apply that centered, it increase right, bottom by 100, and decrease left, top for 100. Otherwise, you’ll zoom to a corner.[/QUOTE]

Thanks javaprophet, I will give this a try.

So for the glScale function, when would I use this? I read an article saying that for zooming, you would use the glScale function to scale your matrix.

BTW: I am developing for 2D

I don’t think you need to scale manally, changing the ortho should do it effectively.

Ok, I haven’t had much time but I think that I have another problem.

Currently, when I press down a key, I have it execute this function


void geometryEditorCanvas::onKeyDown(wxKeyEvent &event)
{
    if(event.GetKeyCode() == LETTER_W || event.GetKeyCode() == LETTER_w)
    {
        cameraY -= 16.0f;
    }
	else if(event.GetKeyCode() == LETTER_S || event.GetKeyCode() == LETTER_s)
	{
		cameraY += 16.0f;
	}	
	else if(event.GetKeyCode() == LETTER_A || event.GetKeyCode() == LETTER_a)
	{
		cameraX -= 16.0f;
	}
	else if(event.GetKeyCode() == LETTER_d || event.GetKeyCode() == LETTER_D)
	{	
		cameraX += 16.0f;
	}
    
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glLoadIdentity();
	
	glTranslated(cameraX, cameraY, 0.0f);
	glPushMatrix();
	
    this->Refresh();// This will force the canvas to experience a redraw event
}

Normally, I would expect this to translate whatever my current view is. However, what happens is that my view is rest back to the way it was before I zoomed in.

I think that the issue lies in the Pop and Push functions. However, I do not have a firm understanding on these two and how to utilize them effectively