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 (i.e. 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 :/
Related
Forgive me if I am asking similar question but I am not getting the right answer or may be I am unable to understand how to implement it
I have to load HUD in front of camera I got camera DOF (x,y,z,apha, beta, gamma) I have only this information. How can I use camera DOF to translate the HUD in front of camera.
float x = eye[ 0 ].X()+ 0.465;
float y = eye[ 0 ].Y()+ 1.0; //bringing in front of camera
float z = eye[ 0 ].Z()- 0.08;
I am adding few magic numbers to x,z (above mentioned lines ) and then HUD is right on the screen but if the camera is moved the hud is disappeared because these magic numbers are for only that camera position. I want to know the solution
one of my friend told me following
Feed the camera rotation into the HUD_DOF_All so the HUD rotates to face the camera square on.
Then in SetInstancePosition use the eyePos + eyeDir * M
I dont know how to achieve that or if it is true.
Thanks in advance
How can I use camera DOF to translate the HUD in front of camera.
You're thinking too complicated: OpenGL just draws points, lines and triangles. OpenGL does not maintain a 3D scene!
To draw a HUD you simply draw it at the desired position. You do this simply be setting the right projection and modelview transformations that put the HUD at the desired location of the screen. If you're using the programmable pipeline (shaders) you set the appropriate uniforms. If you use the fixed function pipeline, setup a fresh, HUD appropriate projection and modelview matrix, then draw the HUD.
I've got a particular model that acts as controls in the viewer. The user can click on different parts of it to perform transformations on another model in the viewer (like controls/handles in applications like Unity or Blender).
We'd like the controls to remain the same size regardless how zoomed in/out the camera is. I've tried scaling the size of it based on the distance between the object and the camera but it isn't quite right. Is there a standard way of accomplishing something like this?
The controls are rendered using the fixed pipeline, but we've got other components using the programmable pipeline.
The easy answer is "use the programmable pipeline" because it's not that difficult to write
if(normalObject) {
gl_Position = projection * view * model * vertex;
} else {
gl_Position = specialMVPMatrix * vertex;
}
Whereas you'll spend a lot more code trying to get this to work in the Fixed-Function-Pipeline and plenty more CPU cycles rendering it.
With the fixed pipeline, the easiest way to do this is to simply not apply any transformations when you render the controls:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// draw controls
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
The glPushMatrix()/glPopMatrix() calls will make sure that the previous matrices are restored at the end of this code fragment.
With no transformation at all, the range of coordinates mapped to the window will be [-1.0 .. 1.0] in both coordinate directions. If you need anything else, you can apply the necessary transformations before you start drawing the controls.
I'm having a "5am problem" with my code.
My program has to display a 3d model and I need to rotate using the arcball method
so far everything i calculated was ok ( i believe...)
what I want to happen next is that every time i drag the curser ( which created the vectors)
the model will keep rotating from where it is.
I tried using the getFloatv and mult it but was with no success
the model keeps returning to its starting point of view .
Note : I've used push and pop matrix command in every function so no mess will be done
you could say the real question is how to use this quatrainon and matrix multiply
to add rotations to one another
so is there anything missing? or anything missplaced?
thanks,
EDIT :::::::::::::::: updated code:
Hey, thanks for answering but i still have a problem
i tried using an if statement to only multmatrix when the rotation is done
but then there is no continuous rotation, it just jumps to the beginning every time
glGetFloatv(GL_MODELVIEW_MATRIX,_oldRotationsQuatro);
glTranslatef(0.f,0.f,DRAWFARONZAXIS);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Modeling transformation
glLoadIdentity();
glColor3d(1,1,1);
drawObject(model);
glRotated(model->getCurrRotatingAngle(),model->getRotatingAroundVector().getX(),
model->getRotatingAroundVector().getY(),
model->getRotatingAroundVector().getZ());
// if (end rotate)
glMultMatrixf(_oldRotationsQuatro);
drawCamera();
glPopMatrix();
good rotation but super speed...
EDIT
Thanks i figured something out. the glmultmatrix doesnt work exactly as i thought
so i just added another matrix and used some old savings.
thanks!
What you need to do is compute a rotation matrix offset from the angle/axis representation you have. When you stop dragging, you need to store this matrix as rotation in your model object. When you start dragging again, you first apply the rotation, and then the offset with glMultMatrix. When you stop dragging, you multiply offset onto rotation. Pseudo code:
Initialization: Set rotation to identity.
While dragging: Compute offset from axis/angle, glMultMatrix(rotation); glMultMatrix(offset).
Stop dragging: Set rotation = rotation * offset.
I'm new to OpenGL and I've been experiencing the "Black Screen Effect". I've spent ages trying to work out why I'm not seeing anything and I haven't had much success. I'm using LWJGL and here is the piece of code I'm trying to run:
glViewport(0,0,DISPLAY_WIDTH,DISPLAY_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 6200000.0f, 6300000.0f, 350000.0f, 380000.0f, -10000000.0f, 100000000.0f);
gluLookAt(368000.0f, 6250000.0f, -10000.0f, 368000.0f, 6250000.0f, 10000.0f, 0.0f,1.0f,0.0f);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
if(ready)
{
glColor3f(1.0f,0.5f,1.0f);
glPointSize(100);
glBegin(GL_POINTS);
for(int i = 0; i < data.length; i += 100)
{
glColor3f(1.0f,1.0f,1.0f);
glVertex3f((float) data[i][1], (float) data[i][2],0.0f);
System.out.println((float) data[i][1] + ", " + (float) data[i][2]);
}
glEnd();
System.out.println("\n\nfinished drawing\n\n");
glFlush();
I am drawing in a different colour that i used to clear the screen.
My data set is quite large (over 100 000 points) so I tried plotting every hundredth point, but that's not working.
I am also trying to plot points at positions such as (400 000, 6 800 000) would this be presenting me with problems? I'm pretty sure that 32bit floating point numbers should be able to handle these values.
I am pretty certain that a pixel with size=1 will try to plot as 1 pixel on the screen, regardless of how small it is compared with the bounds of the orthographic projection.
Maybe I'm dealing with the projection matrix incorrectly.
First, like said in my comment don't use gluLookAt on the projection matrix. It defines the camera (view) and therefore belongs to the model view matrix. This isn't the cause for your problem and it should also work this way, but it is conceptually wrong.
Next, if you call this code every frame, you push a new matrix onto the stack every frame, without calling glPopMatrix. glPushMatrix is generally there to save the current matrix and restore it later with a call to glPopMatrix, because every other command (like glLoadIdentity, but also gluLookAt and glOrtho) modifies the current matrix (the one selected by glMatrixMode).
Otherwise, you should always keep the size of your scene in relation to the viewing volume (the glOrtho parameters in your case) in mind. At the moment you're looking from point (368000, 6250000, -10000) to point (368000, 6250000, 10000). Together with the glOrtho parameters this should define your viewing volume to be the [368000-6300000 , 368000-6200000] x [6250000+350000 , 6250000+380000] x [-10000000-10000, 100000000-10000] box. If you don't transform your points further by any local transformations, their coordinates should ly in these intervals to be visible. Keep an eye on the minus in the x-interval. This is due to the fact that you actually rotated the view volume 180 degrees around the y-axis, because you defined the view to look from -z to z, whereas GL's default eye-space defines the viewer to look from z to -z (which usually is not that much of a problem with an origin-symmetric viewing volume, but yours is highly asymmetric).
Although your numbers are extremely strange they should be handlable by 32bit floats. But are you really sure you want your points to have a size of 100 pixels (if this is even supported)?
And if you only draw 2D points in an orthographic view, I'm also not sure if you need such a HUGE depth range.
I'm trying to implement stereoscopic 3d in OpenGL using a side-by-side technique.
I've read this article which in great detail explains how to set up the camera for left and right views. It uses a camera model and set up the left and right views using gluLookAt.
However in my case I want to adapt existing code that already set up the projection.
See the following example where "existingcode" represents the code that I cannot make changes to.
//Render left view
// setUpCamera set the gl projection and model matrix
existingcode.setUpCamera()
..
here I want to somehow modify the current gl projection matrix for the left view
..
existingcode.renderScene()
//.. then render right view
Can it be done, perhaps by calling glGetMatrix and modify it somehow?
What you've to do is employ some lens shiftig.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
stereo_offset = eye * near * parallax_factor / convergence_distance;
glFrustum(stereo_offset + left, stereo_offset + right, bottom, top, near, far);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(eye * parallax_factor * convergence_distance, 0, 0);
/* now use gluLookAt here as this were a normal 2D rendering */
parallax_factor should be no larger than the ratio of half_eye_distance / screen_width, so the larger the screen gets the smaller the parallax_factor is. A good value for parallax_factor for computer display use is 0.05, for large screens (think cinema) it's something like 0.01
This projection shifting technique is exactly what I used for re-rendering Elephants Dream in stereoscopic 3D, although, since Blenders offline renderer doesn't use OpenGL the code looks a little bit different http://www.youtube.com/watch?v=L-tmaMR1p3w