seedFilling & glReadPixels

来源:互联网 发布:ajax上传文件到阿里云 编辑:程序博客网 时间:2024/06/05 02:56
  • 部分转载自:here

图形学作业

  • 种子填充画五角星
#include <GL/glut.h>#include <stdlib.h>#include <unistd.h>#include <iostream>#include <math.h>using namespace std;float pCenter[2];float Length, angle = 0;float R, G, B;int wWidth,wHeight;float *rgb;int PosX, PosY;int vis[1000][1000];const double PI = acos(-1.0);typedef struct tagDIRECTION{    int x_offset;    int y_offset;} DIRECTION;// DIRECTION direction_8[] = { {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} };DIRECTION direction_4[] = { { -1, 0}, {0, 1}, {1, 0}, {0, -1}};float* GetPixel(int x, int y){    float *rgb = new float[3];    glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, rgb);    return rgb;}void myDraw(float Pos[2], float Length, float theta){    // cout << Pos[0] << " " << Pos[1] << endl;    glBegin(GL_LINE_LOOP);    float Short = Length * sin(0.1 * PI) / sin(0.7 * PI);    float beta = 18 + theta; //五角星NE的长半径和x轴的夹角    float p1[2];    glColor3f(R, G, B);    for (int i = 0; i < 5; i++) //从最右边的那个长边顶点开始画    {        p1[0] = Length * cos(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0]; //x坐标 18 * 3.1415926 = 56.55        p1[1] = Length * sin(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1]; //y坐标        glVertex2fv(p1);        p1[0] = Short * cos((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0];        p1[1] = Short * sin((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1];        glVertex2fv(p1);    }    glEnd();}void myDraw1(float Pos[2], float Length, float theta){    // cout << Pos[0] << " " << Pos[1] << endl;    // glBegin(GL_LINE_LOOP);    glBegin(GL_TRIANGLES);    float Short = Length * sin(0.1 * PI) / sin(0.7 * PI);    float beta = 18 + theta; //五角星NE的长半径和x轴的夹角    float p1[2], p2[2];    glColor3f(R, G, B);    p2[0] = Short * cos(4 * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0]; //x坐标 18 * 3.1415926 = 56.55    p2[1] = Short * sin(4 * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1]; //y坐标    for (int i = 0; i < 5; i++) //从最右边的那个长边顶点开始画    {        p1[0] = Length * cos(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0]; //x坐标 18 * 3.1415926 = 56.55        p1[1] = Length * sin(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1]; //y坐标        glVertex2fv(p2);        glVertex2fv(Pos);        glVertex2fv(p1);        p2[0] = p1[0], p2[1] = p1[1];        p1[0] = Short * cos((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0];        p1[1] = Short * sin((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1];        glVertex2fv(p2);        glVertex2fv(Pos);        glVertex2fv(p1);        p2[0] = p1[0], p2[1] = p1[1];    }    glEnd();}void myDraw2(float Pos[2], float Length, float theta){    // cout << Pos[0] << " " << Pos[1] << endl;    // glBegin(GL_LINE_LOOP);    glBegin(GL_TRIANGLES);    float Short = Length * sin(0.1 * PI) / sin(0.7 * PI);    float beta = 18 + theta; //五角星NE的长半径和x轴的夹角    float p1[2], p2[2];    glColor3f(R, G, B);    p2[0] = Short * cos(4 * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0]; //x坐标 18 * 3.1415926 = 56.55    p2[1] = Short * sin(4 * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1]; //y坐标    for (int i = 0; i < 5; i++) //从最右边的那个长边顶点开始画    {        p1[0] = Length * cos(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0]; //x坐标 18 * 3.1415926 = 56.55        p1[1] = Length * sin(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1]; //y坐标        glColor3f(1, 1, 0);        glVertex2fv(p2);        glVertex2fv(Pos);        glVertex2fv(p1);        p2[0] = p1[0], p2[1] = p1[1];        p1[0] = Short * cos((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0];        p1[1] = Short * sin((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1];        glColor3f(1, 0, 1);        glVertex2fv(p2);        glVertex2fv(Pos);        glVertex2fv(p1);        p2[0] = p1[0], p2[1] = p1[1];    }    glEnd();}void seedFilling(int x, int y){    // usleep(10000); //4个0的速度还可以忍受    rgb = GetPixel(x - 1, y); //经过测试发现,前面绘制时会绘制到x - 1, y这个像素点    if (rgb[0] == 1) return;    glColor3f(0, 0, 1);    glBegin(GL_POINTS);    glVertex2i(x, y);    glEnd();    vis[x][y] = 1;    for (int i = 0; i < 4; i++)    {        int xx = x + direction_4[i].x_offset;        int yy = y + direction_4[i].y_offset;        if (!vis[xx][yy])            seedFilling(xx, yy);    }    glFlush();}void display(){    glClearColor(0, 1, 0, 0);    glClear(GL_COLOR_BUFFER_BIT);    // // test    // glColor3f(1, 0, 0);    // glBegin(GL_POINTS);    // glVertex2i(100, 100);    // glEnd();    // glFlush();    // for (int i = 80; i <= 120; i++)    // {    //     for (int j = 80; j <= 120; j++)    //     {    //         rgb = GetPixel(i, j);    //         if (rgb[0] == 1)    //         {    //             cout << i << " " << j << "Pos " << '\t';    //             cout << rgb[0] << " " << rgb[1] << endl;    //         } // 对应于glVertex2i(100, 100); 得到的结果是 99, 100    //     }    // }    pCenter[0] = 100; pCenter[1] = 100; Length = 50;    myDraw1(pCenter, Length, angle);    pCenter[0] = 200; pCenter[1] = 200; Length = 50;    myDraw2(pCenter, Length, angle);    // 种子填充 小bug ,可能中间又一次绘制不了    pCenter[0] = 300; pCenter[1] = 300; Length = 50;    myDraw(pCenter, Length, angle);    // cout << (int)pCenter[0] << " " << pCenter[1] << endl;    seedFilling((int)pCenter[0], (int)pCenter[1]);    glFlush();}void Reshape(GLsizei w, GLsizei h){    // seedFilling(300, 300);    cout << "hello" << endl;    cout << w << " " << h << endl;    glViewport(0, 0, w, h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    // gluOrtho2D(0, w, 0, h);    // cout << "hello" << endl;    // seedFilling((int)pCenter[0], (int)pCenter[1]);    // seedFilling(300, 300);    // wWidth = w;    // wHeight = h;    // glMatrixMode (GL_PROJECTION);    // glLoadIdentity ();    // gluOrtho2D(-w/2, w/2, -h/2, h/2);    // glMatrixMode (GL_MODELVIEW);    // glLoadIdentity ();    // glViewport (0, 0, w, h);}int main(int argc, char*argv[]){    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGB);    glutInitWindowPosition(300, 300);    glutInitWindowSize(400, 400);    glutCreateWindow("test");    R = 1, G = 0, B = 0; //全局定义颜色    PosX = 400; PosY = 400;    gluOrtho2D(0, PosX, 0, PosY);    glutDisplayFunc(display);    glutReshapeFunc(Reshape);    glutMainLoop();    return 0;}

