Sunday, June 12, 2005

glPushAttrib, glPopAttrib

glPushAttrib() cannot be called inside a the glBegin() and glEnd() pair.

This is a sample
// Draw the lines
glPushMatrix();
glPushAttrib(GL_CURRENT_BIT ); // Push the current attributes bit
glBegin(GL_LINES);
glColor3f(.5,.5,.5); // Grey color
glVertex3f(-nRange, 0, 0); // x-axis
glVertex3f(nRange, 0, 0);
glVertex3f(0, -nRange, 0); // y-axis
glVertex3f(0, nRange, 0);
glEnd();
glPopAttrib();
glPopMatrix();

glRotatef Commands

glRotatef rotates the angle counter-clockwise. (Same as how we would draw an angle on a Cartesian plane).

Tuesday, May 03, 2005

Order of Transform

OpenGL does a post-order transform. THis means that if you specify something like
 glRotatef(45, 0, 0, 1);
glTranslatef(20,0,0);

glBegin(GL_QUADS);

glVertex3f(-60,0,-10);
glVertex3f(60,0,-10);
glVertex3f(60,60,-10);
glVertex3f(-60,60,-10);
//glVertex3f(-10,0,0);

glEnd();
The Quads will be translated and then followed by rotation.

The following code
 glTranslatef(20,0,0);
glRotatef(45, 0, 0, 1);

glBegin(GL_QUADS);

glVertex3f(-60,0,-10);
glVertex3f(60,0,-10);
glVertex3f(60,60,-10);
glVertex3f(-60,60,-10);

glEnd();

glPopMatrix();
would result in the Quad being rotated first before being translated.

Tuesday, February 08, 2005

Rendering Font in GLUT - 1

There are two ways to display text in GLUT. The first is using bitmap fonts -- unscalable and doesn’t response to modelview transform. My preferred way is stroke fonts -- fonts that are drawn from OpenGL primitives.

(i) To insert fonts in GLUT (see here for documentation)

void glutStrokeCharacter(void *font, int character);
font:
This method can handle two types of font (first argument), namely
GLUT_STROKE_ROMAN
GLUT_STROKE_MONO_ROMAN
The MONO version is a fixed-width font (like Courier New, etc)

character:

Takes in any ASCII character from 32 through 127

(ii) To get the measurement of its length

int glutStrokeLength(void *font, const unsigned char *string);

This method returns the width in units from the unscaled modeling units


This is how to use them:
(1) Define a string generator function
This function serves to render the string being passed to it.

void renderStrokeString( void *font, const string& str )
{
for (int i = 0; i < str.length(); i++)
glutStrokeCharacter(font, str[i]);
}
(2) Set up position / scaling / rotation, etc

string str = "12";
float strLength = glutStrokeLength(GLUT_STROKE_ROMAN, (const unsigned char*)str.c_str() );
float strScale = 0.3;

glPushMatrix();
glLineWidth(2.0);
glTranslatef( -strLength * strScale / 2, 0.0, 0.0 );
glScalef(strScale, strScale, strScale);
glColor3ub(255, 0, 0);
renderStrokeString( GLUT_STROKE_ROMAN, str );
glPopMatrix();

That’s it!

Monday, February 07, 2005

Anti-Aliasing

To enable Anti-Aliasing:

(1) Enable blending
glEnable(GL_BLEND);

(2) Set the blending function to be GL_ONE_MINUS_SRC_ALPHA
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

(3) Set the blend equation to GL_FUNC_ADD
glBlendEquation(GL_FUNC_ADD);

(4) Call the antialis functions
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);




Steps to Write a Simple OpenGL Program - 2

RenderScene function is called whenever our drawing scene is to be drawn or updated.

The code for RenderScene()

// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color

glClear(GL_COLOR_BUFFER_BIT);

// Enable smooth shading

glShadeModel(GL_SMOOTH);

// Draw the triangle

glBegin(GL_TRIANGLES);

// Red Apex
glColor3ub(255, 0, 0);
glVertex3f(0.0f,200.0f,0.0f);

// Green on the right bottom
corner

glColor3ub(0,255,0);
glVertex3f(200.0f,-70.0f,0.0f);

// Blue on the left bottom corner
glColor3ub(0,0,255);
glVertex3f(-200.0f, -70.0f, 0.0f);

glEnd();

// Flush drawing commands
glutSwapBuffers();
}

Explanation:

(1) The glClear(GL_COLOR_BUFFER_BIT) will clear the color buffer with the color specified with the call to glClearColor(), e.g. glClearColor(0.0, 0.0, 0.0, 1.0) . The color buffer is screen pixel value, clearing it will replace all pixels by the spefied color.

(2) glShadeModel(GL_SMOOTH) determines the shadding model for the objects drawn. A flat shadding model (GL_FLAT) means the polygons, triangles and other shapes take on a single solid color. Whereas a smooth shadding model (GL_SMOOTH) will interpolate the different colors from the RGB color cube from one vertex to the other.

(3) All rendering of primitives are done within the glBegin(GL_TRIANGLES) and glEnd() block. The glBegin() call signals that all the subsequent functions are to used to render an object. The argument of glBegin() tells OpenGL how to interprete the individual vertex. In our case, we are drawing a triangle and 3 vertice will be group as a triangle.

(4) glColor3ub() takes in 3 unsigned byte (8 bit - max value of 255) of Red, Green and Blue component and assign it to the vertex following it.

(5) glVertex3f() sets the vertex in 3D space, x, y, z respectively.

(6) glutSwapBuffers() will set the display to the current buffer and switch the drawing buffer.


Tuesday, February 01, 2005

Steps to Write a Simple OpenGL Program - 1

1) Include the neccessary header files

2) The code

In main(int argc, char* argv[] )

