I have created a bunny and a duck image in my blank window. My plan was to display it twice: once by itself and another image like it rotated at a 90 degrees. I've tried creating the image a second time and turning the image by changing values, but was difficult and couldn't work at all. Which axes needs to be used to rotate an image in a plane and the right way to accomplish it.
void myInit(void){
glClearColor(1.0, 1.0, 1.0, 0); // the background is white
glColor3f(0.0f, 0.0f, 0.0f); // set drawing color
gluOrtho2D(0.0, (GLdouble) screenWidth, 0.0, (GLdouble) screenHeight);
}
void drawBunny(){
glClear(GL_COLOR_BUFFER_BIT);
// draw the outline of box (bunny)
glLineWidth(2);
glBegin(GL_LINE_LOOP);
glVertex2i(50,50);
glVertex2i(150,50);
glVertex2i(150,100);
glVertex2i(50,100);
glEnd();
//draw bunny tail
glLineWidth(1);
glBegin(GL_LINE_STRIP);
glVertex2i(50,50);
glVertex2i(50,35);//2nd wider top/bottom
glVertex2i(70,35);//1st- shrink tail left/right
glVertex2i(70,50);//1st- shrink tail left/right
glEnd();
// draw first ear
glBegin(GL_LINE_LOOP);
glVertex2i(175,85);
glVertex2i(175,100);
glVertex2i(150,100);
glVertex2i(150,85);
glEnd();
//draw second ear
glBegin(GL_LINE_LOOP);
glVertex2i(175,70);
glVertex2i(175,100);
glVertex2i(150,100);
glVertex2i(150,70);
glEnd();
// draw the head
glBegin(GL_LINE_LOOP);
glVertex2i(150,100);
glVertex2i(150,110);
glVertex2i(125,110);
glVertex2i(125,100);
glEnd();
// draw first feet
glBegin(GL_LINE_LOOP);
glVertex2i(110,60);
glVertex2i(110,75);
glVertex2i(30,75); //decrease value increase feet
glVertex2i(30,60);
glEnd();
//draw second feet
glBegin(GL_LINE_LOOP);
glVertex2i(50,100);
glVertex2i(50,85);
glVertex2i(30,85); //decrease value increase feet
glVertex2i(30,100);
glEnd();
//* draw eyes
glBegin(GL_LINE_LOOP);
glVertex2i(140,100);
glVertex2i(140,105);
glVertex2i(135,105);
glVertex2i(135,100);
glEnd();
glFlush();
}
int main (int argc, char** argv){
glutInit(&argc, argv); // initialize the toolkit
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowPosition(100,150); // set window position
glutInitWindowSize(screenWidth,screenHeight); // set window size
glutCreateWindow("House"); // create & open window
glutDisplayFunc(drawBunny); // register redraw function
myInit();
glutMainLoop(); // loop forever
}
write a display function which consist of 2 bunnies and rotate them :
void display()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
drawBunny();
glPushMatrix();
glRotatef(degreetoreturn,x,y,z); // Adjust parameters according to what you need
drawBunny();
glPopMatrix();
glutSwapBuffers();
}
Delete glClear() function and glFlush() functions from your drawBunny function. And finally in your main function change this line :
glutDisplayFunc(drawBunny); // register redraw function
to
glutDisplayFunc(display); // register redraw function
Related
I am trying to draw two 2D diamonds facing each other.
So I drew the first diamond then I drew the second diamond after using:
glTranslated(0, -150, 0);
so it can appear exactly under my first diamond .
However, I ran into a problem that I couldn't flip the second diamond so it could look like a mirror.
Here is what i am trying to do:
I searched online for solutions and they all mentioned that I should
use
glScalef(1.0f,-1.0f,1.0f);
but each time I use it the drawing disappears.
The function
glRotatef(angle,x,y,z);
caught my attention but i couldn't use it properly resulting in wrong direction.
Here is how my image looks like right now without glRotate():
So I think I need the proper technique to use any of these functions.
Note: I am using many line loops and vertices to draw.
#include <windows.h> // For MS Windows
#include <GL/glut.h> // (or others, depending on the system in use)
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0); // Set display-window color to
white.
glMatrixMode(GL_PROJECTION); // Set projection parameters.
gluOrtho2D(0.0, 400.0, 0.0, 400.0);
}
void drawDiamond()
{
glBegin(GL_LINE_LOOP);
glVertex2f(125, 350);
glVertex2f(245, 350);
glVertex2f(290, 300);
glVertex2f(182, 200);
glVertex2f(75, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(109, 333);
glVertex2f(138, 350);
glVertex2f(159, 337);
glVertex2f(123, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(109, 333);
glVertex2f(123, 300);
glVertex2f(154, 225);
glVertex2f(92, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(290, 300);
glVertex2f(75, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(123, 300);
glVertex2f(159, 337);
glVertex2f(154, 300);
glVertex2f(171, 225);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(181, 300);
glVertex2f(159, 337);
glVertex2f(181, 350);
glVertex2f(209, 337);
glVertex2f(181, 300);
glVertex2f(171, 225);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(181, 300);
glVertex2f(209, 337);
glVertex2f(219, 300);
glVertex2f(195, 225);
glVertex2f(181, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(209, 337);
glVertex2f(243, 300);
glVertex2f(195, 225);
glVertex2f(219, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(209, 337);
glVertex2f(229, 350);
glVertex2f(260, 333);
glVertex2f(243, 300);
glVertex2f(209, 337);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(260, 333);
glVertex2f(278, 300);
glVertex2f(210, 225);
glVertex2f(243, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(195, 225);
glVertex2f(182, 200);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(171, 225);
glVertex2f(182, 200);
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT); // Clear display window.
glColor3f(0.0, 0.0, 0.0); // Set line segment color to blue.
// your code goes here
drawDiamond();
glTranslatef(0.0f, -150, 0.0f);
drawDiamond();
glFlush(); // Process all OpenGL routines as quickly as possible.
}
void main(int argc, char** argv)
{
glutInit(&argc, argv); // Initialize GLUT.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // Set display mode.
glutInitWindowPosition(50, 100); // Set top-left display-window
position.
glutInitWindowSize(400, 400); // Set display-window width and
height.
glutCreateWindow("Diamond Project"); // Create display window.
init(); // Execute initialization procedure.
glutDisplayFunc(display); // Send graphics to display window.
glutMainLoop(); // Display everything and wait.
}
What you want to do is to mirror (flip) the object around an axis, which is parallel to the X-axis, and goes through the bottom bounding of the object (diamond).
To do so, the bottom Y coordinate (bottomY) has to be found and the object has to be translated in the opposite direction. Note the bottom of the model coordinates (vertices) and not the bottom of final coordinates on the viewport:
float bottomY = 200.0f;
glTranslatef( 0.0f, -bottomY , 0.0f );
At next the object has to be flipped. This can either be done by
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
or by
glScalef(1.0f, -1.0f, 0.0f)
Note, both operations result in the same transformation matrix, because cos(90°) = cos(-90°), sin(90°) = -sin(90°).
Then the bottomY translation has to be reversed:
glTranslatef( 0.0f, bottomY, 0.0f );
But note that the OpenGL fixed function pipeline stack operates in the the reverse order, because the current matrix is multiplied by the matrix which is specified by the new operation.
Translation: See the documentation of glTranslate:
glTranslate produces a translation by x y z . The current matrix (see glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix.
Rotation: See the documentation of glRotate:
glRotate produces a rotation of angle degrees around the vector x y z . The current matrix (see glMatrixMode) is multiplied by a rotation matrix with the product replacing the current matrix.
Scaling: See the documentation of glScale:
glScaleproduces a nonuniform scaling along the x, y, and z axes. The three parameters indicate the desired scale factor along each of the three axes.
The current matrix (see glMatrixMode) is multiplied by this scale matrix.
This means the the following should do what you want:
float bottomY = 200.0f;
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
drawDiamond();
glTranslatef( 0.0f, bottomY , 0.0f );
glRotatef( 180.0f, 1.0f, 0.0f, 0.0f );
glTranslatef( 0.0f, -bottomY , 0.0f );
drawDiamond();
and is the same as:
glTranslatef( 0.0f, bottomY , 0.0f );
glScalef( 1.0f, -1.0f, 1.0f );
glTranslatef( 0.0f, -bottomY , 0.0f );
Depending on how your vertices are setup and depending on if you have Back Face Culling enabled you might have to change your diamond or (model's) center point to be the bottom tip from there you can then simply rotate about the X axis provided that you declared that as the Horizontal Axis. To do so shouldn't be all that hard. It would look something like:
glRotatef( 180.0f, 1, 0, 0 );
provided you are rotating in degrees as opposed to radians.
For each vertex (I'm assuming that you use immediate mode for designating vertices), you can glVertex2i(myVertex.x, symmetryLine - myVertex.y, 0) where myVertex are the x and y values you previously used, and symmetryLine the value you wish to mirror against. Best way would be to use a negative glScale though. Your diamond is rotationally symmetric glRotate also works but you know, not a very elegant way to do it.
I am writing a Programm, trying to display some kind of sphere consisting of independent blocks. Unfortunately, from some angles I can see through the blocks, seeing the ones behind them.
good angle: http://i.imgur.com/6o120KF.png
bad angle: http://i.imgur.com/DbB9iVO.png
I was checking some posts, but nothing helped. I cared for depth buffer, zNear but now I have no ideas.May someone halp?
My Code
int main(int argc, char** argv) {
//init world
world.init();
//configure GLUT
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(WIDTH, HEIGHT); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutKeyboardFunc(keyboard); // call keyboard() when key is hit
glutIdleFunc(display); // if no rendering to be, call display
glutReshapeFunc(reshape); // Register callback handler for window re-size event
initGL(); // Our own OpenGL initialization
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f); // Set background depth to farthest
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDisable(GL_BLEND);
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
glClear(GL_DEPTH_BUFFER_BIT);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
glLoadIdentity(); // Reset the model-view matrix
//formulas for camera changes
glTranslatef(translatex, 2.0f, -7.0f); // Move right and into the screen
glRotated(rotAnglex, 1, 0, 0); // rotate by rotAngle about y-axis
glRotated(rotAngley, 0, 1, 0); // rotate by rotAngle about y-axis
glRotated(rotAnglez, 0, 0, 1); // rotate by rotAngle about y-axis
glScalef(zoom ,zoom ,zoom);
glBegin(GL_LINES);
// draw line for x axis
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0 - xmove, 0.0 - ymove, 0.0 - zmove);
glVertex3f(100.0 - xmove, 0.0 - ymove, 0.0 -zmove);
// draw line for y axis
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0 - xmove, 0.0 - ymove, 0.0 - zmove);
glVertex3f(0.0 - xmove, 100.0 - ymove, 0.0 -zmove);
// draw line for Z axis
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0 - xmove, 0.0 - ymove, 0.0 - zmove);
glVertex3f(0.0 - xmove, 0.0 - ymove, 100.0 -zmove);
glEnd();
glBegin(GL_QUADS);
//draw axes
if(it_counter++ < iterations){
//print world
BOOST_FOREACH(std::Cell* now_cell, world.cells){
BOOST_FOREACH(std::Voxel* now_voxel, now_cell->content){
addVoxel(*now_voxel);
}
}
}
glEnd(); // End of drawing color-cube
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(-1.5f, 0.0f, -6.0f); // Move left and into the screen
glScalef(3.0f ,3.0f ,3.0f);
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}
Is the order of adding blocks (voxels in code) important for rendering?
It seams as if you created a window without a depth buffer. Enabling the depth-test will only work if your window has such a buffer.
To solve your problem, you have to change
glutInitDisplayMode(GLUT_DOUBLE);
to
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
Main function:
int _tmain(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitWindowSize (500, 500);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glutInitWindowPosition (700, 100);
glutCreateWindow("Result");
glutDisplayFunc(display2);
glutReshapeFunc(reshape2);
glutMouseFunc(main_mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Display2 function:
void display2()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Green square
glColor3f(0.0,1.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.5,0.5,-1.0);
glVertex3f(0.5,1.5,-1.0);
glVertex3f(1.5,1.5,-1.0);
glVertex3f(1.5,0.5,-1.0);
glEnd();
//Red square
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,-2.0);
glVertex3f(0.0,1.0,-2.0);
glVertex3f(1.0,1.0,-2.0);
glVertex3f(1.0,0.0,-2.0);
glEnd();
glutSwapBuffers();
}
reshape2 function
void reshape2(int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glOrtho(-3.0,3.0,-3.0,3.0,0.01,3.0);
}
I have problem with depth buffer in openGL. I try to draw 2 square red and green. The red one is located behind the green one.
Red square have z value -2 while green square have z value -1. But the red square displayed at front of green square. I have enabled the depth test but still not work. What is wrong with my program?
Don't call any gl* function before you call glutCreateWindow, so move glEnable and glDepthFunc after it.
Every gl functions make calls to the context which is only created with the GLUT window. No OpenGL functions is effective before that.
I need to make this wheel to make a rotation animation around its center in openGL continuously without clicking the mouse,because the wheel makes its rotation if the left button of the mouse is clicked!!, this is the wheel:
This is the code I used to draw the wheel and to make the rotation:
#include <freeglut.h>
#include <glaux.h>
void whiteStud()
{
glColor3f(1.0, 1.0, 1.0);
glutSolidSphere(0.01, 16, 16);
}
void blackWheel()
{
glColor3f(0.129412, 0.129412, 0.129412);
glutSolidSphere(0.1, 16, 16);
}
void wheelWithStuds()
{
/**********************************/
int iTimeElapsed = glutGet(GLUT_ELAPSED_TIME);
float fScale= 0.5f;
long i;
/**********************************/
/* clear all pixels */
glClear(GL_COLOR_BUFFER_BIT);
/**********************************/
glPushMatrix();
glTranslatef(0.25, 0.25, 0.0);
glRotatef(iTimeElapsed * fScale,0.0,0.0,1.0);
blackWheel(); // draw the wheel without studs.
/**********************************/
// five studs, step 72 degree (72*5=360 degree).
for (i=0; i<5; i++) {
glPushMatrix();
glRotatef(72*i,0.0,0.0,1.0); // rotate coordinate 72 degree.
glTranslatef(0.04, 0.0, 0.0);// translate on the rotated coordinate.
whiteStud(); // draw the stud.
glPopMatrix();
}
glTranslatef(0.0, 0.0, 0.0);// translate in order to draw a stud at the center of the wheel.
whiteStud();// draw the stud at the center of the wheel.
/**********************************/
/* don't wait! start processing buffered OpenGL routines */
glFlush();
glPopMatrix();
/**********************************/
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(10, 10);
glutCreateWindow("(-Rotating Car Wheel-)");
/* select clearing (background) color */
glClearColor(1.0, 1.0,1.0, 1.0);
/* initialize viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutDisplayFunc(wheelWithStuds);
glutMainLoop();
return 0;
}
I want this wheel to rotate by itself without clicking the left button of the mouse, how can I perform this?
Here is a new draw_wheel() with the desired motion. Notably, you forgot glutPostRedisplay() at the end of the draw method; this function tells glut to redraw the window. Also you were not resetting your first call to glTranslatef(), so every time you clicked the window the object got further away from its original position.
void draw_wheel()
{
int iTimeElapsed = glutGet(GLUT_ELAPSED_TIME);
float fRevolveScale1 = 0.2f;
float fRevolveScale2 = 0.4f;
long i;
// clear all pixels
glClear(GL_COLOR_BUFFER_BIT);
// push temp state
glPushMatrix();
// translate to center
glTranslatef(0.5f, 0.5f, 0.0);
// rotate around pivot
glRotatef(iTimeElapsed * fRevolveScale1,0.0,0.0,1.0);
// translate to planet location
glTranslatef(0.25f, 0.25f, 0.0);
glRotatef(iTimeElapsed * fRevolveScale2,0.0,0.0,1.0);
glColor3f(0.129412f, 0.129412f, 0.129412f);
glutSolidSphere(0.1f, 16, 16);
// five bolts, step 72 degree (72*5=360 degree)
glColor3f(1.0, 1.0, 1.0);
for(i=0; i<5; ++i)
{
glPushMatrix();
glRotatef(72.0f*i,0.0,0.0,1.0); // rotate coordinate 72 degree
glTranslatef(0.04f, 0.0, 0.0);// translate on the rotated coordinate
glutSolidSphere(0.01f, 16, 16);
glPopMatrix();
}
glTranslatef(0.0f, 0.0f, 0.0f);// translate on the rotated coordinate
glutSolidSphere(0.01, 16, 16);
// pop temp state
glPopMatrix();
glFlush();
glutPostRedisplay();
}
I was following this tutorial, the triangle renders perfectly, but when I hit the Page Up key, nothing happens.
Here's my code:
// made in Visual Studio Express 2008
// OpenGL3-1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
// if you are not using Visual Studio to compile this then remove stdafx.h
#include <stdlib.h>
#include <windows.h>
#include "glut.h"
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel (GL_SMOOTH);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Loading the Identity matrix means we reset the screen coordinate system to XYZ axis of lenght 1:
The screen starts at z=0, x=-1 to x=1 and y=-1 to y=1 */
glLoadIdentity ();
glTranslatef(0,0.0f,-6.0f);
// translate everything by 6 units in the z axis.
glBegin(GL_TRIANGLES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd(); // Done Drawing A Triangle
Sleep(5);
glutSwapBuffers();
}
void reshape (int w, int h)
{
// just the window reshape function
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
// escapes from the program if the ESC key is hit
switch (key) {
case 27:
exit(0);
break;
}
}
void keyspecial( int key, int x, int y )
{
if( key == GLUT_KEY_PAGE_UP) // Page up
{
glTranslatef(90.0,0.0,0.0);
// ...... do what ever you want to do
glutPostRedisplay(); // redraw everything to reflect the changes
}
if (key == GLUT_KEY_PAGE_DOWN)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
if (key == GLUT_KEY_HOME)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
if (key == GLUT_KEY_END)
{
// ...... do what ever you want to do
glutPostRedisplay();// redraw everything to reflect the changes
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard); // tell glut to call this function when the user presses a key
glutSpecialFunc(keyspecial); // tell glut to call this function when the user presses a special a key
glutMainLoop();
return 0;
}
Note:
The tutorial suggested using glTranslate(x,y,z) instead of glTranslatef(x,y,z). I assumed that was a typo since glTranslate() doesn't exist
You're resetting your matrix in display, so your glTranslate* from the key event handler is lost. Rethink what you're trying to achieve.
What you're doing in this function is not the right thing to do
void reshape (int w, int h)
{ // just the window reshape function
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode (GL_MODELVIEW);
}
Speak with me: Don't set the viewport size and projection in the reshape handler!
You always set viewport and projection together with everything else in the display handler. It's the only right place to do it.
Next, you don't "place" objects using OpenGL matrix functions. You're just manipulating the transformation matrix, which should be set according to the placement of the objects, which may be perfectly well stored as matrix but independently of OpenGL state. So your keyboard handler should set some variable, which is then used for setting the modelview matrix at the right moment.