OpenGL: Bresenham's Line Drawing Algorithm Implementation - c++

I've been trying to generate a line using Bresenham's Algorithm (Yes, I know in built functions exist, but this is something I've been asked to implement) using the following code.
But for some reason, I am not being able to see the line on the window. I just get an empty window.
I initially tried drawing points with SetPixel() but I was short of 2 arguments(HDC and COLORREF) apart from just the X and Y coordinates. I don't know what the other 2 arguments do, so I had to try something else.
So I used a solution I found here on StackOverflow to generate the point. Though I do not get any compilation error or warnings, the code just doesn't seem to work. How about you try looking for the problem:
#include<iostream>
#include<GL/glut.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
int x00;
int y00;
int xEnd;
int yEnd;
void init(){
glClearColor(1,0,0,0);
glMatrixMode( GL_PROJECTION );
gluOrtho2D(0,500,0,500);
}
void bres()
{
int dx = fabs(xEnd - x00), dy = fabs(yEnd - y00);
int p = 2*dy-dx;
int x, y;
if(x00>xEnd){
x=xEnd;
y=yEnd;
xEnd=x00;
}
else{
x=x00;
y=y00;
}
//Stack Overflow Solution to generate a point:
glBegin(GL_POINTS);
glColor3f(0,0,0);
glVertex2i(x,y);
glEnd();
while(x<xEnd){
x++;
if(p<0){
p = p + 2*dy;
}
else{
y++;
p= p + 2*dy - 2*dx;
}
glBegin(GL_POINTS);
glColor3f(0,0,0);
glVertex2i(x,y);
glEnd();
}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
bres();
glFlush();
}
int main(int argc, char* argv[])
{
cout<<"Enter the co ordinates for 2 points: ";
cin>>x00>>y00>>xEnd>>yEnd;
glutInit(&argc, argv);
glutInitWindowSize(600,600);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Bresenham's Algo");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}

Since you are using a double buffered window
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
you have to call glutSwapBuffers instead of glFlush.
If you would use a single buffered window
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
then glFlush would work.
Change your code somehow like this:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
bres();
//glFlush();
glutSwapBuffers();
}

Related

How to invert the output of OpenGL code?

I have written the following code to print the Koch curve using OpenGL. But I am getting an inverted output. What modifications are required to invert the output in OpenGL? Also, is there any other formula to find the vertex coordinates of the equilateral triangle of the Koch curve?
#include<iostream>
#include<GL/glut.h>
#define COS 0.5
#define SIN 0.866
int x1=10,x2=550,y1=200,y2=200;
void myinit()
{
glClearColor(0.0,1.0,0.0,1.0);
glColor3f(0.0,0.0,1.0);
glPointSize(3.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,640,0,480);
}
void koch(int x1, int y1, int x2, int y2, int m)
{
int x[5],y[5],xx,yy,lx,ly;
lx=(x2-x1)/3;
ly=(y2-y1)/3;
x[0]=x1;
y[0]=y1;
x[4]=x2;
y[4]=y2;
x[1]=x[0]+lx;
y[1]=y[0]+ly;
x[3]=x[0]+2*lx;
y[3]=y[0]+2*ly;
xx=x[3]-x[1];
yy=y[3]-y[1];
x[2]=xx*(COS)+yy*(SIN);
y[2]=-xx*(SIN)+yy*(COS);
x[2]=x[1]+x[2];
y[2]=y[1]+y[2];
if(m>0)
{
koch(x[0],y[0],x[1],y[1],m-1);
koch(x[1],y[1],x[2],y[2],m-1);
koch(x[2],y[2],x[3],y[3],m-1);
koch(x[3],y[3],x[4],y[4],m-1);
}
else
{
glBegin(GL_LINES);
glVertex2d(x[0],y[0]);
glVertex2d(x[1],y[1]);
glEnd();
glBegin(GL_LINES);
glVertex2d(x[1],y[1]);
glVertex2d(x[2],y[2]);
glEnd();
glBegin(GL_LINES);
glVertex2d(x[2],y[2]);
glVertex2d(x[3],y[3]);
glEnd();
glBegin(GL_LINES);
glVertex2d(x[3],y[3]);
glVertex2d(x[4],y[4]);
glEnd();
}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
koch(x1,y1,x2,y2,2);
glEnd();
glFlush();
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutCreateWindow("Grllp");
glutDisplayFunc(display);
myinit();
glutMainLoop();
}

How to Improve Accuracy of Iteration?

I'm trying to make code, c++, to plot the Mandlebrot Set. However, whenever I run my code, see below, the convergence is poor. How do I fix that? I provided some code below. There's also a screenshot of the Mandelbrot Set, red, and my code's approximation, greyscale.
#include <GL/glut.h>
void renderscene(void) {
double x=0;
double y=0;
double ix=0;
double iy=0;
int n=1;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for(x=-3;x<3;x=x+0.01){
for(y=-3;y<3;y=y+0.01){
for(n=1;n<50;n=n+1){
ix=ix*ix-iy*iy+x;
iy=2*iy*ix+y;
if(ix*ix+iy*iy>4){
break;
}
}
ix=0;
iy=0;
glPointSize(1);
glColor3f(0.1*n,0.1*n,0.1*n);
glBegin(GL_POINTS);
glVertex2f(x*0.4,y*0.4);
glEnd();
}
}
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowPosition(300,200);
glutInitWindowSize(500,500);
glutCreateWindow("Hello");
glutDisplayFunc(renderscene);
glutMainLoop();
return 1;
}
You are using the wrong ix in the computation of the new iy.
Try
double nextix=ix*ix-iy*iy+x;
iy=2*iy*ix+y;
ix = nextix;

Why is my OpenGL code not working

I'm a complete novice in OpenGL and have started following a book on this topic. The first program that they demonstrate is the Sierpinski Gasket program. Here's what the code looks like in the book:
#include<GL/glut.h>
#include<stdlib.h>
void myinit()
{
//attributes
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(1.0,0.0,0.0); //draw in red
//set up viewing
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,50.0,0.0,50.0);
glMatrixMode(GL_MODELVIEW);
}
void display()
{
GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; //triangle
GLfloat p[2]={7.5,5.0}; //arbitrary point
glClear(GL_COLOR_BUFFER_BIT); //clear the window
glBegin(GL_POINTS);
//Gasket Program
for(int i=0;i<5000;i++){
int j=rand()%3;
//compute points halfway between random vertex and arbitrary point
p[0]=(vertices[j][0]+p[0])/2;
p[1]=(vertices[j][1]+p[1])/2;
//plot the point
glVertex2fv(p);
}
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(display);
myinit();
glutMainLoop();
return 0;
}
However, when I compile the program it only displays a window completely filled with white and nothing else. Why isn't the above code working the way it should?
Swap glFlush() for glutSwapBuffers():
#include<GL/glut.h>
void display()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT); //clear the window
//set up viewing
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,50.0,0.0,50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; //triangle
GLfloat p[2]={7.5,5.0}; //arbitrary point
glColor3f(1.0,0.0,0.0); //draw in red
glBegin(GL_POINTS);
//Gasket Program
for(int i=0;i<5000;i++)
{
int j=rand()%3;
//compute points halfway between random vertex and arbitrary point
p[0]=(vertices[j][0]+p[0])/2;
p[1]=(vertices[j][1]+p[1])/2;
//plot the point
glVertex2fv(p);
}
glEnd();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
glFlush() won't actually swap the back/front buffers requested by GLUT_DOUBLE. You need glutSwapBuffers() for that.

