glReadPixels GL_DEPTH_COMPONENT и цвет

Как получить информацию о глубине и цвете из любого рисунка OpenGL? Я хотел бы сохранить изображение глубины и изображение цвета на диск. Я пробовал следующее:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

glBegin(GL_POINTS);
    glColor3f(1.0f,1.0f,1.0f); 
    for(int i=0; i<mesh->vertices.size();i++) {

        if(! mesh->colors.empty()) {
            glColor3f(mesh->colors[i][0],mesh->colors[i][1],mesh->colors[i][2]); 
        }   

        float x= mesh->vertices[i][0];
        float y= mesh->vertices[i][1];
        float z = mesh->vertices[i][2];         
        glVertex3f(x, y, z);

    }

glEnd();

glFlush();
glFinish();

int width = 1280;
int height = 960;

GLfloat* depths;
depths = new GLfloat[ width * height ];

GLfloat * color;
color = new GLfloat[width * height];

glReadPixels (0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depths); 
glReadPixels (0, 0, width, height, GL_BLUE, GL_FLOAT, color);

Но похоже, что заполнен только массив глубин?


person Ben    schedule 06.12.2010    source источник
comment
Есть ли в цветах вершин вашего меша синий цвет?   -  person genpfault    schedule 06.12.2010
comment
Да, они делают..! Но все та же проблема. Пробовал так: IplImage* toSave = cvCreateImage(cvSize((int)width,(int)height), IPL_DEPTH_32F, 3); glReadPixels( 0, 0, (int)width, (int)height, GL_BGR, GL_FLOAT, toSave-›imageData ); toSave-›origin = 1; cvSaveImage(test.png, toSave);   -  person Ben    schedule 06.12.2010
comment
Если я использую то же самое внутри qglviewer, он работает... но я не знаю, почему...   -  person Ben    schedule 07.12.2010


Ответы (2)


Для сохранения результата рендеринга в изображение необходимо сохранить информацию о цветовом буфере (не напрямую из буфера глубины).

Вы можете предоставить отдельные проходы для цвета (в цветовой буфер) и глубины в тот же цветовой буфер. И просто используйте glReadPixels два раза, сначала после рендеринга цвета в цветовой буфер, а второй после рендеринга глубины в цветовом буфере.

Для одновременной записи цвета и глубины в два отдельных цветовых буфера за один проход вы можете использовать MRT (Multiple Render Targets), учебник - http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-рендеринг-в-текстуру/ .

Я бы выбрал МРТ. :) После этого вы можете сохранить свои результаты, используя glReadPixels, как в технике двух проходов.

Но сначала вы должны настроить, из какого цветового буфера вы хотите считывать пиксели, используя glReadBuffer, цветовой буфер по умолчанию — GL_BACK, что означает буфер контекста OpenGL по умолчанию. Используя MRT, вы должны использовать одно из значений GL_COLOR_ATTACHMENTi для записи в буферы цвета, а также одно из значений glReadBuffer.

Итак, просто настройте glReadBuffer с одним из GL_COLOR_ATTACHMENTi и используйте glReadPixels.

person xmash    schedule 16.02.2015

Попробуй это:

#include <GL/freeglut.h>
#include <vector>
#include <sstream>

int mx = 0, my = 0;
void passiveMotion( int x, int y )
{
    mx = x;
    my = glutGet( GLUT_WINDOW_HEIGHT ) - y;
    glutPostRedisplay();
}

void display()
{
    glEnable(GL_DEPTH_TEST);
    glClearColor( 0, 0, 0, 1 );
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    const int w = glutGet( GLUT_WINDOW_WIDTH );
    const int h = glutGet( GLUT_WINDOW_HEIGHT );
    const double ar = (double)w / (double)h;
    glOrtho( -10 * ar, 10 * ar, -10, 10, -10, 10 );

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

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

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

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho( 0, w, 0, h, -1, 1 );
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // print depth
    {
        GLfloat depth = 0.0f;
        glReadPixels( mx, my, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth ); 
        std::ostringstream oss;
        oss << "Depth: " << depth;
        glColor3ub( 255, 255, 255 );
        glRasterPos2i( 10, 10 );
        glutBitmapString( GLUT_BITMAP_9_BY_15, (const unsigned char*)oss.str().c_str() );
    }

    // print color
    {
        GLubyte color[4];
        glReadPixels( mx, my, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color ); 
        std::ostringstream oss;
        oss << "Color:"
            << " " << (unsigned int)color[0]
            << " " << (unsigned int)color[1]
            << " " << (unsigned int)color[2]
            << " " << (unsigned int)color[3];
        glColor3ub( 255, 255, 255 );
        glRasterPos2i( 10, 25 );
        glutBitmapString( GLUT_BITMAP_9_BY_15, (const unsigned char*)oss.str().c_str() );
    }

    glutSwapBuffers();
}

int main( int argc, char** argv )
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowSize(400,400);
    glutCreateWindow("GLUT");
    glutDisplayFunc( display );
    glutPassiveMotionFunc( passiveMotion );
    glutMainLoop();
    return 0;
}
person genpfault    schedule 06.12.2010