Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I created a rubik's cube with 26 squares(not 27 since you cant see the middle one). I am trying to rotate the cube. I thought about using Pushstack Popstack, but I couldnt find any good examples I could look at.
I was wondering what is a good way to rotate. I used 26 of the following code to create the cubes
glBegin(GL_POLYGON);
//glColor3f( 1.0, 0.0, 1.0 );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 1.5, -0.5, -0.5 );
glVertex3f( 1.5, 0.5, -0.5 );
glVertex3f( 1.5, 0.5, 0.5 );
glVertex3f( 1.5, -0.5, 0.5 );
glEnd();
Your code produces a face, not a whole cube. But you will need 26 complete small cubes in order to render it correctly. Otherwise, if you rotate a cube, there will be holes.
You can do something like the following:
Organize the big cube as a 3x3x3 grid. Each grid cell contains a small cube. Each small cube consists of its geometry data and its rotation information. You can store the geometry data as a vertex buffer or as a display list or as a method that generates the geometry on the fly. Just as you wish. So if you don't have any rotations yet and you render the pure geometry, you should get the whole cube well-aligned.
For the rotations it is reasonable to use a quaternion for each small cube. However, you could use matrices as well, but those are a bit trickier to handle. Actually, I would store two quaternions for each cube. One that describes the target rotation and one that describes the current rotation (for animation purposes). When updating the current rotation towards the target rotation, you can do something like this:
interpolationVariable = c ^ timeStep //to allow a fluid and continuous animation.
//c is usually between 0.99 and 1, depending on the desired animation smoothness
currentRotation := interpolationVariable * currentRotation + (1 - interpolationVariable ) * targetRotation
currentRotation.normalize()
This is actually an infinite adjustment. You should introduce a threshold for the difference of currentRotation and targetRotation to set currentRotation to targetRotation and update only if currentRotation != targetRotation.
Now we have the rotation specified as a quaternion. In order to render the cube, you can apply the quaternion as a model transformation (after the conversion to a matrix) and render the geometry.
To rotate a cube slice, you simply have to apply a rotation transformation to the according cubes. E.g. if you want to rotate about the x-axis:
quat = QuaternionRotation( (1,0,0) /* axis */ , Pi / 2 /* angle */ )
for each affected cube
cube.targetRotation = cube.targetRotation * quat
next
// Update the grid
And the slice will rotate nicely to the target position. If you have the geometry well-alignes (around the origin), you don't need any translation because all rotations will be about the origin (or an axis through the origin).
Related
After searching many pages, glm documentation, tutorials...etc, I'm still confused on some things.
I'm trying to understand why I need to apply the following transformations to get my 800x600 (fullscreen square, assume the screen of the user is 800x600 for this minimal example) image to draw over everything. Assume I'm only drawing CCW triangles. Everything renders fine in my code, but I have to do the following:
// Vertex data (x/y/z), using EBOs
0.0f, 600.0f, 1.0f,
800.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
800.0f, 600.0f, 1.0f
// Later on...
glm::mat4 m, v, p;
m = scale(m, glm::vec3(-1.0, 1.0, 1.0));
v = rotate(v, glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f));
p = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, 0.5f, 1.5f);
(Note that just since I used the variable names m, v, and p doesn't mean they're actually the proper transformation for that name, the above just does what I want it to)
I'm confused on the following:
Where is the orthographic bounds? I assume it's pointing down the negative z-axis, but where do the left/right bounds come in? Does that mean [-400, 400] on the x-axis maps to [-1.0, 1.0] NDC, or that [0, 800] maps to it? (I assume whatever answer here applies to the y-axis). Then documentation just says Creates a matrix for an orthographic parallel viewing volume.
What happens if you flip the following third and fourth arguments (I ask because I see people doing this and I don't know if it's a mistake/typo or it works by a fluke... or if it properly works regardless):
Args three and four here:
_____________
| These two |
p1 = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, 0.5f, 1.5f);
p2 = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.5f, 1.5f);
Now I assume this third question will be answered with the above two, but I'm trying to figure out if this is why my first piece of code requires me flipping everything on the x-axis to work... which I will admit I was just messing around with it and it happened to work. I figure I need a 180 degree rotation to turn my plane around so it's on the -z side however... so that just leaves me with figuring out the -1.0, 1.0, 1.0 scaling.
The code provided in this example (minus the variable names) is the only stuff I use and the rendering works perfectly... it's just my lack of knowledge as to why it works that I'm unhappy with.
EDIT: Was trying to understand it from here by using the images and descriptions on the site as a single example of reference. I may have missed the point.
EDIT2: As a random question, since I always draw my plane at z = 1.0, should I restrict my orthographic projection near/far plane to be as close to 1.0 as possible (ex: 0.99, 1.01) for any reason? Assume nothing else is drawn or will be drawn.
You can assume the visible area in a orthographic projection to be a cube given in view space. This cube is then mapped to the [-1,1] cube in NDC coordinates, such that everything inside the cube is visible and everything outside will be clipped away. Generally, the viewer looks along the negative Z-axis, while +x is right and +Y is up.
How are the orthographic bounds mapped to NDC space?
The side length of the cube are given by the parameters passed to glOrtho. In the first example, parameters for left and right are [0, 800], thus the space from 0 to 800 along the X axis is mapped to [-1, 1] along the NDC X axis. Similar logic happens along the other two axes (top/bottom along y, near/far along -z).
What happens when the top and bottom parameters are exchanged?
Interchanging, for example, top and bottom is equivalent to mirroring the scene along this axis. If you look at second diagonal element of a orthographic matrix, this is defined as 2 / (top - bottom). By exchanging top and bottom only the sign of this element changes. The same also works for exchanging left with right or near with far. Sometimes this is used when the screen-space origin should be the lower left corner instead of upper left.
Why do you have to rotate the quad by 180° and mirror it?
As described above, near and far values are along the negative Z-axis. Values of [0.5, 1.5] along -Z mean [-0.5, -1.5] in world space coordinates. Since the plane is defined a z=1.0 this is outside the visible area. By rotating it around the origin by 180 degrees moves it to z=-1.0, but now you are looking at it from the back, which means back-face culling strikes. By mirroring it along X, the winding order is changed and thus back and front side are changed.
Since I always draw my plane at Z = 1.0, should I restrict my orthographic projection near/far plane to be as close to 1.0 as possible?
As long as you don't draw anything else, you can basically choose whatever you want. When multiple objects are drawn, then the range between near and far defines how precise differences in depth can be stored.
My code Currently looks like this :
glViewport (0, 0, this->w(), this->h());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
//glTranslated (m_fXmovement, 0.0, m_fZmovement - 5);
//glRotated (m_fYangleView, 1.0, 0.0, 0.0);
//glRotated (m_fXangleView, 0.0, 1.0, 0.0);
///// Model View \\\\\
glMatrixMode(GL_MODELVIEW);
glTranslated (m_fXmovement, 0.0, m_fZmovement - 5 );
glRotated (m_fYangleView, 1.0, 0.0, 0.0);
glRotated (m_fXangleView, 0.0, 1.0, 0.0);
DrawWaveFrontObject (m_pDataObjectMedia);
glPushMatrix();
glTranslated (0.0, -3.0, 0.0);
DrawArea();
glPopMatrix();
DrawClickAnimation();
glLoadIdentity();
First I had the movement part in GL_PROJECTION and all was running fine until I was working with fog.... It felt like the Camera isn't moving, it felt more like an additional camera pointing to that camera....
Then I accidentally copied the movement parts to the GL_MODELVIEW and the fog was acting as I wanted it to act..... all was fine accepting the click animation wasn't in relation to the area anymore, now the animation moved with my ego perspective.... and I don't really get it what kind of drawing I have to put in which of these two VIEW's. Could anyone give me examples or explanations according to my code or a hint what I could improve in my styl?
Quote from opengl.org forum:
The projection matrix is used to create your viewing volume. Imagine a
scene in the real world. You don't really see everything around you,
only what your eyes allow you to see. If you're a fish for example you
see things a bit broader. So when we say that we set up the projection
matrix we mean that we set up what we want to see from the scene that
we create. I mean you can draw objects anywhere in your world. If they
are not inside the view volume you won't see anything. When you create
the view volume imagine that you create 6 clipping planes that define
your field of view.
As for the modelview matrix, it is used to make various
transformations to the models (objects) in your world. Like this you
only have to define your object once and then translate it or rotate
it or scale it.
You would use the projection matrix before drawing the objects in your
scene to set the view volume. Then you draw your object and change the
modelview matrix accordingly. Of course you can change your matrix
midway of drawing your models if for example you want to draw a scene
and then draw some text (which with some methods you can work easier
in orthographic projection) then change back to modelview matrix.
As for the name modelview it has to do with the duality of modeling
and viewing transformations. If you draw the camera 5 units back, or
move the object 5 units forwards it is essentially the same.
First of all, I suggest that you try to abandon the fixed-function pipeline (glTranslate etc) since it's been deprecated for like 10 years now. Look here for a more modern tutorial if you're interested.
As for your problem, you can imagine the meaning of the two matrices like this: The projection matrix essentially captures properties intrinsic to the camera itself, like how its field of view is shaped.
On the other hand, the modelview matrix is composed of two parts, the model matrix and the view matrix. The model part is for transforming from object space (relative to an object itself) to world space. Then, the view part translates from there to the eye space, in which the camera sits at the origin and points down the (negative?) z axis. Together, the modelview matrix essentially states how objects are to be positioned relative to the camera.
For further information, this resource gives a detailed description of graphics transformations in the context of OpenGL.
[Jan, 2017] Edit: Pages from the first link seem to be unable to access these days, so there is another link to the same content from their archive.
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 an application which uses DirectX, and hence a left-handed world-coordinate systen, a view which looks down positive z and a projection which projects into the unit cube but with z from 0..1.
I'm porting this application to OpenGL, and OpenGL has a different coordinate system etc. In particular, it's right-handed, the view looks down along negative z, and the projection is into the real unit cube.
What is the easiest way to adapt the DirectX matrices to OpenGL? The world-space change seems to be easy, just by flipping the x-axis, but I'm not entirely sure how to change the view/projection. I can modify all of the matrices individually before multiplying them together and sending them off to my shader. If possible, I would like to stick with the DirectX based coordinate system as far down the pipeline as possible (i.e. I don't want to change where I place my objects, how I compute my view frustum, etc. -- ideally, I'll only apply some modification to the matrices right before handing them over to my shaders.)
The answer is: There's no need to flip anything, only to tweak the depth range. OpenGL has -1..1, and DX has 0..1. You can use the DX matrices just as before, and only multiply a scale/bias matrix at the end on top of the projection matrix to scale the depth values from 0..1 to -1..1.
Not tested or anything, just out of the top of my head :
oglProj = transpose(dxProj)
glScalef (1., 1., -1.); // invert z
glScalef(0.5, 0.5, 1); // from [-1,1] to [-0.5, 0.5]
glTranslatef(0.5, 0.5, 0) // from [-0.5, 0.5] to [0,1]
oglView = transpose(dxView)
glScalef (1., 1., -1.); // invert z
oglModel = transpose(dwModel)
glScalef (1., 1., -1.); // invert z
oglModelView = oglView * oglModel
There is an age-old extension for OpenGL exactly for that: GL_ARB_TRANSPOSE_MATRIX. It transposes matrices on GPU and should be available on every video card.
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