how to rotate only one object with GL11

Started by stevenlin111, September 05, 2012, 01:12:45

Previous topic - Next topic

stevenlin111

I'm trying to rotate one of two objects on the screen. How should I do this? I can only get it to rotate all the objects on the screen.
glColor3f(1, 0, 0);
			glBegin(GL_QUADS);
				glVertex3f(0f, 0f, 0f);
				glVertex3f(0f, .5f, 0f);
				glVertex3f(.5f, .5f, 0f);
				glVertex3f(.5f, 0f, 0f);
			glEnd();
			glRotated(.1, 0f, 1f, 0f);
			glRotated(.1, 1f, 0f, 0f);
			glRotated(.1, 0f, 0f, 1f);
			glBegin(GL_QUADS);
				glVertex3f(2f, 0f, 0f);
				glVertex3f(2f, .5f, 0f);
				glVertex3f(2.5f, .5f, 0f);
				glVertex3f(2.5f, 0f, 0f);
			glEnd();


code I have so far.

Meanz

I am not good at explaining stuff, but it looks to me like you are not "resetting" the identity matrix.

so in the beginning of your render code after the glClear call I suggest you add "glLoadIdentity();"
You can google the meaning of it.

That should make only one of your objects rotate.

delt0r

Another "old" way to do things is push the matrix and pop it to get back to the old transform. This lets you use "local coordinates". However the stack is not that big. These days you should more or less manage some/all of that yourself. Well the transform stack anyways.
If you want a plot read a book and leave Hollywood out of it.

stevenlin111

I still don't understand the usage of glLoadIdentity() though. I know it's used for resetting the matrix back to the identity matrix, but how does it apply to rotation of a single object? Wouldn't the rotation of the object be nonexistent after calling glLoadIdentity()?

abcdef

stevenlin111

Here is a simple example, I have a triangle to render. I have a single set of vertex data (say (-1,0,0),(1,0,0),(0,1,0))

The triangle I want to move 10 places up in the y direction and rotate 90 degrees in the z axis

If I do

move 10 in y
rotate 90 degrees in z
render data

In the first frame everything will look good, but in the second frame my starting point is now not (0,0,0) with no rotation it (0,10,0) with 90 degrees rotation. I am just moving from the place where I finished the previous frame. If I run glLoadIndentity() at the beginning of each render cycle I reset my starting point back to (0,0,0) with no rotation and I draw exactly what I drew before.

If we make it more complicate and we want to render two triangles we have the same problem (remember opengl is state based). To get round this I can then push and then pop the matrix. This effectively saves the point and rotation you are at lets you do something then go back to the point for further rendering. This is of course using opengl 1.0 type architecture. Its not advisable to use the push and pop and to instead pre work out your final positions or to have a shader calculate the final position no the fly.

broumbroum

hi,
to do correct transformations, such as a scaling, rotation, translation, you have to know how the modelview is modified by each of the gl* calls. That is with opengl like a simple matrix multiplication. According the glmultmatrix() specs, the current transform matrix C is replaced with the matrix C x M where M is the multiplied transformation matrix.

