Tuesday, April 17, 2007


It is very common, to want to have a program which can open other little windows.

How can we create little windows that are called by another window?

Maybe, these little windows could be called by a special event, perhaps a mouse event>

void mouse(int button, int state, int x, int y){//controla mouse de la window principal
switch( button ){
case GLUT_RIGHT_BUTTON:
if( state == GLUT_DOWN ){
subWindows=glutCreateWindow( "coordenadas" );
glutDisplayFunc( renderScene);
//glutIdleFunc(renderScene);
glutMouseFunc(raton);


// if(GLUT_VISIBLE) glutIdleFunc(NULL);



}
break;

}

In this function, we are going to be creating another little window, that shall show the spienski fractal. This window will be created when we right click our first window.
subWindows=glutCreateWindow( "coordenadas" ); subWindows is a int identifier that can help us, for example when we wish to destroy the window.
We are also especifiy what functions to call when it is isrt displayed, when it is wating to recieve a comand from the mouse (idle situation) and we are also telling the window to what function relate the mouse to. Doing this, we can decide what happens when the user right clicks being in this window. In this case, we shall open an animation of another triangle.( Not of a robot, cuz our little robot friend was made with windows api, and ahhh we're using glut right now..and it gets really complicated..)

Notice that the idle function is not speciphid right now for this function, it isn't necesary to have this function actived since this window can pretty much stay with the same state as it had with it's display function. tHhis idle function is very important, when we have an animation, for example for the triangle one, and for the first window that prints the mouse coordinates.
We must define for each window animation what idle function should be called, notice that the main window has one, and that the triangle animation has another. We also tell the window to stop is idle functiton when it isn't visible, since it would just be a waste of energy to be moving around without really having anyone that pays attention to you.. it also better o tell which function has it's idle related to it, so you don't et taht while one window is running suddenly the others take uo this idle also.
This is done with the following fucntion>
glutSetWindow(subWindow3);

Anyway...here is the code>
#include
#include "./glut.h"
#include
#include
#include
#include "myDefs.h"
#include //por using sprintf, convers int to a string

void raton2(int button, int state, int x, int y);
void subTriangle(int n, float x1, float y1, float x2, float y2, float x3, float y3);

float angleT=0;//for moing the riangle animation
float angle=0.0,deltaAngle = 0.0,ratio;
int mainWindows=0,subWindow=0,subWindow3=0,subWindow1=0,subWindows=0;
int depth = 7;
float x=0.0f,y=1.75f,z=30.0f;
float Xm,Ym;
float lx=0.0f,ly=0.0f,lz=-1.0f;
int deltaMove = 0;
sPoint mida;
sPoint midc,midb,a,b,c;
float scaling=1;
int font=(int)GLUT_STROKE_ROMAN;
int counter=0;
int delta=1;
bool IsDragging = false;
int red=0,blue=1,green=1;
void myTimer(int value);
void drawSierpinski(float x1, float y1, float x2, float y2, float x3, float y3);

void raton(int button, int state, int x, int y);

void renderScene3(void) {

glutSetWindow(subWindow3);
// notice that we're now clearing the depth buffer
// as well this is required, otherwise the depth buffer
// gets filled and nothing gets rendered.
// Try it out, remove the depth buffer part.
glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);

// save the previous settings, in this case save
// we're refering to the camera settings.
glPushMatrix();
angleT++;// finally increase the angle for the next frame

// Perform a rotation around the y axis (0,1,0)
// by the amount of degrees defined in the variable angle
glRotatef(angleT, 0.0,1.0,0.0);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();

// discard the modelling transformations
// after this the matrix will have only the camera settings.


// swapping the buffers causes the rendering above to be
// shown

glPopMatrix();
glutSwapBuffers();



}
void drawLines(float x,float y, float z)
{
int ranx=rand()%1;
int rany=rand()%1;
int ranz=rand()%1;
if(red=0)red=1;
glTranslatef(x,y,z);
glBegin(GL_LINES);

glColor3f(1,rany,ranz);



glVertex3f(109.0, 104.0, 2.0);
glVertex3f(-6.0, -24.0, 3.3);
glEnd();
counter=0;

}

void changeSize(int w, int h)
{

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;

ratio = 1.0f * w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set the viewport to be the entire window
glViewport(0, 0, w, h);

// Set the clipping volume
gluPerspective(45,ratio,1,10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);


}



void initScene() {

glEnable(GL_DEPTH_TEST);
glLineWidth(4.0);
glutTimerFunc(1000,myTimer,1);
a.x=0;
a.y=0;
b.x=2.5;
b.y=4.3;
c.x=5;
c.y=0;


mida.x=(b.x-a.x)/2;
mida.y=(b.y-a.y)/2;//bottom left

midb.x=(c.x-a.x)/2;
midb.y=(c.y-a.y)/2;

midc.x=c.x-((c.x-b.x)/2);
midc.y=(b.y-a.y)/2; //bottom right


}

void myTimer(int value){



counter=counter+delta;

glutPostRedisplay();

glutTimerFunc( 1000,myTimer, 1);

}


void orientMe(float ang) {


lx = sin(ang);
lz = -cos(ang);
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}


void moveMeFlat(int i) {
x = x + i*(lx)*0.1;
z = z + i*(lz)*0.1;
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}


void renderStrokeCharacter(float x, float y, float z, void *font,char *string)
{

char *c;
glPushMatrix();
glTranslatef(x, y, z);
glScalef(scaling,scaling,0);
for (c=string; *c != '\0'; c++) {
glutStrokeCharacter(font, *c);
}
glPopMatrix();
}

void renderScene(void) {

/*if (deltaMove)
moveMeFlat(deltaMove);
if (deltaAngle) {
angle += deltaAngle;
orientMe(angle);
}*/

glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);


char result[100];

sprintf( result, "%f", Xm );
/*if(counter==5)
{
// randomize();
int x1=rand()%99;
int y1=rand()%99;
drawLines(x1,y1,0);
counter=0;

}*/



drawSierpinski(b.x,b.y,a.x,a.y,c.x,c.y);

glPopMatrix();
//glFlush();

glutSwapBuffers();




}

