I was implementing this dda algorithm using opengl. However, for some reason, it doesn't plot the second line. I tried putting printf at every line, which shows that it IS executing. However, there is no output in my window
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>
int choice = 0;
void DDA(x0, y0, x1, y1)
const x0, y0, x1, y1;
{
glOrtho(-500, 500, -500, 500, -1, 1);
float dx = x1 - x0;
float dy = y1 - y0;
int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
float xInc = (float)steps/dx;
float yInc = (float)steps/dy;
int x = x0, y = y0;
for(int i = 0; i < steps; i++) {
glBegin(GL_POINTS);
glColor3f(1.0, 3.0, 2.0);
glVertex2i(x, y);
x += xInc;
y += yInc;
glEnd();
glFlush();
}
}
void Bresenham(x0, y0, x1, y1)
const x0, y0, x1, y1;
{
glOrtho(-500, 500, -500, 500, -1, 1);
int x = x0;
int y = y0;
int dx = x1 - x0;
int dy = y1 - y0;
int p = 2*dy-dx;
int m = dy / dx;
glBegin(GL_POINTS); {
glColor3f(2.0, 3.0, 5.0);
while(x != x1) {
if(m < 1) {
glVertex2i(x, y);
x++;
if(p >= 0) {
p += 2*(dy - dx);
y++;
}
else {
p += 2*dy;
}
}
else {
glVertex2i(x, y);
y++;
if(p >= 0) {
p += 2*(dx - dy);
x++;
}
else {
p += 2*dx;
}
}
}
glVertex2i(x, y);
}
glEnd();
glFlush();
}
void circle(x0, y0, r)
const x0, y0, r;
{
}
void renderDDA(void) {
DDA(0, 0, 300, 400);
DDA(0, 0, 200, 200);
}
void renderBresenham(void) {
Bresenham(0, 0, 300, 100);
Bresenham(0, 0, 500, 0);
}
void renderCircle(void) {
}
main(argc, argv)
char** argv;
{
redo:
printf("ENTER YOUR CHOICE: ");
scanf("%d", &choice);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(1920, 1680);
glutCreateWindow(argv[1]);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
switch (choice) {
case 0:
glutDisplayFunc(renderDDA);
break;
case 1:
glutDisplayFunc(renderBresenham);
break;
case 2:
glutDisplayFunc(renderCircle);
break;
default:
printf("NO SUCH CHOICE!!");
goto redo;
}
glutMainLoop();
return 0;
}
I also tried swapping the lines. Then it draws only the upper line. it does execute the second call however.
glOrtho
does not set an orthographic projection, it defines an orthographic projection matrix and multiplies the current matrix by the orthographic projection matrix.
You've to set the identity matrix before calling glOrtho
:
glLoadIdentity();
glOrtho(-500, 500, -500, 500, -1, 1);
Further there is an issue in the algorithm. The type of x
and y
has to be float
. If you would trunc the result to int
, then it is only possible to draw lines with angles that are aligned to multiples of 45 degreess, because x
and y
change exactly by 0 or 1 at each step:
float x = x0, y = y0;
for(int i = 0; i < steps; i++) {
glBegin(GL_POINTS);
glColor3f(1.0, 3.0, 2.0);
glVertex2i((int)(x+0.5f), (int)(y+0.5f));
x += xInc;
y += yInc;
glEnd();
}
Note, changing the type from int
to float
causes that x
and y
are tracked with full precision. glVertex2i((int)(x+0.5f), (int)(y+0.5f))
ensures that coordinates (x
, y
) are rounded to the integral position when the point is draw.
I recommend to move the setting of the projection matrix from and glFlush
from DDA
respectively Bresenham
to renderDDA
respectively renderBresenham
:
void DDA(float x0, float y0, float x1, float y1)
{
float dx = x1 - x0;
float dy = y1 - y0;
int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
float xInc = (float)steps/dx;
float yInc = (float)steps/dy;
float x = x0, y = y0;
for(int i = 0; i < steps; i++) {
glBegin(GL_POINTS);
glColor3f(1.0, 3.0, 2.0);
glVertex2i((int)(x+0.5f), (int)(y+0.5f));
x += xInc;
y += yInc;
glEnd();
}
}
void Bresenham(float x0, float y0, float x1, float y1)
{
int x = x0;
int y = y0;
int dx = x1 - x0;
int dy = y1 - y0;
int p = 2*dy-dx;
int m = dy / dx;
glBegin(GL_POINTS); {
glColor3f(2.0, 3.0, 5.0);
while(x != x1) {
if(m < 1) {
glVertex2i(x, y);
x++;
if(p >= 0) {
p += 2*(dy - dx);
y++;
}
else {
p += 2*dy;
}
}
else {
glVertex2i(x, y);
y++;
if(p >= 0) {
p += 2*(dx - dy);
x++;
}
else {
p += 2*dx;
}
}
}
glVertex2i(x, y);
}
glEnd();
}
void renderDDA(void) {
glLoadIdentity();
glOrtho(-500, 500, -500, 500, -1, 1);
DDA(0, 0, 300, 400);
DDA(0, 0, 200, 200);
glFlush();
glutSwapBuffers();
}
void renderBresenham(void) {
glLoadIdentity();
glOrtho(-500, 500, -500, 500, -1, 1);
Bresenham(0, 0, 300, 100);
Bresenham(0, 0, 500, 0);
glFlush();
glutSwapBuffers();
}