我一直在尝试使用我进行设置的 Visual Studio 代码在我的 m1 mac 上执行一个简单的 边界填充 程序,包括配置默认构建任务的所有库,并且构建进展顺利。
但问题是当窗口可见时,程序有一个鼠标单击事件侦听器,单击时应该开始用所需的颜色填充区域,但似乎仅在绘制一条线后就停止了。
这是我的程序,
#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;
}
请检查图像——在此阶段之后,递归停止,这意味着以 8 个连接的方法填充更多像素。
正交投影覆盖 [0, 500]^2 像素的区域,而算法假设 [0, 500)^2 像素的区域。请注意包含范围和排除范围之间的差异。 这可能会导致
glReadPixels
读取您期望读取的位置左边(和/或下方)的像素值,从而破坏算法。要解决此问题,请对 glOrtho2D
使用不同的尺寸:
gluOrtho2D(0, 499, 0, 499);
另外,注意
glReadPixels
的宽度和高度参数应为整数,即:
glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, CurrentColor);
并且直接比较浮点值并不是一个好主意(请参阅 StackOverflow 上的其他地方)。相反,使用这样的东西:
#include <math.h>
int isEqualFloat(float x, float y)
{
return fabs(x - y) < 0.001F;
}
我假设使用
glReadPixels
是出于教育目的。更好的方法是为“访问的”像素存储一个布尔矩阵,这样就无需比较浮点值中的颜色并从 GPU 内存中检索数据。
最后,使用最新的 Mac 可能会产生影响。对于某些低分辨率程序,操作系统决定重复每个像素以避免窗口非常小。然而,这实际上使分辨率加倍,而 OpenGL 并不知道。