Scan-line fill OpenGL/GLUT algorithm in C++ - c++

I am trying to learn the scan-line fill algorithm implemented in OpenGL/GLUT. I cannot wrap my mind around the concept. Could anybody explain to me the algorithm in a reasonably simple fashion? The algo is below:
#include<GL/glut.h>
float x1,x2,x3,x4,y1,y2,y3,y4;
void draw_pixel(int x,int y)
{
glColor3f(0.0,1.0,1.0);
glPointSize(1.0);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
}
void edgedetect(float x1,float y1,float x2,float y2,int *le,int *re)
{
float temp,x,mx;
int i;
if(y1>y2)
{
temp=x1,x1=x2,x2=temp;
temp=y1,y1=y2,y2=temp;
}
if(y1==y2)
mx=x2-x1;
else
mx=(x2-x1)/(y2-y1);
x=x1;
for(i=int(y1);i<=(int)y2;i++)
{
if(x<(float)le[i]) le[i]=(int)x;
if(x>(float)re[i]) re[i]=(int)x;
x+=mx;
}
}
void scanfill(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4)
{
int le[500],re[500],i,j;
for(i=0;i<500;i++)
le[i]=500,re[i]=0;
edgedetect(x1,y1,x2,y2,le,re);
edgedetect(x2,y2,x3,y3,le,re);
edgedetect(x3,y3,x4,y4,le,re);
edgedetect(x4,y4,x1,y1,le,re);
for(j=0;j<500;j++)
{
if(le[j]<=re[j])
for(i=le[j];i<re[j];i++)
draw_pixel(i,j);
}
}
void display()
{
x1=250.0;y1=200.0;x2=150.0;y2=300.0;x3=250.0;
y3=400.0;x4=350.0;y4=300.0;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINE_LOOP);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glVertex2f(x3,y3);
glVertex2f(x4,y4);
glEnd();
scanfill(x1,y1,x2,y2,x3,y3,x4,y4);
glFlush();
}
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,499.0,0.0,499.0);
}
void main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutCreateWindow("scanline");
glutDisplayFunc(display);
init();
glutMainLoop();
}

The scanfill function is filling the the pixels coverted by the 4-sided polygon described by the four x-y coordinates. To do this, it uses the edgedetect function, which simulates drawing the edges of the polygon and remembers the minimum and maximum x coordinate for each y coordinate. The scanfill function then goes through each y coordinate and draws a horizontal line of pixels across the remembered range.

Related

draw in animated opengl scene

