I have the following OpenGL code in the display function:
glLoadIdentity();
gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx, upy, upz);
// called as: gluLookAt(20, 5, 5, -20, 5, 5, 0, 1, 0);
axis();
glutWireCube (1.);
glFlush ();
axis() draws lines from (0,0,0) to (10,0,0), (0,10,0) and (0,10,0), plus a line from (1,0,0) to (1,3,0).
My reshape function contains the following:
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45.0, (GLsizei) w / (GLsizei) h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
This image shows the result of running the program with 1. as the argument to glutWireCube:
As you can see, the cube isn't centered around (0,0,0) as the documentation says it should be:
The cube is centered at the modeling
coordinates origin (...) (source)
If I run the program with 5. as the argument, the cube is displaced even further:
Why is that, and how do I place the cubes around (0,0,0)?
FURTHER INFORMATION
It doesn't matter if I switch the order of axis() and glutWireCube. Surrounding axis() with glPushMatrix() and glPopMatrix() doesn't fix it either.
SOLUTION
I modified gluPerspective to start looking further away from the camera, and now the Z-buffering works properly, so it is clear that the cubes are placed around the origin.
Are you sure axis does not mess with the view matrix ?
What happens if you call it after the drawing of the cube ?
Edit to add:
Actually... Looking at the picture closer, it looks like it might be centered at the origin.
The center of the cube seems to align exactly with the intersection of the 3 axes. The only thing that looks suspicious is that the red line does not write over the white edge. do you have Z-buffering properly set up ?
It might be right, I think it's hard to determine due to the perspective ... But I guess it isn't from staring a bit more at it.
To quickly rule out that axis() isn't modifying the model view matrix, surround the call with matrix push/pops:
glPushMatrix();
axis();
glPopMatrix();
Things to investigate/check:
Is this the entire window? It seems odd that the view is down in one corner.
Does it help if you add an increasing rotation before the rendering? That can make it easier to determine the perspective, by giving more clues.
You can also try moving the "camera" around, by changing the arguments to gluLookAt() dynamically.
Related
I'm doing this OpenGL project for my Computer Graphics class, where I display an object and I rotate it and stuff, the thing is that at the beginning of the project we used glOrtho() and it looked really great.
But now the teacher said that we have to use glFrustum() for perspective and if I use that function, the object is drawn like this and I really don't know why does this happens:
This is my code from the init() function where everything changes:
void init (void)
{
/* select clearing (background) color */
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0, 100.0, -60.0, 160.0, -100.0, 100.0);
//glFrustum(-100, 100 ,-100 ,100 ,1 , 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(90,0,1,0);
}
I'd appreciate your help.
EDIT: If I use glFrustum(-100, 100, -100, 100, 20, 200) it looks like this, like I'm getting closer but what about the left, right, top and bottom parameters? Are they okay with that values?
It's hard to be certain without more information. Perhaps the model could give some insight. But I suspect it may have to do with your clipping planes (nearVal and farVal as described here) arguments passed to glFrustum (1, 40). Perhaps try setting them to a broader range like your glOrtho call: 1, 150 (Note: neither nearVal or farVal can be negative when passed to glFrustum).
This all depends on the scale of the model and how it is positioned relative to the camera. If part of the model falls outside of the clipping planes, then it will be, well... clipped.
I am using a perspective projection camera in OpenGL with an eye-target-up approach along the lines of gluLookAt()
I would like to move the entire 3d view to a different location within the 2d window, as shown in the image below:
I know this can be done with glViewport(), but I would ultimately like to be able to rotate the 3d view in addition to translating it, which I understand won't work with a glViewport approach.
I also understand that taking a non-glViewport approach will require the additional step of stenciling. I'll leave that step for later.
For now, I'm hoping to simply translate the 3d view as shown in the image above (ignoring the stenciling issue).
It seems like translating the projection matrix is the correct approach, however the translation extent is not what I expect. Perhaps I need to scale the parameter I'm using? In any case, I'm hoping someone can explain how to (more-or-less) simulate a translatable/rotatable glViewport for a 3d perspective view.
Thanks!
You use glViewport(). For each view port, you set the viewport, setup model view matrix and draw scene.
For first viewport
glViewport (0, 0, window_width/2, window_height/2);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//do something with projection matrix
drawScene();
For second viewport
glViewport (window_width/2, 0, window_width/2, window_height/2);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//do something different with projection matrix
drawScene();
I need to get a slightly 3D representation of a two-dimensional layer of plant cells in OpenGL 2.1 (actually Compatibility profile). It's looking pretty good so far with no transformations:
What you see in the center is a small 3D cube I drew for comparison purposes. It uses the same transformation matrix as all other models. Every cell consists of an extruded plateau (lighter parts) and sloped walls (the shadowy bits). There's a diffuse white light source pointed at the cell from somewhere about the eye.
Now comes the part where I'm stuck. Scaling and translations work just fine, but I can't get 3D rotations of the cell to work. The cube, defined around (0, 0, 0) rotates exactly as expected but the cells show a strange behaviour I haven't managed to explain.
Here's the same model slightly rotated.
First of all, the shadows are different (as expected I'd say). The light source doesn't move. I've tried moving it but it didn't really change much, so that's another problem altogether. What's especially peculiar to me is the way the cells get cut off. The lower left corner has missing pieces. One could say we're looking under that part of the cell, but then the other part of that cell doesn't look quite like expected. Or is the lighting just bad?
I'm looking for a rotation of this only slightly 3D model that would look more pleasing to the user. Would I go about changing the lighting? Mind you there is no way I can use Glu so there's no gluLookAt to instead view my camera around. Would there be another way around though? Creative answers are encouraged. In short, I need a way for a user to navigate around this slightly 3D model, knowing it's mostly 2D, that feels intuitive.
Some more images for context. The application supports rotation by dragging around the screen with the mouse so playing around is easy.
Rotated 90 degrees about the y axis (OK)
Ever so slightly rotated
Transformations:
glLoadIdentity();
glScalef(m_preferences->m_mesh_magnification, m_preferences->m_mesh_magnification, 1.0);
glRotatef(m_totalRotation.x() / 5., 0, 1, 0); // user rotation
glRotatef(m_totalRotation.y() / 5., -1, 0, 0); // user rotation
Body of resizeGL(w, h), responsible for the projection view:
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho(-((GLdouble) w) / 2, ((GLdouble) w) / 2, ((GLdouble) h) / 2, -((GLdouble) h) / 2, -1.0, 1.0);
//glFrustum(...) if we want a realistic projection
glMatrixMode (GL_MODELVIEW);
Basically I make y point down and have (0, 0) in the middle. The y direction I believe mimicks Qt's default, while the origin's location was a project decision.
EDIT: final result after rotating
glOrtho(-((GLdouble) w) / 2, ((GLdouble) w) / 2, ((GLdouble) h) / 2, -((GLdouble) h) / 2, -1.0, 1.0);
The -1.0, 1.0 are your near and far clipping planes. Anything in front of the near plane or behind the far plane will not be drawn. You'll need to increase those values -- but not much more than you need to, because you'll lose Z-buffer precision.
I'm working on interactive scenes for a computer graphics course. I've set up a program which will generate color cubes, and let me rotate them with the keyboard. However they're getting cut open by the near clip plane of my camera:
I've tried to use gluPerspective, but the OpenGL documentation doesn't give any examples of its use. I found it being used in an example program online, and semi-replicated their code:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 65, 1, 0.01, 100 );
glMatrixMode(GL_MODELVIEW);
Any thoughts?
UPDATE:
As suggested in the comments below, I tried using glFrustum instead, with the following code:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum( -0.5, 0.5, -0.5, 0.5, 0.1, 100 );
glMatrixMode(GL_MODELVIEW);
Again, there was no difference. Am I not pushing the resulting matrices correctly or something?
Perhaps you need to move your objects a little farther from the Camera. Right now it seems that they are closer than 0.0.
Considering your update "I moved the cubes one whole unit away from the camera, and now as they rotate they get clipped by both the near and the far clip planes" your cubes may be too large for your clipping depth (100 - 0.1). Move cubes away from the camera by 50 and set your clipping planes to 0.1 .. 1000 to make sure everything fits.
If the problem remains we might need to look at your matrices code.
I have a simple OpenGL drawing. When the user changes the window's size, I want the drawing to maintain it's aspect ration. I accomplished that by setting the glViewport to the maximum rectangle with the appropriate aspect ration whenever the reshape method is called.
My problem is that I want to draw a square that will always remain in the top right corner of the window, no matter what the size or shape of the window is. Right now, that square moves around the screen whenever the window is reshaped.
Can anyone please explain how to do this?
Thank you,
You need to move/size the square when the screen is re-sized. You can fix a square to the top left by using device coordinates but it won't necessarily be square of the aspect ratio changes. Therefore you need to resize the square to keep it square.
One way of doing this would be to create a new ortho matrix that maps to pixel coordinates (left = 0, bottom = 0, right = window-width, top = window-height) and set the gl-viewport to cover the entire window whenever the window changes. That way, you can draw a square by specifying pixel coordinates, if you make sure you have an identity model-view matrix set up.
It's not the only way, though. No matter what non-singular transformation you have, you should be able to come up with a way of hitting the correct pixels as long as the gl-viewport covers those, it's just easier this way.
If I understand correctly, you wish to draw a square at the top right corner of the window, regardless of where your scene viewport is positioned.
The easiest way to do this is to, after having rendered your normal scene with desired aspect, change the gl viewport to the square you want to draw in the top corner. Then draw a "full-screen" quad to fill the square, with full-screen in-fact becoming full-viewport in this case.
Untested semi-pseudo code would go something like this:
// Draw normal scene
glViewport(x, y, w, h);
drawScene();
// Draw top-right red square
glViewport( windowWidth - squareWidth, windowHeight - squareHeight,
squareWidth, squareHeight );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glColor3f(1.f, 0.f, 0.f);
glRectf(-1.f, -1.f, 1.f, 1.f);
Making sure that the winding of the glRectf matches your current gl cull face configuration. Alternatively, just temporarily disable culling by glDisable(GL_CULL_FACE) / glEnable(GL_CULL_FACE).
To draw a square in the top-right corner of the window, you need the viewport to cover this area. Having a viewport smaller than the window won't allow drawing in the corner.
You want your viewport to cover all the window (as done usually), and your square coordinates should be mapped to something like:
X0 = 1-2*s/width
X1 = 1
Y0 = 1-2*s/height
Y1 = 1
where s is the side of the square (pix), and width, height the dimensions of the window (pix).