![]() |
are you ready for a mindfuck? |
|
....::::Menu::::.... ---------------------------...::About::... ...::Articles::... ...::Contact::... ...::Home & News::... ...::Links & Credits::... --------------------------- --------------------------- |
Hello Worldby Elie De BrauwerGoal of this fileIn this article the elementary basics will be covered, clearing a window to a certain color, drawing a rectangle and we will look at handling changes of the window. History of this file
Drawing a rectangleClearing
Now what we will do now is create a program, that opens a window, clears the windows to a black color and draws a white rectangle
in it. DrawingWe draw the rectangle by calling the glRectf() (or glRecti, or glRectd or glRects).This function call takes 4 parameters (x1,y1, x2,y2) but what are the coordinates on the screen ? Simple, we call glOrtho() (6 parameters, the dimensions of the screen, the first two are the minimum and maximum x or horizontal values, the next two are the min and max y or vertical values and the last two are the min and max viewable z coordinates). Calling glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0) would make our window accessible by x coordinates in the range 0...1 and y coordinates in the range 0...1. We don't mind the z coordinates since we are only getting started and we are only working in 2 dimensions. Another option for 2D programs is usign gluOrtho2D. This is basicly the same as glOrtho except that it takes only 4 parameters and keeps de z coordinates fixed to -1.0 and 1.0. Handling a window resizeSince each project is different I will start by offering you three possible methods of handling a reshape. Each has its advantages and it's disadvantages. reshape
void reshape(int x,int y){
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,100,0,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Let's follow the steps the code takes, first we change the viewable area on the screen to the dimensions of the window (with glViewport), next we say we need to alter the projection matrix (with glMatrixMode we select another matrix, the fact that multiple transformation matrices exist will become clear later). We load the identity matrix, the current matrix and we paste our coordinates on top of the window, lower left corner we give coordinates 0,0 and upper left we give coordinates 100,100. This is the simplest reshape function but when a resize occurs the odds are very high that the image will be taken out of perspective, see image below:
The glViewport() function takes 4 parameters, the last two define the size of the rectangle that can be used to draw in and the first two parameters define the lower left corner of that rectangle. reshape1
void reshape1(int x,int y){
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,x,0,y);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
When we use this reshape function we can be certain of 2 things. a) the image will in pixel size will always be the same and b) it will never be taken out of proportion, this is because we by mapping its own sizes to the window we achieve that a point with coordinates (a,b) will be exactly a pixels away from the lower left corner (horizontal) en b pixels away from the lower left corner (vertical). But image a 1000 by 1000 pixels square on a monitor that does 1600x1200 and one one that does 640x480.
reshape2
void reshape2(int x,int y){
if(x<y)
glViewport(0,(y-x)/2,x,x);
else
glViewport((x-y)/2,0,y,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,100,0,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
The third solution uses the biggest possible square that can be used in the window and uses that as working area, since there are no square screen this means a waste of space but on the other hand, images are scaled, and not taken out of proportion. Currently this solution will do fine for our next steps into OpenGL and this reshape function will be used in the next articles.
The programYou can change the reshape functions by using the keys 1, 2 and 3, you can change the background color between green and black by using the g and b keys and quit by pressing q.
#include <iostream>
#include <cstdlib> // for exit()
#include <GL/glut.h> // also includes GL/gl.h and GL/glu.h
using namespace std;
typedef unsigned char uchar;
// callback prototypes
void disp(void);
void reshape(int x, int y);
void reshape1(int x, int y);
void reshape2(int x, int y);
void keyb(uchar key, int x, int y);
////////////////////////////////
// main
int main(int argc, char **argv){
glutInit(&argc, argv);
// no double buffering since we don't need no animations
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutInitWindowSize(400,400);
glutCreateWindow("hello world");
// clear to black
glClearColor(0.0,0.0,0.0,0.0);
glutDisplayFunc(disp);
glutKeyboardFunc(keyb);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
////////////////
// disp
void disp(void){
glClear(GL_COLOR_BUFFER_BIT);
// draw a white rectangle (only 3 parameters, no alpha)
glColor3d(1.0,1.0,1.0);
glRectf(25,25,75,75);
// update the screen, not needed when using double
// buffering and glutSwapBuffers()
glFlush();
}
//////////////////////////
// reshape
void reshape(int x,int y){
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,100,0,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* this reshape maps the coordinates of the screen to [0,100] and [0,100] this can
take everything out of proportion when resized
*/
}
///////////////////////////
// reshape1
void reshape1(int x,int y){
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,x,0,y);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* this won't take anything out of proportion but it won't scale the image either
the height and width of the window in pixels determine the size of the square
*/
}
//////////////////////////
// reshape2
void reshape2(int x,int y){
if(x<y)
glViewport(0,(y-x)/2,x,x);
else
glViewport((x-y)/2,0,y,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,100,0,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* this will scale the image but keep the area available to OpenGL for drawing a square
so nothing will be taken out of proportion, not the entire window is accesible.
*/
}
///////////////////////////////////
// keyb
void keyb(uchar key, int x, int y){
switch(key){
case '1':
glutReshapeFunc(reshape);
cout << "Selected reshape " << endl;
glutPostRedisplay();
break;
case '2':
glutReshapeFunc(reshape1);
cout << "Selected reshape1" << endl;
glutPostRedisplay();
break;
case '3':
glutReshapeFunc(reshape2);
cout << "Selected reshape2" << endl;
glutPostRedisplay();
break;
case 'g':
glClearColor(0.0,1.0,0.0,0.0);
cout << "Will now clear to green" << endl;
glutPostRedisplay();
break;
case 'b':
glClearColor(0.0,0.0,0.0,0.0);
cout << "Will now clear to black" << endl;
glutPostRedisplay();
break;
case 'q':
exit(0);
break;
}
}
Or download the source code.
|