I am trying to make a Chaos Game in c using OpenGL and for some reason I am only creating a triangle and one point right now, when I am expecting to get 60,000 points. I think that this is because of the begin and end statements being inside of a for loop, and if not, then I'm not sure what is wrong. Any help solving the problem would be appreciated!
BTW the chaos game is where you start with one point, and then choose a random point on the triangle and then place a new point halfway between the chosen point and the original point and continue, and in my case I will repeat this 60,000 times. :)
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT); //clears all pixels
int choice, i;
float x = 0.15, y = 0.85;
glColor3f (0.0, 0.0, 0.0); //this sets the drawing color to black
glBegin(GL_LINE_LOOP); //The triangle
glVertex3f(0.2, 0.2, 0.0);
glVertex3f(0.5, 0.8, 0.0);
glVertex3f(0.8, 0.2, 0.0);
glVertex3f(0.2, 0.2, 0.0);
glEnd();
glPointSize(3.0); //sets point size
glBegin(GL_POINTS); //this is the original point
glVertex3f(x, y, 0.0);
glEnd();
for(i=0; i<60,000; i++)
{
choice = (rand()%3);
switch(choice)
{
case 0:
x = (x + 0.5)/2; //this is the x1+x2/2 part of the midpoint theorem
y = (y + 0.8)/2; //this is the y1+y2/2 part of the midpoint theorem
glBegin(GL_POINTS);
glVertex3f(x, y, 0.0);
glEnd();
break;
case 1:
x = (x + 0.8)/2;
y = (y + 0.2)/2;
glBegin(GL_POINTS);
glVertex3f(x, y, 0.0);
glEnd();
break;
case 2:
x = (x + 0.2)/2;
y = (y + 0.2)/2;
glBegin(GL_POINTS);
glVertex3f(x, y, 0.0);
glEnd();
default:
break;
}
}
glFlush ();
}
void init (void)
{
glClearColor (1.0, 1.0, 1.0, 0.0); //this sets the background color to white
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition (100, 100);
glutCreateWindow(argv[0]);
init ();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Try replacing 60,000 with 60000. In C, 60,000 evaluates to 0.
For more on the comma operator, see the Wikipedia entry on it.
Related
This code almost works, but the problem is that it leaves behind the last control point like if it doesn't exist. I cannot find the error and I don't know why, I checked the transformation matrix and the converted control point many times but nothing
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include <math.h>
// Begin globals.
static int numVal = 0;
// Final control points.
static float controlPoints[4][3] =
{
{-30.0, 0.0, 0.0}, { -10.0, 20.0, 0.0},
{10.0, -20.0, 0.0}, {30.0, 0.0, 0.0}
};
//Matrix multiplication Mb^-1 * Mi
static float conversion[4][4] =
{
{1.0,0.0,0.0,0.0},{-0.8333,3.0,-1.5,0.3333},{0.3333,-1.5,3.0,-0.8333},{0.0,0.0,0.0,1.0}
};
//End globals
//Control point conversion for evaluator
void convertcp(float ctrlpoints[4][3]){
int i,j,k;
float tot = 0.0;
for(i = 0; i < 4;i++){
for(j = 0;j < 4;j++){
ctrlpoints[i][j] = 0;
for(k = 0; k < 3;k++){
ctrlpoints[i][j] += conversion[i][k] * controlPoints[k][j];
}
}
}
}
// End globals.
// Initialization routine.
void setup(void){glClearColor(1.0, 1.0, 1.0, 0.0);}
// Drawing routine.
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
int indx;
float ctrlpoints[4][3];
convertcp(ctrlpoints);
// Draw the control polygon in light gray.
glColor3f(0.7,0.7, 0.7);
glBegin(GL_LINE_STRIP);
for (indx = 0; indx < 4; indx++)
glVertex3fv(controlPoints[indx]);
glEnd();
// Specify and enable the Bezier curve.
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
// Draw the Bezier curve by defining a sample grid and evaluating on it.
glColor3f(0.0, 0.0, 0.0);
glMapGrid1f(100, 0.0, 1.0);
glEvalMesh1(GL_LINE, 0, 100);
// Draw the Bezier control points as dots.
glPointSize(5.0);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (indx = 0; indx < 4; indx++)
glVertex3fv(controlPoints[indx]);
glEnd();
// Highlight selected control point,
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POINTS);
glVertex3fv(controlPoints[numVal]);
glEnd();
glutSwapBuffers();
glutPostRedisplay();
}
// OpenGL window reshape routine.
void resize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
case ' ':
if (numVal < 3) numVal++;
else numVal = 0;
glutPostRedisplay();
break;
default:
break;
}
}
// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{
if(key == GLUT_KEY_UP) controlPoints[numVal][2] += 1.0;
if(key == GLUT_KEY_DOWN) controlPoints[numVal][2] -= 1.0;
if(key == GLUT_KEY_LEFT) controlPoints[numVal][0] -= 1.0;
if(key == GLUT_KEY_RIGHT) controlPoints[numVal][0] += 1.0;
glutPostRedisplay();
}
// Routine to output interaction instructions to the console window.
void printInteraction(void)
{
printf("Interaction:\n");
printf("Press space to select a control point.\n");
printf("Press the arrow keys to move the selected control point.\n");
}
// Main routine.
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Interpolating Curves");
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyInput);
glewExperimental = GL_TRUE;
glewInit();
setup();
glutMainLoop();
}
I have been asked to design and animate a solar system in openGL. I am doing so in C. I am a bit confused as to exactly how I should go about animating the orbits. How should I be incrementing the rotation angle for each planet to control the speed of it's orbit around the sun?
Here is all of the code I have written so far, just trying to take it step by step:
#include <GL/glut.h>
#include <GL/glu.h>
#define FACTOR 30.0
#define SLICES 25
#define STACKS 25
//Viewing angle variables
int eye_x = 2.0;
int eye_y = 3.0;
int eye_z = 10.0;
int up_x = 0.0;
int up_y = 1.0;
int up_z = 0.0;
//Planet diameters in relation to earth
double sun_radius = 100.0;
double earth_radius = 1.0;
double moon_radius = 0.2724;
double mercury_radius = 0.383;
double venus_radius = 0.949;
double mars_radius = 0.532;
double jupiter_radius = 11.21;
double saturn_radius = 9.45;
double uranus_radius = 4.01;
double neptune_radius = 3.88;
double pluto_radius = 0.187;
//Planet distances from sun in relation to earth's distance
double mercury_distance = (sun_radius / FACTOR) + 0.387;
double venus_distance = mercury_distance + 0.723;
double earth_distance = venus_distance + 1.0;
double mars_distance = earth_distance + 1.52;
double jupiter_distance = mars_distance + 5.20;
double saturn_distance = jupiter_distance + 9.58;
double uranus_distance = saturn_distance + 19.20;
double neptune_distance = uranus_distance + 30.05;
double pluto_distance = neptune_distance + 39.24;
/**
* Init function initializing the background to black.
*/
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glOrtho(-100.0, 100.0, -100.0, 100.0, -100.0, 100.0);
glMatrixMode(GL_MODELVIEW | GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
gluLookAt(eye_x, eye_y, eye_z, 0.0, 0.0, 0.0, up_x, up_y, up_z);
}
/*
void stars()
{
int noOfStars = rand() % 10;
int i = 0;
while(i < noOfStars)
{
glColor3f(1.0, 1.0, 1.0);
glPointSize(20.0f);
int x = rand() % 10;
int y = rand() % 10;
int z = -8.0;
glBegin(GL_POINTS);
glVertex3f(x, y, z);
glEnd();
i++;
}
glFlush();
glutSwapBuffers();
}
*/
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//stars();
//"Zoom out"
glTranslatef(0.0, 0.0, -20.0);
//Draw sun
glColor4f(1.0, 0.5, 0.0, 0.3);
glutWireSphere(sun_radius / FACTOR, SLICES, STACKS);
//Draw mercury
//Rotate around sun
//glRotatef(, 0.0, 1.0, 0.0);
//Distance from sun to mercury
glTranslatef(mercury_distance, 0.0, 0.0);
glPushMatrix();
//glRotatef( , 0.0, 1.0, 0.0);
glColor4f(1.0, 0.75, 0.75, 0.3);
glutWireSphere(mercury_radius, SLICES, STACKS);
glPopMatrix();
/*
//Draw venus
//Distance from sun to venus
glTranslatef(venus_distance, 0.0, 0.0);
glPushMatrix();
glColor4f(1.0, 0.75, 0.75, 0.3);
glutWireSphere(venus_radius, SLICES, STACKS);
glPopMatrix();
//Draw earth
//Distance from sun to earth
glTranslatef(earth_distance, 0.0, 0.0);
glPushMatrix();
glColor4f(1.0, 0.75, 0.75, 0.3);
glutWireSphere(earth_radius, SLICES, STACKS);
glPopMatrix();
*/
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(0,0);
glutInitWindowSize(1000, 1000);
glutCreateWindow("solar system");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
First, there is not a single distance from the sun for any of the planets - they move in a Kepler ellipse. (Earth was closest to the sun two weeks ago at the beginning of January and will be farthest away in summer.)
Accordingly, the position angle of a planet will not change at a constant rate, if you want to do this accurately. You can of course simplify and say that planetary orbits are close enough to circles for this not to matter (and say that Pluto is not a planet any more, so it even doesn't matter there).
But let's go for an exact solution: This is governed by Newton's law:
F = g * M_1 * M_2 / r^2 // How do you put equations here?
and energy conservation, trading kinetic energy E = M v^2 / 2 for potential energy E = - g * M_1 * M_2 / r
So, to simulate the motion of a planet around the sun, get its position, its velocity and the gravitational force acting upon it, calculate where you end up one time step later, calculate the new velocity and force acting on it, and repeat. (Do the same for all planets and ignore gravitational interactions between them for the moment.)
That would be an actual simulation of the solar system. If you only want to simulate the positions at any given time, look up Keplers laws - essentially a consequence of applying Newtons law.
I just saw that the article above even has a section on "Position as a function of time" - so that should help you with the algorithm.
How is the reshape() function working in this code and how is it getting its parameter from glutReshapeFunc(reshape) without any parameter in reshape of glutReshapeFunc(reshape)?
What is the value of int x, int y in void keyboard (unsigned char key, int x, int y) function?
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
static int year = 0, day = 0;
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glPushMatrix();
glutWireSphere(1.0, 20, 16); /* draw sun */
glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
glTranslatef (2.0, 0.0, 0.0);
glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
glutWireSphere(0.2, 10, 8); /* draw smaller planet */
glPopMatrix();
glutSwapBuffers();
}
void reshape (int w, int h)
{
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);
glLoadIdentity();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case `d':
day = (day + 10) % 360;
glutPostRedisplay();
break;
case `D':
day = (day - 10) % 360;
glutPostRedisplay();
break;
case `y':
year = (year + 5) % 360;
glutPostRedisplay();
break;
case `Y':
year = (year - 5) % 360;
glutPostRedisplay();
break;
default:
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
It appears that the glutReshapeFunc() function takes a pointer to a function; presumably, in fact, it is declared as something somewhat similar to:
void glutReshapeFunc(void (*function)(int x, int y));
Similarly, glutDisplayFunc() takes another pointer to a function, and glutKeyboardFunc() also takes a pointer to a function. When a function is specified by name without the function call parentheses after it, it reduces to 'pointer to a function' (or you can think of a bare function name as a pointer to the function body, like a bare array name is a pointer to the start of the array).
You'd have to read the manual to discover the purpose of the x and y parameters to the keyboard() function. They aren't used by the code shown. They are likely the position of something, but which something is less than clear without reading the manual.
reshape and keyboard functions are used as so called callbacks. You're giving GLUT pointers to those functions, GLUT keeps those pointers and calls those function, with parameters, at the times as specified in the GLUT documentation.
About like that:
void (*display_callback)(void);
void (*reshape_callback)(int, int);
void (*keyboard_callback(unsigned char, int, int);
/* ... */
void eventloop(...)
{
while(...) {
if( keyboard_event )
keyboard_callback(keyboard_event->key, mouse_x, mouse_y);
if( window_reshaped )
reshape_callback(window->width, window->height);
if( needs_redraw )
display_callback();
}
}
Now regarding what's done in the reshape callback: Everything that's placed there in beginner tutorials is actually much better done in the display function. Setting the viewport, setting the projection I mean. Later you'll probably want to draw a HUD, some text or a minimap, or a split view. And once you've reached that point, a reshape function doing viewport and projection setup becomes a liability. So get rid of it now.
void display(void)
{
int const w = glutGet(GLUT_WINDOW_WIDTH);
int const h = glutGet(GLUT_WINDOW_HEIGHT);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
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);
glLoadIdentity();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
glutWireSphere(1.0, 20, 16); /* draw sun */
glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
glTranslatef (2.0, 0.0, 0.0);
glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
glutWireSphere(0.2, 10, 8); /* draw smaller planet */
glPopMatrix();
glutSwapBuffers();
}
I hope this will be a direct answer to this question.
The reshape function is a call back function which is called whenever size or shape of the application window changes. Reshape function takes 2 arguments,they are width and height of reshaped window. Mainly these parameters are used to set a new viewport.
I've created a program to display a lined cube on a white canvas but I am unsure how to multiple that cube into lets say? 10 x 10.
Another question is how would I go about creating the same cube in a 3D space?
Here's my code:
void drawScene(void)
{
int i, j;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLoadIdentity();
glTranslatef(0.0, 0.0, -25.0);
glutWireCube(5.0); // Box.
glColor3f(1.0, 0.0, 0.0);
for(i=5; i<5; i++)
{
for (j = -5; j < 5; j++)
{
glPushMatrix();
glTranslatef(i*5, j*5, -35.0);
glColor3f(1.0, 1.0, 0);
glutSolidCube(5.0);
glColor3f(0.0, 0.0, 1.0);
glutWireCube(5.0);
glPopMatrix();
}
}
glFlush();
}
void setup(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void resize (int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-10.0, 10.0, -10.0, 10.0, 10.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void KeyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500); /* Size of the Program Window */
glutInitWindowPosition(100,100);
glutCreateWindow("Box.cpp");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(KeyInput);
glutMainLoop();
return 0;
}
The glu library has a lot of useful tidbits like gluLookAt( xfrom, yfrom, zfrom, xto, yto, zto, xup, yup, zup );
You can scale things using glScaled( factor ) / glScalef( factor )
You should poke around Google for some GL 1.X documentation.
I'm reading the sample code for the bezier curve on the online version of opengl's tutorial.
I'm curious about how is resize being handled in the example cause I figure I might use it on my own version of this program , I placed my questions on its comments:
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
glLoadIdentity();
if (w <= h) // is this calculation universal, could I use it on another program?
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
glLoadIdentity(); // why does it get a reset?
}
Full code:
#include <stdlib.h>
#include <GL/glut.h>
GLfloat ctrlpoints[4][3] = {
{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},
{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
}
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
/* The following code displays the control points as dots. */
glPointSize(5.0);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
glVertex3fv(&ctrlpoints[i][0]);
glEnd();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h); // what's GLsizei? Why is it called inside glViewPort?
glMatrixMode(GL_PROJECTION); // is it necessary to reset the projection matrix?
glLoadIdentity();
if (w <= h) // is this calculation universal, could I use it on another program?
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0*(GLfloat)w/(GLfloat)h,
5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW); // why do I set to GL_MODELVIEW at the end?
glLoadIdentity(); // why does it get a reset?
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape); // el reshape funciona correctamente
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
GLsizei is a type, not a function. Therefore, it's not being called; its being casted; it's converting an int into a GLsizei. It's basically an int, but it makes it clear that you're using it for a size (I think). (I'm a Python programmer, so this is a guess)
glMatrixMode(...);
This does not reset the matrix, unless it is followed by a glLoadIdentity() call. Instead, it sets the current target of OpenGL's matrix operations to the matrix specified. This way, OpenGL knows what matrix you're trying to affect.
I've seen that calcuation before in the OpenGL superbible (or at least something like it); why don't you talk yourself through it and see what it's deciding and why? (Hint (I think): it's trying to keep the viewport square to avoid stretching)
At the end, it sets it back to GL_MODELVIEW since that matrix handles transformations, like translation and rotation, which are used to position vertices onscreen. It should be reset every frame so that your code can assume that the coordinate plane is currently at (0,0); that simplifies calculations about where to translate to.
Also note that reshape is not called by OpenGL, but by GLUT. OpenGL is platform-independent and does not handle windowing; this is why you need GLUT.
If you're new to OpenGL, you should work through it from the beginning - later tutorials will assume this sort of knowledge.