OpenGL - Highlighting squares - c++

I'm making a 2D drawing canvas in OpenGL that allows you to draw shapes on the drawing canvas by simply selecting which shape you want to draw.
I have created the entire interface for the 2D drawing canvas and also added in a mouse function that reads a screen size of 1000x800 that works perfectly fine also, however with some squares that I have drawn out, I want to be able to change the colour of them depending on which is click (Highlighting them basically).
Here's my drawSquare function that draws the 4 points to make a square:
void drawSquare(GLfloat length, GLfloat x, GLfloat y, GLfloat outline)
{
// x1,y1 is the top left-hand corner coordinate
// and so on...
GLfloat x1, y1, x2, y2, x3, y3, x4, y4;
x1 = x - length / 2;
y1 = y + length / 2;
x2 = x + length / 2;
y2 = y + length / 2;
x3 = x + length / 2;
y3 = y - length / 2;
x4 = x - length / 2;
y4 = y - length / 2;
// ACTUAL SQUARE OBJECT
glColor3f(0.0, 1.0, 1.0); // Colour: Cyan
glBegin(GL_POLYGON);
glVertex2f(x1, y1); // vertex for BLUE SQUARES
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
if (outline == true)
{
// SQUARE OUTLINE
glColor3f(0.0, 0.0, 0.0); // Colour: Black
glBegin(GL_LINE_LOOP);
glLineWidth(2);
glVertex2f(x1, y1); // vertex for OUTLINE
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
}
glFlush();
}
And to draw it, I simply call the function in my display() function using drawSquare(100, 50, 350,true);.
But if I want to be able to highlight each square when clicked, how would I do this?

Related

how can I add collision to my object and around the screen in my program?

