2013-04-07 120 views
2

这是一个简单的程序,试图实现边界填充算法。作为一个例子,它会尝试用蓝色填充绿色矩形,并保持其他所有内容不变。简单的Opengl程序不工作,因为它应该是

这个程序有什么问题?

这是应用该算法之前的图片: enter image description here 这是算法应用时的图片。正如你可以清楚地看到算法/应用程序停留在一个地方!

enter image description here

这是源代码:

#include <iostream> 
#include <glut.h> 

using namespace std; 
bool b = false; 
void init(void) 
{ 
    glClearColor(1.0,0.0,0.0,0.0); 
    glMatrixMode(GL_PROJECTION); 
    gluOrtho2D(0.0,1366.0,0.0,768.0); 
} 

bool getpixelcolor(GLint x, GLint y) 
{ 
    unsigned char pick_col[3]; 
    float r,g,b; 
    glReadPixels(x , y , 1 , 1 , GL_RGB , GL_UNSIGNED_BYTE , pick_col); 

    r = pick_col[0]/255.0; 
    g = pick_col[1]/255.0; 
    b = pick_col[2]/255.0; 

    //cout<<"b:"<<b<<"\r\n"; 
    if ((r != 1)&&(b != 1)&&(g == 1))//g==1 
    { 
     return true; 
    } 
    else  
    { 
     return false; 
    } 
} 

void PutPoint(int x, int y) 
{ 
    glBegin (GL_POINTS); 
    glColor3f (1.0,1.0,1.0); 
    glVertex2i (x,y); 
    glEnd(); 

    glFlush(); 
    glPointSize(1); 
    glBegin (GL_POINTS); 
    glColor3f (0.0,0.0,1.0); 
    glVertex2i (x,y); 
    glEnd(); 
    glFlush(); 
} 

void Filling(int x,int y) 
{ 
    bool Value = getpixelcolor(x,y); 
    if (Value==true) 
    { 
     PutPoint(x, y); 
     Filling (x+1,y); 
     Filling (x-1,y); 
     Filling (x,y+1); 
     Filling (x,y-1); 
    } 
} 
void displayfnc() 
{ 
    if (b==false) 
    { 
    glClear(GL_COLOR_BUFFER_BIT); 
     b=true; 
     glColor3f(0.0,1.0,0.0); 
     glRecti(100,100,200,200); 
     glFlush(); 
     Filling(180,180); 
    } 

} 
void Timer(int extra) 
{ 
    glutPostRedisplay(); 
    glutTimerFunc(30,Timer,0); 
} 
int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
    glutInitWindowSize(1366,768); 
    glutInitWindowPosition(0, 0); 
    glutCreateWindow("BoundaryFill"); 
    init(); 
    glutDisplayFunc(displayfnc); 
    glutTimerFunc(10,Timer,0); 
    glutMainLoop(); 
    return 0; 
} 

回答

1

以下是你需要的程序: 有两种方法,您可以使用。
我觉得方法2是你和其他人也需要的边界4填充算法。

方法1:

