从其他线程将 opengl 纹理保存在 tiff 文件中

Save an opengl texture in tiff file from an other thread

我正在尝试从其他线程将纹理保存在 tiff 文件中。但我得到的唯一结果是一张白色图片,我认为它来自 glcontext(因为多个线程不可能有一个 glcontext)。这就是为什么我试图创建两个 glcontext 并共享显示上下文。但我仍然没有 gl 纹理。我无法从第二个 opengl 上下文中获取纹理 .我正在尝试这样做,因为最后纹理将是来自相机的视频流。 这是我的上下文创建:

static  PIXELFORMATDESCRIPTOR pfd =
                {
                    sizeof(PIXELFORMATDESCRIPTOR),              // Size Of This Pixel Format Descriptor
                    1,                                          // Version Number
                    PFD_DRAW_TO_WINDOW |                        // Format Must Support Window
                    PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL
                    PFD_DOUBLEBUFFER,                           // Must Support Double Buffering
                    PFD_TYPE_RGBA,                              // Request An RGBA Format
                    8,                                          // Select Our Color Depth
                    0, 0, 0, 0, 0, 0,                           // Color Bits Ignored
                    0,                                          // No Alpha Buffer
                    0,                                          // Shift Bit Ignored
                    0,                                          // No Accumulation Buffer
                    0, 0, 0, 0,                                 // Accumulation Bits Ignored
                    16,                                         // 16Bit Z-Buffer (Depth Buffer)  
                    0,                                          // No Stencil Buffer
                    0,                                          // No Auxiliary Buffer
                    PFD_MAIN_PLANE,                             // Main Drawing Layer
                    0,                                          // Reserved
                    0, 0, 0                                     // Layer Masks Ignored
                };

                GLuint PixelFormat;
                // create the pixel pixel format descriptor
                PixelFormat = ChoosePixelFormat(dc, &pfd);
                //  set the pixel format descriptor
                SetPixelFormat(dc, PixelFormat, &pfd);
                gl = wglCreateContext(dc);
                gl2 = wglCreateContext(dc);
                wglShareLists(gl, gl2);
                wglMakeCurrent(dc, gl);
                GLenum g= glewInit();
                wglewInit();
                loadImage();
                rec = new Recorder(dc,gl2);
                rec->Start_StopRecord(text, true);

这是保存到 tiff 文件的代码:

    Recorder::Recorder(HDC &hdc, HGLRC &_gl)
{
    isStarted = false;
    dc = hdc;
    gl = _gl;
}


Recorder::~Recorder()
{
    if (isStarted) {
        isStarted = false;
        recordThread.join();
        CloseTifFile();
        delete mp_fileTifIn;
    }
}

void Recorder::Start_StopRecord(GLuint Texture, bool launched){
    if (launched) {
        if (isStarted) {
            wglMakeCurrent(dc, gl);
            isStarted = false;
            recordThread.join();
            CloseTifFile();
            pixels.release();
        }
        else {
            isStarted = true;
            //wglMakeCurrent(NULL, NULL);
            //RecordShot(&Texture);
            recordThread = std::thread(&Recorder::RecordShot, this,&Texture);
        }
    }
}
void Recorder::RecordShot(GLuint* texture){
    wglMakeCurrent(dc, gl);

    OpenTifFile(*texture);

    pixels = std::unique_ptr<int>(new int[width*height]);

        //while (isStarted) {
            WriteTif8Bits(*texture);
            WriteDirectory();
            //Sleep(16);
        //}
        pixels.release();
}

void Recorder::OpenTifFile(GLuint &Texture){
    char* filename="../test3.tiff";
    glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height);
    glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width);
    mp_fileTifIn = TIFFOpen(filename,"w");

}

void Recorder::CloseTifFile(){
    TIFFClose(mp_fileTifIn);
}
/*
 * Open Sub data for a Tiff file (allow multiple picture in one tif file)
 */
void Recorder::WriteDirectory(){
    TIFFWriteDirectory(mp_fileTifIn);
}

void Recorder::WriteTif8Bits(GLuint &Texture){
    //Setup Tiff Configuration
    TIFFSetField(mp_fileTifIn,TIFFTAG_IMAGEWIDTH,width);
    TIFFSetField(mp_fileTifIn,TIFFTAG_IMAGELENGTH,height);
    TIFFSetField(mp_fileTifIn,TIFFTAG_SAMPLESPERPIXEL,4);
    TIFFSetField(mp_fileTifIn,TIFFTAG_BITSPERSAMPLE,8);
    TIFFSetField(mp_fileTifIn,TIFFTAG_ROWSPERSTRIP,TIFFDefaultStripSize(mp_fileTifIn,width));
    TIFFSetField(mp_fileTifIn,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT);
    TIFFSetField(mp_fileTifIn,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
    TIFFSetField(mp_fileTifIn, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
    TIFFSetField(mp_fileTifIn, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
    glBindTexture(GL_TEXTURE_2D,Texture);
    assert(glGetError() == GL_NO_ERROR);

    glGetTexImage(GL_TEXTURE_2D,0,GL_RGBA,GL_UNSIGNED_BYTE,pixels.get());
    assert(glGetError() == GL_NO_ERROR);
    //Image Reversal
    Reverse(pixels.get(), height, width);

    //Write one picture
    /*for (int row = 0; row < height; row++) {
        TIFFWriteScanline(mp_fileTifIn, pixels.get(), row, 0);
        lineChange(pixels.get(), width);
    }*/
    TIFFWriteEncodedStrip(mp_fileTifIn, 0, pixels.get(), height*width * sizeof(int));
}
void Recorder::lineChange(int* pointer, int width) {
    pointer -= width;
}
void Recorder::Reverse(int* pointer, int height, int width) {
    pointer += (height - 1) * width;
}

这里是 loadImages 函数

int loadImage() {
wglMakeCurrent(dc, gl);
cv::Mat image;
image = cv::imread(std::string("C:/Users/Public/Pictures/Sample Pictures/Desert.jpg"), CV_LOAD_IMAGE_COLOR);
if (!image.data)
    return -1;
cvNamedWindow("try", cv::WINDOW_AUTOSIZE);
cv::imshow("try", image);
cv::flip(image, image, 0);
glGenTextures(1, &text);
GLenum g=glGetError();
glBindTexture(GL_TEXTURE_2D, text);
assert(glGetError() == GL_NO_ERROR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.cols, image.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, image.ptr());
return 0;

}

这是一个测试项目,我正在使用 opencv 加载图片,并尝试将其保存在另一个线程中:https://mega.nz/#!SBMUnJRI!dLC_l9hmCkhIDDUaygHuq4Kw2SKIuxRE7m19md74p0k

到运行项目你需要Opencv和glew,libtiff已经打包在里面了 如果您认为此 post 缺少某些想法,我邀请您在降级之前对其发表评论,因为我正在关注我的主题

我终于通过在一个线程中执行所有 opengl 操作解决了我的问题(我检索图像并在一个线程中显示它,然后将其保存在另一个不需要 openglcontext 的线程中) 另一件让我困惑的事情是

的错误配置
glGetTexImage(GL_TEXTURE_2D,0,GL_RGBA,GL_UNSIGNED_BYTE,this->rec[0].pixels.get());

但我的纹理是 GL_TEXTURE_RECTANGLE_NV,这就是为什么我有时只有一张白色图片。