- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
所以,我的目标是绘制具有半透明像素的 Sprite 。
首先,我使用仅渲染不透明像素的着色器渲染 Sprite 。然后,我禁用深度缓冲区写入并使用仅渲染半透明(或透明 Sprite )的着色器渲染相同的 Sprite ,如下所述:
这是我用作测试的动画 Sprite 表:
这是我的渲染器更新函数:
updateRenderData();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glDepthMask(GL_FALSE);
glUseProgram(_translucencyPogramID);
render();
_window->SwapBuffers();
这是我的渲染函数(以防万一你想知道我是如何渲染 Sprite 的):
GLint baseInstance = 0;
GLsizei spriteCount;
for (int i = 0; i < _spriteManager->GetSpriteBatchVector()->size(); i++)
{
_SpriteBatch* spriteBatch = _spriteManager->GetSpriteBatchVector()->at(i);
setTexture(spriteBatch->GetTexture());
spriteCount = (GLsizei)spriteBatch->GetSpriteVector()->size();
glDrawElementsInstancedBaseInstance(_quad.renderMode, _quad.indexCount, _quad.indexDataType, 0, spriteCount, baseInstance);
baseInstance += spriteCount;
}
但是当我执行这段代码时,它只渲染半透明像素: /image/f4AY6.png
事实上,如果我删除第二个 render() 调用(仅调用,我仍然更改着色器并将深度 mask 设置为 false),则不会呈现任何内容(黑屏),如下所示:
updateRenderData();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glDepthMask(GL_FALSE);
glUseProgram(_translucencyPogramID);
_window->SwapBuffers();
但如果我在第一次渲染后不更改着色器也不将 glDepthMask 设置为 false,它会正确渲染我的 Sprite 的不透明像素。
编辑:这是我在第二遍中使用的片段着色器:
out layout(location = 0) vec4 outColor;
in vec2 texCoord;
uniform sampler2D tex;
void main()
{
vec4 texel = texture(tex, texCoord);
if(texel.a == 1)
{
discard;
}
outColor = texel;
}
第一遍是一样的,但如果 alpha < 1 则丢弃。顶点着色器是标准的。
那么,我的问题是:是什么原因造成的?
编辑 2:
澄清一下,这会正确呈现(没有半透明像素):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
这根本不渲染:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glDepthMask(GL_FALSE);//Just added this line
这也根本不会呈现:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glUseProgram(_translucencyPogramID);//Just added this line
最佳答案
假设 _programID
用于绘制鸟的不透明部分,_translucencyPogramID
用于绘制半透明部分。
您提供的代码中没有任何内容显示可能的原因。然而,它可能是以下结果:
_programID
时,您实际上并没有调用 render()
。_programID
之后你glClear(GL_COLOR_BUFFER_BIT)
GL_ONE_MINUS_SRC_ALPHA
作为 glBlendFunc()
的 sfactor
假设您的_programID
的片段着色器包括:
if (texel.a < 1.0)
discard;
和您的_translucencyPogramID
的片段着色器包括:
if (texel.a == 1.0)
discard;
然后授予你的绘制循环是这样的(伪代码):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE)
glUseProgram(_programID)
for each sprite
glDrawArrays(....)
glDepthMask(GL_FALSE)
glUseProgram(_translucencyPogramID)
for each sprite
glDrawArrays(....)
glDepthMask(GL_TRUE)
然后在使用 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
时,应该会给出所需的结果。
编辑
那么当您添加 glDepthMask(GL_FALSE)
时它会中断的原因是因为您之后没有再次启用它。您可以通过以下方式检查:
GLboolean enabled;
glGetBooleanv(GL_DEPTH_WRITEMASK, &enabled);
assert(enabled == GL_TRUE);
在你 glClear(GL_DEPTH_BUFFER_BIT)
之前。
它中断的原因是如果写入深度缓冲区被禁用,则 glClear(GL_DEPTH_BUFFER_BIT)
将不会执行任何操作,因此深度缓冲区保持原样。
正如您在下面看到的,在第二张图片上,它有点模糊了所有鸟框的轮廓。这是因为深度缓冲区永远不会被清除,而这只鸟是最前面的鸟。如果在调用 glClear(GL_DEPTH_BUFFER_BIT)
时启用写入深度缓冲区,那么它会正确生成第一张图片。
左图:在 glClear 上启用了深度写入。右图:在 glClear 上禁用了深度写入。
请注意,此关系适用于 glClear(...)
和任何 gl*Mask(GL_FALSE)
。
关于c++ - Opengl 半透明 Sprite ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43005866/
我在 NSWindow 中有一个 NSView,NSWindow 是标准的 Mac 灰色/米色。 我想让 NSView 稍微半透明和灰色(例如 alpha 为 0.2 的灰色),以便 NSWindow
我对 openGL 中的 alpha 混合有疑问... 我尝试了一些绘制透明对象的方法...通过在绘制透明面之前禁用 GL_DEPTH_TEST 并在绘制透明面后再次重新启用 GL_DEPTH_TES
我将导航栏自定义为清除。所以我将backgroundImage设置为UIImage()并且isTranslucent = true。所以我遇到的问题是:这就是我在 xib 中设置的。现在 TopCon
我一直在研究这个,似乎唯一的方法是使用 UIActionSheet,问题是我的 UIActionSheet 只覆盖了一半的屏幕,我的代码是: MyViewController *myVC = [[my
我希望在我的主要 Activity 中使用半透明的状态栏和导航栏,而所有其他 Activity 都使用 Material 设计。 到目前为止我得到的是: if (Build.VERSION.SDK_I
我可以在不使用私有(private)方法等的情况下获得对 UIAlertView 的 backgroundImageView 的引用。但是我的 alpha 设置为 1.0 被忽略了。控件仍然有点半透明
我正在研究 UIWebView,我想要的是 webView 不要过度说唱 View 。 所以这就是问题所在。我设置了 UIWebView ,状态栏覆盖在内容上。 我该如何处理?我在制作 UIImage
我正在为一款小型 2d 游戏在其他图像之上绘制半透明图像。目前要混合图像,我正在使用此处找到的公式:https://en.wikipedia.org/wiki/Alpha_compositing#Al
我正在尝试将 Splash Screen 4 制作成 Win 应用程序。 我的设置: 表单边框样式设置为无。起始位置是屏幕中心。表单的背景图像设置为 PNG 文件,具有圆形边缘和“内置”投影。 在我设
(此问题发生在使用 Java 1.7.0_45 的 Mac OS X 10.10 上。在使用 Java 1.7.0_55 的 Windows 7 上我没有遇到此问题。) 我有一个半透明的“始终在最前面
如果您知道学习如何使用 Adobe Flash 为 iPhone 应用程序甚至 Air 应用程序创建此类效果的任何良好起点,那将会有很大帮助。 具体来说,我希望它不保存叠加层,只在用户从相机拍摄图
我有以下行: label.setBackground(new java.awt.Color(0, 150, 0, 50)); 我将它放在 MouseAdapter 中的 mouseRe
我正在制作幻灯片。我希望导航栏看起来与照片应用程序中的一样。我如何获得这种透明度? 我试过: - (void)drawRect:(CGRect)rect { [[UIColor clearCo
我试图在半透明的 div 上获取文本。这是在 Chrome 中,如果相关(即 Chrome 错误)。出于某种原因,每当文本位于 div 顶部(移动到负边距顶部)时,它也是部分透明的。 HTML 如下(
我在 NSVisualEffectView 上有 2 个 NSButton。第一个按钮图像是系统 NSEnterFullScreenTemplate 图像。第一个按钮上的图像是半透明的。 在第二个按钮
我想在RelativeLayout中创建一个RelativeLayout半透明。 它是页脚的项目。它始终可见,但我只想使其黑色的透明度为 50%。 我尝试过使用#11000000 Alpha chan
我正在尝试使用 Qt (C++) 应用程序跨操作系统完成以下任务。运行该程序后,会弹出一个新窗口,一个全屏 QWidget。现在我希望它是透明的/透明的,这样用户就不会真正看到它。在这个“层”上,用户
所以,我的目标是绘制具有半透明像素的 Sprite 。 首先,我使用仅渲染不透明像素的着色器渲染 Sprite 。然后,我禁用深度缓冲区写入并使用仅渲染半透明(或透明 Sprite )的着色器渲染相同
CSS .popup { z-index: 10000; filter: alpha(opacity=40); -moz-opacity: .40; backgroun
我正在尝试创建一个 lightbox effect在我的应用程序中。为实现这一点,我有一个 UserControl,其中一个面板代表半透明覆盖层,另一个面板托管所有必要的内容。 当我显示此 UserC
我是一名优秀的程序员,十分优秀!