#include <iostream> 
    #include <glut.h> 

    using namespace std; 
    bool b=true,c=true; 
    bool A[50][50]={false}; 
    void init(void) 
    { 
     glClearColor(1.0,0.0,0.0,0.0); 
     glMatrixMode(GL_PROJECTION); 
     gluOrtho2D(0.0,100.0,0.0,100.0); 
    } 

    bool getpixelcolor(GLint x, GLint y) 
    { 
     unsigned char pick_col[3]; 
     glReadPixels(x , y , 1 , 1 , GL_RGB , GL_UNSIGNED_BYTE , pick_col); 
     float r,g,b; 
     r = pick_col[0]/255.0; 
     g = pick_col[1]/255.0; 
     b = pick_col[2]/255.0; 

     if ((r!=1)&&(b!=1)&&(g==1))g==1 
     { 

      return true; 
     } 
     else  
     { 
      return false; 
     } 
    } 

    void PutPoint(int x, int y) 
    { 

     glPointSize(2); 
     glBegin (GL_POINTS); 
     glColor3f (0.0,0.0,1.0); 
     glVertex2i (x,y); 
     glEnd(); 
     glFlush(); 

    } 

    void Filling(int x,int y) 
    { 
     if (A[x][y]==b&&x<50&&y<50&&x>10&&y>10) 
     { 
      A[x][y]=c; 
      PutPoint(x, y); 
      Filling (x+1,y); 
      Filling (x-1,y); 
      Filling (x,y+1); 
      Filling (x,y-1); 
     } 

    } 
    void displayfnc() 
    { 
      glClear(GL_COLOR_BUFFER_BIT); 
      if(b==false) 
      {b=true; 
      c=false; 
      } 
      else 
       {b=false; 
      c=true; 
      } 

      glColor3f(0.0,1.0,0.0); 
      glRecti(10,50,10,50); 
      Filling(40,40); 

      glFlush(); 

    } 
    int main(int argc, char** argv) 
    { 

     glutInit(&argc, argv); 
     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
     glutInitWindowSize(100,100); 
     glutInitWindowPosition(0, 0); 
     glutCreateWindow("BoundaryFill"); 
     init(); 
     glutDisplayFunc(displayfnc); 
     glutMainLoop(); 
     return 0; 
    } 

方法2:

#include <iostream> 
    #include <glut.h> 

    using namespace std; 
    unsigned char pick_col[50][50][3]; 
    void init(void) 
    { 
     glClearColor(1.0,0.0,0.0,0.0); 
     glMatrixMode(GL_PROJECTION); 
     gluOrtho2D(0.0,100.0,0.0,100.0); 
    } 

    void readAllToBuffer(GLint _start, GLint _end) 
    { 

     for (int i=_start;i<_end;i++) 
     { 
      for (int j=_start;j<_end;j++) 
      { 
       glReadPixels(i , j , 1 , 1 , GL_RGB , GL_UNSIGNED_BYTE , pick_col[i][j]); 
      } 
     } 
    } 

    bool getpixelcolor(GLint x, GLint y) 
    { 
     int r,g,b; 
     r = pick_col[x][y][0]; 
     g = pick_col[x][y][1]; 
     b = pick_col[x][y][2]; 

     //cout<<"b:"<<b<<"\r\n"; 
     if ((r!=255)&&(b!=255)&&(g==255))//g==1 
     { 
      return true; 
     } 
     else  
     { 
      return false; 
     } 
    } 

    void PutPoint(int x, int y) 
    { 
     pick_col[x][y][0]=0; 
     pick_col[x][y][1]=0; 
     pick_col[x][y][2]=255; 
     glPointSize(2); 
     glBegin (GL_POINTS); 
     glColor3f (0.0,0.0,1.0); 
     glVertex2i (x,y); 
     glEnd(); 
     glFlush(); 

    } 

    void Filling(int x,int y) 
    { 
     bool Value=getpixelcolor(x,y); 
     if (Value==true) 
     { 
      PutPoint(x, y); 

      Filling (x+1,y); 
      Filling (x-1,y); 
      Filling (x,y+1); 
      Filling (x,y-1); 
     } 
    } 
    void displayfnc() 
    { glClear(GL_COLOR_BUFFER_BIT); 

      glColor3f(0.0,1.0,0.0); 
      glRecti(0,0,50,50); 
      glFlush(); 
      readAllToBuffer(0, 49); 
      Filling(40,40); 
      glFlush(); 

    } 
    void Timer(int extra) 
    { 
     glutPostRedisplay(); 
     glutTimerFunc(30,Timer,0); 
    } 
    int main(int argc, char** argv) 
    { 

     glutInit(&argc, argv); 
     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 
     glutInitWindowSize(100,100); 
     glutInitWindowPosition(0, 0); 
     glutCreateWindow("BoundaryFill"); 
     init(); 
     glutDisplayFunc(displayfnc); 
     //glutTimerFunc(10,Timer,0); 
     glutMainLoop(); 
     return 0; 
    } 