i've a problem with drawing firework effect in animated scene when i clicked on mouse button. Why it don't drawing?
My Code:
#include<GL/glut.h>
struct Point {
GLint x;
GLint y;
};
Point p1, p2;
int ww=600,wh=400;
int xi,yi,xf,yf,y1b,x1b,y2b,x2b;
float px, py, t;
float x=0.,y=0.,x1=5.;
void update()
{
x+=0.01;
x1 -= 0.02;
if (x>6)
{
x -= 6;
x1 = 4;
}
}
There I create a function that draw firework effect on the basis of bezier curves. It will Okey if I draw on the static window.
// Bezier curve firework
void bezier(int xi, int yi, int xf, int yf)
{
// Coordinates for additional points of bezier curve
x1b = xi + rand()%15;
y1b = yi + rand()%5;
x2b = xf + rand()%15;
y2b = xf + rand()%5;
calculate and draw the curves
for (t=0.;t<=1.;t+=0.001)
{
px=(1-t)*(1-t)*(1-t)*xi+3*t*(1-t)*(1-t)*x1b+3*t*t*(1-t)*x2b+t*t*t*xf;
py=(1-t)*(1-t)*(1-t)*yi+3*t*(1-t)*(1-t)*y1b+3*t*t*(1-t)*y2b+t*t*t*yf;
glPointSize(2);
glBegin(GL_POINTS);
//glColor3f(1,0,0);
glVertex2d(px,py);
glEnd();
glFlush();
}
}
void initRendering()
{
glEnable(GL_DEPTH_TEST);
}
void reshaped(int w , int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (double)w/(double)h,1,200);
}
// If pressed ESC -> exit
void keyPressed(unsigned char k, int x, int y)
{
if(k==27)
{
exit(0);
}
}
Then, if I pressed mouse button it should call the function above and draw what I need. But nothing(
// If pressed mouse button -> draw firework effect
void mousePressed(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
xi=x;
yi=wh-y;
xf=x + 5.;
p1.x = xi; p1.y = yi;
p2.x = xf; p2.y = yi;
//drawLine(xi,yi,xf,yi);
bezier(xi, yi,xf, yi);
}
glutPostRedisplay();
}
There I create animated window. Two clouds move in gorizontal waves.
// Display a two moving clouds and the earth
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(x1,y,-5.0);
glBegin(GL_POLYGON);
glColor3f(1.,0.,0.5);
glVertex3f(-1.,1.,-5.);
glVertex3f(0.,2.,-5.);
glVertex3f(-2.,2.,-5.);
glVertex3f(1.,1.,-5.);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslatef(x,y,-5.);
glBegin(GL_POLYGON);
glColor3f(0.,0.5,0.5);
glVertex3f(1.,0.7,-5.);
glVertex3f(1.5,1.0,-5.0);
glVertex3f(0.7,1.5,-5.0);
glVertex3f(0.0,2.0,-5.0);
glVertex3f(-0.7,1.5,-5.0);
glVertex3f(-1.4,1.6,-5.0);
glVertex3f(-1.7,1.0,-5.0);
glVertex3f(-1.5,0.7,-5.0);
glVertex3f(-1.0,0.5,-5.0);
glEnd();
glPopMatrix();
glBegin(GL_POLYGON);
glColor3f(1.,1.,1.5);
glVertex3f(-2.,-2.,-5.);
glVertex3f(-2.0,-2.0,-5.0);
glVertex3f(-1.0,-1.5,-5.0);
//glVertex3f(0.0,0.0,-5.0);
glVertex3f(2.0,-2.0,-5.0);
glVertex3f(1.2,-1.5,-5.0);
glEnd();
update();
glutSwapBuffers();
glFlush();
}
void myinit()
{
glViewport(0,0,ww,wh);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char **argv)
{
// Initialization
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("Salute | Clouds");
initRendering();
// Registration
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshaped);
// Handler of
myinit();
glutKeyboardFunc(keyPressed);
glutMouseFunc(mousePressed);
// Main Loop
glutMainLoop();
return(0);
}
I think the problem is as follows:
I'm trying to draw my firework in an updated animated window. And every time I clicked on the screen, it is updated. And in the end, nothing is visible.
Actually the question:
How to make so that function glutMoseFunk would draw my salute in updated window?
While your scene is draw in perspective projection, the function bezier works with orthographic projection. This means you have to change the projection matrix befor you call bezier.
Further, do all the rendering in the main loop (display function). The event mousePressed should only be used to change parameters (set xi, yi, ...).
The display function may look like this:
int ww=400, wh=400;
void display()
{
// clear the frame buffer
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// setup perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, (double)ww/(double)wh,1,200);
// set model view matrix (identity matrix)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// draw scene
.....
// setup ortihgraphic projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
bezier(xi, yi,xf, yi);
update();
glutSwapBuffers();
glutPostRedisplay();
}
The reshaped function should set the viewport and notice the window size only:
void reshaped(int w , int h)
{
ww = w;
wh = h;
glViewport(0, 0, ww, wh);
}

Opengl Performance issues ,

