Display the position of the 8 vertices of a cube after rotation
-
Hello,
i had drawn a cube with OpenGL in Qt5.3.2 and i can rotate it with the mouse.
Now i want to display the new position of each vertices after the rotation of the cube.
is that possible?? if yes , how can i do that.I 'am Just new with openGL and Qt and i'm using Qt5.3.2.
-
OK then, you have a couple of choices.
-
Use the transformation matrices that you fed into OpenGL to transform the input vertex positions on the CPU.
-
If you are using desktop OpenGL you could use a transform feedback object to pass the vertex positions that come out of the vertex shader back into another buffer object. Then map that back to CPU address space and read out the transformed positions.
For the case of a simple cube, option 1) is much easier. If you were doing this with 1million vertices then the hassle of setting up a transform feedback object would be worth it. But for a cube it will be just as quick to compute the transformed vertices on the CPU.
Next you need to decide which coordinate system you want your rotated vertices in. I will assume you still want them in world space, just transformed. In this case you want something like
@
// Set up your rotation matrix
QMatrix4x4 modelMatrix;
modelMatrix.rotate(...);// Transform each input vertex
foreach (const QVector3D& p, positions) {
qDebug() << "Rotated position =" << modeMatrix * p;
}
@That is we basically repeat the world transform that the vertex shader does when drawing.
Hope this helps.
-
-
I'm not sure that i understand very well your suggestions, but i will try to do it>
My code is very simple as i m new on OpenGl:
@
void MyWidget::initializeGL()
{
qglColor(Qt::blue);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHT0);
static GLfloat lightPosition[4] = { 0, 0, 10, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
}void MyWidget::resizeGL(int width, int height)
{
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2, +2, -2, +2, 1.0, 15.0);
glMatrixMode(GL_MODELVIEW);}
void MyWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);glBegin(GL_QUADS); //1st quad
qglColor(Qt::green);
glNormal3f(0.0f, 0.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);qglColor(Qt::green); // 2nd quad
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);qglColor(Qt::white); 3rd quad
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);qglColor(Qt::white); 4th quad
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);qglColor(Qt::red); //5th quad
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);qglColor(Qt::blue); 6th quad
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);glEnd();
}
static void qNornalizeAngle(int angle)
{
while(angle < 0)
angle += 360 *16
while(angle > 0)
angle -= 360 *16
}void MyWidget::setXRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != xRot) {
xRot = angle;
updateGL();
}
}void MyWidget::setYRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != yRot) {
yRot = angle;
updateGL();
}
}void MyWidget::setZRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != zRot) {
zRot = angle;
updateGL();
}
}
@the rotation angle are xRot, yRot, ZRot.
then i want to find the new coordinates of vertices after each rotation.
Thanks you for your help
[Edited: Please use code tags "@@" - p3c0]
-
Oh boy, right, sorry, I didn't realise you were using legacy OpenGL. I thought you would be using modern OpenGL with shaders and uniform variables. Anyway the principle is the same. You need to construct a transformation matrix from your code that performs the translation and the rotations around the axes.
In your code this code is the calls to
@
glTranslatef(0.0, 0.0, -10.0);
glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);
@This code is basically modifying the matrix stack built into OpenGL (legacy versions anyway). What you need to do is to build your own transformation matrix that does the same thing. Luckily, QMatrix4x4 has similar functions:
@
QMatrix4x4 m;
m.translate(0.0, 0.0, -10.0);
m.rotate(xRot / 16.0, 1.0, 0.0, 0.0);
m.rotate(yRot / 16.0, 0.0, 1.0, 0.0);
m.rotate(zRot / 16.0, 0.0, 0.0, 1.0);
@should build you a suitable matrix. You'll need to check if I got the ordering correct (it may be inverted).
Then for each of your cube vertices just premultiply by this matrix:
@
qDebug() << "Transformed pos =" << m * QVector3D( 1.0f, 1.0f, 1.0f );
...
@HTH
-
I think i'm on the right way but still have problems.
I tried to build the transformation matrix and to use it as you say.
but now i can't draw the cube and the
qDebug() << "Transformed pos =" << m * QVector3D( 1.0f, 1.0f, 1.0f );
gives nothing.any suggestions?
Thank you for your patience but OpenGL seems difficult for me but i try to learn it as soon as possible.
-
Hello ,
for my last question , i had to use glLoadMatrix function before drawing my cube: @glLoadMatrixf(matrix.constData());@
@qDebug() << “Transformed pos =” << m * QVector3D( 1.0f, 1.0f, 1.0f );@ unfortunately,it still not giving me the coordinates of vertices. Don't know where is the problem. i had put that line in my paint function. is it correct??
However , these last days i started to read about Modern openGL, in order to use the first solution given to me here, to get my new vertices' coordinates. My code is like that now:
@
void GLWidget::paintGL()
{QMatrix4x4 matrixTransformation;
matrixTransformation.rotate(alpha, 0,1,0);
matrixTransformation.rotate(beta, 0, 1, 0);QVector3D cameraPosition = matrixTransformation * QVector3D(0,0,distance);
QVector3D cameraUpDirection = matrixTransformation * QVector3D(0, 1, 0);vMatrix.lookAt(cameraPosition, QVector3D(), cameraUpDirection);
// display the coordinates
foreach(const QVector3D& p, cameraPosition) {
qDebug() << "Rotated position =" << matrixTransformation * p;
}
shaderProgram.bind();
shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix *mMatrix);
shaderProgram.setUniformValue("color", QColor(Qt::white));
shaderProgram.setAttributeArray("vertex", vertices.constData());
shaderProgram.enableAttributeArray("vertex");
glDrawArrays(GL_TRIANGLES, 0,vertices.size());
shaderProgram.disableAttributeArray("vertex");
shaderProgram.release();}@
}
an error appeared : error C2039: 'const_iterator' : is not a member of 'QVector3D'
error C2039: 'i' : is not a member of 'QForeachContainer<QVector3D>'I had included <Vector > and <iterator> in my header but the error still there.
Is the way i used correct to get the coordinates of vertices??
the error is from my foreach loop code, and is maybe about the declaration of QVector3D in a qvector3d.h of Qt. How to solve it??
thanks and sorry for my questions which are maybe stupid, but i 'm still learning OpenGL.