我需要使用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中的已知问题?