我正在尝试确定是否可以使OpenGL ES 2.0将缓冲区内容呈现到用户空间中的mmap
内存中,而不是GPU分配的内存中。
不幸的是,glReadPixels()
函数的运行速度非常慢,因为它使整个流水线停滞了,因此即使读取10x10像素也会将帧速率从60hz降至5hz。
我正在阅读本文,并且我了解我可以使用帧缓冲区对象来完成此操作 http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES#Pixmaps
我正在尝试下面的代码,但是我不知道如何获得FBO的地址
我正在使用的硬件是具有WaveShare 3.5英寸SPI TFT LCD和LCD-Show驱动程序的Raspberry Pi3。但这可能与任何硬件有关。
我遇到的问题是无法获取指向FBO的指针,我所拥有的只是OpenCV使用的句柄。所以,即使我想memcpy
从一个地方到另一个我没有GPU的内存地址与工作。因为无法从用户空间访问GPU内存,这不可能完成吗?
谢谢
//CREATE FBO OBJECT
GLuint m_hFBO[2]; // Handles for Frame Buffer Objects
const unsigned int gTextureSize = 1024;
GLuint m_hTexture[2]; // Texture handles
// Generate handles for two dynamically rendered texture maps
glGenTextures(2, m_hTexture);
for (int Index = 0; Index < 2; Index++)
{
// Bind and configure each texture
glBindTexture(GL_TEXTURE_2D, m_hTexture[Index]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, gTextureSize, gTextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
// Generate handles for two Frame Buffer Objects
glGenFramebuffers(2, m_hFBO);
for (int Index = 0; Index < 2; Index++)
{
// Attach each texture to the first color buffer of an FBO and clear it
glBindFramebuffer(GL_FRAMEBUFFER, m_hFBO[Index]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_hTexture[Index], 0);
glClear(GL_COLOR_BUFFER_BIT);
}
//MMAP /DEV/FB1
struct fb_fix_screeninfo finfo;
uint32_t pixels;
const char *device = "/dev/fb1";
int fbfd = open(device, O_RDWR);
if (fbfd == -1) {printf("cannot open /dev/fb1 device"); return;}
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {printf("cannot get /dev/fb1 fixed information"); return;}
struct fb_var_screeninfo vinfo;
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {printf("cannot get /dev/fb1 variable information"); return;}
//---------------------------------------------------------------------
if((vinfo.xres * 2) != finfo.line_length) {printf("assumption failed ... /dev/fb1 lines are padded"); return;}
if ((vinfo.xres % 16) != 0) {printf("/dev/fb1 width must be a multiple of 16"); return;}
if (vinfo.bits_per_pixel != 16){printf("/dev/fb1 is not 16 bits per pixel"); return;}
//---------------------------------------------------------------------
fbp1 = (uint16_t*)mmap(0,finfo.smem_len,PROT_READ | PROT_WRITE,MAP_SHARED,fbfd,0);
if (fbp1 == MAP_FAILED){printf("cannot map /dev/fb1 into memory"); return;}
memset(fbp1, 0, finfo.smem_len);
pixels = vinfo.xres * vinfo.yres;