我一直试图在我的M1Mac上执行一个简单的边界填充程序,使用的是我安装的Visual Studio代码,包括所有配置默认构建任务的库,构建工作完成得很好。
但问题是,当窗口可见时,程序有一个鼠标单击事件侦听器,单击它应该会开始使用所需的颜色填充区域,但似乎在只绘制了一条线后停止。
这是我的节目,
# include<stdio.h>
# include <GLUT/glut.h>
int xmin, ymin, xmax, ymax; //Polygon boundaries
float FillColor[3] = {1.0, 0.0, 0.0}; //Color to be filled - red
float BorderColor[3] = {0.0, 0.0, 0.0}; // Border color of polygon - black
void setPixel(int x, int y)
{
glBegin(GL_POINTS);
glColor3fv(FillColor);
glVertex2i(x, y);
glEnd();
glFlush();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
//Drawing polygon
glColor3fv(BorderColor);
glLineWidth(6);
glBegin(GL_LINES);
glVertex2i(xmin, ymin);
glVertex2i(xmin, ymax);
glEnd();
glBegin(GL_LINES);
glVertex2i(xmax, ymin);
glVertex2i(xmax, ymax);
glEnd();
glBegin(GL_LINES);
glVertex2i(xmin, ymin);
glVertex2i(xmax, ymin);
glEnd();
glBegin(GL_LINES);
glVertex2i(xmin, ymax);
glVertex2i(xmax, ymax);
glEnd();
glFlush();
}
void BoundaryFill(int x,int y)
{
float CurrentColor[3];
glReadPixels(x, y, 1.0, 1.0, GL_RGB, GL_FLOAT, CurrentColor);
// if CurrentColor != BorderColor and CurrentColor != FillColor
if((CurrentColor[0] != BorderColor[0] && (CurrentColor[1]) != BorderColor[1] &&
(CurrentColor[2])!= BorderColor[2]) && (CurrentColor[0] != FillColor[0] &&
(CurrentColor[1]) != FillColor[1] && (CurrentColor[2]) != FillColor[2]))
{
setPixel(x, y);
BoundaryFill(x+1, y);
BoundaryFill(x-1, y);
BoundaryFill(x, y+1);
BoundaryFill(x, y-1);
//Using 4-connected approach, remove comment from below lines to make it 8-connected approach
BoundaryFill(x+1, y+1);
BoundaryFill(x+1, y-1);
BoundaryFill(x-1, y+1);
BoundaryFill(x-1, y-1);
}
}
void mouse(int btn, int state, int x, int y)
{
if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
printf("%d, %d\n", x, y);
BoundaryFill(x, 500-y);
}
}
void init()
{
glClearColor(0.101, 1.0, 0.980, 1.0); //Background color - cyan
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0, 500, 0, 500);
}
int main(int argc, char**argv)
{
printf("Window size - 500x500 i.e. range of x and y is 0 -> 500\n");
printf("\nEnter polygon boundaries:-\n");
printf("Enter xmin: ");
scanf("%d", &xmin);
printf("Enter ymin: ");
scanf("%d", &ymin);
printf("Enter xmax: ");
scanf("%d", &xmax);
printf("Enter ymax: ");
scanf("%d", &ymax);
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Boundary-Fill Algorithm");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
1条答案
按热度按时间pgky5nke1#
正交投影覆盖的面积为[0,500]^2像素,而算法假设的面积为[0,500)^2像素。请注意包含范围和排除范围之间的差异。这可能会导致
glReadPixels
读取其预期读取位置左侧(和/或下方)的像素值,从而破坏算法。要解决此问题,请为glOrtho2D
使用不同的尺寸:另外,
glReadPixels
的宽度和高度参数应该是整数,即:而且直接比较浮点值并不是一个好主意(参见StackOverflow的其他部分)。取而代之的是使用如下内容:
我假设
glReadPixels
在这里的用法是为了教育目的。一种更好的方法是存储“已访问”像素的布尔矩阵,这样就不需要比较浮点值中的颜色和从GPU内存中检索数据。最后,使用最新的Mac电脑可能会产生影响。对于一些低分辨率的程序,操作系统决定重复每个像素,以避免窗口太小。然而,这实际上会在OpenGL不知情的情况下将分辨率提高一倍。