So i'm making a game(something similar to a pong)using openGl in cpp , and when i try running the program , the image rendering is too slow ,i feel something is taking a huge toll on my GPU memory ,
(So far i have competed the drawing and movement of the paddle which works fine and the problem arises when the ball is set to motion on the press of a button , Everything slows down after this )
Here i have attached a portion of my code
Point out any deficiencies in my code
#include<stdlib.h>
#include<GL/glut.h>
#include<windows.h>
#include<iostream>
//#include<sstream>
#include<stdio.h>
#include<ctime>
#include<string.h>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
//GLvoid player1_box();
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key){
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
//printf("Inside switch r");
break;
}
glutPostRedisplay();
}
void display()
{
Sleep(2);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
//printf("x move in disp:%1f \n",xmove);
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball(); //To draw the ball
glPopMatrix();
glFlush();
}
void moveBall(){ //glutidlefunction
if(release==1)
{ //Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
Sleep(500);
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void reshape(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,w,h);
//glutPostRedisplay();
//Use the whole window for rendering
}
int main(int argc ,char **argv)
{
//clock_t begin= clock();
char n1,n2;
int ack;
/*printf("The object of Tic Tac Toe is to get three in a row. \n . Players alternate placing Xs and Os(Traingles and Boxes in this version) \n on the game board until either opponent has three \n in a row or all nine squares are filled(Which would be a drawObviously). \n");
printf("\n Press 1 if acknowledged \n");
scanf("%d",&ack);*/
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutIdleFunc(moveBall);
glClearColor(1,1,1,1);
glutMainLoop();
//clock_t end=clock();
}
You're using c++, use C++-style (stdlib.h -> cstdlib) headers.
Apply your projection/modelview matrices each time through display() instead of a reshape callback, helps prevent annoying matrix stack issues.
Don't Sleep(), use a timer/idle callback to glutPostRedisplay(). Bonus points for framerate-independent movement (you can use glutGet(GLUT_ELAPSED_TIME) to calculate delta-t).
Without Sleep() there's no reason to drag windows.h into things.
All together:
#include <GL/glut.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cstring>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key)
{
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
break;
}
}
void display()
{
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball();
glPopMatrix();
glFlush();
}
void moveBall()
{
if(release==1)
{
//Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void timer( int value )
{
moveBall();
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}
int main(int argc ,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
}

Continuous Line On Mouse Drag

I am making a basic OpenGl program which is my weekend project.
Description: If I drag the mouse on the window screen then after I release the button(left) a line should appear that shows the path of dragging the mouse and a circle should traverse that line from start to end.
My Code Works Very Well but the problem is that the line drawn is not continuous[rather its dashed] and it may be because of the mapping of OS screen to OpenGL screen.
SO is there any way to make a continous line path or correct me If I am doing something wrongHere is my code:
#include <iostream>
#include <glut.h>
#include <string.h>
#define WIDTH 600
#define HEIGHT 600
using namespace std;
double arr[5000][4];
int z=0;
int flag=0;
float radius=0.03;
int ptr=0;
int faltu_bit=1;
float color[3][3]={{1.0,1.0,1.0},{1.0,1.0,0.0},{0.0,1.0,0.0}};
void drawText(char *str,float x,float y,int id)
{
int i;
int len=strlen(str);
//glLoadIdentity();
glColor3f(color[id][0],color[id][1],color[id][2]);
glRasterPos2f(x,y);
for(i=0;i<len;i++)
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,str[i]);
}
void init()
{
glClearColor( 0.0, 0.0, 0.0, 1.0);
glMatrixMode( GL_PROJECTION);
gluOrtho2D(0.0,WIDTH,0.0,HEIGHT);
memset(arr,0,5000);
glPointSize(20.0);
}
void resetAll()
{
memset(arr,0,5000);
z=0;
}
///OPENGL MAPPING///
float getOpenGLX(int x)
{
double ox = x/ (double)WIDTH*(WIDTH);
return ox;
}
float getOpenGLY(int y)
{
double oy = (1 - y/ (double) HEIGHT)*HEIGHT;
return oy;
}
void drawPoints()
{
glBegin( GL_POINTS );
glColor3f( 0.0,1.0,0.0 );
for ( int i = 0; i < z; i++ )
{
glVertex2f( arr[i][0],arr[i][1]);
}
glEnd();
}
void drawBall(float x,float y)
{
glBegin( GL_POINTS);
glColor3f( 1.0,1.0,0.0 );
glVertex2f(x,y);
glEnd();
}
void drawLines()
{
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
for(int i=0;i<z;i++)
{
glVertex2f(arr[i][0],arr[i][1]);
}
glEnd();
}
void addValue(int x,int y)
{
arr[z][0]=getOpenGLX(x);
arr[z++][1]=getOpenGLY(y);
}
void trackBall()
{
drawPoints();
}
void myDisplay()
{
glClear( GL_COLOR_BUFFER_BIT);
if(!flag)
{
drawLines();
if(!faltu_bit)
drawBall(arr[ptr][0],arr[ptr][1]);
}
if(faltu_bit)
{
drawText("Project by: Adil Ansar [10 CSS-32]",50.0,500.0,0);
drawText("Welcome",250.0,300.0,1);
drawText("Drag the Mouse Any Where in the Window to see the Path",10.0,200.0,2);
}
glutSwapBuffers();
glutPostRedisplay();
glFlush();
}
void myMouseStat(int button,int state,int x, int y)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
if(!flag)
{
if(faltu_bit)
{
faltu_bit=0;
}
resetAll();
flag=1;
}
}
else if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
{
if(flag)
{
ptr=0;
flag=0;
}
}
}
void myPressedMove(int x,int y)
{
if(flag)
{
addValue(x,y);
}
}
void myTimer(int t)
{
if(ptr!=z)
{
ptr++;
}
else
{
ptr=0;
}
glutTimerFunc(100,myTimer,0);
}
int main( int argc, char ** argv)
{
glutInit( &argc, argv);
glutInitDisplayMode( GLUT_DOUBLE| GLUT_RGB);
glutInitWindowPosition( 100, 100);
glutInitWindowSize(WIDTH,HEIGHT);
glutCreateWindow( "Testing");
init();
glutDisplayFunc(myDisplay);
glutMouseFunc(myMouseStat);
glutMotionFunc(myPressedMove);
glutTimerFunc(100,myTimer,0);
glutMainLoop();
return 0;
}
This Is What I get:
In this code
void drawLines()
{
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
for(int i=0;i<z;i++)
{
glVertex2f(arr[i][0],arr[i][1]);
}
glEnd();
}
GL_LINES is a drawing mode where two consecutive vertices make a line segment. Then the next two and so so. What you're drawing is a line strip; replacing GL_LINES with GL_LINE_STRIP will give you your expected result.
On a side note: You should abandon using immediate mode (glBegin, glVertex, glEnd). It's slow, it's cumbersome to work with and in the long term can become a major PITA. Use at least vertex arrays; they've been the recommended way of supplying geometry data for well over 15 years. Plus it makes your code much simpler. Your code above can be replaced with this:
/* vertex data comes from an array */
glEnableClientState(GL_VERTEX_ARRAY);
/* we want to use a common color for all vertices */
glDisableClientState(GL_COLOR_ARRAY);
glColor3f(1.0, 0.0, 0.0);
/* where to get the data from */
glVertexPointer(2, GL_DOUBLE, sizeof(double)*4, arr);
/* draw the whole thing */
glDrawArrays(GL_LINE_STRIP, 0, z);
/* cleanup */
glDisableClientState(GL_VERTEX_ARRAY);
As you can see it's shorter, more concise, easier to read and it avoids doing z+3 function calls, each of which taking some time to execute.
Important that OpenGL can digest that multidimensional array arr is due to the fact, that statically allocated storage of multidimensional arrays is always contiguous. It would not work if you'd allocate an array of pointers to arrays (the naive way to allocate multidimensional arrays dynamically).