Thereby one would rotate an object in the z-axis by FIRST rotating the z THEN by translating to the location where he wants the object to stand.
If the current modelview/transform matrix is C and the object has the vertices v0,v1,v2,v3 then multiply C with the rotation transform glRotate(), then translate with gltranslate() replace C with C x Translate x Rotate before to send v* vertices. This supposes that the object is defined with vertices around the origin, such as the triangle -1,-1,0; 1,-1,0; 0,1,0. (otherwise it's linear algebra : things are a bit different, because it must feature the orthonormal basis change)

My definition of the order of the three common transform operations Scaling, Rotation, Translation is likewise : S x T x R x v. Opengl calls are in the reverse order as they appear :
glmatrixmode(modelview);
glpushmatrix(): // I should have my own implementation

glscale(); // THIRD 
gltranslate(); // SECOND
glrotate(); // FIRST

glbegin(quads|triangles...);
glvertex(); 
...
glend();

glmatrixmode(modelview);
glpopmatrix();


good luck!


stevenlin111

so just to get this right,
you can glLoadIdentity() every time in the game loop, and then you glPushMatrix() to save the matrix. Render the data, apply the transformations, and then save it using glPopMatrix(). Then call glLoadIdentity() again to reset the transformations, and render the other data. So it'll be something like this?

glLoadIdentity()
glPushMatrix()
glBegin(GL_LINE);
glVertex2i(0, 10);
glVertex2i(0, 20);
glEnd();
glTranslated(1, 1, 0);//happens second
glRotated(10f, 1f, 0f , 0f);//happens first
glPopMatrix();
glBegin(GL_LINE);
glVertex2i(100, 10);
glVertex2i(100, 20);
glEnd();//happens first

and this should only translate and rotate the first object while the second object doesn't move?

matheus23

Quote from: stevenlin111 on September 14, 2012, 16:48:27
so just to get this right,
you can glLoadIdentity() every time in the game loop, and then you glPushMatrix() to save the matrix. Render the data, apply the transformations, and then save it using glPopMatrix(). Then call glLoadIdentity() again to reset the transformations, and render the other data. So it'll be something like this?

glLoadIdentity()
glPushMatrix()
glBegin(GL_LINE);
glVertex2i(0, 10);
glVertex2i(0, 20);
glEnd();
glTranslated(1, 1, 0);//happens second
glRotated(10f, 1f, 0f , 0f);//happens first
glPopMatrix();
glBegin(GL_LINE);
glVertex2i(100, 10);
glVertex2i(100, 20);
glEnd();//happens first

and this should only translate and rotate the first object while the second object doesn't move?
Mhmm. Almost.
At the beginning of your rendering loop, call glLoadIdentity();, then, in each object-render, call one time glPushMatrix(); to save the current transformations, and at the end of each object-render call glPopMatrix();.
My github account and currently active project: https://github.com/matheus23/UniverseEngine

stevenlin111

so it should be like this?
glLoadIdentity()
glPushMatrix()
glBegin(GL_LINE);
glVertex2i(0, 10);
glVertex2i(0, 20);
glEnd();
glTranslated(1, 1, 0);//happens second
glRotated(10f, 1f, 0f , 0f);//happens first
glPopMatrix();
glPushMatrix();
glBegin(GL_LINE);
glVertex2i(100, 10);
glVertex2i(100, 20);
glEnd();//happens first
glPopMatrix()

I'm not very good with matrix transformations since I'm not in calc yet

broumbroum

that"s right. Though you rotate 10 degrees around the x-axis, thereby the second line will rotate "facing you", like if you were facing a rope to climb on it.  8)
And one push() for one pop() and one begin() for one end(), ok.

dangerdoc

So, how do I rotate something without continuing the rotation across frames?

What if I want to increment/decrement the rotation manually via other variables, then say glRotate(x, y, z) each time without just adding x, y, z to each object's rotation (just set the rotation instead of increment)?

Also, which specific lines of code separate this object's rotation from the rest of the objects?

Thank you
“We build but to tear down. Most of our work and resource is squandered. Our onward march is marked by devastation. Everywhere there is an appalling loss of time, effort and life. A cheerless view, but true.” - Nikola Tesla

daboross

I'm not sure this is what you want, but I would just un-rotate at the end of rendering the object instead of doing those things with the matrices.
Would it work to apply an opposite rotation at the end, instead of having to load the identity matrix?
I am kind of new to lwjgl, but I think that would work.
~Dabo Ross daboross.net

Fool Running

Quote from: daboross on April 02, 2013, 03:52:08
I'm not sure this is what you want, but I would just un-rotate at the end of rendering the object instead of doing those things with the matrices.
Would it work to apply an opposite rotation at the end, instead of having to load the identity matrix?
I am kind of new to lwjgl, but I think that would work.
The problem with that is that after doing that several times you would start to introduce rounding errors which would most likely show up as twitchy objects (i.e. object that move a couple pixels back and forth as the view is moved).
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

dangerdoc

Well? Do I have to code my own rotation code or is there a way to set as opposed to increment?
“We build but to tear down. Most of our work and resource is squandered. Our onward march is marked by devastation. Everywhere there is an appalling loss of time, effort and life. A cheerless view, but true.” - Nikola Tesla

RiverC

There is quaternion code in the pack, but it's not quite set up to be used to code rotation code.

When I came to this problem, I wrote some code to create 4x4 matricies which could be used to translate and rotate points in the vertex shader.

When I get home I'll look over what I have and share some. But yes, at the moment, you do have to write your own code.

Note that once you have the rotation matrix, you can simply multiply the vertex by it to rotate it in the shader. You could also do this outside the shader, effectively meaning you wouldn't need a shader, but in my view you want to make the card do the work it is specialized at doing (matrix math!)

By the way, I think I know how to modify the Quaternion code to actually be, um, useful for what Quaternions are supposed to be used for. You know, rotating stuff.

There aren't currently any tutorials for 'qpq*' or ones that take the stuff in Wikipedia and make it practical for a computer science type.

------

To rotate your points you can do this

// create a quaternion to rotate 45 degrees on the z-axis (visually, rolling the points around the origin)
// x,y,z,w : x,y,z = axis normal, w = angle in radians
// note: I'm not sure how well Quaternion included works with various arbitrary axes; 
// I only use it with pure axes to repeat yaw, pitch and roll
Quaternion q = new Quaternion();
q.setFromAxisAngle(new Vector4f(0,0,1,(float)Math.PI*.25f));
// turn a point into a Quaternion
// like when you're working with GL vector4f's, 
// points are just x,y,z,0 (w is always 0.)
Quaternion p = new Quaternion(1,1,1,0);

// now do the multiplication to rotate the point
// qpq* (where q* is the conjugate/negation -x,-y,-z,w of q)
// the inner 'mul' happens first to resolve the first argument to mulInverse
// mulInverse, per its header multiplies the first argument by the inverse of the second
// thus we do 'qp' inside, then (qp)q* outside.
p = Quaternion.mulInverse(Quaternion.mul(q,p,p),q,p);

System.out.println(p);
// should print out ~0,~sqrt(2),1,0 or, x=0,y=1.414,z=1


This is less efficient than creating the rotation matrix and sending it to a shader. But you can create a rotation matrix from the Quaternion! I'll come up with a quick demo tomorrow.