简单的Opengl程序不工作,因为它应该是
这是一个简单的程序,试图实现边界填充算法。作为一个例子,它会尝试用蓝色填充绿色矩形,并保持其他所有内容不变。简单的Opengl程序不工作,因为它应该是
这个程序有什么问题?
这是应用该算法之前的图片: 这是算法应用时的图片。正如你可以清楚地看到算法/应用程序停留在一个地方!
这是源代码:
#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;
}
以下是你需要的程序: 有两种方法,您可以使用。
我觉得方法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;
}
我的第一个建议是阅读整个显示图像到本地存储,这使你不需要做很多的OpenGL调用。然后在本地建立一个新的图像,然后将其推送到显示屏。
。没有glutSwapBuffers()
这是看到的东西很重要。
。您不必使用glFlush()
冲洗管线,即使不是之前的glutSwapBuffers()
。逐像素绘制/读取是缓慢作为地狱,使用纹理或一些聪明的多边形绘制魔法。
首先,你不应该在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纹理,并在帧缓冲区。
你为什么让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;
}
}
非常感谢你,但我应该怎么做,如果我不打算使用上述语句在OpenGL,诚实我不知道你通过在内存中使用cpu进行洪水填充来告诉我什么,然后上传到opengl纹理中!对不起,我是opengl上的noob。 – Breeze 2013-04-07 15:17:12
和我的大问题是,当我阅读像素是绿色的..它显示我的像素是绿色的,当我用蓝色绘制该像素并再次阅读时,我didnet说它的像素是蓝色的...我想知道为什么它剂量显示第二个像素绘图(背景颜色为红色,第一个颜色为绿色,第二个为蓝色) – Breeze 2013-04-07 15:54:17
@Hossein:将整个图片读入一个大缓冲区(即宽度和高度> 1的glReadPixels),然后执行所有像素操作那个缓冲区。另外OpenGL并不意味着被用作像素操作API;这样做效率非常低。 – datenwolf 2013-04-07 16:45:19