I want to draw a cube of side 40 at bootom left corner. my glortho function is
glOrtho(0, // left
1000, // right
0, // bottom
1000, // top
0, // zNear
1000 // zFar
);
and lenght of x,y,z axis is up to 1000. so cube should be at bottom left and dimensions should be as i given. and what should be the gluLookAt(); function. I am not getting correct output. If there is any mistakes in the code, correct it and what function should add to the code.
#include <gl/glut.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#define GL_GLEXT_PROTOTYPES
#ifdef __APPLE__
#else
#endif
void display();
void specialKeys();
double rotate_y=0;
double rotate_x=0;
void display(){
// Clear screen and Z-buffer
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();
// Rotate when user changes rotate_x and rotate_y
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
// side - FRONT
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0, 0, 0);
glVertex3f( 40,0,0);
glVertex3f(40,40,0 );
glVertex3f(0,40,0 );
glEnd();
// side - BACK
glBegin(GL_POLYGON);
glColor3f( 1.0,0.0,1.0 );
glVertex3f( 0,0,40 );
glVertex3f( 0,40,40);
glVertex3f( 40,40,40 );
glVertex3f( 40,0,40 );
glEnd();
// side - RIGHT
glBegin(GL_POLYGON);
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 40,40,0 );
glVertex3f( 40,0,0 );
glVertex3f( 40,0,40 );
glVertex3f( 40,40,40 );
glEnd();
// side - LEFT
glBegin(GL_POLYGON);
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( 0,0,0 );
glVertex3f( 0,40,0 );
glVertex3f( 0,40,40 );
glVertex3f( 0,0,40 );
glEnd();
// side - TOP
glBegin(GL_POLYGON);
glColor3f( 0.0,0.0,1.0 );
glVertex3f( 0,40,0);
glVertex3f( 0,40,40 );
glVertex3f( 40,40,40 );
glVertex3f( 40,40,0 );
glEnd();
// side - BOTTOM
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.5, 0.0 );
glVertex3f( 0,0,0 );
glVertex3f( 40,0,0 );
glVertex3f( 40,0,40 );
glVertex3f( 0,0,40);
glEnd();
glFlush();
glutSwapBuffers();
}
void init()
{
glClearColor(0.5,0.5,0.0, 0.0);
glColor3f(1,0,0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluOrtho2D(-1.0,1.0,-1.0,1.0);
glOrtho(0, // left
1000, // right
0, // bottom
1000, // top
0, // zNear
1001 // zFar
);
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -1000.0, 0.0, 1000.0, 0.0);
}
void specialKeys( int key, int x, int y ) {
// Right arrow - increase rotation by 5 degree
if (key == GLUT_KEY_RIGHT)
rotate_y += 5;
// Left arrow - decrease rotation by 5 degree
else if (key == GLUT_KEY_LEFT)
rotate_y -= 5;
else if (key == GLUT_KEY_UP)
rotate_x += 5;
else if (key == GLUT_KEY_DOWN)
rotate_x -= 5;
// Request display update
glutPostRedisplay();
}
int main(int argc, char* argv[]){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1000, 1000);
glutInitWindowPosition(10, 10);
// Create window
glutCreateWindow("Awesome Cube");
// Enable Z-buffer depth test
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
init();
glutMainLoop();
return 0;
}
You screwed up your transformations. In Init() you set the current matrix mode to GL_PROJECTION and load some ortho matrix. Then you multiply the lookAt matrix onto this. This is wrong in principle, as the lookAt matrix should be applied to the GL_MODELVIEW stack. (The lookAt parameters you chose actually result in an identity lookAt matrix, so that call has no effect, but that is only a side note).
However, the real error is in display(). There you have glLoadIdentity() which will just overwrite your previous matrix with an identity matrix, so you lose the Ortho transform you did set up, since you still have GL_PROJECTION matrix stack active.
The correct way would be something like:
void init()
{
// ... your other stuff
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( /* your ortho params */ );
glMatrixMode(GL_MODELVIEW); // switch back to the modelView matrix stack
}
void display()
{
glLoadIdentity();
gluLookAt( /* your Lookat parameters */ );
glRotate/Scale/Translate(...); // your local transformations
// ...
}
Note that all of that stuff is completely deprecated and has been removed from the core profile of modern OpenGL versions. When learing OpenGL nowadays, you should consider not learning that old cruft from 20 years ago.
Related
I am trying to draw the cube as vertices and window position is set,but i am not getting right cube. I am getting the cube at right top side and dimensions are not as I gave. I am new to opengl. please help.
#include <gl/glut.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#define GL_GLEXT_PROTOTYPES
#ifdef __APPLE__
#else
#endif
void display();
void specialKeys();
double rotate_y=0;
double rotate_x=0;
void display(){
// Clear screen and Z-buffer
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();
// Rotate when user changes rotate_x and rotate_y
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
// side - FRONT
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0, 0, 0);
glVertex3f( 40,0,0);
glVertex3f(40,40,0 );
glVertex3f(0,40,0 );
glEnd();
// side - BACK
glBegin(GL_POLYGON);
glColor3f( 1.0,0.0,1.0 );
glVertex3f( 0,0,40 );
glVertex3f( 0,40,40);
glVertex3f( 40,40,40 );
glVertex3f( 40,0,40 );
glEnd();
// side - RIGHT
glBegin(GL_POLYGON);
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 40,40,0 );
glVertex3f( 40,0,0 );
glVertex3f( 40,0,40 );
glVertex3f( 40,40,40 );
glEnd();
// side - LEFT
glBegin(GL_POLYGON);
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( 0,0,0 );
glVertex3f( 0,40,0 );
glVertex3f( 0,40,40 );
glVertex3f( 0,0,40 );
glEnd();
// side - TOP
glBegin(GL_POLYGON);
glColor3f( 0.0,0.0,1.0 );
glVertex3f( 0,40,0);
glVertex3f( 0,40,40 );
glVertex3f( 40,40,40 );
glVertex3f( 40,40,0 );
glEnd();
// side - BOTTOM
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.5, 0.0 );
glVertex3f( 0,0,0 );
glVertex3f( 40,0,0 );
glVertex3f( 40,0,40 );
glVertex3f( 0,0,40);
glEnd();
glFlush();
glutSwapBuffers();
}
void init()
{
glClearColor(0.5,0.5,0.0, 0.0);
glColor3f(1,0,0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluOrtho2D(-1.0,1.0,-1.0,1.0);
glOrtho(0, // left
1000, // right
0, // bottom
1000, // top
0, // zNear
1000 // zFar
);
}
void specialKeys( int key, int x, int y ) {
// Right arrow - increase rotation by 5 degree
if (key == GLUT_KEY_RIGHT)
rotate_y += 5;
// Left arrow - decrease rotation by 5 degree
else if (key == GLUT_KEY_LEFT)
rotate_y -= 5;
else if (key == GLUT_KEY_UP)
rotate_x += 5;
else if (key == GLUT_KEY_DOWN)
rotate_x -= 5;
// Request display update
glutPostRedisplay();
}
int main(int argc, char* argv[]){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1000, 1000);
glutInitWindowPosition(10, 10);
// Create window
glutCreateWindow("Awesome Cube");
// Enable Z-buffer depth test
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
init();
glutMainLoop();
return 0;
}
Its is because since you didn't specify your camera Position and LookAt Position. So opengl Assume you are looking to Origin (0,0,0). So it is normal that your cube will appear top right on the screen.
if you want to see it in the center you can apply translatef function before rotation calls :
glTranslatef(-20.0f,-20.0f,-20.0f); //Shift your object to the center
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
...
I'm trying to recognize a drawn object on a mousPressEvent in OpenGL in Qt with picking.
I did some research but wasn't able to find the problem.
Clearly it recognizes something (because the return value of glRenderMode(GL_RENDER) is often an integer > 0), but not necessarily when I click on an object.
I think gluPerspective is the problem right here, but i just don't know how to resolve it.
mousePressEvent:
void WorldView::mousePressEvent(QMouseEvent *e)
{
GLuint buff[256];
GLint hits;
GLint view[4];
//Buffer to store selection data
glSelectBuffer(256, buff);
//Viewport information
glGetIntegerv(GL_VIEWPORT, view);
//Switch to select mode
glRenderMode(GL_SELECT);
//Clear the name stack!
glInitNames();
//Restric viewing volume
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//Restrict draw area
gluPickMatrix(e->x(), e->y(), 1.0, 1.0, view);
gluPerspective(40.0f, (GLfloat)view[2]/(GLfloat)view[3], 1.0, 100.0);
//Draw the objects onto the screen
glMatrixMode(GL_MODELVIEW);
//Draw only the names in the stack
paintGL();
//Back into projection mode to push the matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
hits = glRenderMode(GL_RENDER);//number of recognized objects
printf("\n%d\n",hits);
//Back to modelview mode
glMatrixMode(GL_MODELVIEW);
}
Draw function:
void WorldView::paintGL ()
{
this->dayOfYear = (this->dayOfYear+1);
this->hourOfDay = (this->hourOfDay+1) % 24;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
//Draw objects we want to pick
glPushName(0);
glBegin(GL_TRIANGLES);
glVertex3d(1,1,1);
glVertex3d(2,3,2);
glVertex3d(5,2,2);
glEnd();
glPopName();
glPushName(1);
glBegin(GL_TRIANGLES);
glVertex3d(7,-5,1);
glVertex3d(10,3,2);
glVertex3d(10,2,2);
glEnd();
glPopName();
glPushName(2);
glBegin(GL_TRIANGLES);
glVertex3d(1,-5,7);
glVertex3d(2,3,9);
glVertex3d(5,2,9);
glEnd();
glPopName();
}
EDIT1: Maybe completing the code could help?
Initializer:
void WorldView::initializeGL ()
{
this->dayOfYear = 0;
this->hourOfDay = 0;
// Initialize QGLWidget (parent)
QGLWidget::initializeGL();
glShadeModel(GL_SMOOTH);
// Black canvas
glClearColor(0.0f,0.0f,0.0f,0.0f);
// Place light
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable(GL_DEPTH_TEST);
GLfloat light0_position [] = {0.1f, 0.1f, 0.1f, 0.1f};
GLfloat light_diffuse []={ 1.0, 1.0, 1.0, 1.0 };
glLightfv ( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv ( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
}
resizer:
void WorldView::resizeGL ( int width, int height )
{
if ((width<=0) || (height<=0))
return;
//set viewport
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set persepective
//change the next line order to have a different perspective
GLdouble aspect_ratio=(GLdouble)width/(GLdouble)height;
gluPerspective(40.0f, aspect_ratio, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Use bullet raycast and not gl_Select which is way too slow and unwieldy. This will also make you get away from calling paintGL manually and other glCalls...in qt mousepressevent. Dont do this!
I am trying to draw a large polygon behind the cube to appear like the floor. How ever when ever the background floor is behind the cube it disappears completely. Here is the display function including the background I want to add and one of the cubes sides.
void display(){
// Clear screen and Z-buffer
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();
//background floor
glBegin(GL_POLYGON);
glColor3f( 0.5, 0.5, 0.5);
glVertex3f( 1, -0.9, 1 ); // x-y-z right bottom
glVertex3f( 0.6, 0.5, 1 ); //right top
glVertex3f( -0.6, 0.5, 1 ); //left top
glVertex3f( -1, -0.9, 1 ); //left bottom
glEnd();
// Rotate when user changes rotate_x and rotate_y
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
// FRONT side of cube
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.5, 0.0 );
glVertex3f( 0.05, -0.05, -0.05 );
glVertex3f( 0.05, 0.05, -0.05 );
glVertex3f( -0.05, 0.05, -0.05 );
glVertex3f( -0.05, -0.05, -0.05 );
//I have omitted the other 5 sides
glEnd();
glFlush();
glutSwapBuffers();
}
I suspect your poligon is facing outwards.
Try disabling backface culling with glDisable(GL_CULL_FACE). If this works swap the order of the vertices (should be CCW or trigonometric, on the side that the polygon should be visible from).
Don't leave the face culling disabled, unless you don't care about performance.
I just started trying to folow simple "draw cube" openGl tutorial. After final victory over getting OpenGL to work, I still have very veird results. My problem is that the objects tend to resize themselves to match the window size. Instead, I'd like the window size determine the rendering area - the larger the window is, the more you may see.
Here are some screenshots of the resizing:
Normal size
Resized
Images kept as links intentionally!
This auto-resizing behavior brings a question what the coordinates used in OpenGL are.
First thing to keep in mind: OpenGL is a drawing API. It doesn't maintain a scene or something like that.
So what OpenGL does is, it maps geometry input coordinates in the form of vertex attributes to screen space. In the old fixed function there's a special vertex attribute called "vertex position" or just short "vertex" (the actual vertex is more than just position).
The position is transformed to what's usually called "screen" space (but depending on where the viewport is placed, it might as well be called "window" or "viewport) space) in a three step process:
1. Transformation into view/eye space: This is done by multiplying the vertex position with the modelview matrix.
Certain further calculations, like illumination calculation are done in view space.
2. Transformation to clip space: The view space position is transformed into clip space. This is usually called the projection and aptly the matrix describing this transformation is called the projection matrix
In clip space some special things happen, summarized as clipping, you don't have to worry about yet.
3. In the final step transformed the clipped geometry into normalized device coordinates (NDC). NDC space is practically a 1:1 mapping toward the viewport, i.e. the limits of the NDC volume directly correspond to the offset and dimension of the viewport set with glViewport.
You can't change the way the 3rd step happens, and the 1st step is reserved for transforming stuff into view space. So any adjustments must happen in the 2nd step.
So here's what you have to do: The projection limits must be directly proportional to the viewport extents. Like this for example
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-width/2, width/2, -height/2, height/2, -1, 1);
Oh, and just on a general note: You should always set the viewport and projection setup in the drawing function, too. If you see a tutorial that puts those statements in a window resize handler, just disregard it and just do it in the drawing code anyway. On the long term this really simplifies things.
The interesting part:
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH ) / 300.0;
double h = glutGet( GLUT_WINDOW_HEIGHT ) / 300.0;
glOrtho( -1 * w, 1 * w, -1 * h, 1 * h, 10, -10);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
In context:
#include <GL/glut.h>
void display();
void specialKeys();
double rotate_y=0;
double rotate_x=0;
void display(){
// Clear screen and Z-buffer
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH ) / 300.0;
double h = glutGet( GLUT_WINDOW_HEIGHT ) / 300.0;
glOrtho( -1 * w, 1 * w, -1 * h, 1 * h, 10, -10);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// Rotate when user changes rotate_x and rotate_y
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
//Multi-colored side - FRONT
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 0.0 ); glVertex3f( 0.5, -0.5, -0.5 ); // P1 is red
glColor3f( 0.0, 1.0, 0.0 ); glVertex3f( 0.5, 0.5, -0.5 ); // P2 is green
glColor3f( 0.0, 0.0, 1.0 ); glVertex3f( -0.5, 0.5, -0.5 ); // P3 is blue
glColor3f( 1.0, 0.0, 1.0 ); glVertex3f( -0.5, -0.5, -0.5 ); // P4 is purple
glEnd();
// White side - BACK
glBegin(GL_POLYGON);
glColor3f( 1.0, 1.0, 1.0 );
glVertex3f( 0.5, -0.5, 0.5 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glVertex3f( -0.5, -0.5, 0.5 );
glEnd();
// Purple side - RIGHT
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 1.0 );
glVertex3f( 0.5, -0.5, -0.5 );
glVertex3f( 0.5, 0.5, -0.5 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( 0.5, -0.5, 0.5 );
glEnd();
// Green side - LEFT
glBegin(GL_POLYGON);
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -0.5, -0.5, 0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glVertex3f( -0.5, 0.5, -0.5 );
glVertex3f( -0.5, -0.5, -0.5 );
glEnd();
// Blue side - TOP
glBegin(GL_POLYGON);
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.5, 0.5, 0.5 );
glVertex3f( 0.5, 0.5, -0.5 );
glVertex3f( -0.5, 0.5, -0.5 );
glVertex3f( -0.5, 0.5, 0.5 );
glEnd();
// Red side - BOTTOM
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.5, -0.5, -0.5 );
glVertex3f( 0.5, -0.5, 0.5 );
glVertex3f( -0.5, -0.5, 0.5 );
glVertex3f( -0.5, -0.5, -0.5 );
glEnd();
glFlush();
glutSwapBuffers();
}
void specialKeys( int key, int x, int y ) {
// Right arrow - increase rotation by 5 degree
if (key == GLUT_KEY_RIGHT)
rotate_y += 5;
// Left arrow - decrease rotation by 5 degree
else if (key == GLUT_KEY_LEFT)
rotate_y -= 5;
else if (key == GLUT_KEY_UP)
rotate_x += 5;
else if (key == GLUT_KEY_DOWN)
rotate_x -= 5;
// Request display update
glutPostRedisplay();
}
int main(int argc, char* argv[]){
// Initialize GLUT and process user parameters
glutInit(&argc,argv);
// Request double buffered true color window with Z-buffer
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
// Create window
glutCreateWindow("Awesome Cube");
// Enable Z-buffer depth test
glEnable(GL_DEPTH_TEST);
// Callback functions
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
// Pass control to GLUT for events
glutMainLoop();
// Return to OS
return 0;
}
I am trying to create a very simple physics simulator for a school project, all i want it to do is have a cube that falls dew to gravity and when it hits a floor it will bounce and so on until the cube has no energy and it will just stop moving e.g. rest on the floor. I haven't added the collision detection in yet but most other things work fine the only problem i have is that the cube doesn't fall smoothly its very jumpy e.g. it falls and speed up then slows down and then speeds up again and i have no idea why.
I have incluided the code below:
timestep++;
velo += 0.005;
cout << velo << "\n";
glTranslatef(0.0, -velo, 0.0);//timestep * gravity, 0.0);
I have also included the entire program code just incase it is a probem somewhere else the extract above is just at the top of the display function
#include <GLTools.h>
#include <GLShaderManager.h>
#include <GLFrustum.h>
#include <GLBatch.h>
#include <GLFrame.h>
#include <GLMatrixStack.h>
#include <GLGeometryTransform.h>
#include <StopWatch.h>
#include <math.h>
#include <stdio.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
#include <iostream>;
using namespace std;
void display();
void specialKeys(int, int, int);
void animate();
double rotate_y = 0;
double rotate_x = 0;
// Gravity Varibles
int timestep = 0;
float gravity = 0.0098;
float velo = 0.0f;
int main( int argc, char* argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL );
glutCreateWindow("DANIELS CUBE");
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
glutIdleFunc(animate);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutMainLoop();
return 0;
}
void animate()
{
glutPostRedisplay();
}
void display()
{
//Clears the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Changes the way the polygons are drawn so it looks like a wire frame
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
///////////
// CUBE ///
///////////
// Resets the transformation matrix
glLoadIdentity();
glScalef(0.2, 0.2, 0.2);
// Rotates the cuube around the x by 'rotate_x'
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
// Rotates the cuube around the y by 'rotate_y'
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
// move dew to gravity
timestep++;
velo += 0.005;
cout << velo << "\n";
glTranslatef(0.0, -velo, 0.0);//timestep * gravity, 0.0);
// Defines the folowing verticys as this polygon
glBegin(GL_POLYGON);
//Changes color
glColor3f( 1.0, 0.0, 0.5 );
// Adds verted to polygon
glVertex3f( -0.5, -0.5, -0.5 ); // F1
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -0.5, 0.5, -0.5 ); // F2
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.5, 0.5, -0.5 ); // F3
glColor3f( 1.0, 0.0, 1.0 );
glVertex3f( 0.5, -0.5, -0.5 ); // F4
// Closes the polygon
glEnd();
glBegin(GL_POLYGON);
glColor3f( 1.0, 1.0, 1.0 );
glVertex3f( 0.5, -0.5, -0.5 ); // Back1
glVertex3f( 0.5, 0.5, -0.5 ); // Back2
glVertex3f( 0.5, 0.5, 0.5 ); // Back3
glVertex3f( 0.5, -0.5, 0.5 ); // Back4
glEnd();
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 1.0 );
glVertex3f( 0.5, -0.5, -0.5 ); // F1
glVertex3f( 0.5, 0.5, -0.5 ); // F2
glVertex3f( 0.5, 0.5, 0.5 ); // F3
glVertex3f( 0.5, -0.5, 0.5 ); // F4
glEnd();
glBegin(GL_POLYGON);
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -0.5, -0.5, 0.5 ); // F1
glVertex3f( -0.5, 0.5, 0.5 ); // F2
glVertex3f( -0.5, 0.5, -0.5 ); // F3
glVertex3f( -0.5, -0.5, -0.5 ); // F4
glEnd();
glBegin(GL_POLYGON);
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.5, 0.5, 0.5 ); // F1
glVertex3f( 0.5, 0.5, -0.5 ); // F2
glVertex3f( -0.5, 0.5, -0.5 ); // F3
glVertex3f( -0.5, 0.5, 0.5 ); // F4
glEnd();
glBegin(GL_POLYGON);
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.5, -0.5, -0.5 ); // F1
glVertex3f( 0.5, -0.5, 0.5 ); // F2
glVertex3f( -0.5, -0.5, 0.5 ); // F3
glVertex3f( -0.5, 0.5, -0.5 ); // F4
glEnd();
////////////
// Floor //
//////////
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLoadIdentity();
// Rotates the cuube around the x by 'rotate_x'
glRotatef( rotate_x, 1.0, 0.0, 0.0 );
// Rotates the cuube around the y by 'rotate_y'
glRotatef( rotate_y, 0.0, 1.0, 0.0 );
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
for( GLfloat i = -2.5; i < 2.5; i += 0.25 )
{
glVertex3f(i, -1.0, 2.5);
glVertex3f(i, -1.0, -2.5);
glVertex3f(2.5, -1.0, i);
glVertex3f(-2.5, -1.0, i);
}
glEnd();
// Flushes the buffers
glFlush();
// Draws what has just been done on the screen
glutSwapBuffers();
}
void specialKeys( int key, int x, int y )
{
if( key == GLUT_KEY_RIGHT )
{
rotate_y += 5;
}
else if( key == GLUT_KEY_LEFT )
{
rotate_y -= 5;
}
else if( key == GLUT_KEY_UP )
{
rotate_x += 5;
}
else if( key == GLUT_KEY_DOWN )
{
rotate_x -= 5;
}
glutPostRedisplay();
}
There are a couple problems I see with your code:
Assuming fixed timestep
Your display function isn't guaranteed to be called at evenly spaced intervals. Essentially you're giving your cube's velocity in "meters per frame (m/f)" instead of "meters per second (m/s)". (I'm using meters here as a general distance unit)
So, some basic math tells me that m/f = m/s * s/f. In other words, you want to scale the amount you move the cube per frame by the actual timestep since the last frame.
Velocity problem
The way your code is written, your velo variable actually represents the position, and you update it each frame with the number 0.005 which I think is what you mean to be your acceleration. If you want to have something accelerating due to gravity, you need to store two values, its position and its velocity. Then each frame, you need to update the velocity by adding the acceleration, and the position by adding the velocity.
Here's some code that does both of these things
int lastTime=0;
void display() {
int time = glutGet(GLUT_ELAPSED_TIME); // Time since the start of the program
if (lastTime>0) { // Don't move anything the first frame
int deltaTime = time-lastTime; // millis elapsed since the last frame
velo += -0.005*deltaTime; // Gravity accelerates downwards
pos += velo*deltaTime; // Position updated by velocity
glTranslateF(0.0, pos, 0.0); // Actually position the square in the correct location
}
lastTime = deltaTime;
}
Notice how when I update my velocity with the acceleration I scale that by deltaTime, and when I update my position with the velocity I do the same. Again, the unit analysis from before is an easy way to remember this: deltaTime tells you the number of milliseconds elapsed since the last frame, so its units are "s/f". velo should have units "m/s" to make the motion smooth over time. The amount to update the position this frame is m/s * s/f = m/f. Those units make sense, they measure a distance per frame.