void renderSceneCoor(void) {

/*if (deltaMove)
moveMeFlat(deltaMove);
if (deltaAngle) {
angle += deltaAngle;
orientMe(angle);
}*/
glutSetWindow(mainWindows);

glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);

glPushMatrix();
char result[100];
char result2[100];

sprintf( result, "%f", Xm );
sprintf( result, "%f", Ym );


renderStrokeCharacter(-600,150,-800,(void *)font,"x");
renderStrokeCharacter(-400,150,-800,(void *)font,result);
renderStrokeCharacter(-600,-60,-800,(void *)font,"y");

renderStrokeCharacter(-400,-60,-800,(void *)font,result2);

drawSierpinski(b.x ,b.y,a.x,a.y,c.x,c.y);


glPopMatrix();
//glFlush();


glutSwapBuffers();




}






void pressKey(int key, int x, int y) {

switch (key) {
case GLUT_KEY_LEFT : scaling=2; deltaAngle = - 0.01f;break;
case GLUT_KEY_RIGHT : scaling=2; deltaAngle = 0.01f;break;
case GLUT_KEY_UP : deltaMove = 1;break;
case GLUT_KEY_DOWN : deltaMove = -1;break;
}
}

void releaseKey(int key, int x, int y) {

switch (key) {
case GLUT_KEY_LEFT :
case GLUT_KEY_RIGHT : deltaAngle = 0.0f;break;
case GLUT_KEY_UP :
case GLUT_KEY_DOWN : deltaMove = 0;break;
}
}

void processMenuEvents(int option) {

font = option;
}


/*void createMenus() {
int menu = glutCreateMenu(processMenuEvents);

glutAddMenuEntry("Roman",(int)GLUT_STROKE_ROMAN);

glutAddMenuEntry("Mono Roman",(int)GLUT_STROKE_MONO_ROMAN);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}*/
void mouse(int button, int state, int x, int y){//controla mouse de la window principal
switch( button ){
case GLUT_RIGHT_BUTTON:
if( state == GLUT_DOWN ){
subWindows=glutCreateWindow( "coordenadas" );
glutDisplayFunc( renderScene);
//glutIdleFunc(renderScene);
glutMouseFunc(raton);


// if(GLUT_VISIBLE) glutIdleFunc(NULL);



}
break;

}



}// end mouse


void raton(int button, int state, int x, int y){//mueve mouse fur 2 fenster
switch( button ){
case GLUT_RIGHT_BUTTON:
if( state == GLUT_DOWN ){

subWindow3=glutCreateWindow( "robot" );
glutDisplayFunc( renderScene3 );
//glutIdleFunc(renderScene3);

glutMouseFunc(raton2);

if (GLUT_VISIBLE)
glutIdleFunc(renderScene3);
else
glutIdleFunc(NULL);




//glutMotionFunc( mouseDragg );

}
break;
case GLUT_LEFT_BUTTON:
if(state==GLUT_DOWN){
//glutDestroyWindow(subWindows);
}
break;

}
}
void raton2(int button, int state, int x, int y){//mueve mouse fur 2 fenster
switch( button ){
case GLUT_RIGHT_BUTTON:
if( state == GLUT_DOWN ){
glutDestroyWindow(subWindow3);




}
break;

}



}// end raton2, ventana2


void drawSierpinski(float x1, float y1, float x2, float y2, float x3, float y3)
{
//Draw the 3 sides of the triangle as black lines

glBegin(GL_TRIANGLES);

glColor3f( 1.0, 1.0, 0.0 );




glVertex2d( x1,y1);//top
glVertex2d( x2,y2);//bottom left
glVertex2d(x3,y3); //bott
glEnd();


//Call the recursive function that'll draw all the rest. The 3 corners of it are always the centers of sides, so they're averages
subTriangle
(
1, //This represents the first recursion
(x1 + x2) / 2, //x coordinate of first corner
(y1 + y2) / 2, //y coordinate of first corner
(x1 + x3) / 2, //x coordinate of second corner
(y1 + y3) / 2, //y coordinate of second corner
(x2 + x3) / 2, //x coordinate of third corner
(y2 + y3) / 2 //y coordinate of third corner

);
}

//The recursive function that'll draw all the upside down triangles
void subTriangle(int n, float x1, float y1, float x2, float y2, float x3, float y3)
{
//Draw the 3 sides as black lines

glBegin(GL_TRIANGLES);

glColor3f( 1.0, 0.0, 0.0 );
glVertex2d(x1,y1);//top
glVertex2d( x2,y2);//bottom left
glVertex2d(x3,y3); //bott
glEnd();

//Calls itself 3 times with new corners, but only if the current number of recursions is smaller than the maximum depth
if(n < xm="x;" ym="y;" isdragging =" true;" realy =" viewport[3]" x =" wx;" y =" wy;" key ="=" mainwindows="glutCreateWindow(">

No comments: