I am trying to set the angle of View with gluLookAt()
Here I have my code where I tried to set the camera without results
Here the function displaycone():
void displayCone(void)
{
glMatrixMode(GL_MODELVIEW);
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// clear the identity matrix.
glLoadIdentity();
// traslate the draw by z = -4.0
// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
glTranslatef(0.0,0.0,-4.5);
// Red color used to draw.
glColor3f(0.8, 0.2, 0.1);
// changing in transformation matrix.
// rotation about X axis
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
// scaling transfomation
glScalef(1.0,1.0,1.0);
// built-in (glut library) function , draw you a Cone.
// move the peak of the cone to the origin
glTranslatef(0.0, 0.0, -height);
glutSolidCone(base,height,slices,stacks);
// Flush buffers to screen
gluLookAt(3,3,3,0,0,-4.5,0,1,0);
glFlush();
// sawp buffers called because we are using double buffering
// glutSwapBuffers();
}
With my main:
int main (int argc, char **argv)
{
glutInit(&argc, argv);
//double buffering used to avoid flickering problem in animation
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// window size
glutInitWindowSize(400,350);
// create the window
glutCreateWindow("Cone Rotating Animation");
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glClearColor(0.0,0.0,0.0,0.0);
//Assign the function used in events
glutDisplayFunc(displayCone);
glutReshapeFunc(reshapeCone);
glutIdleFunc(idleCone);
//Let start glut loop
glutMainLoop();
return 0;
}
The function idlecone instead changes the values of xRotated, yRotated... and displays the cone. Any ideas?
I am pretty sure I didn't understand the right moment where to use gluLookAt()...
gluLookAt changes the current matrix, similar to glTranslatef or glRotatef.
The operation defines a transformation matrix and multiplies the current matrix by the new transformation matrix.
gluLookAt has to be called before glutSolidCone, e.g.:
void displayCone(void)
{
// set matrix mode
glMatrixMode(GL_MODELVIEW);
// clear model view matrix
glLoadIdentity();
// multiply view matrix to current matrix
gluLookAt(3,3,3,0,0,-4.5,0,1,0); // <----------------------- add
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// traslate the draw by z = -4.0
// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
glTranslatef(0.0,0.0,-4.5);
// Red color used to draw.
glColor3f(0.8, 0.2, 0.1);
// changing in transformation matrix.
// rotation about X axis
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
// scaling transfomation
glScalef(1.0,1.0,1.0);
// built-in (glut library) function , draw you a Cone.
// move the peak of the cone to the origin
glTranslatef(0.0, 0.0, -height);
glutSolidCone(base,height,slices,stacks);
// Flush buffers to screen
// gluLookAt(3,3,3,0,0,-4.5,0,1,0); <----------------------- delete
glFlush();
// sawp buffers called because we are using double buffering
// glutSwapBuffers();
}
Related
(code snippet. I know it's ugly but i wanted to make it work before making it better so please don't pay too much attention to the structure)
I modified slightly the glfw example present in the documentation to have a triangle that rotates when pressing the right arrow key and draws a circle described by the position of one of his vertices (the blue one in this case).
I clear the GL_COLOR_BUFFER_BIT only when initializing the window to avoid having to store all the coordinates that will be needed to draw the line (they would be hundreds of thousands in the final program), that means that on the screen every time i press the right arrow a "copy" of the triangle is draws rotated by 12 degrees and a line is drawn that connects the old blue angle position to the new one.
The problem now is that i would want to be able to press the escape key GLFW_KEY_ESCAPE and "delete" the triangles while keeping the lines drawn.
I tried using a z-buffer to hide the triangles behind a black rectangle but only the last line drawn is visualized (i think this is because opengl doesn't know the z of the previous lines since i don't store them).
Is there a way to do what i want without having to store all the point coordinates and then clearing the whole screen and redrawing only the lines? If this is the case, what would be the best way to store them?
Here is part of the code i have so far.
bool check = 0;
Vertex blue = {0.f, 0.6f, 0.5f};
Vertex green = {0.6f,-0.4f, 0.5f};
Vertex red = {-0.6f, -0.4f, 0.5f};
Vertex line = {0.f, 0.6f, 0.f};
Vertex line2 = {0.f, 0.6f, 0.f};
static void
key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
check = !check;
if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS) {
line.x = line2.x;
line.y = line2.y;
rotation -= 12;
rad = DegToRad(-12);
double x = line.x*cos(rad) - line.y * sin(rad);
double y = line.y * cos(rad) + line.x * sin(rad);
line2.x = x;
line2.y = y;
}
int main(void) {
GLFWwindow *window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(1280, 720, "Example", NULL, NULL);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glClear(GL_COLOR_BUFFER_BIT);
while (!glfwWindowShouldClose(window)) {
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(rotation, 0.f, 0.f, 1.f);
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(red.x, red.y, red.z);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(green.x, green.y, green.z);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(blue.x, blue.y, blue.z);
glEnd();
glLoadIdentity();
glLineWidth(1.0);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex3f(line.x, line.y, line.z);
glVertex3f(line2.x, line2.y, line2.z);
glEnd();
if (check){
//hide the triangles but not the lines
}
glEnd();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
I clear the GL_COLOR_BUFFER_BIT only when initializing the window
That's your problem right there. It's idiomatic in OpenGL to always start with a clear operation of the main framebuffer color bits. That is, because you don't know the state of your window main framebuffer when the operating system is asking for a redraw. For all you know it could have been all replaced with cat pictures in the background without your program knowing it. Seriously: If you have a cat video running and the OS felt the need to rearrange your window's main framebuffer memory this is what you might end up with.
Is there a way to do what i want without having to store all the point coordinates and then clearing the whole screen and redrawing only the lines?
For all intents and purposes: No. In theory one could come up with a contraption made out of a convoluted series of stencil buffer operations to implement that, but this would be barking up a very wrong tree.
Here's something for you to try out: Draw a bunch of triangles like you do, then resize your window down so there nothing remains, then resize it back to its original size… you see where the problem? There's a way to address this particular problem, but that's not what you should do here.
The correct thing is to redraw everything. If you feel that that's to slow you have to optimize your drawing process. On current generation hardware it's possible to churn out on the order of 100 million triangles per second.
Well, I have the following C code on a GLUT Project (I use CodeBlocks).
It draw some 2D shapes (something like Robot :p ).
I want to make the whole drawing shapes to be moved with the keyboard arrow keys. I have wrote the following, but for some reason when I push the arrow keys, it seems like it zoom in/out. It does not move.
#include <GL/glut.h>
GLuint head_x1=5, head_y1=30, head_x2=15, head_y2=30, head_x3=15,head_y3=40, head_x4=5,head_y4=40;
// shape
GLuint listID;
void MrRobot(GLsizei displayListID)
{
glNewList(displayListID,GL_COMPILE);
//Save current colour state
glPushAttrib(GL_CURRENT_BIT);
// body
glColor3f(0.5,0.5,0.5);
glBegin(GL_POLYGON);
glVertex2f(0,10);
glVertex2f(20,10);
glVertex2f(20,30);
glVertex2f(0,30);
glEnd();
// head
glColor3f(0,0,1);
glBegin(GL_POLYGON);
glVertex2f(head_x1,head_y1);
glVertex2f(head_x2,head_y2);
glVertex2f(head_x3,head_y3);
glVertex2f(head_x4,head_y4);
glEnd();
// legs
glColor3f(1,0,0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(10,10);
glVertex2f(20,0);
glVertex2f(10,-5);
glVertex2f(0,0);
glEnd();
// right hand
glColor3f(0,1,0);
glBegin(GL_TRIANGLES);
glVertex2f(20,30);
glVertex2f(30,27.5);
glVertex2f(20,25);
glEnd();
// left hand
glColor3f(0,1,0);
glBegin(GL_TRIANGLES);
glVertex2f(-10,27.5);
glVertex2f(0,30);
glVertex2f(0,25);
glEnd();
//Recall saved colour state
glPopAttrib();
glEndList();
}
void display()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,0,0);
//Defining a modelview transform matrix
glScalef(0.3,0.3,0.3);
//Execute the display list (the modelview matrix will be applied)
glCallList(listID);
glFlush();
}
void keyboard(unsigned char key,int x, int y)
{
printf("\nKeyboard event detected. \nCharacter key: %c\nMouse pointer position: x=%d y=%d",key,x,y);
if (key==GLUT_KEY_UP)
{
head_y1++;
head_y2++;
head_y3++;
head_y4++;
}
if (key==GLUT_KEY_DOWN)
{
head_y1--;
head_y2--;
head_y3--;
head_y4--;
}
if (key==GLUT_KEY_LEFT)
{
head_x1--;
head_x2--;
head_x3--;
head_x4--;
}
if (key==GLUT_KEY_RIGHT)
{
head_x1++;
head_x2++;
head_x3++;
head_x4++;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitWindowPosition(50,50);
glutInitWindowSize(800,600);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("Mr Robot");
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-5,35,-5,30);
listID=glGenLists(1);
MrRobot(listID);
glutDisplayFunc(display);
glutSpecialFunc(keyboard);
glutMainLoop();
return 0;
}
Maybe is something with the axis, but have no idea what I should change.
Any help?
Well there are a lot of problems. You seem to be writing OpenGL a little bit differently.
Anyways here is the problem.
The reason its scaling is because everytime you call display you are calling glScalef(0.3, 0.3, 0.3); without loading the identity matrix.
Also when you press a key the increment is happening but you havent even called MrRobot() in the display function. You have only called it once in the main function
Also just before you call display you must call glMatrixMode(GL_MODELVIEW); or else all transformations you do will affect the GL_PROJECTION matrix
I have made a cube with display list using GL_POLYGON.I have initialised it in the origin of the coordinates that means in (0,0,0).In my display function which is called in glutDisplayFunc I use the code:
glLoadIdentity();
glOrtho(0,0,0,0,1,1);
glMatrixMode(GL_MODELVIEW);
I want to use orthographic projection using glOrtho.Well, my question is that: Is it normal that I still can see my cube considering that my window size is 600x600?
What's more, I would like some guidelines on how to move my cube or my camera with the relative OpenGL functions.Let's say I would like to move my camera back(to z axis) or my cube to the front(to -z axis).How can I do that?
First of you also need to set glMatrixMode() to GL_PROJECTION before you call glOrtho(), So it would look like this instead.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(...); // Replace ... with your values
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
To move the sceen you can simply call one or more of the following functions.
glTranslate*()
glRotate*()
glScale*()
You can click the above links to read how and what each function does. But basically:
glTranslate*() translates/moves the current selected matrix.
glRotate*() rotates the current selected matrix.
glScale*() scales the current selected matrix.
You can also use glPushMatrix() and glPopMatrix() to push and pop the current matrix stack.
Extra
Also be aware that you're using old and deprecated functions. You shouldn't use them, instead you're now suppose to calculate and create your own Matrix Stack.
Edit
Camera & Objects
Basically you do that by combining the above functions. Might sound harder that it actually is.
I will create an example of 1 camera and 2 objects, basically to give you the idea of how it works.
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// The Camera Rotations & Translation
glRotatef(camera_pitch, -1f, 0f, 0f);
glRotatef(camera_yaw, 0f, 1f, 0f);
glTranslate(-camera_x, -camera_y, -camera_z);
// Object 1
glPushMatrix();
glRotatef(...);
glTranslate(...);
// Render Object 1
glPopMatrix();
// Object 2
glPushMatrix();
glRotatef(...);
glTranslate(...);
// Render Object 2
glPopMatrix();
}
Again replace the ... with your own values.
The reason why need to translate the camera coordinates negatively is because why aren't moving a camera, we are actually "pushing" (translating, etc) everything away from the camera/center (Thereby the camera is in the center at all times).
Important the order in which you rotate then translate or translate and then rotate, is important. When needing to the camera transformations you always need to rotate then translate.
Edit
gluLookAt ?
gluLookAt does 100% the same, like in my example.
Example:
// The Camera Rotations & Translation
glRotatef(camera_pitch, -1f, 0f, 0f);
glRotatef(camera_yaw, 0f, 1f, 0f);
glTranslate(-camera_x, -camera_y, -camera_z);
This is my own function which does 100% the same as gluLookAt. How do I know? Because I've looked at the original gluLookAt function, and then I made the following function.
void lookAt(float eyex, float eyey, float eyez, float centerx, float centery, float centerz)
{
float dx = eyex - centerx;
float dy = eyey - centery;
float dz = eyez - centerz;
float pitch = (float) Math.atan2(dy, Math.sqrt(dx * dx + dz * dz));
float yaw = (float) Math.atan2(dz, dx);
pitch = -pitch;
yaw = yaw - 1.57079633f;
// Here you could call glLoadIdentity() if you want to reset the matrix
// glLoadIdentity();
glRotatef(Math.toDegrees(pitch), -1f, 0f, 0f);
glRotatef(Math.toDegrees(yaw), 0f, 1f, 0f);
glTranslatef(-eyex, -eyey, -eyez);
}
You might need to change the Math.* calls, since the above code isn't written in C.
I want to learn OpenGL, and decided to start with a very simple example - rendering the shape of comet Wild 2 as inferred from measurements from the Stardust spacecraft (details about the data in: http://nssdc.gsfc.nasa.gov/nmc/masterCatalog.do?ds=PSSB-00133). Please keep in mind that I know absolutely NOTHING about OpenGL. Some Google-fu helped me get as far as the code presented below. Despite my best efforts, my comet sucks:
I would like for it to look prettier, and I have no idea how to proceed (besides reading the Red book, or similar). For example:
How can I make a very basic "wireframe" rendering of the shape?
Suppose the Sun is along the "bottom" direction (i.e., along -Y), how can I add the light and see the shadow on the other side?
How can I add "mouse events" so that I can rotate my view by, and zoom in/out?
How can I make this monster look prettier? Any references to on-line tutorials, or code examples?
I placed the source code, data, and makefile (for OS X) in bitbucket:
hg clone https://arrieta#bitbucket.org/arrieta/learning-opengl
The data consists of 8,761 triplets (the vertices, in a body-fixed frame) and 17,518 triangles (each triangle is a triplet of integers referring to one of the 8,761 vertex triplets).
#include<stdio.h>
#include<stdlib.h>
#include<OpenGL/gl.h>
#include<OpenGL/glu.h>
// I added this in case you want to "copy/paste" the program into a
// non-Mac computer
#ifdef __APPLE__
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
/* I hardcoded the data and use globals. I know it sucks, but I was in
a hurry. */
#define NF 17518
#define NV 8761
unsigned int fs[3 * NF];
float vs[3 * NV];
float angle = 0.0f;
/* callback when the window changes size (copied from Internet example) */
void changeSize(int w, int h) {
if (h == 0) h = 1;
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45.0f, ratio, 0.2f, 50000.0f); /* 45 degrees fov in Y direction; 50km z-clipping*/
glMatrixMode(GL_MODELVIEW);
}
/* this renders and updates the scene (mostly copied from Internet examples) */
void renderScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 10000.0f, /* eye is looking down along the Z-direction at 10km */
0.0f, 0.0f, 0.0f, /* center at (0, 0, 0) */
0.0f, 1.0f, 0.0f); /* y direction along natural y-axis */
/* just add a simple rotation */
glRotatef(angle, 0.0f, 0.0f, 1.0f);
/* use the facets and vertices to insert triangles in the buffer */
glBegin(GL_TRIANGLES);
unsigned int counter;
for(counter=0; counter<3 * NF; ++counter) {
glVertex3fv(vs + 3 * fs[counter]); /* here is where I'm loading
the data - why do I need to
load it every time? */
}
glEnd();
angle += 0.1f; /* update the rotation angle */
glutSwapBuffers();
}
int main(int argc, char* argv[]) {
FILE *fp;
unsigned int counter;
/* load vertices */
fp = fopen("wild2.vs", "r");
counter = 0;
while(fscanf(fp, "%f", &vs[counter++]) > 0);
fclose(fp);
/* load facets */
fp = fopen("wild2.fs", "r");
counter = 0;
while(fscanf(fp, "%d", &fs[counter++]) > 0);
fclose(fp);
/* this initialization and "configuration" is mostly copied from Internet */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0, 0);
glutInitWindowSize(1024, 1024);
glutCreateWindow("Wild-2 Shape");
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 30.0 };
GLfloat light_position[] = {3000.0, 3000.0, 3000.0, 0.0 };
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
glutMainLoop();
return 0;
}
EDIT
It is starting to look better, and I have now plenty of resources to look into for the time being. It still sucks, but my questions have been answered!
I added the normals, and can switch back and forth between the "texture" and the wireframe:
PS. The repository shows the changes made as per SeedmanJ's suggestions.
It's really easy to change to a wireframe rendering in OpenGL, you'll have to use
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
and to switch back to a fill rendering,
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
About the lights, OpenGL allows you to use at most 8 different lights, generating your final rendering thanks to the normals, and materials. You can activate a lighting mode with:
glEnable(GL_LIGHTING);
and then activate each of your lights with either:
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
to change a light property like its position, please look at
http://linux.die.net/man/3/gllightfv
You'll have to set up your normals for each vertices you define, if your using the glBegin() method. In VBO rendering it's the same but normals are also contained in the vram. In the glBegin() method, you can use
glNormal3f(x, y, z); for example
for each vertex you define.
And for more information about what you can do, the redbook is a good way to begin.
Moving your "scene" is one more thing OpenGL indirectly allows you to do. As it all works with matrix,
you can either use
glTranslate3f(x, y, z);
glRotate3f(num, x, y, z);
....
Managing key events and mouse events has (i'm almost sure about that) nothing to do with OpenGL, it depends on the lib your using, for example glut/SDL/... so you'll have to refer to their own documentations.
Finaly, for more further information about some of the functions you can use, http://www.opengl.org/sdk/docs/man/, and there's also a tutorial part, leading you to different interesting websites.
Hope this helps!
How can I make a very basic "wireframe" rendering of the shape?
glPolygonMode( GL_FRONT, GL_LINE );
Suppose the Sun is along the "bottom" direction (i.e., along -Y), how can I add the light and see the shadow on the other side?
Good shadows are hard, especially with the fixed-function pipeline.
But before that you need normals to go with your vertices. You can calculate per-face normals pretty easily.
How can I add "mouse events" so that I can rotate my view by, and zoom in/out?
Try the mouse handlers I did here.
Though I some like to say "Start with something simpler", I think, sometimes you need to "dive in" to get a good understanding, on a small time span! Well done!
Also if you would like an example, please ask...
I have written a WELL DOCUMENTED, and efficient,
but readable pure Win32 (No .NET, or MFC) OpenGL FPS!
Though it appears other people answered most of you questions...
I can help you if you would like, maybe make a cool texture (if you don't have one)...
To answer this question:
glBegin(GL_TRIANGLES);
unsigned int counter;
for(counter=0; counter<3 * NF; ++counter) {
glVertex3fv(vs + 3 * fs[counter]); /* here is where I'm loading
the data - why do I need to
load it every time? */
}
glEnd();
That is rendering the vertices of the 3D Model (in the case the view has changed)
and using the DC (Device Context), BitBlt's it- onto the Window!
It has to be done repeatedly (in case something has caused the window to clear)...
In many OpenGL tutorials, e.g. swiftless tutorials and many others, whenever there is an animation in the scene and the window is resized, the speed of the animation changes.
Description of strange behaviour
when the window is small, the animation speeds upwhen the window is large the animation slows downIs there an explanation for this?
#include <GL/glew.h> // Include the GLEW header file
#include <GL/glut.h> // Include the GLUT header file
bool* keyStates = new bool[256]; // Create an array of boolean values of length 256 (0-255)
bool movingUp = false; // Whether or not we are moving up or down
float yLocation = 0.0f; // Keep track of our position on the y axis.
float yRotationAngle = 0.0f; // The angle of rotation for our object
void keyOperations (void) {
if (keyStates[GLUT_KEY_LEFT]) { // If the left arrow key has been pressed
// Perform left arrow key operations
}
}
void display (void) {
keyOperations();
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our <a title="window" href="http://www.swiftless.com/tutorials/opengl/window.html">window</a> to red
glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glTranslatef(0.0f, 0.0f, -5.0f); // Push eveything 5 units back into the scene, otherwise we won't see the primitive
glTranslatef(0.0f, yLocation, 0.0f); // Translate our object along the y axis
glRotatef(yRotationAngle, 0.0f, 1.0f, 0.0f); // Rotate our object around the y axis
glutWireCube(2.0f); // Render the primitive
glFlush(); // Flush the OpenGL buffers to the window
if (movingUp) // If we are moving up
yLocation -= 0.005f; // Move up along our yLocation
else // Otherwise
yLocation += 0.005f; // Move down along our yLocation
if (yLocation < -3.0f) // If we have gone up too far
movingUp = false; // Reverse our direction so we are moving down
else if (yLocation > 3.0f) // Else if we have gone down too far
movingUp = true; // Reverse our direction so we are moving up
yRotationAngle += 0.005f; // Increment our rotation value
if (yRotationAngle > 360.0f) // If we have rotated beyond 360 degrees (a full rotation)
yRotationAngle -= 360.0f; // Subtract 360 degrees off of our rotation
}
void reshape (int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
}
void keyPressed (unsigned char key, int x, int y) {
keyStates[key] = true; // Set the state of the current key to pressed
}
void keyUp (unsigned char key, int x, int y) {
keyStates[key] = false; // Set the state of the current key to not pressed
}
int main (int argc, char **argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode (GLUT_SINGLE); // Set up a basic display buffer (only single buffered for now)
glutInitWindowSize (500, 500); // Set the width and height of the window
glutInitWindowPosition (100, 100); // Set the position of the window
glutCreateWindow ("You’re first OpenGL Window"); // Set the title for the window
glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
glutIdleFunc(display); // Tell GLUT to use the method "display" as our idle method as well
glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping
glutKeyboardFunc(keyPressed); // Tell GLUT to use the method "keyPressed" for key presses
glutKeyboardUpFunc(keyUp); // Tell GLUT to use the method "keyUp" for key up events
glutMainLoop(); // Enter GLUT's main loop
}
The way this is written it uses an "as fast as possible" rendering approach. This, together with V-Sync disabled will make the animation speed depend on the time it takes to calculate the pixels of one frame. The larger the window, the more pixels there are to fill (look up the keyword fillrate).
The solution is, to measure the time between rendering frames and advance the animation by this.