The code below creates 2 square polygons, red and green.
I'm trying to place a red square on top of the green, but I can't.
The depth buffer is declared, cleaned when necessary, an orthogonal system is configured correctly.
If I specify a value outside the range (2;-2), the polygon disappears as it should.
#include <...>
constexpr auto FPS_RATE = 120;
int windowHeight = 600, windowWidth = 600, windowDepth = 600;
void init();
void idleFunction();
void displayFunction();
double getTime();
double getTime()
{
using Duration = std::chrono::duration<double>;
return std::chrono::duration_cast<Duration>(
std::chrono::high_resolution_clock::now().time_since_epoch()
).count();
}
const double frame_delay = 1.0 / FPS_RATE;
double last_render = 0;
void init()
{
glutDisplayFunc(displayFunction);
glutIdleFunc(idleFunction);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-windowWidth / 2, windowWidth / 2, -windowHeight / 2, windowHeight / 2, 2, -2);
glClearColor(0.0, 0.0, 0.0, 0.0);
}
void idleFunction()
{
const double current_time = getTime();
if ((current_time - last_render) > frame_delay)
{
last_render = current_time;
glutPostRedisplay();
}
}
void displayFunction()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
//move the red square to the foreground
glTranslatef(-32.5, -32.5, 2);
glColor3f(1, 0, 0);
glBegin(GL_POLYGON);
glVertex3i(-150, 150, 0);
glVertex3i(150, 150, 0);
glVertex3i(150, -150, 0);
glVertex3i(-150, -150, 0);
glEnd();
glPopMatrix();
glPushMatrix();
//move the green square to the background
glTranslatef(32.5, 32.5, -2);
glColor3f(0, 1, 0);
glBegin(GL_POLYGON);
glVertex3i(-150, 150, 0);
glVertex3i(150, 150, 0);
glVertex3i(150, -150, 0);
glVertex3i(-150, -150, 0);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) - windowWidth) / 2, (GetSystemMetrics(SM_CYSCREEN) - windowHeight) / 2);
glutCreateWindow("Window");
init();
glutMainLoop();
return 0;
}
You've to enable the Depth Test:
glEnable( GL_DEPTH_TEST );
The default depth test function (glDepthFunc) is < (GL_LESS).
If the distance to the far plane is 2.0 and the geometry is drawn with z coordinate of 2.0, then the geometry is clipped by the far plane, because the depth of the geometry is not less than the initialization depth of the depth buffer.
Change the depth function to <= (GL_LEQUAL):
glDepthFunc( GL_LEQUAL );
In a Right-handed system the viewspace z-axis points out of the viewport.
So if the z coordinate is "less than", then the object is "behind" an other object.
The projection matrix transforms from view space to normalized device space. In compare to the view space, the normalized device space is a left handed system, where the z-axis points in the viewport. The normalized device z-coordinate in range [-1, 1] (from the front to the back), is mapped to the depth value (in general in range [0, 1]), which is used for the depth test.
To deal with that glOrtho inverts the z-axis, if the near parameter is set less then the far parameter (this is how the function is suggested to be used).
This cause that the depth (z) order doesn't change, when the geometry is transformed form view space to normalized device space.
Note, glOrtho(-w, w, -h, h, -z, z) is the same as glScaled(1.0/w, 1.0/h, -1.0/z)
Since the z-axis is not inverted by the orthographic projection in your example, because near > far,
glOrtho(-windowWidth / 2, windowWidth / 2, -windowHeight / 2, windowHeight / 2, 2, -2);
the z coordinate has to be greater, to be "behind".
If the green rectangle should be behind the red one, then you've to change the orthographic projection (near < far). e.g.:
glOrtho(-windowWidth / 2, windowWidth / 2, -windowHeight / 2, windowHeight / 2, -2, 2);
If you don't want to change the projection, then you've to swap the z-coordinates of the geometry:
glPushMatrix();
//move the red square to the foreground
glTranslatef(-32.5, -32.5, -2.0); // foreground because near > far
// ...
glPopMatrix();
glPushMatrix();
//move the green square to the background
glTranslatef(32.5, 32.5, 2.0); // background because near > far
// ...
glPopMatrix();
Related
I tried to draw a teapot and view it in 3D but when I ran the program, nothing showed up. There is nothing in the window. I know it has something to do with my gluLookAt() function but I am not sure how to fix it.
// helloteapot.cc
//#include <GLUT/gl.h>
#include <GLUT/glut.h>
#include "GL/glui.h"
void display () {
/* clear window */
glClear(GL_COLOR_BUFFER_BIT);
/* draw scene */
glColor3f(1.0, 0.0, 0.0);
glTranslatef(0.0, 0.5, 0.0);
glutSolidTeapot(0.15);
/* flush drawing routines to the window */
glFlush();
}
int main ( int argc, char * argv[] ) {
glutInit(&argc,argv);
/* setup the size, position, and display mode for new windows */
glutInitWindowSize(800,600);
glutInitWindowPosition(0,0);
glutInitDisplayMode(GLUT_RGB);
/* create and set up a window */
glutCreateWindow("hello, teapot!");
glutDisplayFunc(display);
/*GLfloat width = 800;
GLfloat height = 600;
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);*/
// Set the aspect ratio of the clipping volume to match the
viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection
matrix
glLoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
//luPerspective(45.0f, aspect, -100.0f, 100.0f);
gluLookAt(0, 0, 0, 0, 0.5, 0, 0, -1, 0);
/* tell GLUT to wait for events */
glutMainLoop();
}
You have asked GL to position the camera at the origin, aim the camera upwards towards the point (0, 0.5, 0), and have also specified (incorrectly) the up vector to be 0, -1, 0. The problem is that the camera's forward direction is (0, 1, 0) [as specified by your eye and aim positions], and this direction conflicts with the up vector or (0, -1, 0). Try using a vector at right angles to the forward direction instead! (e.g. [1, 0, 0], [0, 0, 1])
gluLookAt(
0, 0, 0, //< camera location
0, 0.5, 0, //< looking towards point
1, 0, 0); //< which direction is up?
I'm trying to look at the square from the other side using the gluLookAt() function.
After using the function, nothing changes, although I expected that the corners of the square will change.
I set the camera point to the rightmost part of the world and look at its center, where the square is located.
He had to stretch out to the sides. Why hasn't anything changed?
Code:
#include "includes.h"
using namespace std;
constexpr auto FPS_RATE = 60;
int windowHeight = 600, windowWidth = 600, windowDepth = 600;
void init();
void idleFunction();
void displayFunction();
double getTime();
double getTime()
{
using Duration = std::chrono::duration<double>;
return std::chrono::duration_cast<Duration>(
std::chrono::high_resolution_clock::now().time_since_epoch()
).count();
}
const double frame_delay = 1.0 / FPS_RATE;
double last_render = 0;
void init()
{
glutDisplayFunc(displayFunction);
glutIdleFunc(idleFunction);
glViewport(0, 0, windowWidth, windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-windowWidth / 2, windowWidth / 2, -windowHeight / 2, windowHeight / 2, -windowDepth / 2, windowDepth / 2);
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
}
void idleFunction()
{
const double current_time = getTime();
if ((current_time - last_render) > frame_delay)
{
last_render = current_time;
glutPostRedisplay();
}
}
void displayFunction()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POLYGON);
gluLookAt(-300, 0, 0,
0, 0, 0,
0, 1, 0);
glColor3f(1, 1, 1);
glVertex3i(-150, 150, 0);
glVertex3i(150, 150, 0);
glVertex3i(150, -150, 0);
glVertex3i(-150, -150, 0);
glEnd();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) - windowWidth) / 2, (GetSystemMetrics(SM_CYSCREEN) - windowHeight) / 2);
glutCreateWindow("Window");
init();
glutMainLoop();
return 0;
}
The issue is caused because gluLookAt() is call with in a glBegin/glEnd sequence. This is not allowed. You've to call gluLookAt before glBegin.
Once drawing of primitives was started by glBegin it is only allowed to specify vertex coordinates (glVertex) and change attributes (e.g. glColor, glTexCoord ...), till the drawn is ended (glEnd).
All other instruction will be ignored and cause a GL_INVALID_OPERATION error (error code 1282).
Further note, that glLookAt doesn't set a the current matrix. It defines a matrix and multiplies the current matrix by the new matrix. Set the matrix mode (glMatrixMode) and set Identity matrix by glLoadIdentity before gluLookAt.
With the view matrix
gluLookAt(-300, 0, 0, 0, 0, 0, 0, 1, 0);
you want "see" anything, because with that matrix the line of sight is set along the x-axis and you look at the 2 dimensional polygon from the side.
Note, the polygon is a 2D object. The size of the object appears different if you look at it from the front, from the side (then it is a line and not visible) or from an direction in between. The first 3 parameters of gluLookAt define the point of view the next 3 parameters define the point you look at. The vector from the point of view to the point you look at is the line of sight.
Probably yo want look along the z-axis:
void displayFunction()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, -300, 0, 0, 0, 0, 1, 0);
glBegin(GL_POLYGON);
glColor3f(1, 1, 1);
glVertex3i(-150, 150, 0);
glVertex3i(150, 150, 0);
glVertex3i(150, -150, 0);
glVertex3i(-150, -150, 0);
glEnd();
glutSwapBuffers();
}
You use Orthographic (parallel) projection. If you would use Perspective projection, then the projected size of the object would decrease, when the distance to the point of view increases. Perspective projection can be set by gluPerspective. e.g.:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0, (double)windowWidth / windowHeight, 0.1, 600.0);
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<GL/glut.h>
double cameraAngle;
void grid_and_axes() {
// draw the three major AXES
glBegin(GL_LINES);
//X axis
glColor3f(0, 1, 0); //100% Green
glVertex3f(-150, 0, 0);
glVertex3f(150, 0, 0);
//Y axis
glColor3f(0, 0, 1); //100% Blue
glVertex3f(0, -150, 0); // intentionally extended to -150 to 150, no big deal
glVertex3f(0, 150, 0);
//Z axis
glColor3f(1, 1, 1); //100% White
glVertex3f(0, 0, -150);
glVertex3f(0, 0, 150);
glEnd();
//some gridlines along the field
int i;
glColor3f(0.5, 0.5, 0.5); //grey
glBegin(GL_LINES);
for (i = -10; i <= 10; i++) {
if (i == 0)
continue; //SKIP the MAIN axes
//lines parallel to Y-axis
glVertex3f(i * 10, -100, 0);
glVertex3f(i * 10, 100, 0);
//lines parallel to X-axis
glVertex3f(-100, i * 10, 0);
glVertex3f(100, i * 10, 0);
}
glEnd();
}
void display() {
//codes for Models, Camera
//clear the display
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 0); //color black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear buffers to preset values
/***************************
/ set-up camera (view) here
****************************/
//load the correct matrix -- MODEL-VIEW matrix
glMatrixMode(GL_MODELVIEW); //specify which matrix is the current matrix
//initialize the matrix
glLoadIdentity(); //replace the current matrix with the identity matrix [Diagonals have 1, others have 0]
//now give three info
//1. where is the camera (viewer)?
//2. where is the camera looking?
//3. Which direction is the camera's UP direction?
//gluLookAt(0,-150,20, 0,0,0, 0,0,1);
gluLookAt(150 * sin(cameraAngle), -150 * cos(cameraAngle), 50, 0, 0, 0, 0, 0, 1);
/*************************
/ Grid and axes Lines
**************************/
grid_and_axes();
/****************************
/ Add your objects from here
****************************/
/*glColor3f(1, 0, 0);
glutSolidCone(20, 20, 20, 20);
glColor3f(0, 0, 1);
GLUquadricObj *cyl = gluNewQuadric();
gluCylinder(cyl, 10, 10, 50, 20, 20);
glTranslatef(0, 0, 50);
glColor3f(1, 0, 0);
glutSolidCone(10, 20, 20, 20);
*/
glColor3f(1, 0, 0);
glutSolidCube(1);
I am not getting any cube here.
However if I use any transformation property like scaling or rotate then I get the desired cube like
glColor3f(1, 0, 0);
glScalef(50,5,60);
glutSolidCube(1);
what is the problem?
Another problem I am facing that color doesn't work if i don't use transformation property like above mentioned. If I write:
glColor3f(1, 0, 0);
glutSolidCone(20, 20, 20, 20);
For above codes color doesn't work; i get the default colored cone
However if I change this two lines to these 3 lines then color works perfectly:
glColor3f(1,0,0);
glTranslatef(0, 0, 50);
glutSolidCone(10,20,20,20);
then color works; what is the problem? Please help
//ADD this line in the end --- if you use double buffer (i.e. GL_DOUBLE)
glutSwapBuffers();
}
void animate() {
//codes for any changes in Models, Camera
cameraAngle += 0.001; // camera will rotate at 0.002 radians per frame.
//codes for any changes in Models
//MISSING SOMETHING? -- YES: add the following
glutPostRedisplay(); //this will call the display AGAIN
}
void init() {
//codes for initialization
cameraAngle = 0; //angle in radian
//clear the screen
glClearColor(0, 0, 0, 0);
/************************
/ set-up projection here
************************/
//load the PROJECTION matrix
glMatrixMode(GL_PROJECTION);
//initialize the matrix
glLoadIdentity();
/*
gluPerspective() — set up a perspective projection matrix
fovy - Specifies the field of view angle, in degrees, in the y direction.
aspect ratio - Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
zNear - Specifies the distance from the viewer to the near clipping plane (always positive).
zFar - Specifies the distance from the viewer to the far clipping plane (always positive).
*/
gluPerspective(70, 1, 0.1, 10000.0);
}
int main(int argc, char **argv) {
glutInit(&argc, argv); //initialize the GLUT library
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
/*
glutInitDisplayMode - inits display mode
GLUT_DOUBLE - allows for display on the double buffer window
GLUT_RGBA - shows color (Red, green, blue) and an alpha
GLUT_DEPTH - allows for depth buffer
*/
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Some Title");
init(); //codes for initialization
glEnable(GL_DEPTH_TEST); //enable Depth Testing
glutDisplayFunc(display); //display callback function
glutIdleFunc(animate); //what you want to do in the idle time (when no drawing is occuring)
glutMainLoop(); //The main loop of OpenGL
return 0;
}
I am not getting any cube here.
You do get a cube. It is just that tiny speck where the axis intersect. What else would you expect to see when you draw something 2 units big, ~160 units away, with a 70 degree field of view?
Another problem I am facing that color doesn't work if i don't use transformation property like above mentioned.
[...] I get the default colored cone.
I've no idea what you even mean by that. The "default color" would be the initial value of GL's builtin color attribute - which is (1, 1, 1, 1) - white. With the code you have set up, you will get the color which you set before. So the only guess I can make here is that you confused yourself by not properly taking GL's state machine into account.
But besides all that, you should not use that code at all - this is using the fixed function pipeline and immediate mode drawing - features which are deprecated since a decade now, and not supported at all by modern core profiles of OpenGL. Trying to learn that stuff in 2017 is a waste of time. And btw:
glutMainLoop(); //The main loop of OpenGL
Nope. Just NO!!!. OpenGL does not have a "main loop". GLUT is not OpenGL. Honestly, this is all just horrible.
I am trying to render a rectangle onto the screen. When the program is run, only the clear color shows up, and no rectangle.
Here's the code:
glClearColor(0.0, 0.0, 0.0, 0.0);
glViewport(0, 0, 1280, 720);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1280, 720, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT || GL_DEPTH_BUFFER_BIT); //Clear the screen and depth buffer
int x = 100;
int y = 100;
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x + 10, y);
glVertex2f(x + 10, y + 10);
glVertex2f(x, y + 10);
glEnd();
gsm->update();
gsm->render();
glfwSwapBuffers(window);
}
It got culled. You had inverted Y axis with your projection, by supplying bottom =720 larger than top 0. Your quad is counterclockwise in your local coordinates, but in normalized coordinates it is clockwise. Remember, projection matrix is a part of global transform matrix! Now, if that's default state, then out of those two winding directions
the GL_CCW is the actual one, it is considered "Front". By default OpenGL culls triangles with mode glCullFace(GL_BACK), and quad internally is considered as pair of triangles).
Either change order of vertices
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x, y + 10);
glVertex2f(x + 10, y + 10);
glVertex2f(x + 10, y);
glEnd();
or change culling mode to match left-handedness of your coordinate system or disable culling.
See also:
1. https://www.khronos.org/opengl/wiki/Viewing_and_Transformations
2. The answer to Is OpenGL coordinate system left-handed or right-handed?
I am a beginner in OpenGl and I am struggling a bit with setting up the glOrtho camera to match the window size so that I can draw a line using the window's coordinates. For example, if I want to draw a line from coordinates 0,10 (x,y) to 600,10. I managed to draw the line (which will be a "Separator" from the viewport and a toolbar with buttons) in my current set up but it was by "try end error" approach and the coordinates that I needed to put don't make any sense to me. When I tried to draw a line using the above-mentioned coordinates, the line simply did not show up. What I need to change in the glOrtho set up in order to work with these (1000x600) screen size and draw my vertices and not these:
glVertex3f(-2.0, 11.0, 0.0);
glVertex3f(20.0, 11.0, 0.0);
Note, my current window size is 1000x600 (width/height)
This is the line (on the top that crosses the whole screen):
This is my OGWindow class that handles all of the drawing:
void OGWindow::MyReSizeGLScene(int fwidth, int fheight)
{
// Store window size in class variables so it can be accessed in myDrawGLScene() if necessary
wWidth = fwidth;
wHeight = fheight;
// Calculate aspect ration of the OpenGL window
aspect_ratio = (float) fwidth / fheight;
// Set camera so it can see a square area of space running from 0 to 10
// in both X and Y directions, plus a bit of space around it.
Ymin = -1;
Ymax = 12;
Xmin = -1;
// Choose Xmax so that the aspect ration of the projection
// = the aspect ratio of the viewport
Xmax = (aspect_ratio * (Ymax -Ymin)) + Xmin;
glMatrixMode(GL_PROJECTION); // Select The Projection Stack
glLoadIdentity();
glOrtho(Xmin, Xmax, Ymin, Ymax, -1.0, 1.0);
glViewport(0, 0, wWidth, wHeight); // Viewport fills the window
}
void OGWindow::myDrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the drawing area
OGWindow::myDrawModel();
drawToolbar();
glutSwapBuffers(); // Needed if we're running an animation
glFlush();
}
void OGWindow::myDrawModel(GLvoid)
{
switch ( squareColour ) {
case RED:
glColor3f(1.0, 0.0, 0.0);
break;
case BLUE:
glColor3f(0.0, 0.0, 1.0);
break;
}
glBegin( GL_QUADS );
glVertex3f( squareX, squareY, 0.0 ); // Coordinates of bottom-left corner of square
glVertex3f( squareX + squareWidth, squareY, 0.0 );
glVertex3f( squareX + squareWidth, squareY + squareHeight, 0.0 );
glVertex3f( squareX, squareY + squareHeight, 0.0 );
glEnd();
}
// Convert from screen coords returned by mouse
// to world coordinates.
// Return result in worldX, worldY
void OGWindow::screen2World(int screenX, int screenY, double & worldX, double & worldY)
{
// Dimensions of rectangle viewed by camera projection
double projWidth = Xmax -Xmin;
double projHeight = Ymax - Ymin;
// Screen coords with origin at bottom left
int screenLeft = screenX;
int screenUp = wHeight - screenY;
worldX = Xmin + screenLeft * projWidth / wWidth ;
worldY = Ymin + screenUp * projHeight / wHeight ;
}
//Method to draw the toolbar separator line
void OGWindow::drawToolbar(GLvoid) {
//draw toolbar line separator
glColor3f(0.0,0.0,0.0);
glBegin(GL_LINES);
glVertex3f(-2.0, 11.0, 0.0);
glVertex3f(20.0, 11.0, 0.0);
glEnd();
//draw create button
glPushMatrix();
glTranslatef(2.0, 10.0, 0.0);
glutSolidCube(2.0);
glPopMatrix();
}
This is my main class where I am ivoking the methods from OGWindow:
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize( 1000, 600 );
glutInitWindowPosition(0, 0);
glutCreateWindow("OpenGL Demo");
glEnable(GL_DEPTH_TEST); // enable the depth buffer test
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMotion);
glutPassiveMotionFunc(mousePassiveMotion);
glutIdleFunc(Idle);
theWindow.initGL();
glutMainLoop();
}
Check out the documentation of glOrtho function. As you see, there are 6 parameters: left, right, bottom, top, near, far. You made mistake by setting window width to top instead of bottom parameter. Here's proper use of function:
glOrtho (0, 1000, 600, 0, -1.0, 1.0)
So, first your ortho settings. If you want your camera to match the screen dimensions, glOrtho has to use the same dimensions.
// This will anchor the camera to the center of the screen
// Camera will be centered on (0,0)
glOrtho( -screenWidth/2.f, screenWidth/2.f, -screenHeight/2.f, screenHeight/2.f, -1, 1 );
// This will anchor the camera to the lower left corner of the screen
// Camera will be centered on (screenWidth/2, screenHeight/2)
glOrtho( 0, screenWidth, 0, screenHeight, -1, 1 );
Try both and see the difference. Although if you are making some sort of editor, where your camera doesn't move, you may be looking for the second ortho setup.
Second, you only ever use (apparently) the GL_PROJECTION matrix mode. You must use this mode to set the camera projection and GL_MODELVIEW to apply transforms to the camera or the objects.
So when you call resize and don't change the matrix mode back to GL_MODELVIEW, you'll be applying translations to the projection matrix.
If you did forget to initialize the modelview matrix it may contain garbage values and yield unexpected results.