I am trying to create a car game with along with obstacles. I want to add collision so every time my object hits one of the obstacles, obstacle changes color and we know there has been a collision. I also want there to be a collision around my screen so that my object can not leave the view port?
--void 'draw car' is my movable object
#include "include\freeglut.h" // OpenGL toolkit - in the local shared folder
#include <cmath>
#include <iostream>
//set up some constants
#define X_CENTRE 0.0 /* centre point of square */
#define Y_CENTRE 0.0
#define LENGTH 5.0 /* lengths of sides of square */
//forward declaration - best in the header
void drawStar(GLfloat radius, GLfloat x, GLfloat y);
void drawSquare(GLfloat length, GLfloat x, GLfloat y);
void drawRect(GLfloat lengthX, GLfloat lengthY, GLfloat x, GLfloat y);
void drawCar(GLfloat length, GLfloat x, GLfloat y);
GLfloat red = 1.0, green = 1.0, blue = 1.0;
GLint xmove = -12.0, ymove = -12.5, zmove = 0.0;
/* reshape callback function
executed when window is moved or resized. This function should be used in Tutorial 1 */
void reshape(int width, int height)
{
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity();
// glOrtho(-10.0, 10.0, -10.0, 10.0, -1.0, 1.0); //sets the x,y,z plane from -1 to 1
if (width <= height) //if aspect is less or equal to 1
glOrtho(-10.0, 10.0, -10.0/aspect, 10.0/aspect, -1.0, 1.0);
else // aspect is greater than 1
glOrtho(-10.0 * aspect, 10.0* aspect, -10.0 , 10.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
/* display callback function
called whenever contents of window need to be re-displayed */
//this is the all important drawing method - all drawing code goes in here
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT); /* clear window */
/*glColor3f(1.0, 1.0, 1.0); /* white drawing objects */
glColor3f(0.0, 0.0, 1.0); /* blue drawing objects */
/* define object to be drawn as a square polygon */
glColor3f(0.3, -3.0, 4.0);
drawSquare(2, -3, 8);
glColor3f(0.3, -1.0, 2.0);
drawSquare(2, -3, 8);
glColor3f(1.0, 0.0, 0.0);
drawSquare(2, -5, -6);
glColor3f(0.0, 1.0, 0.0);
drawSquare(2, 0.0, 0.0);
glColor3f(2.0, 3.0, 1.1);
drawSquare(2, 6.0, 0.0);
glColor3f(0.3, -1.0, 2.0);
drawSquare(2, -6, 5);
glColor3f(0.7, -1.0, 2.0);
drawSquare(2, 5, -5);
glColor3f(0.0, 0.0, 1.0);
drawSquare(2, 5, 8);
glColor3f(0.75, 0.5, 0.25);
drawCar(1,0,0);
glFlush(); /* execute drawing commands in buffer */
}
void drawCar(GLfloat length, GLfloat x, GLfloat y) {
glPushMatrix();
glTranslatef(xmove, ymove, zmove);
//glBegin(GL_TRIANGLES);
////specify the vertices (points in 3D space) of the shape - note that these are 2D points
//glVertex2f(X_CENTRE - LENGTH / 3, Y_CENTRE - LENGTH / 3);
//glVertex2f(X_CENTRE - LENGTH / 3, Y_CENTRE + LENGTH / 3);
//glVertex2f(X_CENTRE + LENGTH / 3, Y_CENTRE + LENGTH / 3);
//glVertex2f(X_CENTRE + LENGTH / 3, Y_CENTRE - LENGTH / 3);
//glEnd();
glRectf(3, 4, 6, 2);
glPopMatrix();
glFlush();
}
void keyInput(unsigned char key, int x, int y)
{
switch (key)
{
case 'w':
ymove++;
if (ymove >= 10) ymove = 3.0;
break;
case 's':
ymove--;
// if (ymove <= -5) ymove = 0.0;
break;
case 'd':
xmove++;
// if (xmove >= 5) xmove = 0.0;
break;
case 'a':
xmove--;
// if (xmove <= -5) xmove = 0.0;
break;
}
glutPostRedisplay();
}
void drawSquare(GLfloat length, GLfloat x, GLfloat y)
{
//x1,y1 is the top left-hand corner coordinate
GLfloat x1, y1, x2, y2, x3, y3, x4, y4;
//glColor3f(0.1, 1.0, 0.2);
x1 = x - length / 2;
y1 = y + length / 2;
x2 = x + length / 2;
y2 = y + length / 2;
x3 = x + length / 2;
y3 = y - length / 2;
x4 = x - length / 2;
y4 = y - length / 2;
glBegin(GL_POLYGON);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
glFlush();
}
void drawRect(GLfloat lengthX, GLfloat lengthY, GLfloat x, GLfloat y)
{
//x1,y1 is the top left-hand corner coordinate
GLfloat x1, y1, x2, y2, x3, y3, x4, y4;
//This example is for a rectangle
x1 = x - lengthX / 2;
y1 = y + lengthY / 2;
x2 = x + lengthX / 2;
y2 = y + lengthY / 2;
x3 = x + lengthX / 2;
y3 = y - lengthY / 2;
x4 = x - lengthX / 2;
y4 = y - lengthY / 2;
glBegin(GL_POLYGON);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
glFlush();
}
//Draws a 5 pointed star using lines
void drawStar(GLfloat radius, GLfloat x, GLfloat y)
{
//x1,y1 is the top coordinate
//glColor3f(0.0, 1.0, 1.0);
GLfloat x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
x1 = x;
y1 = y + radius;
x2 = x + 0.90 * radius;
y2 = y + 0.40 * radius;
x3 = x + 0.65 * radius;
y3 = y - 0.55 * radius;
x4 = x - 0.65 * radius;
y4 = y - 0.55 * radius;
x5 = x - 0.90 * radius;
y5 = y + 0.40 * radius;
glLineWidth(1.0);
glBegin(GL_LINES);
glVertex2f(x1, y1);
glVertex2f(x3, y3);
glVertex2f(x1, y1);
glVertex2f(x4, y4);
glVertex2f(x2, y2);
glVertex2f(x4, y4);
glVertex2f(x2, y2);
glVertex2f(x5, y5);
glVertex2f(x3, y3);
glVertex2f(x5, y5);
glEnd();
glFlush();
}
/* graphics initialisation */
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0); //Setting up the background color
}
int main(int argc, char** argv)
{
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use single-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
/* window width = 400 pixels, height = 400 pixels */
/* window width = 640 pixels, height = 480 pixels for a 4:3 ascpect ratio */
/* window width = 1024 pixels, height = 576 pixels for a 16:9 ascpect ratio */
glutInitWindowSize(750, 750);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window with command argument in its title bar */
glutCreateWindow("Example 1");
glutKeyboardFunc(keyInput);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
Keep track of your window size (750, 750), and your orthographic projection multiplier (10.0), then you should be able to tell when a certain world space coordinate is at the edge of the screen from these two.

OpenGL the direction of translation is not right after rotation

I'm writing a simple demo with the fixed pipeline mode in OpenGL
First I write some codes that will draw a rectangle, with top-left point (x1,y1), and buttom-right point (x2,y2)
// Drawing here
glPushMatrix();
// Perform rotation first
glTranslatef(x_cent, y_cent, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glScalef(scale, scale, 1.0f);
// Set origin back to the screen center with the rotation set above
glTranslatef(-x_cent, -y_cent, 0.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
{
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glVertex2f(x1, y1);
}
glEnd();
// End of drawing
glPopMatrix();
After I tweak the value of the angle with arrow keys, say 45 degrees counter-clockwise, and now the rectangle will rotate 45 degrees counter-clockwise. Then I translate it with arrow keys, it moves in the direction of up, down, left, and right. Everything works fine.
So I write anoter part of code that will draw a general polygon. It's similar to the code above. I simply draw lines between each pair of points
for (int i = 0; i < p_size; i++)
{
float x1 = point[i].x, x2 = point[(i + 1) % p_size].x;
float y1 = point[i].y, y2 = point[(i + 1) % p_size].y;
x1 = ((x1 + 0.5f) / winWidth) * 2.0f - 1.0f;
x2 = ((x2 + 0.5f) / winWidth) * 2.0f - 1.0f;
y1 = ((-y1 + 0.5f) / winHeight) * 2.0f + 1.0f;
y2 = ((-y2 + 0.5f) / winHeight) * 2.0f + 1.0f;
// Set the curent coord origin to this poly's center
float x_cent = (left + right) / 2.0, y_cent = (top + down) / 2.0;
float ratio = winWidth / winHeight;
if (ratio > 1)
{
x1 *= ratio;
x2 *= ratio;
}
else //if (ratio < 1)
{
y1 /= ratio;
y2 /= ratio;
}
// Drawing here
glPushMatrix();
// Perform rotation first
glTranslatef(x_cent, y_cent, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glScalef(scale, scale, 1.0f);
// Set origin back to the screen center with the rotation set above
glTranslatef(-x_cent, -y_cent, 0.0f);
glBegin(GL_LINES);
{
glVertex2f(x1, y1);
glVertex2f(x2, y2);
}
glEnd();
// End of drawing
glPopMatrix();
}
I rotate the polygon with arrow keys, that works fine, say also 45 degrees counter-clockwise. But after the rotation, when I translate it with up key, it moves not up but in the direction of 45 degrees.
Bbut why can the rectangle translate normally in the 4 directions after rotation? These two part of codes are almost the same, why is this happening...

OpenGL Squares and Arrows

i'm trying to create a square and on top of it i'm creating an arrow. its like a 2D meter something similar to that. But i don't know how to create the arrow on top of the square.
int count = 1;
for (float y = 1; y < 11; y++) {
y1 = y1 - 0.51;
y2 = y2 - 0.51;
float x2 = -2.0;
for (float x1 = -2.5; x1 < 2.5; x1 = x1 + 0.51) {
glColor3f(windy[count], 1.0, 0.0);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
count = count + 1;
x2 = x2 + 0.51;
}
}
glutSwapBuffers();
glEnd(); //End the glBegin Function
And this is what i want to be on top of it.
glBegin(GL_LINE_LOOP);//start drawing a line loop
glVertex3f(-1.0f, 0.0f, 0.0f);//left of window
glVertex3f(0.0f, -1.0f, 0.0f);//bottom of window
glVertex3f(1.0f, 0.0f, 0.0f);//right of window
glVertex3f(0.0f, 1.0f, 0.0f);//top of window
glEnd();//end drawing of line loop
Why did you swap buffers before glEnd() call:
int count = 1;
for (float y = 1; y < 11; y++) {
y1 = y1 - 0.51;
y2 = y2 - 0.51;
float x2 = -2.0;
for (float x1 = -2.5; x1 < 2.5; x1 = x1 + 0.51) {
glColor3f(windy[count], 1.0, 0.0);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
count = count + 1;
x2 = x2 + 0.51;
}
}
//glutSwapBuffers(); // wrong place
glEnd(); //End the glBegin Function
glutSwapBuffers(); // Must be after draw operation
to draw arrow on the top of the shape must be even more:
int count = 1;
for (float y = 1; y < 11; y++) {
y1 = y1 - 0.51;
y2 = y2 - 0.51;
float x2 = -2.0;
for (float x1 = -2.5; x1 < 2.5; x1 = x1 + 0.51) {
glColor3f(windy[count], 1.0, 0.0);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
count = count + 1;
x2 = x2 + 0.51;
}
}
//glutSwapBuffers(); // wrong place
glEnd(); //End the glBegin Function
// draw arrow
glBegin(GL_LINE_LOOP);//start drawing a line loop
glVertex3f(-1.0f, 0.0f, 0.0f);//left of window
glVertex3f(0.0f, -1.0f, 0.0f);//bottom of window
glVertex3f(1.0f, 0.0f, 0.0f);//right of window
glVertex3f(0.0f, 1.0f, 0.0f);//top of window
glEnd();//end drawing of line loo
// atlast we can swap our buffers
glutSwapBuffers(); // Must be after draw operation

Open GL Rotation

i'm trying to draw 100 arrows in a grid and trying to rotate each arrow according to the size of the input i read. But here when i try to rotate one arrow, all the arrows rotate at once with it. whats wrong with it ?
void drawArrow(void) {
float y1 = 2.0;
float y2 = 2.15;
float y3 = 2.4;
int count2 = 0;
for (float col = 0; col < 10; col++) {
y1 -= 0.5;
y2 -= 0.5;
y3 -= 0.5;
float x1 = -2.25;
float x2 = -2.20;
float x3 = -2.15;
float x4 = -2.35;
float x5 = -2.30;
for (float rows = 0; rows < 10; rows++) {
glPushMatrix();
glTranslatef(-0.35 + 0.5 - 0.1, 0.4 - 0.01 + 0.1, 0.0);
float m = (windx[count2] * windx[count2]) + (windy[count2] * windy[count2]);
float rotator = sqrt(m);
glRotatef(rotator-50, 0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);//start drawing a line loop
glColor3f(1.0, 0.0, 0.0);
glVertex3f(x1, y1, 0.0f);
glVertex3f(x2, y2, 0.0f);
glVertex3f(x3, y2, 0.0f); // drawing a arrow
glVertex3f(x1, y3, 0.0f);
glVertex3f(x4, y2, 0.0f);
glVertex3f(x5, y2, 0.0f);
glVertex3f(x1, y1, 0.0f);
x1 += .5;
x2 += .5;
x3 += .5;
x4 += .5;
x5 += .5;
count2 ++;
glEnd();//end drawing of line loop
glPopMatrix();
}
}
int main(int argc, char **argv) {
glMatrixMode(GL_PROJECTION);
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_SINGLE); // Set up a basic display buffer (only single buffered for now)
glutInitWindowSize(1000, 800); // Set the width and height of the window
glutInitWindowPosition(100, 100); // Set the position of the window
glutCreateWindow("Weather Analysis"); // Set the title for the window
readDataFile(); //Read Data From File
glutKeyboardFunc(keyboard);
glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping
glutMainLoop(); // Enter GLUT's main loop
void reshape(int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
}
void display(void) {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red
glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glTranslatef(0.0f, 0.5f, -6.0f);
renderPrimitive(); // Render the primitive
drawArrow();
glFlush(); // Flush
}
and ALSO i dont know what to enter in the GLtranslatef method. Im really a beginner, sorry.
Try to draw your arrow in one rutine lets call it DrawArrow I suggest it size must be between [-1.0f; 1.0f] than place it at the proper position using affine transform first of all translation secondly rotation.
void DrawArrow(void)
{
float x1 = 0;
float x2 = -0.05;
float x3 = -0.1;
float x4 = 0.1;
float x5 = 0.05;
float y1 = -0.15;
float y2 = 0;
float y3 = 0.15;
glBegin(GL_LINE_STRIP);//start drawing a line loop
glColor3f(1.0, 0.0, 0.0);
glVertex3f(x1, y1, 0.0f);
glVertex3f(x2, y2, 0.0f);
glVertex3f(x3, y2, 0.0f); // drawing a arrow
glVertex3f(x1, y3, 0.0f);
glVertex3f(x4, y2, 0.0f);
glVertex3f(x5, y2, 0.0f);
glVertex3f(x1, y1, 0.0f);
glEnd();//
}
Than your array drawing function like this (you may correct inacurrances):
void drawArrows(void) {
float y1 = 2.0;
int count2 = 0;
for (float col = 0; col < 10; col++) {
y1 -= 0.5;
float x1 = -2.25;
for (float rows = 0; rows < 10; rows++) {
glPushMatrix();
glTranslatef(x1, y1, 0.0);
float m = (windx[count2] * windx[count2]) + (windy[count2] * windy[count2]);
float rotator = sqrt(m);
glRotatef(rotator-50, 0.0, 0.0, 1.0);
DrawArrow();
x1 += .5;
count2 ++;
glPopMatrix();
}
}
}
I have made some tests the result will be like this (with constant rotator).

OpenGL circle radius issue when drawing square

I have a function that draws a circle.
glBegin(GL_LINE_LOOP);
for(int i = 0; i < 20; i++)
{
float theta = 2.0f * 3.1415926f * float(i) / float(20);//get the current angle
float rad_x = ratio*(radius * cosf(theta));//calculate the x component
float rad_y = radius * sinf(theta);//calculate the y component
glVertex2f(x + rad_x, y + rad_y);//output vertex
}
glEnd();
This works dandy. I save the x, y and radius values in my object.
However when I try and draw a square with the following function call:
newSquare(id, red, green, blue, x, (x + radius), y, (y + radius));
I get the following image.
As you see, the square is nearly double as wide (looks more like the diameter). The following code is how I create my square box. As you can see it starts in the center of the circle in which it should. And should stretch out to the edge of the circle.
glBegin(GL_QUADS);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glEnd();
I can't seem to understand why this is!
If you're correcting the x-position for one object, you have to do it for all others as well.
However, if you continue this, you'll get into trouble very soon. In your case, only the width of objects is corrected but not their positions. You can solve all your problems by setting an orthographic projection matrix and you won't ever need to correct positions again. E.g. like so:
glMatrixMode(GL_PROJECTION); //switch to projection matrix
glOrtho(-ratio, ratio, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW); //switch back to model view
where
ratio = windo width / window height
This constructs a coordinate system where the top edge has y=1, the bottom edge y=-1 and the left and right sides have x=-ratio and x=ratio, respectively.