我正在使用LibGDX框架处理绘图应用程序,我正在使用他们的FrameBuffer类将用户绘制的内容合并到实体纹理上,这就是他们所看到的绘图.这方面工作得很好,但是,用户可以绘制的区域并不总是大小相同,并且我无法在除整个窗口之外的分辨率上正确显示它.
我已经对此进行了非常广泛的测试,看起来似乎正在发生的事情是FrameBuffer以与窗口本身相同的分辨率创建纹理,然后简单地拉伸或缩小它以适应它原本应该在的实际区域,这是对于任何比窗口更大或更小的绘图而言,这是一种非常不愉快的效果.
我已经在我的过程中的每一步都证实了我自己从未做过任何这样的伸展,并且正确地绘制了所有内容以及正确的尺寸和位置.我也查看了FrameBuffer类本身试图找到答案,但奇怪的是也没有找到任何东西,但是,考虑到我所做的所有测试,它似乎是这个问题的唯一可能的地方以某种方式创造.
我完全没有想法,花了相当多的时间来解决这个问题.
我正在尝试为 Linux 创建一个直接写入帧缓冲区 /dev/fb0 的应用程序。为了使其成为双缓冲,我尝试使虚拟屏幕成为屏幕大小的两倍。这是我写的程序:
struct fb_var_screeninfo screeninfo_var;
struct fb_fix_screeninfo screeninfo_fixed;
unsigned int* screenbuffer;
void gfx_init()
{
fb0 = open("/dev/fb0", O_RDWR);
if(fb0 == 0)
error("Could not open framebuffer located in /dev/fb0!");
if (ioctl(fb0, FBIOGET_FSCREENINFO, &screeninfo_fixed) == -1)
error("Could not retrive fixed screen info!");
if (ioctl(fb0, FBIOGET_VSCREENINFO, &screeninfo_var) == -1)
error("Could not retrive variable screen info!");
screeninfo_var.xres_virtual = screeninfo_var.xres;
screeninfo_var.yres_virtual = screeninfo_var.yres * 2;
screeninfo_var.width = screeninfo_var.xres;
screeninfo_var.height = screeninfo_var.yres;
screeninfo_var.xoffset = 0;
screeninfo_var.yoffset = 0;
if (ioctl(fb0, FBIOPUT_VSCREENINFO, &screeninfo_var) == …Run Code Online (Sandbox Code Playgroud) 我们正在使用Nexus 10上的OpenGL ES 2.0开发动态壁纸.
动态壁纸使用2个小型(128x128)外部帧缓冲器在它们之间进行乒乓渲染以模糊图像.
虽然这在任何设备上都能正常工作(即使是在老化的摩托罗拉里程碑上),但Nexus 10存在一个奇怪的问题.仅当设备处于横向时才有效.如果设备在任何其他位置(90度,180度或270度)旋转,则帧缓冲区仅具有清晰的颜色.我已经设置glClearColor为红色,因此可以清楚地看到这些帧缓冲区被清除但没有任何内容被渲染到它们中.
我在Tegra 2,Tegra 3,Adreno 200,Adreno 320,2 PowerVR GPU上进行了测试,它运行得很好.
这看起来像一些奇怪的驱动程序错误,但也可能是Mali驱动程序的一些细节.请指教.
代码摘录.
Init帧缓冲区:
private void initBloomStuff() {
mBloomTextureID = loadTexture("textures/empty128.png");
mBloomVertTextureID = loadTexture("textures/empty128.png");
mBloomFBHeight = 128;
mBloomFBWidth = 128;
float blurSize = 1.0f;
// Texel offset for blur filter kernel
m_fTexelOffset = 1.0f / mBloomFBWidth / blurSize;
ByteBuffer tmpFB, tmpRB;
IntBuffer handle, renderbuffers;
int result;
tmpFB = ByteBuffer.allocateDirect(4);
tmpFB.order(ByteOrder.nativeOrder());
handle = tmpFB.asIntBuffer();
GLES20.glGenFramebuffers(1, handle);
framebufferHandle = handle.get(0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mBloomTextureID);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferHandle);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, …Run Code Online (Sandbox Code Playgroud) 根据我的理解,它们是不同的。Linux 帧缓冲区是一个软件对象,GPU 的内存是映射到 GPU 设备的物理内存。
我的问题如下:
1)我的理解正确吗?
2)如果是这样,以某种方式将两个东西合并成一个看起来可能会提高性能(我猜还有更多的技术细节为什么这是不可能的等等......)
3)如果没有,你能解释一下 Linux 帧缓冲区和 GPU 是如何协同工作的吗?
我想在未连接到任何物理显示器的帧缓冲区设备上测试一些文本绘制功能。有没有办法实时查看我正在绘制到 /dev/fb0 的内容?
我正在编写一个小型库来与 Linux 的帧缓冲区抽象接口。我的所有显卡都使用相同的像素格式(每个通道一个八位字节,四个通道,BGRA 排序),因此到目前为止,库仅采用这种格式。但是,如果我希望该库在任何 Linux 帧缓冲区上工作,帧缓冲区 API 提供了我必须使用的像素格式数据。你不需要知道帧缓冲区是如何工作的来回答这个问题(我希望),只需要一些我不熟悉的小技巧。这是我的标题中提供的像素格式信息:
/* Interpretation of offset for color fields: All offsets are from the right,
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
* can use the offset as right argument to <<). A pixel afterwards is a bit
* stream and is written to video memory as that unmodified.
*
* For pseudocolor: offset and length should be the same for all color
* components. Offset specifies the position …Run Code Online (Sandbox Code Playgroud) 我有一个系统,可以使用 C++ 中的 OpenGL 将不同的对象渲染成不同的 RGBA 纹理。我想将这些纹理叠加在一起,但我的问题是每个纹理都有 glClearColor 渲染到其中。
如何告诉 OpenGL 将纹理的 ClearColor 部分设为透明(0.0f alpha),以便我仍然可以看到其他图层后面的图层部分?
我正在使用 OpenCL 进行一些图像处理,并希望使用它将 RGBA 图像直接写入帧缓冲区。工作流程如下图所示:
1) 将帧缓冲区映射到用户空间。
2) 使用 clCreateBuffer 创建 OpenCL 缓冲区,标志为“CL_MEM_ALLOC_HOST_PTR”
3)使用clEnqueueMapBuffer将结果映射到framebuffer。
然而,这不起作用。屏幕上什么也没有。然后我发现帧缓冲区映射的虚拟地址与映射OpenCL的虚拟地址不同。有没有人做过从 GPU 到帧缓冲区的数据零复制移动?我应该使用什么方法来实现此目的有任何帮助吗?
一些关键代码:
if ((fd_fb = open("/dev/fb0", O_RDWR, 0)) < 0) {
printf("Unable to open /dev/fb0\n");
return -1;
}
fb0 = (unsigned char *)mmap(0, fb0_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
...
cmDevSrc4 = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, sizeof(cl_uchar) * imagesize * 4, NULL, &status);
...
fb0 = (unsigned char*)clEnqueueMapBuffer(cqCommandQueue, cmDevSrc4, CL_TRUE, CL_MAP_READ, 0, sizeof(cl_uchar) * imagesize * 4, 0, NULL, NULL, &ciErr);
Run Code Online (Sandbox Code Playgroud) 尝试在延迟着色之上实现抗锯齿,我尝试使用多重采样渲染缓冲区,然后使用缓冲区位块传输传递解析样本。
按照延迟着色的传统做法,我使用发出 3 个颜色输出的专用着色器来渲染场景:
然后将它们用于照明计算通道,从而产生最终的场景纹理
使用简单的着色器将场景纹理渲染到全屏四边形的屏幕上
正如您可能猜到的,渲染到屏幕时,屏幕上的 MSAA 不会应用于场景纹理的内容:为了实现抗锯齿,我因此选择在步骤 1) 中使用多重采样渲染缓冲区,并引入了额外的步骤1.1) 分辨率。当然,多重采样仅对彩色图是必要的/有用的,对其他两张图来说不是必需的/有用的。
我的问题是,显然,具有多个渲染缓冲区/颜色附件的帧缓冲区只能为相同类型的附件定义;这意味着如果一个附件经过多次采样,那么所有其他附件也必须经过多次采样。
这成为分辨率期间位置和法线缓冲区的一个问题,因为几何体和照明会因抗锯齿而受到影响。
// Create the frame buffer for deferred shading: 3 color attachments and a depth buffer
glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
{
// - Position color buffer
glGenRenderbuffers(1, &gPosition);
glBindRenderbuffer(GL_RENDERBUFFER, gPosition);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, gPosition);
// - Normal color buffer
glGenRenderbuffers(1, &gNormal);
glBindRenderbuffer(GL_RENDERBUFFER, gNormal);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, gNormal);
// …Run Code Online (Sandbox Code Playgroud) opengl multisampling framebuffer deferred-rendering deferred-shading
我需要使用,但由于帧缓冲区驱动程序pygame的权限,它无法作为普通用户初始化屏幕。root 可以做,但用户不能做。用户位于“视频”组中,可以在 上书写。用户缺少什么权限才能工作。
遇到错误:pygame.display.init()/dev/fb0pygame.display.init()pygame.error: Unable to open a console terminal
所以,我尝试使用pygame来在帧缓冲区上显示内容/dev/fb0。要使用某些功能,我需要(例如pygame.Surface.convert)必须初始化显示器。但是,当调用时pygame.display.init()我遇到错误,但仅当不以 root 身份执行此操作时才会出现错误。
根据@Nodraak (参考),它与帧缓冲区驱动程序的权限有关 。
回答晚了,但我希望我能早点尝试一下:
您可能需要成为 root 才能使用帧缓冲区驱动程序。
(这对我的情况有帮助:RaspberryPi 2 没有运行 X,但连接了屏幕。我现在可以通过 SSH 或直接在 RPi 上打开显示器)
Atree -fupg / | grep fb | grep rwx 似乎没有显示任何可以由 root 执行但不能由其他人执行的二进制文件。我非常确定将我的用户添加到组中,或在某处调整文件权限就足以解决问题。
注意:出于安全原因,不能以 root 身份运行软件。
我正在尝试转换具有功能的表面pygame.Surface.convert(...)。但收到以下错误:
pygame.error: cannot convert without pygame.display initialized
Run Code Online (Sandbox Code Playgroud)
然而,初始化 …
framebuffer ×10
linux ×4
c ×2
opengl ×2
android ×1
glsl ×1
gpu ×1
java ×1
libgdx ×1
nexus-10 ×1
opencl ×1
pixelformat ×1
pygame ×1
python ×1
raspberry-pi ×1
scaling ×1
sdl-2 ×1
textures ×1
transparency ×1
zero-copy ×1