i) [Optional] Call glutInit(&argc, argv)
To initialize the glut with program options arguments.

ii) Call glutInitDisplayMode(GLUT_DOUBLE GLUT_RGB GLUT_DEPTH)
Input arguments are ORed together.

iii) [Optional] Call glutInitWindowSize(800,600)
Create a window of that particular size.

iv) Call glutCreateWindow("Name of Window")
Crates an OpenGL-enabled Window.

v) Call glutReshapeFunc(ChangeSize)
Sets the window reshape event for the current window


  • What the reshape function handler does is to ensure that we’re working with square pixels. If we don’t ensure that, when our window changes size, it will still have the same “dimensions”, meaning our objects will be oblongated or squeezed.
  • Whenever a reshape occurs, the function being passed to the glutReshapeFunc will be called.

  • The function should have the signature of void function(int x, int y)

  • x - new width

  • y - new height of the window


vi) Call glutDisplayFunc(RenderScene)
Tells GLUT which function to call whenever the windows contents must be drawn.
Occurs when the GLUT window is resized, uncovered, asked to redraw with call to glutPostRedisplay.

Takes in a function of type void redrawFunction(void)

vii) Call our own initialize function - e.g. SetupRC()
SetupRC() is for initializing the background color, etc.

viii) Call glutMainLoop()
Begins the GLUT main event-handling loop. This function does not return until program terminates.



Drawing Color - glColor

The glColor function sets the curent color that is used for all vertices drawn after the command.

A point
A point has only one vertex -- any color we indicate for that vertex will be the color of that point.

A line
A line has two vertices (each can have different color). Color of the line depends on the shading model. (Smooth transition from one color to the next)


Setting up GLUT - 2

glutReshapeFunc(ChangeSize)

void ChangeSize(int w, int h)
{
GLfloat windowHeight,windowWidth;
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;
// Set the viewport to be the entire window

glViewport(0, 0, w, h);

// Reset the coordinate system before modifying

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Keep the square square.
// Window is higher than wide

if (w <= h)
{ windowHeight = 250.0f*h/w;
windowWidth = 250.0f;
}
// Window is wider than high
else
{ windowWidth = 250.0f*w/h;
windowHeight = 250.0f;
}
// Set the clipping volume

glOrtho(-windowWidth, windowWidth, -windowHeight, windowHeight, 1.0f, -1.0f);
// All future transformation will affect our models (what we draw)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity();
}


Explanation
1) We check to see if h == 0, if it is, we make it 1

2) We call void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
x - The number of pixels from the left side of the window to start the viewport
y - The number of pixels from the bottom side of hte window to star tthe viewport

This function sets the portion of a window that can be drawn in by openGL (clipping window)
In our case here, we want the entire window to be drawable by openGL, so we supply glViewPort(0, 0, w, h)

3) Reset the viewing volume - call glLoadIdentity()
A call to glLoadIdentity() is needed because the glOrtho function (which is used to set the clipping volume of our drawing window is accumulative, meaning it will be influenced by any previous settings to the clipping volume). [ToDo: How is it accumulative?]



Sunday, January 30, 2005

Projection Matrix

Projection Matrix

Specifies the size and shape of our viewing volume. We use glOrtho, to set an orthographic projection (no perspective, left, right, far, near are all equal in logical width).

Perspective Projections

Use the function gluPerspective() to change hte viewing perspective.




Matrice

Identity Matrix

Each call to transformation functions are cummulative. Each time those functions are called, the appropriate matrix is constructed and multipled by the current modelview matrix. The new matrix then becomes the current modelview matrix, which is then multiplied by the next transformation, and so on.

In order to reset the coordinate system back to the center of origin of the eye coordinate system -- we load the modelview matrix wit hteh identity matrix. Identity matrix specifies that no transformation is to occur -- all cooridnates we specify when drawing are eye coordinates.

Loading the identity matrix means that no transformations are performed on the vertices. This is how you do it:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

First line specifies that the current operating matrix is the modelview matrix. After the current operating matrix is sent, it remains active until you change it. Second line loads the current matrix (modelview matrix in this case) with the identity matrix.

Saturday, January 29, 2005

Transformation

Eye Coordinates
Eye coordinates are from your viewpoint, regardless of any transformation. It is the absolute screen coordinates. It represents a virtual fixed coordiante system that is used as a common frame of reference. In the abscence of any transformation, the observer (us) will look towards the -z (perpendicular to the monitor).

Modelview Transformation
glMatrixMode(GL_MODELVIEW);
The Modelview transformation allows us to translate, rotate and scale our objects. The coordinates of the modelview transformation (using functions such as glTranslate, glRotatef, glScalef) are in reference to the Projection matrix (GL_PROJECTION)

The modelview transformationBy default the point of observation in a perspective projection is at the origin (0, 0, 0) looking down toward the negative z-axis (“into the monitor”). The modelview transformation allows us to place our objects, rotate and scale them. New transformations are performed with respect to the last transformation.

Projection Transformation
glMatrixMode(GL_PROJECTION);
This projection defines the viewing volumne and establishes clipping planes. Clipping planes are plane equations in 3D space that openGL uses to determine whether geometry can be seen by the viewer.

There are two types of projections: orthographic (using glOrtho) and perspective (using gluPerspective) .

Orthograhpic
All the polygons are drawn onscreen with exactly the relative dimensions specified. No matter how far they are, lines and polygons are mapped directly to the 2D screen using parallel lines.

Perspective
Shows scenes more as they appear in real life. It makes distant objects appear smaller than nearby objects of the same size. (Using railroad tracks for example, they are parallel using orthographic projection but converges to a point using perspective.)

Viewport Transformation
This is the final transformation that maps all the 3D objects to 2D screen pixels.

You use the function glViewport to do that transformation.