OpenGL: Error moving object using keyboard

I'm new to OpenGL and I'm trying to paint a stickman and then move it using the arrow-keys from the keyboard.
My idea was to use global variables for the stickman and to change them when a certain key is pressed. Afterwards the draw-function (myDisplay()) is called again.
Unfortunately i always get the following error-message:
"Error 10 error C2371: 'myDisplay' : redefinition; different basic types "
When I replace the myDisplay()-call in the keyboard-function with glutPostRedisplay() as suggested in some tutorials I read the error message disapears and the build is successful. But the stickman doesn't move when pressing the keys.
Here's my code:
#include <GL/glut.h>
GLint x; GLint y; GLint d; //parameters for the stickman
void myKeyboard(unsigned char key, int mx, int my) {
int x1 = mx;
int y1 = 480 - my;
switch(key){
case GLUT_KEY_LEFT :
x = x-50;
myDisplay();
break;
case 'E' :
exit(-1);
break;
default:
break;
}
}
void stickman () {
glBegin(GL_LINES); //body
glVertex2i(x, y);
glVertex2i(x, y-2*d);
glVertex2i(x-d, y-d);
glVertex2i(x+d, y-d);
glVertex2i(x, y-2*d);
glVertex2i(x-d, y-3*d);
glVertex2i(x, y-2*d);
glVertex2i(x+d, y-3*d);
glEnd();
glBegin(GL_LINE_LOOP); //head
glVertex2i(x,y);
glVertex2i(x+0.5*d, y);
glVertex2i(x+0.5*d, y+0.5*d);
glVertex2i(x-0.5*d, y+0.5*d);
glVertex2i(x-0.5*d, y);
glEnd();
}
void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
stickman();
glFlush();
}
void myInit() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
void main(int argc, char** argv) {
x = 320;
y = 350;
d = 100;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(200, 50);
glutCreateWindow("Stickman");
glutDisplayFunc(myDisplay);
glutKeyboardFunc(myKeyboard);
glutPostRedisplay();
myInit();
glutMainLoop();
}
As I found out (GLUT Keyboard Tutorial) the problem wasn't the repaint of the picture, but rather that the left arrow key wasn't recognized.
I needed to write another keyboard-function for my special keys such as the arrow keys.
Now my code looks like this and it works:
void processNormalKeys (unsigned char key, int mx, int my) {
if (key == 'E')
exit(-1);
}
void processSpecialKeys (int key, int mx, int my) {
switch(key){
case GLUT_KEY_LEFT :
x = x-5;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT :
x = x+5;
glutPostRedisplay();
break;
case GLUT_KEY_UP :
y = y+5;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN :
y = y-5;
glutPostRedisplay();
break;
default:
break;
}
}
I also had to adjust the main function:
glutKeyboardFunc(processNormalKeys);
glutSpecialFunc(processSpecialKeys);
But thanks for your help anyways!
glutPostRedisplay() is used to tell mark that the current window needs to be redisplayed as said in the documentation. That means that you need to call this function at the end of your myKeyboard function.
I will also recommend you to use double or tripple buffer to avoid undesired results. For double buffer you need to change glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ); with glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB ); and then at the end of your display function you need to add glutSwapBuffers();. You can find more info here http://www.swiftless.com/tutorials/opengl/smooth_rotation.html.

