Please see the following image:
Which mathematical method or POV-Ray/OpenGL command will lessen the convergence of a grid like this? (The grid converges too quickly; theta should be 90 degrees, matching the center line, for this purpose.)
Perspective is still desired, but convergence should happen at a slower rate, as if the distance was shorter or you were using a telephoto lens.
Although this image is from Blender, the methods being used are OpenGL and POV-Ray so a solution in either method would be appreciated.
I have some lines modeled in OpenGL and POV-Ray.
I have tried location, look--at, angle, right and up in POV-Ray, including camera transformations like rotate, scale, translate and matrix.
In OpenGL I have tried gluPerspective, glFrustum and glDepthRange.
Does anyone have a solution to this problem?
(Also, looking down on the grid is not an option in this case)
You're after an orthographic projection...
glOrtho()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(left, right, bottom, top, near, far);
glMatrixMode(GL_MODELVIEW);
It's always nice to be able to swap between orthographic and perspective though since moving around a scene in orthographic can take a while to get used to.
There's an image here... https://blender.stackexchange.com/questions/648/what-are-the-differences-between-orthographic-and-perspective-views
edit
To keep using perspective, but with less perspective effect, you can decrease the field of view parameter. Unfortunately this will make the projection appear to zoom in. To undo the zoom, move the camera back. You can then update the near/far accordingly if need be.
Related
I want to mix a perspective and orthographic view, but I can't get it to work.
I want X and Y coordinates to be orthographic and Z perspective. For clarification I added a sketch of the desired transformation from OpenGL coordinates to screen display:
(I started from a tutorial, but couldn't find how to get values top, bottom, etc.)
What you've drawn is simply perspective, not a mix. You just have to make sure that the viewing direction is parallel to the z axis to make the front and back faces of the box stay rectangular.
You could probably use glFrustum to achieve this.
If you use a standard perspective matrix and the camera faces the box front on, X/Y will be uniform, however movement away from the camera will move the X/Y coordinates towards the centre, shrinking them for a standard parallax effect. What you've drawn is movement towards the top of the window. All you need to do is crop the perspective projection to below its standard centre. That's where glFrustum comes in - move the normally symmetrical top/bottom arguments down, align the camera/view matrix along the axis you want and you should have the desired projection.
Any rotation of the camera/view will destroy the uniform projection in the X/Y plane. For camera movement you're then limited to panning and moving the glFrustum bounds.
EDIT Come to think of it, you could probably just throw in a glTranslatef(shearX, shearY, 0) before the call to gluPerspective and achieve the same thing.
In OpenGL (all versions, though I happen to be working in OpenGL ES 2.0) there is the option of using a perspective projection versus an orthogonal one. Is there a way to control the degree of orthogonality?
For the sake of picturing the issue (and please don't take this as the actual question, I am well aware there is no camera in OpenGL) assume that a scene is rendered with the viewport "looking" down the -z axis. Two parallel lines extending a finite distance down the -z axis at (x,y)=1,1 and (x,y)=-1,1 will appear as points in orthogonal projection, or as two lines that eventually converge to a single pixel in perspective projection. Is there a way to have the x- and y- values represented by the outer edges of the screen remain the same as in projection space - I assume this requires not changing the frustum - but have the lines only converge part of the way to a single pixel?
Is there a way to control the degree of orthogonality?
Either something is orthogonal, or it is not. There's no such thing like "just a little orthogonal".
Anyway, from a mathematical point of view, a perspective projection with an infinitely narrow field of view is orthogonal. So you can use glFrustum with a very large near and far plane distance, together with a countering translation in modelview to bring the far away viewing volume back to the origin.
and this time i have loaded a model successfully! yay!!
but theres a slight problem, one that i had with another obj loader...
heres what it looks like:
http://img132.imageshack.us/i/newglitch2.jpg/
heres another angle if u cant see it right away:
http://img42.imageshack.us/i/newglitch3.jpg/
now this is supposed to look like a cube, but as you can see, the edges of the faces on the cube are being very choppy
is anyone else having this problem, or if anyone knows how to solve this then let me know
also comment if theres any code that needs to be shown, ill be happy to post it.
hey i played around with the code(changed some stuff) and this is what i have come up with
ORIGINAL:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.f,(double)800 / (double)600,0.f,200.f);
glTranslatef(0.f, 0.f, -10.0f);
result: choopy image(look at images)
CURRENT:
glMatrixMode(GL_MODELVIEW);
gluPerspective(50.f,(double)800 / (double)600,0.f,200.f);
glTranslatef(0.f, 0.f, -50.0f);
glLoadIdentity();
result: model is not choppy but cannot move camera(model is right in front of me)
gluPerspective(50.f,(double)800 / (double)600,0.f,200.f);
^^^
|
That's your problem right there ---------------+
The near clip distance must be greater than 0 for perspective projections. Actually you should choose near to be as far away as possible and the far clip plane to be as near as possible.
Say your depth buffer is 16 bits wide, then you slice the scene into 32768 slices. The slice distribution follows a 1/x law. Technically you're dividing by zero.
Well this looks like a projection setting issue. Some parts of your cube, when transformed into clip space, exceed near/far planes.
From what I see you are using orthogonal projection matrix - it's standard for making 2D UI. Please review nearVal and farVal of your glOrtho call. For 2D UI they are usually set as -1 and 1 respectively (or 0 and 1), so may want to either scale down cube or increase view frustum depth by modifying mentioned parameters.
I have looked at the documentation on MSDN about these 2 functions. However, I don't exactly understand the difference between these 2 functions, other than one is for setting camera view for 3D, and the other one is for setting camera view for 2D. It would be great if it can be answered. Thanks in advance for comments.
An orthographic projection is basically a 3D projection that does not have perspective. Essentially it means that a given position does not get closer to the centre of projection the further it gets from the viewer. Perspective is obviously the opposite. Due to the fact that you divide by w after projecting it means that a value with a larger W (One that is further from the centre of projection in world terms) will "appear" closer to the centre of projection post w-divide. It is this perspective projection and w-divide that gives us the sense of depth in 3D graphics.
If you recall drawing a cube in early maths lessons you will recall that if you draw each of the 2 squares that make up the end of the cube as the same size then the back end of the cube will look larger. This is an orthographic projection. It looks weird because our eyes are used to seeing things with perspective.
IF you shrink that second square then you get perspective and hence the perspective projection.
Wikipedia has some good images demonstrating the difference as well as a good explanation.
Parallel (or Othographic) projection
Perspective (or 3D) projection
a decent explanation of perspective in general
I'm trying to do a simple rotation in OpenGL but must be missing the point.
I'm not looking for a specific fix so much as a quick explanation or link that explains OpenGL rotation more generally.
At the moment I have code like this:
glPushMatrix();
glRotatef(90.0, 0.0, 1.0, 0.0);
glBegin(GL_TRIANGLES);
glVertex3f( 1.0, 1.0, 0.0 );
glVertex3f( 3.0, 2.0, 0.0 );
glVertex3f( 3.0, 1.0, 0.0 );
glEnd();
glPopMatrix();
But the result is not a triangle rotated 90 degrees.
Edit
Hmm thanks to Mike Haboustak - it appeared my code was calling a SetCamera function that use glOrtho. I'm too new to OpenGL to have any idea of what this meant but disabling this and rotating in the Z-axis produced the desired result.
Ensure that you're modifying the modelview matrix by putting the following before the glRotatef call:
glMatrixMode(GL_MODELVIEW);
Otherwise, you may be modifying either the projection or a texture matrix instead.
Do you get a 1 unit straight line? It seems that 90deg rot. around Y is going to have you looking at the side of a triangle with no depth.
You should try rotating around the Z axis instead and see if you get something that makes more sense.
OpenGL has two matrices related to the display of geometry, the ModelView and the Projection. Both are applied to coordinates before the data becomes visible on the screen. First the ModelView matrix is applied, transforming the data from model space into view space. Then the Projection matrix is applied with transforms the data from view space for "projection" on your 2D monitor.
ModelView is used to position multiple objects to their locations in the "world", Projection is used to position the objects onto the screen.
Your code seems fine, so I assume from reading the documentation you know what the nature of functions like glPushMatrix() is. If rotating around Z still doesn't make sense, verify that you're editing the ModelView matrix by calling glMatrixMode.
The "accepted answer" is not fully correct - rotating around the Z will not help you see this triangle unless you've done some strange things prior to this code. Removing a glOrtho(...) call might have corrected the problem in this case, but you still have a couple of other issues.
Two major problems with the code as written:
Have you positioned the camera previously? In OpenGL, the camera is located at the origin, looking down the Z axis, with positive Y as up. In this case, the triangle is being drawn in the same plane as your eye, but up and to the right. Unless you have a very strange projection matrix, you won't see it. gluLookat() is the easiest command to do this, but any command that moves the current matrix (which should be MODELVIEW) can be made to work.
You are drawing the triangle in a left handed, or clockwise method, whereas the default for OpenGL is a right handed, or counterclockwise coordinate system. This means that, if you are culling backfaces (which you are probably not, but will likely move onto as you get more advanced), you would not see the triangle as expected. To see the problem, put your right hand in front of your face and, imagining it is in the X-Y plane, move your fingers in the order you draw the vertices (1,1) to (3,2) to (3,1). When you do this, your thumb is facing away from your face, meaning you are looking at the back side of the triangle. You need to get into the habit of drawing faces in a right handed method, since that is the common way it is done in OpenGL.
The best thing I can recommend is to use the NeHe tutorials - http://nehe.gamedev.net/. They begin by showing you how to set up OpenGL in several systems, move onto drawing triangles, and continue slowly and surely to more advanced topics. They are very easy to follow.
Regarding Projection matrix, you can find a good source to start with here:
http://msdn.microsoft.com/en-us/library/bb147302(VS.85).aspx
It explains a bit about how to construct one type of projection matrix. Orthographic projection is the very basic/primitive form of such a matrix and basically what is does is taking 2 of the 3 axes coordinates and project them to the screen (you can still flip axes and scale them but there is no warp or perspective effect).
transformation of matrices is most likely one of the most important things when rendering in 3D and basically involves 3 matrix stages:
Transform1 = Object coordinates system to World (for example - object rotation and scale)
Transform2 = World coordinates system to Camera (placing the object in the right place)
Transform3 = Camera coordinates system to Screen space (projecting to screen)
Usually the 3 matrix multiplication result is referred to as the WorldViewProjection matrix (if you ever bump into this term), since it transforms the coordinates from Model space through World, then to Camera and finally to the screen representation.
Have fun