使用带有nvidia立体3D的OpenGL Quad Buffer显示延迟

时间:2014-09-16 10:02:32

标签: opengl 3d

我需要使用OpenGL Quad Buffer在c ++中进行视频渲染的立体3D应用程序,以实现实时性能(60fps)。该应用程序在Xubuntu Lts 14.04上运行。 我的硬件设置由两个Gopro摄像头,一个nvidia quadro k4000卡和一个120Hz显示器组成。

我在观看显示的立体声视频时遇到图像延迟。 在单声道设置中仅使用一台摄像机进行显示时没有重要的延迟,而不使用四重缓冲功能。

当测量从OpenGL执行显示功能的时间时,在大多数周期内执行时间不到10毫秒,但是有超过60毫秒的峰值可能是这种延迟的起因。

我已经在图片卡上设置了同步到vblank选项并进行了测试,差异非常小,导致屏幕上出现相同的延迟图像。

下面的代码是更复杂的应用程序的一部分,所以我希望我提供的部分至少可以阐明我想要实现的目标。

编辑1:这是显示功能之外的初始化代码。

createTexture(&textureID, width, height);

createPBO(&pbo, width, height);

// map OpenGL buffer object for writing from CUDA
cudaGLMapBufferObject((void **)(Img, pbo);

// Unmap Buffers
cudaGLUnmapBufferObject(pbo);

// Paths for the stereo shaders' files
const std::string vertex_file_path = "VertexShader_stereo.vertexshader";
const std::string fragment_file_path = "FragmentShader_stereo.fragmentshader";

GLfloat vertices [] = {
    // Position (2 elements) Texcoords (2 elements)
    -1.0f, 1.0f, 0.0f, 0.0f,  // Top-left
    1.0f, 1.0f,  1.0f, 0.0f,  // Top-right
    1.0f, -1.0f,  1.0f, 1.0f, // Bottom-right
    -1.0f, -1.0f, 0.0f, 1.0f  // Bottom-left
  };

GLushort elements [] = {
    0, 1, 2, // indices of the first triangle
    2, 3, 0  // indices of the second triangle
  };

// Create a pixel buffer object for the right view
createPBO(&pbo_Right, width, height);

// map OpenGL buffer object for writing from CUDA
cudaGLMapBufferObject((void **)Img_Right, pbo_Right);

// Unmap Buffers
cudaGLUnmapBufferObject(pbo_Right);

// Create a vector buffer object
createVBO(&vbo, vertices, sizeof(vertices));
// Create a element buffer object
createEBO(&ebo, elements, sizeof(elements));

// Create shader program from the shaders
shaderProgram = LoadShader(vertex_file_path, fragment_file_path);

posAttrib = glGetAttribLocation(shaderProgram, "position");
texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
}

编辑2:createPBO功能如下:

createPBO(GLuint* pbo_, unsigned int w, unsigned int h) {
        // set up vertex data parameter
        int num_texels = w * h;
        int num_values = num_texels * 4;
        int size_tex_data = sizeof(GLubyte) * num_values;

        // Generate a buffer ID called a PBO (Pixel Buffer Object)
        glGenBuffers(1, pbo_);
        // Make this the current UNPACK buffer (OpenGL is state-based)
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *pbo_);
        // Allocate data for the buffer. 4-channel 8-bit image
        glBufferData(GL_PIXEL_UNPACK_BUFFER, size_tex_data, NULL, GL_DYNAMIC_COPY);
        cudaGLRegisterBufferObject(*pbo_);
}

Bellow是我与OpenGL环境相关的显示功能的一部分。我使用了几个glFinish()调用作为实验,因为它似乎增强了执行时间。

// Make this the current array buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo);

// Make this the current element array buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

// Activate shader program
glUseProgram(shaderProgram);

// Specify the layout of the vertex data
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib,           // index of of attribute in array
                      2,                   // size
                      GL_FLOAT,            // type
                      GL_FALSE,            // normalized
                      4 * sizeof(GLfloat), // stride 
                      0);                  // offset in the array

glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib,                     // index of of attribute in array
                      2,                             // size
                      GL_FLOAT,                      // type
                      GL_FALSE,                      // normalized
                      4* sizeof(GLfloat),            // stride 
                      (void*)(2 * sizeof(GLfloat))); // offset in the array


glFinish();

// Specifies the target to which the buffer object is bound. GL_PIXEL_UNPACK_BUFFER affects the glTexSubImage2D command.
glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo);
// Draw Left Back Buffer
glDrawBuffer(GL_BACK_LEFT);

// Specifies the target (GL_TEXTURE_2D) to which the texture is bound
glBindTexture(GL_TEXTURE_2D, textureID);

// Note: NULL indicates the data resides in device memory
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

// Specifies the target to which the buffer object is bound. GL_PIXEL_UNPACK_BUFFER affects the glTexSubImage2D command.
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_Right);
// Draw Right Back Buffer
glDrawBuffer(GL_BACK_RIGHT);

// Note: NULL indicates the data resides in device memory
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); 

glFinish();

// Disable and unbind objects
glDisableVertexAttribArray(posAttrib);
glDisableVertexAttribArray(texAttrib);
glUseProgram(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

// Swap buffers
glutSwapBuffers();
glutPostRedisplay();

可以进行一些优化吗?或者这是立体3D中的已知问题?

0 个答案:

没有答案