Draw a square in opengl at mouse position

I am trying to draw a simple square wherever I press the left mouse button using opengl/glut. My program runs perfectly except for the part where it does not draw the square where I click the left mouse button :). Can someone point out what I am doing wrong?
#include <stdlib.h>
#include <glut.h>
GLsizei WIDTH = 1300, HEIGHT = 700;
GLsizei MOUSEx, MOUSEy;
GLfloat SIDE=1;
GLfloat RED[3] = {1,0,0};
GLfloat GREEN[3] = {0,1,0};
GLfloat BLUE[3] = {0,0,1};
GLfloat WHITE[3] = {1,1,1};
GLfloat BLACK[3] = {0,0,0};
GLfloat YELLOW[3] = {1,1,0};
GLfloat CYAN[3] = {0,1,1};
GLfloat MAGENTA[3] = {1,0,1};
void drawSquare(int x, int y)
{
glColor3fv(YELLOW);
glBegin(GL_POLYGON);
glVertex3f(x+SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y-SIDE,0);
glVertex3f(x+SIDE, y-SIDE,0);
glEnd();
glFlush();
}
void drawSquare1()
{
int x=0,y=0;
glColor3fv(BLUE);
glBegin(GL_POLYGON);
glVertex3f(x+SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y-SIDE,0);
glVertex3f(x+SIDE, y-SIDE,0);
glEnd();
glFlush();
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,0,-5);
drawSquare1();
glFlush();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
WIDTH=w;
HEIGHT=h;
}
void setX(int x)
{
MOUSEx=x;
}
void setY(int y)
{
MOUSEy=y;
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
setX(x);
setY(y);
drawSquare(MOUSEx,HEIGHT-MOUSEy);
glutPostRedisplay();
}
if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
{
exit(1);
}
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (WIDTH, HEIGHT);
glutInitWindowPosition (10, 10);
glutCreateWindow ("New Window");
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutMouseFunc(mouse);
//glutMotionFunc(drawSquare);
glutMainLoop ();
return 0;
}
In short words: OpenGL is not a scene graph. That means that those drawing commands issued in the mouse handler don't create some kind of "persistency".
Instead clicking the mouse you should store the position in a list/array and draw the squares from the values in that list in the display function.
I am fresh to this Coding But I done it.
Here is My Code It will Work.
#include <GL/glut.h>
GLsizei MOUSEx=0, MOUSEy=0;
GLfloat SIDE=50;
GLfloat BLUE[3] = {0,0,1};
void drawSquare1()
{
glColor3fv(BLUE);
glBegin(GL_POLYGON);
glVertex3f(MOUSEx, MOUSEy,0);
glVertex3f(MOUSEx+SIDE, MOUSEy,0);
glVertex3f(MOUSEx+SIDE, MOUSEy+SIDE,0);
glVertex3f(MOUSEx, MOUSEy+SIDE,0);
glEnd();
glFlush();
}
void display(void)
{
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
drawSquare1();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho(0.0,1368,768,0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void spindisplay(void)
{
glutPostRedisplay();
}
void setX(int x)
{
MOUSEx=x;
}
void setY(int y)
{
MOUSEy=y;
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
setX(x);
setY(y);
//drawSquare(MOUSEx,HEIGHT-MOUSEy);
glutPostRedisplay();
}
if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
{
exit(1); // To Exit the Program
}
}
int main(int argc, char **argv)
{ glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1366,768);
glutInitWindowPosition(0,0);
glutCreateWindow("Moving squares");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutIdleFunc(spindisplay);
glutMainLoop();
}
Below is the sample code taken from OpenGL Projects. Try to execute this and I think the problem with your drawing squares in OpenGL would be solve easily. If any question kindly ask.
#include<stdlib.h>
#include<glut.h>
GLsizei wh=500,ww=500;
GLfloat size=3.0;
void display()
{
glFlush();
}
void myInit()
{
glViewport(0,0,ww,wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,1.0);
glColor3f(1.0,0.0,0.0);
}
void myReshape(GLsizei w,GLsizei h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,w,h);
ww=w;
wh=h;
}
void drawSquare(int x,int y)
{
y=wh-y;
glBegin(GL_POLYGON);
glVertex2f(x+size,y+size);
glVertex2f(x-size,y+size);
glVertex2f(x-size,y-size);
glVertex2f(x+size,y-size);
glEnd();
glFlush();
}
void size_menu(int id)
{
switch(id)
{
case 2: size=size*2;
break;
case 3:if(size>1) size=size/2;
break;
}
glutPostRedisplay();
}
void top_menu(int id)
{
switch(id)
{
case 1:exit(0);break;
}
glutPostRedisplay();
}
void myMouse(int button,int state,int x,int y)
{
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
drawSquare(x,y);
if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
exit(0);
}
int main(int argc,char **argv)
{
int sub_menu;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutCreateWindow("Hierarchical Menus to Draw Squares");
glutDisplayFunc(display);
myInit();
glutMouseFunc(myMouse);
sub_menu=glutCreateMenu(size_menu);
glutAddMenuEntry("Increase Square Size",2);
glutAddMenuEntry("Decrease Square Size",3);
glutCreateMenu(top_menu);
glutAddMenuEntry("Quit",1);
glutAddSubMenu("Resize",sub_menu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutReshapeFunc(myReshape);
glClear(GL_COLOR_BUFFER_BIT);
glutMainLoop();
return 0;
}

Boundary fill problem

Im stuck in this bunch of codes...i cant get the pixel to fill up the circle??...any help
#include<iostream>
#include<glut.h>
struct Color{
float red, green, blue;
};
Color getPixel(int x, int y){ // gets the color of the pixel at (x,y)
Color c;
float color[4];
glReadPixels(x,y,1,1,GL_RGBA, GL_FLOAT, color);
c.red = color[0];
c.green = color[1];
c.blue = color[2];
return c;
}
void setPixel(int x, int y, Color c){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_ALL_ATTRIB_BITS);
glColor3f(c.red, c.green, c.blue);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glPopAttrib();
glFlush();
}
void init()
{
glClearColor(1.0,1.0,1.0,0.0);
gluOrtho2D(0.0,300.0,0.0,300.0);
}
void drawPixel(int x,int y)
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glFlush();
}
void Boundary_fill(int x,int y,Color thisColor){
Color boundary_color;
boundary_color.red=0.0;
boundary_color.green=1.0;
boundary_color.blue=0.0;
Color nextpixel=getPixel(x,y);
if((nextpixel.red!=boundary_color.red)&&(nextpixel.blue!=boundary_color.blue)&&(nextpixel.green!=boundary_color.green) && (nextpixel.red!=thisColor.red)&& (nextpixel.blue!=thisColor.blue)&& (nextpixel.green!=thisColor.green)){
setPixel(x,y,thisColor);
Boundary_fill((x+1),y,thisColor);
Boundary_fill((x-1),y,thisColor);
Boundary_fill(x,(y+1),thisColor);
Boundary_fill(x,(y-1),thisColor);
}
}
void draw(int x1,int y1, int x, int y){
drawPixel(x1+x,y1+y);//quadrant1
drawPixel(x1+x,y1-y);//quadrant2
drawPixel(x1-x,y1+y);//quadrant3
drawPixel(x1-x,y1-y);//quadrant4
drawPixel(x1+y,y1+x);//quadrant5
drawPixel(x1+y,y1-x);//quadrant6
drawPixel(x1-y,y1+x);//quadrant7
drawPixel(x1-y,y1-x);//quadrant8
}
void circle(int px,int py,int r){
int a,b;
float p;
a=0;
b=r;
p=(5/4)-r;
while(a<=b){
draw(px,py,a,b);
if(p<0){
p=p+(2*a)+1;
}
else{
b=b-1;
p=p+(2*a)+1-(2*b);
}
a=a+1;
}
}
void Circle(void)
{
Color thisColor;
thisColor.red=1.0;
thisColor.blue=0.0;
thisColor.green=0.0;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,1.0,0.0);
glPointSize(2.0);
int x0 = 100;
int y0 = 150;
circle(x0,y0,50);
glColor3f(thisColor.red,thisColor.blue,thisColor.green);
Boundary_fill(x0,y0,thisColor);
}
void main(int argc, char**argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400,400);
glutInitWindowPosition(1,1);
glutCreateWindow("Boundary fill in a circle:Taaseen And Abhinav");
init();
glutDisplayFunc(Circle);
glutMainLoop();
}
Your setPixel() routine is broken. It clears the window to white, thereby erasing all previously drawn pixels. You should remove this line and put it in your Circle() routine instead:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Because of that line, getPixel() will always read white pixels (except for one) and will recurse to the right. If you're lucky glReadPixels() will return some random colors when reaching the outside of the frame buffer. Otherwise it will produce a stack overflow. You should therefore also check your pixel position in Boundary_fill().