我正在尝试生成一个frambuffer对象,并使用NDK(r5b)在本机android应用程序中使用模板.目标设备正在运行froyo 2.2,支持OpenGL ES 2.0.
所以,我一直在我的c ++本机库中编写大量的gl代码,除此之外没有遇到任何问题.我似乎无法使它工作.
这是帧缓冲区创建的代码片段.完美性很好,但屏幕仍然完全黑色.这就像我正在创建的fbo并没有真正绑定到应用程序的Java部分创建的gl表面.我的应用程序代码的其余部分都很好,如果我删除fbo创建和绑定,一切都很好,除了我没有我的应用程序所需的模板工作.
GLint backingWidth = 1024;
GLint backingHeight = 1024;
//Create the FrameBuffer and binds it
glGenFramebuffers(1, &_defaultFramebuffer);
checkGlError("glGenFramebuffers");
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer);
checkGlError("glBindFramebuffer");
//Create the RenderBuffer for offscreen rendering // Color
glGenRenderbuffers(1, &_colorRenderbuffer);
checkGlError("glGenRenderbuffers color");
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
checkGlError("glBindRenderbuffer color");
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, backingWidth, backingHeight);
checkGlError("glRenderbufferStorage color");
//Create the RenderBuffer for offscreen rendering // Depth
glGenRenderbuffers(1, &_depthRenderbuffer);
checkGlError("glGenRenderbuffers depth");
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
checkGlError("glBindRenderbuffer depth");
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight);
checkGlError("glRenderbufferStorage depth");
//Create the RenderBuffer for offscreen rendering // Stencil
glGenRenderbuffers(1, …Run Code Online (Sandbox Code Playgroud) 我尝试使用"模板缓冲区"从纹理中显示渲染的一部分,但我的渲染显示没有任何蒙版效果.
这是一个2D iOS项目,使用OpenGL ES 2.0这是我的代码的关注部分:
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
glEnable( GL_STENCIL_TEST );
// mask rendering
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
glStencilFunc( GL_ALWAYS, 1, 1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glBindTexture(GL_TEXTURE_2D, _maskTexture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// scene rendering
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glStencilFunc( GL_EQUAL, 1, 1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
glBindTexture(GL_TEXTURE_2D, _viewTexture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激 !
(和法国开发商一样,对不起我的英文!)
精度:"_ maskTexture"是黑白图片.
我终于用rotoglub和蒂姆的迹象解决了我的问题.谢谢你们俩.
1 /模板缓冲区尚未正确创建.它应该像这样初始化:
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES,
GL_DEPTH24_STENCIL8_OES, …Run Code Online (Sandbox Code Playgroud) 我一直试图在Libgdx项目中做一些模板.到目前为止,我只能模板化多边形(插图后的代码).
问题:我如何在OpenGL ES 2.0中模板化非多边形形状?(即我不希望将透明像素绘制到模板缓冲区)
如何在不使用GL_ALPHA_TEST的情况下实现这一目标(因为OpenGL ES 2.0不允许)?
非常感谢任何帮助或指示,并提前感谢.
编辑:如果您能提供一些代码示例以供理解,那将非常有用.
请考虑下图:

这是渲染代码:
@Override
public void render(float delta) {
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_STENCIL_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
stage.act();
stage.draw();
Gdx.gl20.glColorMask(false, false, false, true);
Gdx.gl20.glDepthMask(false);
Gdx.gl20.glClearStencil(0x0);
Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl20.glStencilFunc(GL20.GL_ALWAYS, 0x1, 0x1);
Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_REPLACE);
batch.begin();
batch.draw(heart, 0, i+50);
batch.end();
Gdx.gl20.glColorMask(true, true, true, true);
Gdx.gl20.glDepthMask(true);
Gdx.gl20.glStencilFunc(GL20.GL_NOTEQUAL, 0x1, 0x1);
Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP);
batch.begin();
batch.draw(heart, 0, i);
batch.end();
Gdx.gl20.glDisable(GL20.GL_STENCIL_TEST);
}
Run Code Online (Sandbox Code Playgroud) OpenGL 参考 pdf 中的文档(OpenGL 3.3 和 4.5 规范)对于应用遮罩时存储的模板值会发生什么情况不太清楚。
例如如果我有以下掩码:
glStencilMask( 0x06);
Run Code Online (Sandbox Code Playgroud)
并且存储在模板缓冲区中已经有这个值:
0x06
Run Code Online (Sandbox Code Playgroud)
如果模板操作是GL_INCR_WRAP
当在该像素上正确调用 StencilOp 时会发生什么?
基本上我有面具:
00000110
Run Code Online (Sandbox Code Playgroud)
和价值
00000110
Run Code Online (Sandbox Code Playgroud)
我尝试增加它,它被包裹了吗?
00000010
Run Code Online (Sandbox Code Playgroud)
或者只是归零?(00000110 + 1) & mask
00000000
Run Code Online (Sandbox Code Playgroud) 基本上,我想在一个立方体周围渲染一个轮廓。为此,我想我可以使用SCNTechnique具有以下渲染通道的 :
问题是,模板中的文档SCNTechnique非常稀少,我无法确切地知道如何使用它。
我已经通过首先在禁用深度测试的情况下绘制较大的“轮廓立方体”然后再绘制普通立方体来成功绘制轮廓,这效果很好,但是由于这种方法的其他复杂性,我想改用模板。
在尝试使用模板缓冲区使其工作时,我的第一遍stencilStates看起来像(以及我认为我需要这些属性的原因):
clear = YES // To clear the buffer from last
enable = YES // To write to the buffer
behavior:
writeMask = 1 // Use bit 1
function = always // Always write to stencil regardless?
Run Code Online (Sandbox Code Playgroud)
第二遍的stencilStates样子:
clear = NO // Keep the buffer from last step
enable = NO // Don't write to the buffer (only read?)
behavior:
readMask = 1 // Use bit …Run Code Online (Sandbox Code Playgroud) 要使用OpenGL绘制复杂的凹多边形,最好将其镶嵌成三角形,还是使用模板缓冲区?我猜测单个帧的模板缓冲区会更快,但如果多边形不变,则三角测量对于多个帧会更好.但是,我还没有尝试过,所以我不知道.
我试图找出一种方法来切出背景纹理的某个区域,以便在屏幕上不为该背景渲染某个自定义图案.例如:
这个方块可以是任何图案.我正在使用Frame Buffer Object和Stencil Buffer来实现这种效果.这是代码:
fbo.begin();
//Disables ColorMask and DepthMask so that all the rendering is done on the Stencil Buffer
Gdx.gl20.glColorMask(false, false, false, false);
Gdx.gl20.glDepthMask(false);
Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl20.glStencilFunc(GL20.GL_ALWAYS, 1, 0xFFFFFFFF);
Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_REPLACE, GL20.GL_REPLACE);
stage.getSpriteBatch().begin();
rHeart.draw(stage.getSpriteBatch(), 1); //Draws the required pattern on the stencil buffer
//Enables the ColorMask and DepthMask to resume normal rendering
Gdx.gl20.glColorMask(true, true, true, true);
Gdx.gl20.glDepthMask(true);
Gdx.gl20.glStencilFunc(GL20.GL_EQUAL, 1, 0xFFFFFFFF);
Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP);
background.draw(stage.getSpriteBatch(), 1); //Draws the background such that the background is not rendered on the required pattern, …Run Code Online (Sandbox Code Playgroud) 在我的项目中,我使用“丢弃”调用来执行自定义模板测试,该测试尝试仅在由模板纹理定义的指定区域上绘制内容。这是片段着色器的代码:
//get the stencil value from a texture
float value=texture2D( stencilTexture, gl_FragCoord.xy/1024.0).x;
//check if value equals the desired value, if not draw nothing
if(abs(value-desiredValue)>0.1)
{
discard;
}
Run Code Online (Sandbox Code Playgroud)
该代码可以工作,但由于“丢弃”调用而出现性能问题。是否有其他方法可以通过 GPU 着色器来实现此目的?告诉我怎么做。
我和一个朋友一直在讨论模板缓冲区.简而言之,我无法找到模板缓冲区比OpenGL 3.2+中的可编程管道工具更具优势的情况.现代OpenGL中的模板缓冲区有用吗?
[编辑]
感谢大家对该主题的所有意见.
这是我第一次尝试使用模板测试,但我见过一些使用 OpenGL 的示例和一些使用 Metal 的示例,但主要关注深度测试。我了解模板测试背后的理论,但我不知道如何在金属上设置它。
我想画不规则的形状。为了简单起见,让我们考虑以下 2D 多边形:

我希望模板通过重叠三角形数量为奇数的地方,这样我就可以达到这样的效果,其中白色区域是要忽略的区域:

我正在按照确切的顺序执行以下步骤:
设置深度StencilPixelFormat:
mtkView.depthStencilPixelFormat = .stencil8
mtkView.clearStencil = .allZeros
Run Code Online (Sandbox Code Playgroud)
模板附件:
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .stencil8, width: drawable.texture.width, height: drawable.texture.height, mipmapped: true)
textureDescriptor.textureType = .type2D
textureDescriptor.storageMode = .private
textureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]
mainPassStencilTexture = device.makeTexture(descriptor: textureDescriptor)
let stencilAttachment = MTLRenderPassStencilAttachmentDescriptor()
stencilAttachment.texture = mainPassStencilTexture
stencilAttachment.clearStencil = 0
stencilAttachment.loadAction = .clear
stencilAttachment.storeAction = .store
renderPassDescriptor.stencilAttachment = stencilAttachment
Run Code Online (Sandbox Code Playgroud)
模板描述符:
stencilDescriptor.depthCompareFunction = MTLCompareFunction.always
stencilDescriptor.isDepthWriteEnabled = true
stencilDescriptor.frontFaceStencil.stencilCompareFunction = MTLCompareFunction.equal
stencilDescriptor.frontFaceStencil.stencilFailureOperation = MTLStencilOperation.keep
stencilDescriptor.frontFaceStencil.depthFailureOperation = MTLStencilOperation.keep
stencilDescriptor.frontFaceStencil.depthStencilPassOperation …Run Code Online (Sandbox Code Playgroud) stencil-buffer ×10
opengl ×4
opengl-es ×3
framebuffer ×2
libgdx ×2
android ×1
android-ndk ×1
concave ×1
graphics ×1
ios ×1
java ×1
metal ×1
opengl-3 ×1
opengl-4 ×1
polygon ×1
scenekit ×1
scntechnique ×1
stencils ×1
swift ×1