Как получить цвет из пикселя? OpenGL

#opengl

#opengl

Вопрос:

Я хотел бы получить цвет из пикселя в моей игре и сохранить этот цвет в переменной. Как это сделать в opengl?

Ответ №1:

glReadPixels() :

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

using namespace std;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-10, 10, -10, 10, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glPushMatrix();
        glScalef(5,5,5);
        glBegin(GL_TRIANGLES);
            glColor3ub(255,0,0);
            glVertex2f(-1,-1);
            glColor3ub(0,255,0);
            glVertex2f(1,-1);
            glColor3ub(0,0,255);
            glVertex2f(1,1);
        glEnd();
    glPopMatrix();

    glutSwapBuffers();
}

void motion(int x, int y)
{
    y = glutGet( GLUT_WINDOW_HEIGHT ) - y;

    unsigned char pixel[4];
    glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
    cout << "R: " << (int)pixel[0] << endl;
    cout << "G: " << (int)pixel[1] << endl;
    cout << "B: " << (int)pixel[2] << endl;
    cout << endl;
}

int main(int argc, char **argv)
{
    glutInitWindowSize(640,480);
    glutInit(amp;argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutCreateWindow("glReadPixels()");

    glutDisplayFunc(display);
    glutPassiveMotionFunc(motion);
    glutMainLoop();
    return 0;
}
  

Комментарии:

1. Красивый код, короткий и работает так, как ожидалось. Вы разместили код для проверки / отображения цвета пикселя внутри процедуры отображения. Это работает быстро, но когда рисунок более сложный, программа не работает должным образом. Как насчет того, чтобы поместить приведенный выше код в процедуру motion, например [здесь] ? ( en.wikibooks.org/wiki/Fractals/Computer_graphic_techniques/2D /… )

Ответ №2:

 struct{ GLubyte red, green, blue; } pixel;
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, amp;pixel);
  

Ответ №3:

 #include <math.h>
#include <gl/glut.h>

struct Point {
    GLint x;
    GLint y;
};

struct Color {
    GLfloat r;
    GLfloat g;
    GLfloat b;
};

void init() {
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glColor3f(0.0, 0.0, 0.0);
    glPointSize(1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, 640, 0, 480);
}
  //this function is used for getting color of pixel
Color getPixelColor(GLint x, GLint y) {
    Color color;
    glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, amp;color);
    return color;
}

void setPixelColor(GLint x, GLint y, Color color) {
    glColor3f(color.r, color.g, color.b);
    glBegin(GL_POINTS);
    glVertex2i(x, y);
    glEnd();
    glFlush();
}

void floodFill(GLint x, GLint y, Color oldColor, Color newColor) {
    Color color;
    color = getPixelColor(x, y);

    if(color.r == oldColor.r amp;amp; color.g == oldColor.g amp;amp; color.b == oldColor.b)
    {
        setPixelColor(x, y, newColor);
        floodFill(x 1, y, oldColor, newColor);
        floodFill(x, y 1, oldColor, newColor);
        floodFill(x-1, y, oldColor, newColor);
        floodFill(x, y-1, oldColor, newColor);
    }
    return;
}

void onMouseClick(int button, int state, int x, int y)
{
    Color newColor = {1.0f, 0.0f, 0.0f};
    Color oldColor = {1.0f, 1.0f, 1.0f};

    floodFill(320, 240, oldColor, newColor);
}

void draw_circle(Point pC, GLfloat radius) {
    GLfloat step = 1/radius;
    GLfloat x, y;

    for(GLfloat theta = 0; theta <= 360; theta  = step) {
        x = pC.x   (radius * cos(theta));
        y = pC.y   (radius * sin(theta));
        glVertex2i(x, y);
    }
}

void display(void) {
    Point pt = {320, 240};
    GLfloat radius = 50;

    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);
        draw_circle(pt, radius);
    glEnd();
    glFlush();
}

int main(int argc, char** argv)
{
    glutInit(amp;argc, argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Open GL");
    init();
    glutDisplayFunc(display);
    glutMouseFunc(onMouseClick);
    glutMainLoop();
    return 0;
}