| | |
OpenGL - Transformation matrix
Please support our Game Development advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved |
Hello, everyone!
I'm starting to learn OpenGL and I have a problem with linear transformations.
The program is very basic: I want to draw 4 squares and make them move individually (by doing translations and rotation). I understand that I need to stock all the transformation in a matrix, so I can multiply it to the square information to get the good translation and rotation parameters. Unfortunately, the red square (the one missing) doesn't want to print on the screen. I have searched for a long time and I don't know what causes the problem: maybe a bad mode initialize or something else... Can someone help me? I have posted the code below.
N.B: You may need to add some includes for the code to work. My confguration of OpenGL only needs <gl/glut.h>
I'm starting to learn OpenGL and I have a problem with linear transformations.
The program is very basic: I want to draw 4 squares and make them move individually (by doing translations and rotation). I understand that I need to stock all the transformation in a matrix, so I can multiply it to the square information to get the good translation and rotation parameters. Unfortunately, the red square (the one missing) doesn't want to print on the screen. I have searched for a long time and I don't know what causes the problem: maybe a bad mode initialize or something else... Can someone help me? I have posted the code below.
N.B: You may need to add some includes for the code to work. My confguration of OpenGL only needs <gl/glut.h>
#include <gl/glut.h>
#include <stdio.h>
/**
This program draws 4 squares and do moves on them (translations, rotations, ...)
*/
GLint windowX;
GLint windowY;
GLdouble redTransformationMatrix[16];
void reshape(GLint x, GLint y)
{
windowX = x;
windowY = y;
glViewport(0,0,windowX,windowY); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
/**
\brief Initializes transformations.
*/
void init()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetDoublev(GL_MODELVIEW_MATRIX, redTransformationMatrix); //Sets the red square transformation matrix with an identity matrix.
}
/**
\brief Function that is called when a key is pressed on the keyboard.
\param key The ASCII value of the key.
\param x The x value of the mouse position at the event.
\param y The y value of the mouse position at the event.
*/
void keyboardPressed(unsigned char key, int x, int y)
{
switch (key)
{
case 'D':
case 'd':
{
//Translation of the red square.
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(redTransformationMatrix);
glTranslated(25.0, 0.0, 0.0);
glGetDoublev(GL_MODELVIEW, redTransformationMatrix);
glutPostRedisplay();
break;
}
}
}
/**
\brief Function that draws a square, knowing the middle point and the length of a side.
\param middleX The X coordinate of the middle point.
\param middleY The Y coordinate of the middle point.
\param sideLength The length of a side of the square.
*/
void DrawSquare(GLdouble middleX, GLdouble middleY, GLdouble sideLength)
{
glBegin(GL_QUADS);
glVertex2d(middleX - (sideLength / 2), middleY + (sideLength / 2));
glVertex2d(middleX + (sideLength / 2), middleY + (sideLength / 2));
glVertex2d(middleX + (sideLength / 2), middleY - (sideLength / 2));
glVertex2d(middleX - (sideLength / 2), middleY - (sideLength / 2));
glEnd();
}
/**
\brief Function that is called for every display on the screen.
*/
void display()
{
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset the current modelview matrix
glLoadIdentity(); //Makes sure that no affine transformation applies here.
//We need to set the viewport and the orthonormal bounds.
glViewport(0, 0, windowX, windowY);
glOrtho(0.0, windowX, 0.0, windowY, -1.0, 1.0);
//Let's draw the squares.
//Red square -- trying here to apply the transformation matrix on the red square.
glPushMatrix();
glLoadMatrixd(redTransformationMatrix);
glColor3d(1.0, 0.0, 0.0);
DrawSquare(200.0, 600.0, 100.0);
glPopMatrix();
//Green square
glColor3d(0.0, 1.0, 0.0);
DrawSquare(600.0, 600.0, 100.0);
//Blue square
glColor3d(0.0, 0.0, 1.0);
DrawSquare(600.0, 200.0, 100.0);
//Yellow square
glColor3d(1.0, 1.0, 0.0);
DrawSquare(200.0, 200.0, 100.0);
glutSwapBuffers(); //Very important, because we are using double buffers and we want to print.
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glClearColor(0.0, 0.0, 0.0, 0.0); //Black background color.
windowX = 800;
windowY = 800;
glutInitWindowPosition(0, 0);
glutInitWindowSize(windowX, windowY);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("FourSquares");
//Basic initialize...
init();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutKeyboardFunc(keyboardPressed);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
//The events may start.
glutMainLoop();
return 0;
} You setup an orthographic projection matrix, and then in the pushmatrix/popmatrix block, you load a matrix in model space, this 'undoes' your projection until the matrix is popped...
You could either replace this:
with this:
Which will work in this case, or much better, use the projection matrix aswell.
The projection matrix is automatically multiplied onto the modelview matrix during vertex transform, and that's typically where glOrtho/glFrustum/etc are used. Eg:
You could either replace this:
glPushMatrix(); glLoadMatrixd(redTransformationMatrix); glColor3d(1.0, 0.0, 0.0); DrawSquare(200.0, 600.0, 100.0); glPopMatrix();
glPushMatrix();
glMultMatrixd(redTransformationMatrix);
glColor3d(1.0, 0.0, 0.0);
DrawSquare(200.0, 600.0, 100.0);
glPopMatrix();The projection matrix is automatically multiplied onto the modelview matrix during vertex transform, and that's typically where glOrtho/glFrustum/etc are used. Eg:
// VIEWPORT AND BUFFER CLEAR FIRST, BECAUSE THEY ARE MATRIX-MODE INDEPENDANT glViewport(0, 0, windowX, windowY); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // SETUP ORTHOGRAPHIC PROJECTION glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, windowX, 0.0, windowY, -1.0, 1.0); // NOW RESET THE MODELVIEW glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // ... ETC...
Plato forgot the nullahedron..
Thanks for the help! My main error was the use of the GL_MODELVIEW flag instead of the GL_MODELVIEW_MATRIX flag.
Now I would like to do rotations. I know how to use glRotate*(), but I don't want to provide a vector expressed by the origin. For example, I would like to put a vector at the center of a square and make this square rotate around this vector. Any ideas to guide me?
Now I would like to do rotations. I know how to use glRotate*(), but I don't want to provide a vector expressed by the origin. For example, I would like to put a vector at the center of a square and make this square rotate around this vector. Any ideas to guide me?
It's easy enough to arbitrarily set the rotation point, e.g. this will work:
The general rule is, translate to the origin, rotate, and then translate back again.
However, you are making your life abit more difficult by offsetting the square outside of the matrix.. that is, you are doing matrix transforms, and then offseting by 200, 600 in that space.. you'll find it easier to initialize your matrix to that 200, 600 offset, and then always draw the square at 0,0 in the space of your matrix transform.
That is, if you do this:
Then, you can just do this:
You will find, when you do get it rotating properly, that any subsequent translation will be in the local space of the previous transform. That is, what you consider to be moving in 'x' will actually be moving in the rotated x direction. If that's what you want, great, otherwise, you can keep transforming in global 'x' by reversing the translate multiplication order, like this:
case 'E':
case 'e':
{
//Rotation of the red square.
glMatrixMode(GL_MODELVIEW_MATRIX);
glLoadMatrixd(redTransformationMatrix);
glTranslated(200.0, 600.0, 0.0);
glRotated(1.0,0.0, 0.0, 1.0);
glTranslated(-200.0, -600.0, 0.0);
glGetDoublev(GL_MODELVIEW_MATRIX, redTransformationMatrix);
glutPostRedisplay();
break;
}The general rule is, translate to the origin, rotate, and then translate back again.
However, you are making your life abit more difficult by offsetting the square outside of the matrix.. that is, you are doing matrix transforms, and then offseting by 200, 600 in that space.. you'll find it easier to initialize your matrix to that 200, 600 offset, and then always draw the square at 0,0 in the space of your matrix transform.
That is, if you do this:
void init()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated (200.0, 600.0, 100.0);
glGetDoublev(GL_MODELVIEW_MATRIX, redTransformationMatrix);
}
...
void display()
{
...
glPushMatrix();
glLoadMatrixd(redTransformationMatrix);
glColor3d(1.0, 0.0, 0.0);
DrawSquare(0.0, 0.0, 0.0);
glPopMatrix();
...
}Then, you can just do this:
case 'E':
case 'e':
{
//Rotation of the red square.
glMatrixMode(GL_MODELVIEW_MATRIX);
glLoadMatrixd(redTransformationMatrix);
glRotated(1.0,0.0, 0.0, 1.0);
glGetDoublev(GL_MODELVIEW_MATRIX, redTransformationMatrix);
glutPostRedisplay();
break;
}You will find, when you do get it rotating properly, that any subsequent translation will be in the local space of the previous transform. That is, what you consider to be moving in 'x' will actually be moving in the rotated x direction. If that's what you want, great, otherwise, you can keep transforming in global 'x' by reversing the translate multiplication order, like this:
case 'D':
case 'd':
{
//Translation of the red square.
glMatrixMode(GL_MODELVIEW_MATRIX);
glLoadIdentity ( );
glTranslated(25.0, 0.0, 0.0);
glMultMatrixd(redTransformationMatrix);
glGetDoublev(GL_MODELVIEW_MATRIX, redTransformationMatrix);
glutPostRedisplay();
break;
} Last edited by MattEvans; May 10th, 2009 at 5:58 pm.
Plato forgot the nullahedron..
![]() |
Similar Threads
- problems with glutInit and related functions (Python)
- How do you get keyboard input while running a standard OpenGL program? (C++)
- OpenGL (Game Development)
Other Threads in the Game Development Forum
- Previous Thread: High Score program
- Next Thread: RPG Battle Algorithms
| Thread Tools | Search this Thread |
3d advertising ai algorithm ban c++ cambridge camera censorship china competition console development engine fov fpx game gamedevelopment gameprogramming gamer games gaming gauntanamo government graphics idaho in-gameadvertisement intel intellectualproperty l-systems laracroft larrabee lindenmayer live manhunt math mathematics matrix mercenaries microsoft mmorpg modded msn multicore naked news nintendo obama opengl palin physics pirate playstation politics processor projection ps3 rpg search selection software sony stephenhawking stocks studio technology terrorism tombraider uk videogame web wii world-of-warcraft xbox xbox-live xbox360






