Hello,
I am new to open GL and I am trying to rubber band a circle, it somewhat works, when I click a circle is made and it will make a larger and smaller circle, but with no user control at all. I saw an example to do it with a square and I have been trying to reformat that code for a circle. The functions in question are
void mouse()
and
void move();
. And on a final note would there be an easy way to call these two processes in the 3rd option of the menu I have created?
Thank you
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
#include <GL/freeglut.h>
#include <math.h>
#include <time.h>
int first = 0; /* vertex the counter */
float finalX, finalY, radius, radiusS;
float globalx;
float globaly;
//int displayMode;
const float DEG2RAD=3.14159/180;
//Returns and x position
float xCon(float x)
{
float xNew;
xNew=(float)x/(500.0/2.0);
xNew=xNew-1.0;
return xNew;
}
//Returns a Y position
float yCon(float y)
{
float yNew;
yNew=(float)y/(500.0/2.0);
yNew=yNew-1.0;
yNew=-yNew;
return yNew;
}
void display(void)
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glutSwapBuffers ( );
}
//Provided code to draw a circle
void drawCircle(float x,float y, float radius)
{
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 360; i++)
{
float degInRad = i * DEG2RAD;
glVertex2f(x+cos(degInRad)*radius, y+sin(degInRad)*radius);
}
glEnd();
glFlush();
}
//RUBBER BAND/////
//Left click for rubber banding, finds the default position and draw a circle
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
x = x/500.;
y = (500-y)/500.;
double x0 = (finalX-x)*(finalX-x);
double y0 = (finalY-y)*(finalY-y);
radius = sqrt (x0 + y0);
drawCircle(x,y, radius);
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
first = 0;
}
//Updates the position so the user can drag the circle to enlarge or shrink it
if(btn==GLUT_LEFT_BUTTON && state == GLUT_UP)
{
drawCircle(finalX,finalY, radius);
glutSwapBuffers ( );
glLogicOp(GL_COPY);
finalX = x/500.0;
finalY = (500-y)/500.0;
double x0 = (finalX-x)*(finalX-x);
double y0 = (finalY-y)*(finalY-y);
radius = sqrt (x0 + y0);
glLogicOp(GL_COPY);
drawCircle(finalX,finalY,radius) ;
glutSwapBuffers ( );
}}
//This takes care of the actual movement of the circle, it writes to two buffers to make the animation smooth
void move(int x, int y)
{
if( first == 1)
{
drawCircle(x,y,radius) ;
glutSwapBuffers ( );
}
x = x/500.0;
y = (500-y)/500.0;
//finalX = x/500.0;
//finalY = (500-y)/500.0;
double x0 = (finalX-x)*(finalX-x);
double y0 = (finalY-y)*(finalY-y);
radiusS = sqrt (x0 + y0);
drawCircle(finalX,finalY,radiusS) ;
glutSwapBuffers ( );
first = 1;
}
//Initilizes a red square at the mouse pointer
void Square(int x, int y)
{
globalx=xCon((float)x);
globaly=yCon((float)y);
glColor3f(1.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(globalx-0.08,globaly-0.08);
glVertex2f(globalx-0.08,globaly+0.08);
glVertex2f(globalx+0.08,globaly+0.08);
glVertex2f(globalx+0.08,globaly-0.08);
glEnd();
glutSwapBuffers ( );
}
//Initilizes a yellow square at the mouse pointer
void drawYellowSquare(int x, int y)
{
globalx=xCon((float)x);
globaly=yCon((float)y);
glColor3f(1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(globalx-0.08,globaly-0.08);
glVertex2f(globalx-0.08,globaly+0.08);
glVertex2f(globalx+0.08,globaly+0.08);
glVertex2f(globalx+0.08,globaly-0.08);
glEnd();
glutSwapBuffers ( );
}
void mouseSquare(int button, int state, int x, int y)
{
//When the left button is held down the red square is drawn
if (button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
globalx=xCon(x);
globaly=yCon(y);
glutMotionFunc(Square);
//glColor3f(1.0,0.0,0.0);
glutSwapBuffers ( );
}
//When the right button is held down the yellow square is drawn
globalx=xCon(x);
globaly=yCon(y);
glutPassiveMotionFunc(drawYellowSquare);
//glColor3f(1.0,1.0,0.0);
glutSwapBuffers ( );
}
//Press Escape to exit program
void keyboard(unsigned char key, int x, int y)
{
if (key == VK_ESCAPE)
exit(0);
}
//Menu to activate the 3 parts of the project
void mymenu(int id)
{
switch(id)
{
case 1:
glutMouseFunc(mouseSquare);
//glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers ( );
glEnd();
break;
case 2:
//Attempts to translate a circle to the top right of the screen
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-1.0f,-1.0f,0);
drawCircle(0,0,.2);
glEnd();
glTranslatef(1.0f,1.0f,0.0f);
drawCircle(0,0,.2);
glFlush();
glEnd();
glutPostRedisplay();
glutSwapBuffers ( );
break;
case 3:
break; }
}
int main(int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("Assignment 1");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(move);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
//Menu to select parts of the project
static int menu;
menu=glutCreateMenu(mymenu);
glutAddMenuEntry("Square",1);
glutAddMenuEntry("Circle",2);
glutAddMenuEntry("Rubberbanding",3);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}