Jump to content

  • Log In with Google      Sign In   
  • Create Account


Quick help needed with 2d rotation of vertex buffer object OpenGL


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 Jevi   Members   -  Reputation: 127

Like
0Likes
Like

Posted 25 October 2012 - 04:55 PM

I have a Ship object made up of 4 lines ( looks like the asteroids game ship ). I am rendering it with the vertex buffer object method. It gets drawn to the screen fine but when i go to rotate the ship the whole ship rotates around the (x,y) coordinate and not about the (x,y) coordinate, if that makes sense.

CODE SNIPPETS - full code at: https://github.com/Jevi/Asteroids/tree/master/src/org/cstutorials


This is how i render the ship object ( which is compromised of 4 lines loaded into a FloatBuffer ( im using LWJGL btw ) that FloatBuffer is loaded in to memory and I draw from that allocated memory. The random GL_POINT is to see where (x,y) currently is.

@Override
public void render(Graphics g)
{
  glLoadIdentity();
  glPushMatrix();
  glBegin(GL_POINTS);
  glVertex2f(x, y);
  glEnd();
  g.rotate(x, y, angle);
  g.drawLines();
  glPopMatrix();
}

This is my drawLines() implementation, the variables seen inside are handled by a gameObjectManager which is not in these snippets ( no need )

public void drawLines()
{
  glEnableClientState(GL_VERTEX_ARRAY);
  glBindBuffer(GL_ARRAY_BUFFER, currentVertexHandle);
  glVertexPointer(numCoordinates, GL_FLOAT, 0, 0L);
  glDrawArrays(GL_LINES, 0, numPairVertices);
  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glDisableClientState(GL_VERTEX_ARRAY);
}

Finally here is my rotatation implementation, it use to work fine when I used immediate mode rendering but now that I have VBOs it does not work the same

public void rotate(float x, float y, float angle)
{
  glTranslatef(x, y, 0);
  glRotatef(angle, 0, 0, 1);
  glTranslatef(-x, -y, 0);
}


Sponsor:

#2 Solias   Members   -  Reputation: 560

Like
0Likes
Like

Posted 25 October 2012 - 05:55 PM

Why are you doing the -x, -y translation? I assume the verts in the VBO are in object space already?

#3 Jevi   Members   -  Reputation: 127

Like
0Likes
Like

Posted 25 October 2012 - 06:01 PM

Why are you doing the -x, -y translation? I assume the verts in the VBO are in object space already?


Because this is the method I used when I was using intermediate mode rendering. If I remove -x, -y translation the rotation error becomes even greater ( or less accurate ).

This is what I do to create the lines and store them to memory

Line[] lines = new Line[] { new Line(x, y - height / 4, x + width / 3, y + height / 4),
    new Line(x + width / 3, y + height / 4, x, y), new Line(x, y, x - width / 3, y + height / 4),
    new Line(x - width / 3, y + height / 4, x, y - height / 4) };
  vertexHandle = glGenBuffers();
  vertexBuffer = BufferUtils.createFloatBuffer(lines.length * Line.numIndividualVertices);
  numCoordinates = Line.numCoordinates;
  numPairVertices = lines.length * numCoordinates;
  for (Line line : lines)
  {
   vertexBuffer.put(new float[] { line.getX1(), line.getY1(), line.getX2(), line.getY2() });
  }
  vertexBuffer.flip();
  glBindBuffer(GL_ARRAY_BUFFER, vertexHandle);
  glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_DYNAMIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER, 0);


#4 NumberXaero   Prime Members   -  Reputation: 1405

Like
0Likes
Like

Posted 25 October 2012 - 06:18 PM

What happens if you try

glRotatef(angle, 0, 0, 1);
glTranslatef(x, y, 0);

#5 Jevi   Members   -  Reputation: 127

Like
0Likes
Like

Posted 25 October 2012 - 07:02 PM

What happens if you try

glRotatef(angle, 0, 0, 1);
glTranslatef(x, y, 0);


That doesn't work either... I feel like if someone could see what was happening they could figure it out so he is a video of what is happening.. notice the dot witch is the x,y coordinate and then notice the ship

https://www.dropbox.com/s/52mq14gj8b80mb4/Untitled.mp4

#6 Kaptein   Prime Members   -  Reputation: 2061

Like
1Likes
Like

Posted 25 October 2012 - 07:26 PM

to do rotations, you have to translate the object to its rotational origin, called a PIVOT position, then rotate it there, and translate it back!
if your object is a box created at (0,0) and all the way to (1,1), you have to translate it to (-0.5, -0.5) to rotate it around itself
however, if your box was created from (-0.5, -0.5) to (0.5, 0.5) you can rotate it immediately, because its rotational origin is now (0, 0) from the start, if you wanted to rotate it around itself!

3ds max (or any other 3d CAD) is a great tool to visualize how this works

to do the same thing with your model, you need to know its dimensions, and then its half-sizes, then translate it backwards so that the object is positioned with (0, 0) at the center of the object, then rotate it there (if that's what you wanted to do)

from looking at the ship creation code from the link.. its hard for me to understand how exactly it is created, except to say i never would be doing it that way myself :S
i'm sure theres some logic to it though!

Edited by Kaptein, 25 October 2012 - 07:33 PM.


#7 Jevi   Members   -  Reputation: 127

Like
0Likes
Like

Posted 25 October 2012 - 07:53 PM

to do rotations, you have to translate the object to its rotational origin, called a PIVOT position, then rotate it there, and translate it back!
if your object is a box created at (0,0) and all the way to (1,1), you have to translate it to (-0.5, -0.5) to rotate it around itself
however, if your box was created from (-0.5, -0.5) to (0.5, 0.5) you can rotate it immediately, because its rotational origin is now (0, 0) from the start, if you wanted to rotate it around itself!

3ds max (or any other 3d CAD) is a great tool to visualize how this works

to do the same thing with your model, you need to know its dimensions, and then its half-sizes, then translate it backwards so that the object is positioned with (0, 0) at the center of the object, then rotate it there (if that's what you wanted to do)

from looking at the ship creation code from the link.. its hard for me to understand how exactly it is created, except to say i never would be doing it that way myself :S
i'm sure theres some logic to it though!


Ok so now the rotation works correctly. I translate back to the starting x,y rotate it there but how do i move the ship to where the current x,y are?

And yes my code may be a little confusing but its hard to stay true to object oriented programming when all the OGL tutorials I have found don't seem to code with that convention... Posted Image

This is my modified code

@Override
public void render(Graphics g)
{
  glLoadIdentity();
  glPushMatrix();
  glBegin(GL_POINTS);
  glVertex2f(x, y);
  glEnd();
  glTranslatef(startx, starty, 0);
  glRotatef(angle, 0, 0, 1);
  glTranslatef(-startx, -starty, 0);
  g.drawLines();
  glPopMatrix();
}

Edited by Jevi, 25 October 2012 - 07:58 PM.


#8 Kaptein   Prime Members   -  Reputation: 2061

Like
0Likes
Like

Posted 25 October 2012 - 07:58 PM

change glTranslatef(-startx, -starty, 0);
to:
glTranslatef(new_x - startx, new_y - starty, 0);

#9 Jevi   Members   -  Reputation: 127

Like
0Likes
Like

Posted 25 October 2012 - 08:02 PM

change glTranslatef(-startx, -starty, 0);
to:
glTranslatef(new_x - startx, new_y - starty, 0);


This does not work

@Override
public void render(Graphics g)
{
  glLoadIdentity();
  glPushMatrix();
  glBegin(GL_POINTS);
  glVertex2f(x, y);
  glEnd();
  glTranslatef(startx, starty, 0);
  glRotatef(angle, 0, 0, 1);
  glTranslatef(x - startx, y - starty, 0);
  g.drawLines();
  glPopMatrix();
}


#10 Jevi   Members   -  Reputation: 127

Like
0Likes
Like

Posted 25 October 2012 - 08:14 PM

I got it I forgot the all this is done slightly backwards so here is the working code if anyone wants to know

So I translate to the startx, starty then i rotate around it, I translate to -startx, -starty ( all that is done is g.rotate(..) ) then I translate to the current x,y coordinates of the object. As you can see in the following code those steps are implemented backwards in the code but are interpreted in the correct order by OGL. a little confusing but its not that bad Posted Image. Thanks for all the help guys!!


@Override
public void render(Graphics g)
{
  glLoadIdentity();
  glPushMatrix();
  glBegin(GL_POINTS);
  glVertex2f(x, y);
  glEnd();
  glTranslatef(x - startx, y - starty, 0);
  g.rotate(startx, starty, angle);
  g.drawLines();
  glPopMatrix();
}

Edited by Jevi, 25 October 2012 - 08:18 PM.


#11 Kaptein   Prime Members   -  Reputation: 2061

Like
1Likes
Like

Posted 25 October 2012 - 08:19 PM

that's good to hear
sorry i got it backwards, yes the order of operations is indeed backwards Posted Image
this is how matrices work in general
once you get a bit further into all this, and you are writing your own little matrix library (it's an important step to take)
then you will see why ;) not to mention the possibilities

Edited by Kaptein, 25 October 2012 - 08:21 PM.


#12 Jevi   Members   -  Reputation: 127

Like
0Likes
Like

Posted 25 October 2012 - 08:30 PM

that's good to hear
sorry i got it backwards, yes the order of operations is indeed backwards Posted Image
this is how matrices work in general
once you get a bit further into all this, and you are writing your own little matrix library (it's an important step to take)
then you will see why ;) not to mention the possibilities


thanks again! getting about 1000 fps more with VBOs as compared to intermediate rendering even though its just a couple of lines on the screen I can already see how this is going to be crucial later on Posted Image




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS