PDA

View Full Version : Zooming



philm0
04-07-2016, 07:32 PM
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();

}

philm0
04-08-2016, 08:18 AM
Anyone? Please, if you need more information, let me know.

javaprophet
04-08-2016, 08:27 AM
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.

philm0
04-08-2016, 08:42 AM
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.

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

javaprophet
04-08-2016, 11:51 AM
I don't think you need to scale manally, changing the ortho should do it effectively.

philm0
04-08-2016, 02:30 PM
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