我正在使用opengl实现此dda算法。但是,由于某种原因,它不会绘制第二行。我尝试将printf放在每一行,这表明它正在执行。但是,我的窗口中没有输出
#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;
}
我也尝试过换线。然后,它仅绘制上线。它确实会执行第二个调用。
答案 0 :(得分:1)
glOrtho
未设置正投影,而是定义了正投影矩阵并将当前矩阵与正投影矩阵相乘。
您必须在调用glOrtho
之前设置身份矩阵:
glLoadIdentity();
glOrtho(-500, 500, -500, 500, -1, 1);
此外,算法中存在问题。 x
和y
的类型必须为float
。如果将结果截断为int
,则只能绘制角度与45度的倍数对齐的线,因为x
和y
的变化恰好为0或1在每个步骤中:
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();
}
请注意,将类型从int
更改为float
会导致对x
和y
进行精确跟踪。 glVertex2i((int)(x+0.5f), (int)(y+0.5f))
确保在绘制点时将坐标(x
,y
)舍入到整数位置。
我建议将投影矩阵的设置分别从glFlush
和DDA
从Bresenham
分别移到renderDDA
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();
}