2

我的第一个建议是阅读整个显示图像到本地存储,这使你不需要做很多的OpenGL调用。然后在本地建立一个新的图像,然后将其推送到显示屏

0

。没有glutSwapBuffers()这是看到的东西很重要。

。您不必使用glFlush()冲洗管线,即使不是之前的glutSwapBuffers()

。逐像素绘制/读取是缓慢作为地狱,使用纹理或一些聪明的多边形绘制魔法。

3

首先,你不应该在OpenGL中用glReadPixels/glBegin(GL_POINTS)窥视和捅像素 - 它的速度要慢得多。如果要在CPU上实施泛洪填充,请回读整个图像并在CPU内存上执行。

你的一个最大的问题是这样的,但:

r = pick_col[0]/255.0; 
g = pick_col[1]/255.0; 
b = pick_col[2]/255.0; 

if ((r != 1)&&(b != 1)&&(g == 1)) 

决不彩车上执行相等测试!老实说,在我看来编译器应该发出一个很大的警告,或者如果你在浮动上执行==!=,甚至可能会出错。浮点数总是与误差幅度相关联,并且当您比较大多数情况下的相等浮点数时,他们将比较为不相等(即使它们只相差很小的ε> 0),它的本质。

为什么不直接测试精确定义的无错整数?

uint8_t r,g,b; 
/* ... */ 
if ((r != 0xff) && (b != 0xff)&& (g == 0xff)) 

如果启用了全屏抗锯齿(FSAA),则可能会遇到的问题是。在这种情况下,您拨动的点可能会反锯齿,导致像素颜色被设置为而不是到您指定的值,在这种情况下,您的填充填充算法将失败。也许增加一些保证金/门槛。或者做一些合理的事情,并掌握如何将值存入内存,自己做,即回读整个图片到CPU内存,做你的洪水填充,并将其上传到OpenGL纹理,并在帧缓冲区。

+0

非常感谢你,但我应该怎么做,如果我不打算使用上述语句在OpenGL,诚实我不知道你通过在内存中使用cpu进行洪水填充来告诉我什么,然后上传到opengl纹理中!对不起,我是opengl上的noob。 – Breeze 2013-04-07 15:17:12

+0

和我的大问题是,当我阅读像素是绿色的..它显示我的像素是绿色的,当我用蓝色绘制该像素并再次阅读时,我didnet说它的像素是蓝色的...我想知道为什么它剂量显示第二个像素绘图(背景颜色为红色,第一个颜色为绿色,第二个为蓝色) – Breeze 2013-04-07 15:54:17

+1

@Hossein:将整个图片读入一个大缓冲区(即宽度和高度> 1的glReadPixels),然后执行所有像素操作那个缓冲区。另外OpenGL并不意味着被用作像素操作API;这样做效率非常低。 – datenwolf 2013-04-07 16:45:19

0

你为什么让r,g,b漂浮?

我会改变这一切功能:

bool getpixelcolor(GLint x, GLint y) 
{ 
    unsigned char pick_col[3]; 
    glReadPixels(x , y , 1 , 1 , GL_RGB , GL_UNSIGNED_BYTE , pick_col); 

    if ((pick_col[0] != 255)&&(pick_col[1] != 255)&&(pick_col[2] == 255))//g==1 
    { 
     return true; 
    } 
    else  
    { 
     return false; 
    } 
} 
+0

坦克,但它并没有改变任何东西! – Breeze 2013-04-07 15:18:48

+0

我只修正了我所知道的(: – 2013-04-07 15:22:57

+0

tanx再bro :) – Breeze 2013-04-07 20:21:49

相关问题