我用这个代码:
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!context || ![EAGLContext setCurrentContext:context] || ![self loadShaders])
{
[self release];
return nil;
}
glGenFramebuffers(1, &defaultFramebuffer);
glGenRenderbuffers(1, &colorRenderbuffer);
glGenRenderbuffers(1, &depthRenderbuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Run Code Online (Sandbox Code Playgroud)
但是当我运行应用程序时,我看到紫色的屏幕?这段代码出了什么问题?
我在网上看到了很多例子(例如),它们做了以下工作
BUFFERS创建和绑定/解除绑定的示例(下面的代码仅用于显示我解释并完美运行的内容),
// create a framebuffer object, you need to delete them when program exits.
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
// create color buffer object and attached to fbo
glGenRenderbuffersEXT(1, &rboId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, TEXTURE_WIDTH, TEXTURE_HEIGHT);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); //UnBind
if(useDepthBuffer) {
glGenRenderbuffersEXT(1, &rboIdDepth);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboIdDepth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); //UnBind
}
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rboId);
if(useDepthBuffer)
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboIdDepth);
// check FBO status
printFramebufferInfo();
bool …Run Code Online (Sandbox Code Playgroud) 我想绘制一个删除了隐藏边缘的对象的边缘.我想要应用的想法是首先将对象的面渲染到深度缓冲区,然后在第二次渲染中绘制边缘并启用深度测试.
由于不是所有的三角形边都应该是可见的,所以边是单独存储的(简单示例:在立方体中,对角线边缘不应该是可见的,尽管它们在那里,因为四边形被渲染为两个三角形).因此使用绘制面,使用单独的顶点缓冲区GL_TRIANGLES绘制边GL_LINES.
问题是隐藏边缘部分用此设置显示,可见边缘部分隐藏.我怎样才能取得适当的结果?
没有深度测试:

深度测试:

渲染到深度缓冲区的面:

