Есть программа, которая должна закрашивать фигуру алгоритмом заполнения с затравкой. Однако из-за ошибки она не работает правильно. Подозреваю, что неверно работает функция glReadPixels в функции coloured.
Код:
#include <GL/glut.h>
#include <Windows.h>
#include <iostream>
#include <locale>
#include <stack>
using namespace std;
int Width = 512, Height = 512;
int points = 0;
//********* Структуры данных
typedef GLubyte colorType[3];
struct GLfloatPoint
{
GLfloat x,y;
};
struct GLintPoint
{
GLint x,y;
};
const int MAX = 100;
struct GLintPointArray
{
GLintPoint pt[MAX];
};
GLintPointArray Pol;
void keyboard ( unsigned char key, int x, int y)
{
switch (key)
{
case 'q': exit(0);
break;
}
}
void drawPolygon (GLintPointArray Pol, colorType c)
{
glColor3ubv(c);
glBegin(GL_LINE_LOOP);
for (int i=0; i < points; i++)
glVertex2i (Pol.pt[i].x,Pol.pt[i].y);
glEnd();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int ax, int ay)
{
if (button == GLUT_LEFT_BUTTON && state != GLUT_DOWN)
{
Pol.pt[points].x = ax;
Pol.pt[points].y = ay;
points++;
}
}
bool max(GLintPointArray Pol , int &x, int &y)
{
for(int i = 0; i < points; i++)
{
if (Pol.pt[i].x > x)
x = Pol.pt[i].x;
if (Pol.pt[i].y > y)
y = Pol.pt[i].y;
}
return 0;
}
bool min(GLintPointArray Pol , GLint &x, GLint &y)
{
for(int i = 0; i < points; i++)
{
if (Pol.pt[i].x < x)
x = Pol.pt[i].x;
if (Pol.pt[i].y < y)
y = Pol.pt[i].y;
}
return 0;
}
bool colour(GLintPoint a, colorType c)
{
glColor3ubv(c);
glBegin(GL_POINTS);
glVertex2i(a.x, a.y);
glEnd();
return 1;
}
// c - цвет заливки, d - цвет контура
bool coloured(GLintPoint a, colorType c, colorType d)
{
GLubyte pixColor[3];
glReadPixels(a.x,a.y,1,1,GL_RGB, GL_UNSIGNED_BYTE, &pixColor);
//если закрашено
if (pixColor[0] == c[0] && pixColor[1] == c[1] && pixColor[2] == c[2])
{
return 1;
}
//если граница
else if (pixColor[0] == d[0] && pixColor[1] == d[1] && pixColor[2] == d[2])
{
return 1;
}
return 0;
}
// алгоритм заполнения с затравкой
void fill(GLintPointArray Pol, colorType c, colorType d)
{
stack <GLintPoint> st;
GLintPoint centr;
// вычисление центра фигуры
int x_max = 0, y_max = 0;
max(Pol, x_max, y_max);
int x_min = x_max, y_min = y_max;
min(Pol, x_min, y_min);
centr.x = (x_max + x_min)/2;
centr.y = (y_max + y_min)/2;
//поместить затравочный пиксель в стек
st.push(centr);
while (!st.empty())
{
// извлечь пиксель из стека
GLintPoint p = st.top();
st.pop();
// закрасить
colour(p, c);
GLintPoint p1, p2, p3, p4;
p1.x = p.x + 1; p1.y = p.y;
p2.x = p.x; p2.y = p.y + 1;
p3.x = p.x; p3.y = p.y - 1;
p4.x = p.x - 1; p4.y = p.y;
if (!coloured(p1, c, d))
st.push(p1);
if (!coloured(p2, c, d))
st.push(p2);
if (!coloured(p3, c, d))
st.push(p3);
if (!coloured(p4, c, d))
st.push(p4);
}
}
void draw()
{
glClear (GL_COLOR_BUFFER_BIT);
colorType Red = {255,0,0};
colorType Green = {0,255,0};
colorType Blue = {0,0,255};
// создать полигон
drawPolygon(Pol, Green);
if (points > 2)
fill(Pol, Red, Green);
glutSwapBuffers();
glutPostRedisplay();
}
void initialize()
{
glClearColor (1.0, 1.0, 1.0, 1.0);
glMatrixMode (GL_PROJECTION);
glClear(GL_COLOR_BUFFER_BIT); // очистить экран
}
int main(int iArgc,char** cppArgv)
{
glutInit (&iArgc, cppArgv);
glutInitDisplayMode (GLUT_RGB);
glutInitWindowSize(Width, Height);
glutInitWindowPosition (0, 0);
glutCreateWindow ("LB");
initialize();
glutReshapeFunc (reshape);
glutMouseFunc(mouse);
glutDisplayFunc (draw);
glutKeyboardFunc(keyboard);
glutMainLoop ();
glutSwapBuffers();
}