glReadPixels Reads wrong color in opengl

There is a simple program which is actually from a bigger one,putting this aside,I tried to do a simple pixel read/write in Opengl.
The first section which involves reading a pixel color succeeds,But the second operation which involves writing a pixel and then reading it fails!.
Here is the program which demonstrates the problem :
#include <iostream>
#include <glut.h>
using namespace std;
void init(void)
{
glClearColor(1.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,100.0,0.0,100.0);
}
void displayfnc()
{
glClear(GL_COLOR_BUFFER_BIT);
unsigned char current[3];
int r,g,b;
//x=0 to 6 is right
glBegin (GL_POINTS);
glColor3f (0.0,0.0,1.0);
glVertex2i (6,0);
glEnd();
//works well.
glReadPixels(6,0, 1, 1 , GL_RGB , GL_UNSIGNED_BYTE ,current);
r = current[0];
g = current[1];
b = current[2];
cout<<"read from x=6::::"<<"r:"<<r<<"g:"<<g<<"b:"<<b<<endl;
//x =7 and other isnt right
glBegin (GL_POINTS);
glColor3f (0.0,0.0,1.0);
glVertex2i (7,0);
glEnd();
//the problem is here in the reading.why this happen?
glReadPixels(7,0, 1, 1 , GL_RGB , GL_UNSIGNED_BYTE ,current);
r = current[0];
g = current[1];
b = current[2];
cout<<"Read from x=7::::"<<"r:"<<r<<"g:"<<g<<"b:"<<b<<endl;
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(100,100);
glutInitWindowPosition(0, 0);
glutCreateWindow("BoundaryFill");
init();
glutDisplayFunc(displayfnc);
glutMainLoop();
return 0;
}
Here is the output:
What is causing the second read procedure to fail?
At least on my system glutInitWindowSize(100,100) is just a suggestion. glutGet(GLUT_WINDOW_WIDTH) actually returns 104, not 100 as your gluOrtho2D() call is assuming.
Try using a dynamic projection instead:
#include <GL/glut.h>
#include <iostream>
using namespace std;
void displayfnc()
{
glClearColor(1.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluOrtho2D(0.0,w,0.0,h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
unsigned char current[3];
int r,g,b;
//x=0 to 6 is right
glBegin (GL_POINTS);
glColor3f (0.0,0.0,1.0);
glVertex2i (6,0);
glEnd();
//works well.
glReadPixels(6,0, 1, 1 , GL_RGB , GL_UNSIGNED_BYTE ,current);
r = current[0];
g = current[1];
b = current[2];
cout<<"read from x=6::::"<<"r:"<<r<<"g:"<<g<<"b:"<<b<<endl;
//x =7 and other isnt right
glBegin (GL_POINTS);
glColor3f (0.0,0.0,1.0);
glVertex2i (7,0);
glEnd();
//the problem is here in the reading.why this happen?
glReadPixels(7,0, 1, 1 , GL_RGB , GL_UNSIGNED_BYTE ,current);
r = current[0];
g = current[1];
b = current[2];
cout<<"Read from x=7::::"<<"r:"<<r<<"g:"<<g<<"b:"<<b<<endl;
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(100,100);
glutInitWindowPosition(0, 0);
glutCreateWindow("BoundaryFill");
glutDisplayFunc(displayfnc);
glutMainLoop();
return 0;
}