我使用带有附加颜色和深度缓冲区的帧缓冲区来绘制我的对象.
// Color buffer setup.
glBindTexture(GL_TEXTURE_2D, objectEdges);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 360, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);
// Depth buffer setup.
glBindRenderbuffer(GL_RENDERBUFFER, objectFaces);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 640, 360);
// Framebuffer setup.
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, objectEdges, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, objectFaces);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
assert(glGetError() == GL_NO_ERROR);
Run Code Online (Sandbox Code Playgroud)
此设置没有任何问题.我绘制我的对象如下:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); …Run Code Online (Sandbox Code Playgroud) 我的 OpenGL 应用程序需要一个模板和深度缓冲区。深度缓冲区至少需要通过帧缓冲区对象渲染到纹理,这样我才能做延迟着色和其他后处理效果。我已经设置了这个帧缓冲区(使用 GL_DEPTH24_STENCIL8),但我有一些顾虑和问题。
首先,我想使用 32 位浮点深度缓冲区。GL_DEPTH32F_STENCIL8 选项似乎是最明显的。我想知道的是,这种格式的实际内存占用是多少?从逻辑上讲,它将是 40 位,但知道我对对齐做了什么,如果他们将其填充为 64,我不会感到惊讶,而且许多消息来源说这正是发生的情况。我想知道。
也许将深度和模板缓冲区分开对我来说会更好?我是否必须担心这不受支持?缓存效率如何,因为模板和深度测试经常一起执行?
附注。我没有使用多重采样。
我一直在尝试将SSAO(基于这里的教程:http://john-chapman-graphics.blogspot.co.nz/2013/01/ssao-tutorial.html)添加到我的项目中,我已经坚持正确渲染深度.
我创建了一个帧缓冲纹理来绘制每个帧的深度.当我将它绘制到四边形时,纹理本身看起来正确,但我无法弄清楚如何正确地将它应用于整个场景.
这是常规场景的样子:

这是应用的深度纹理:

目前在我的片段着色器中,我只使用常规纹理坐标(TexCoord0)来绘制深度纹理.我猜我需要改变它,但我不知道要改变它.这是相关的片段着色器代码:
#version 330 core
in vec2 TexCoord0;
smooth in vec3 vNormal;
smooth in vec3 vWorldPos;
in mat4 ProjectionMatrix;
uniform sampler2D uDepthTex;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = texture(uDepthTex, TexCoord0);
}
Run Code Online (Sandbox Code Playgroud)
关于如何解决这个问题,我有点不知所措.我在网上看了很多示例代码,似乎使用常规纹理坐标来绘制深度.
编辑:这是我的帧缓冲设置代码:
glGenFramebuffers(1, &ssaoFramebufferID);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glGenTextures(1, &ssaoDepthTextureID);
glBindTexture(GL_TEXTURE_2D, ssaoDepthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, …Run Code Online (Sandbox Code Playgroud) OpenGL 说如果深度函数是 GL_LESS 并且布局限定符是 depth_less,那么 OpenGL 将执行早期深度测试。
现在,如果缓冲区中的原始值为 0.5,并且特定像素的深度为 0.8,则早期深度测试将失败。但是如果我们将值修改为 0.4,那么它应该不会失败。在这种情况下这是如何工作的?
在OpenGL中,深度缓冲值是基于场景的近剪裁平面和远剪裁平面计算的.(参考:从深度缓冲区获取真实的z值)
这在WebGL中如何工作?我的理解是WebGL不知道我的场景远近剪裁平面.近剪裁平面和远剪裁平面用于计算我的投影矩阵,但我从不告诉WebGL它们是明确的,因此它不能使用它们来计算深度缓冲值.
在渲染场景时,WebGL如何在深度缓冲区中设置值?
在我的应用程序中,我有一些着色器,它们仅写入深度缓冲区,以便稍后将其用于阴影。另外,我还有一些其他着色器,它们渲染全屏四边形,其深度不会影响所有后续的绘制调用,因此它的深度值可能会被丢弃。
假设应用程序在现代硬件上运行(5 年前至今生产),如果我禁用glColorMask(all to GL_FALSE)阴影贴图着色器的颜色缓冲区写入 ( ) 和全屏四元着色器的深度缓冲区写入 ( 使用glDepthMask()),我是否会获得任何额外的性能?
换句话说,这些函数是否真的禁用了某些内存操作,或者它们只是更改了渲染管道这部分中固定按位操作逻辑中使用的一些掩码位?
关于测试同样的问题。如果我事先知道所有片段都会通过深度测试,禁用深度测试会提高性能吗?
我的 FPS 测量没有显示出任何显着差异,但在另一台机器上结果可能会有所不同。
最后,如果在禁用深度/颜色测试/写入的情况下渲染运行得更快,那么它的运行速度会快多少?这种性能提升不会被 gl 函数调用开销所抵消吗?
我阅读了iOS OpenGL ES逻辑缓冲区加载,通过在每个绘制周期后"丢弃"深度缓冲区可以达到性能增益.我试试这个,但这是因为我的游戏引擎不再渲染.当我尝试渲染下一个循环时,我得到一个glError 1286或GL_INVALID_FRAMEBUFFER_OPERATION_EXT.
如果我要丢弃它,我感觉我需要在每个周期初始化或设置深度缓冲区,但我似乎无法找到任何相关信息.这是我如何初始化深度缓冲区(实际上是所有缓冲区):
// ---- GENERAL INIT ---- //
// Extract width and height.
int bufferWidth, bufferHeight;
glGetRenderbufferParameteriv(GL_RENDERBUFFER,
GL_RENDERBUFFER_WIDTH, &bufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER,
GL_RENDERBUFFER_HEIGHT, &bufferHeight);
// Create a depth buffer that has the same size as the color buffer.
glGenRenderbuffers(1, &m_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, GAMESTATE->GetViewportSize().x, GAMESTATE->GetViewportSize().y);
// Create the framebuffer object.
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, m_colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, m_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);
Run Code Online (Sandbox Code Playgroud)
以下是我想要在每个绘制周期结束时丢弃深度缓冲区的方法:
// Discard the depth buffer
const GLenum discards[] = …Run Code Online (Sandbox Code Playgroud) 我尝试使用 thee.js 仅更新 zbuffer(我使用preserveDrawingBuffer 来创建跟踪效果)。然而,我找不到任何方法只用标准材料写入 zbuffer,到目前为止我已经尝试过:
visible为 false,这会停止对象渲染。opacity为 0.0,这意味着不会渲染任何内容。是否有“标准”方法可以做到这一点,或者我是否需要使用自定义片段着色器?
depth-buffer ×10
opengl ×6
framebuffer ×3
iphone ×2
opengl-es ×2
buffer ×1
c++ ×1
depth ×1
fbo ×1
rendering ×1
textures ×1
three.js ×1
visibility ×1
webgl ×1
zbuffer ×1