我对Framebuffer和Renderbuffer的概念感到困惑.我知道他们需要渲染,但我想在使用之前了解它们.
我知道存储临时绘图结果需要一些位图缓冲区.后缓冲区.当这些图纸正在进行时,需要在屏幕上看到另一个缓冲区.前缓冲区.翻转它们,再画一遍.我知道这个概念,但很难将这些对象与这个概念联系起来.
它们的概念和差异是什么?
我最近对一个奇怪的想法感到震惊,即从/ dev/urandom获取输入,将相关字符转换为随机整数,并使用这些整数作为像素的rgb/xy值绘制到屏幕上.
我做了一些研究(这里是关于StackOverflow和其他地方),许多人建议您可以直接写入/ dev/fb0,因为它是设备的文件表示.不幸的是,这似乎没有产生任何视觉上明显的结果.
我发现了一个示例C程序来自QT教程(不再可用),它使用mmap写入缓冲区.程序成功运行,但同样没有输出到屏幕.有趣的是,当我将我的笔记本电脑放入Suspend并稍后恢复时,我看到了一个瞬间闪现的图像(一个红色正方形),它被更早地写入帧缓冲区.写入帧缓冲区是否在Linux中用于绘制屏幕?理想情况下,我想写一个(ba)sh脚本,但C或类似的也可以.谢谢!
编辑:这是示例程序...兽医可能看起来很熟悉.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
int main()
{
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
long int location = 0;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (fbfd == -1) {
perror("Error: cannot open framebuffer device");
exit(1);
}
printf("The framebuffer …Run Code Online (Sandbox Code Playgroud) 我正在开发一个项目,我需要在Linux FrameBuffer上运行Google Chrome,我需要在没有任何窗口系统依赖的情况下运行它(它应该在我们提供它绘制的缓冲区上绘制,这将使其非常移植到任何嵌入式系统容易),我不需要它的多标签GUI,我只需要在缓冲区中的渲染器窗口,有没有试过这个?我应该使用什么方法的任何帮助?
我已经看过很多关于这个主题的材料,但是我发现的例子之间存在一些差异,而且我很难深入了解正确的过程.希望有人可以告诉我,如果我走在正确的轨道上.我还应该提到我在OS X Snow Leopard和最新版本的Xcode 3上做这个.
举个例子,假设我想写两个目标,一个用于普通,一个用于颜色.为此,我创建了一个帧缓冲区并将两个纹理绑定到它,以及深度纹理:
glGenFramebuffersEXT(1, &mFBO);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
glGenTextures(1, &mTexColor);
glBindTexture(GL_TEXTURE_2D, mTexColor);
//<texture params>
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexColor, 0);
glGenTextures(1, &mTexNormal);
glBindTexture(GL_TEXTURE_2D, mTexNormal);
//<Texture params>
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mTexNormal, 0);
glGenTextures(1, &mTexDepth);
glBindTexture(GL_TEXTURE_2D, mTexDepth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, mTexDepth, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
Run Code Online (Sandbox Code Playgroud)
在渲染之前,我会再次绑定帧缓冲,然后执行:
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(2, buffers); …Run Code Online (Sandbox Code Playgroud) 如何在没有X-Window系统的Linux平台上OpenGL,我可以直接将OpenGL图形发送到Framebuffer设备吗?
项目名为DirectFB(Direct FrameBuffer).使用DirectFB我们可以这样做,但DirectFB需要每个硬件的驱动程序,我想使用只有Linux驱动程序的图形卡.
我通过帧缓冲对象渲染到纹理,当我绘制透明图元时,图元与在单个绘制步骤中绘制的其他图元正确混合,但它们没有与帧缓冲区的先前内容正确混合.
有没有办法正确地将纹理内容与新数据混合?
编辑:更多信息需要,我会尝试更清楚地解释;
我使用的blendmode是GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA.(我相信这通常是标准的混合模式)
我正在创建一个跟踪鼠标移动的应用程序.它绘制了将前一个鼠标位置连接到当前鼠标位置的线条,因为我不想在每个帧上再次绘制线条,我想我会绘制一个纹理,从不清除纹理然后只绘制一个矩形它上面的纹理来显示它.
这一切都很好,除了当我在纹理上绘制alpha小于1的形状时,它不能与纹理的先前内容正确混合.假设我有一些黑色线条,alpha = .6被绘制到纹理上.一对夫妇画了一个周期之后,我在那些线上画了一个alpha = .4的黑色圆圈.圆圈"下方"的线条被完全覆盖.虽然圆圈不是扁平的黑色(它与白色背景正确混合),但圆圈下方没有"深色线条",正如您所期望的那样.
但是,如果我在同一帧中绘制线条和圆圈,它们会正确混合.我的猜测是纹理不会与之前的内容混合.它就像它只与glclearcolor混合.(在这种情况下,<1.0f,1.0f,1.0f,1.0f>)
我有一个渲染系统,我用一个多重采样渲染缓冲区绘制到FBO,然后将其blit到另一个带有纹理的FBO,以便解析样本,以便在绘制到后缓冲区时读取纹理以执行后处理着色( FBO指数0).
现在我想获得一些正确的sRGB输出......问题是当我在OS X和Windows上运行时,程序的行为相当不一致,这也会因机器而异:在带有Intel HD的Windows上3000它不会应用sRGB非线性,但在我的其他机器上使用Nvidia GTX 670.在OS X中的Intel HD 3000上,它也将应用它.
所以这可能意味着我没有GL_FRAMEBUFFER_SRGB在程序的正确位置设置启用状态.然而,我似乎无法找到任何实际告诉我何时应该启用它的教程,他们只提到它很容易并且没有性能成本.
我目前没有加载任何纹理,所以我还没有需要处理线性化他们的颜色.
为了强制程序不要简单地吐出线性颜色值,我试过的只是注释掉我的glDisable(GL_FRAMEBUFFER_SRGB)线,这实际上意味着为整个管道启用了这个设置,我实际上是在每一帧上冗余地强制它.
我不知道这是否正确.它肯定会对颜色应用非线性化,但我不知道这是否会被应用两次(这将是不好的).当我渲染给我的第一个FBO时,它可以应用伽玛.当我把第一个FBO送到第二个FBO时,它可以做到这一点.为什么不?
我已经走到了最后一帧的屏幕截图,并将原始像素颜色值与我在程序中设置的颜色进行比较:
我将输入颜色设置为RGB(1,2,3),输出为RGB(13,22,28).
这似乎是低端的相当多的色彩压缩,并让我质疑伽玛是否被多次应用.
我刚刚通过了sRGB方程式,我可以验证转换似乎只应用一次,因为线性1/255,2/255和3/255确实映射到sRGB 13/255,22/255, 28/255使用等式1.055*C^(1/2.4)+0.055.鉴于这些低颜色值的扩展是如此之大,如果sRGB颜色变换被多次应用,那么它应该是显而易见的.
所以,我还没有确定正确的做法是什么.它glEnable(GL_FRAMEBUFFER_SRGB)仅适用于最终的帧缓冲值,在这种情况下,我只是我的GL初始化程序中设置该忘掉它以下简称?
我教我的儿子编程"正确/艰难",所以我们从C开始,就像真正的男人:)
将文本打印到控制台很有趣,但我仍然记得将我的旧i386切换到320x200x256模式并绘制几个彩色矩形的兴奋......当天就像调用一样简单int 10h然后你只需要写入字节[A000:0000]到在屏幕上绘制像素.
然而,对于现代Linux,这种对硬件的低级访问似乎更复杂(出于显而易见的原因).我简要地看着mmap-ing /dev/fd0描述这里 -原来有没有/dev/fb0在我的Ubuntu 13.04的设备.我也看过使用svgalib- 但是,他们的示例代码在我的显示器上没有显示任何内容.
所以问题是:在现代Linux中是否有简单的方法可以直接访问视频内存,而不需要太多的系统配置和样板代码?它不一定是全屏访问 - 只要通过将数据直接写入内存就可以打开X窗口并绘制像素也可以.
我想将场景渲染到最初为空的纹理.为此,我使用一个Framebuffer对象,我附加一个空的2d纹理和一个深度缓冲区.设置完成后,为了测试,我在场景中绘制了一个简单的四边形.每个顶点都有不同的颜色,所以我最终期望纹理中有一个颜色插值的四边形.然后我使用包含四边形的纹理并将其映射到另一个四边形.所以,我在默认的Framebuffer中有一个四边形,它有一个包含彩色四边形的纹理.我希望这不会太混乱......
无论如何,我必须在这里遗漏一些东西,因为我得到的只不过是灰色的纹理.我基本上遵循了这些非常简单的指示.但是,我无法弄清楚我在这里缺少什么.如果有人能给我一些线索,我将不胜感激.
谢谢沃尔特
这是我到目前为止的代码://创建帧缓冲对象glGenFramebuffers(1,&frameBufferObject);
// create depth buffer
glGenRenderbuffers(1, &depthAttachment);
// create empty texture
int width = 512;
int height = 512;
int numberOfChannels = 3;
GLuint internalFormat = GL_RGB;
GLuint format = GL_RGB;
unsigned char* texels = new unsigned char[width * height * numberOfChannels];
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, texels);
glGenerateMipmap(GL_TEXTURE_2D);
delete[] texels;
texels = NULL;
// activate …Run Code Online (Sandbox Code Playgroud)