void glReadPixels(GLint x,GLint y,GLsizesi width,GLsizei height,GLenum format,GLenum type,GLvoid *pixel);

  • 该函数总共有七个参数。前四个参数可以得到一个矩形,该矩形所包括的像素都会被读取出来。(第一、二个参数表示了矩形的左下角横、纵坐标,坐标以窗口最左下角为零,最右上角为最大值;第三、四个参数表示了矩形的宽度和高度)
  • 第五个参数表示读取的内容,例如:GL_RGB就会依次读取像素的红、绿、蓝三种数据,GL_RGBA则会依次读取像素的红、绿、蓝、alpha四种数据,GL_RED则只读取像素的红色数据(类似的还有GL_GREEN,GL_BLUE,以及GL_ALPHA)。如果采用的不是RGBA颜色模式,而是采用颜色索引模式,则也可以使用GL_COLOR_INDEX来读取像素的颜色索引。目前仅需要知道这些,但实际上还可以读取其它内容,例如深度缓冲区的深度数据等。
  • 第六个参数表示读取的内容保存到内存时所使用的格式,例如:GL_UNSIGNED_BYTE会把各种数据保存为GLubyte,GL_FLOAT会把各种数据保存为GLfloat等。
  • 第七个参数表示一个指针,像素数据被读取后,将被保存到这个指针所表示的地址。注意,需要保证该地址有足够的可以使用的空间,以容纳读取的像素数据。例如一幅大小为256*256的图象,如果读取其RGB数据,且每一数据被保存为GLubyte。
  • 好了,那么重点来了,这个方法的坐标基准点是在画布的左下角!!而我们绘图的基准点是在画布的正中心!!所以我在获取某个点的颜色的时候一直都是错误的结果,这样的话在使用的时候我们的xy坐标值就要加上画布宽高的一半才能正常获取到像素的颜色,希望大家一定注意!!
0 0
原创粉丝点击