如何在 OpenGL ES 上有效地将深度缓冲区复制到纹理

2024-02-20

我正在尝试通过移植在 iOS 上的 OpenGL ES 2.0 中获得一些阴影效果一些代码 http://www.codesampler.com/usersrc/usersrc_8.htm来自标准 GL。示例的一部分涉及将深度缓冲区复制到纹理:

glBindTexture(GL_TEXTURE_2D, g_uiDepthBuffer);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 800, 600, 0);

然而,ES 似乎不支持 glCopyTexImage2D。读一相关主题 https://stackoverflow.com/questions/2596682/opengl-es-2-0-read-depth-buffer,看来我可以使用帧缓冲区和片段着色器来提取深度数据。所以我尝试将深度分量写入颜色缓冲区,然后复制它:

// clear everything
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

// turn on depth rendering
glUseProgram(m_BaseShader.uiId);

// this is a switch to cause the fragment shader to just dump out the depth component
glUniform1i(uiBaseShaderRenderDepth, true);

// and for this, the color buffer needs to be on
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

// and clear it to 1.0, like how the depth buffer starts
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

// draw the scene
DrawScene();

// bind our texture 
glBindTexture(GL_TEXTURE_2D, g_uiDepthBuffer);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0);

这是片段着色器:

uniform sampler2D sTexture;
uniform bool bRenderDepth;

varying lowp    float LightIntensity;
varying mediump vec2  TexCoord;

void main()
{    
    if(bRenderDepth) {
        gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0);
    } else {
        gl_FragColor = vec4(texture2D(sTexture, TexCoord).rgb * LightIntensity, 1.0);
    }
}

我已经尝试过没有“bRenderDepth”分支,但它并没有显着加快速度。

现在几乎只是以 14fps 的速度执行这一步,这显然是不可接受的。如果我以超过 30 fps 的速度拉出副本。我从 Xcode OpenGLES 分析器关于复制命令的两个建议:

  1. 文件:// localhost / Users / xxxx / Documents / Development / xxxx.mm:错误: 验证错误:glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 960, 640, 0) : 高度不是2的幂

  2. 文件:// localhost / Users / xxxx / Documents / Development / xxxx.mm:警告: GPU 等待纹理:您的应用更新了当前正在使用的纹理 用于渲染。这导致CPU等待GPU 完成渲染。

我将努力解决上述两个问题(也许它们是问题的症结所在)。与此同时,有人能建议一种更有效的方法来将深度数据提取到纹理中吗?

提前致谢!


iOS设备一般都支持OES_深度_纹理 http://www.khronos.org/registry/gles/extensions/OES/OES_depth_texture.txt,因此在存在扩展的设备上,您可以设置一个帧缓冲区对象,并将深度纹理作为其唯一附件:

GLuint g_uiDepthBuffer;
glGenTextures(1, &g_uiDepthBuffer);
glBindTexture(GL_TEXTURE_2D, g_uiDepthBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
// glTexParameteri calls omitted for brevity

GLuint g_uiDepthFramebuffer;
glGenFramebuffers(1, &g_uiDepthFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, g_uiDepthFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, g_uiDepthBuffer, 0);

然后,当您绘制场景时,您的纹理会接收写入深度缓冲区的所有值(您可以为此使用一个简单的片段着色器),并且您可以直接从中进行纹理处理,而无需调用glCopyTexImage2D.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 OpenGL ES 上有效地将深度缓冲区复制到纹理 的相关文章

  • 如何正确更新 OpenGL Es 2.0 中的顶点数组?

    当我在 OpenGL 2 0 中更新 iOS 上的顶点数组时 原始顶点数据保留在屏幕上 即第一个刷新是持久的 我发送到 GPU 的初始点集每帧都会渲染 但第二个刷新是持久的 我发送到 GPU 的初始点集每帧都会渲染 第 3 次 第 4 次
  • 如何将文本渲染为位图并绘制它

    我是 android 新手 我的小组目前正在使用 opengl es 2 0 使用 GlSurfaceView 创建图形应用程序 我们最近在绘图上显示了网格和刻度线 现在我被分配了实现数字刻度并将 x 和 y 轴标记为 X 和 Y 的任务
  • OpenGL 与 Cocos2d:该选择什么?

    我知道 cocos2d 它是非常简单的 API 我可以用它来做简单而巨大的 2D 甚至有时 3D 游戏 应用程序 我也知道 OpenGL 它更复杂 它的 API 级别较低等 问题 实现 2D 3D 游戏用什么更好 如果我们有cocos2d这
  • 如何在 WebGL 中创建合适的圆角矩形?

    我试图实现答案这个问题 https stackoverflow com questions 43970170 bordered rounded rectangle in glsl但似乎有点问题 如果您打开他们的 ShaderToys 并尝试
  • Java嵌套内部类访问外部类变量

    嵌套内部类ABar和BBar是否可以访问主类的变量 例如 public class Foo public ABar abar new ABar public BBar bbar new BBar public int someCounter
  • android OpenGL ES简单图块生成器性能问题

    遵循这个问题 老式 2D 类似塞尔达传说游戏的最佳方法 https stackoverflow com questions 2125354 best approach for oldschool 2d zelda like game 感谢之
  • OpenGL ES 像素艺术 - 缩放

    我在 iPhone 上的 OpenGL Es 1 1 上显示基于像素的艺术 想想复古瓷砖和艺术 时遇到问题 图块使用 8 个字节 每行 1 个字节 表示 每一位代表一个像素是否被设置 例如数字为 8 的图块 0 0 0 0 0 0 0 0
  • 未修改的 iOS7 Apple GLPaint 示例混合问题

    在苹果的GLPaint https developer apple com library ios samplecode GLPaint Introduction Intro html例如 用户可以使用半透明画笔在表面上绘图并改变颜色 然而
  • 防止没有 GL 扩展的设备从 Google Play 下载应用程序

    是否可以使应用程序在 Google Play 商店中没有特定 OpenGL ES 扩展的设备上不可用 Since
  • 在 OpenGL 中移动相机时出现故障

    我正在为 iPhone 编写一个基于图块的游戏引擎 除了以下故障之外 它基本上可以正常工作 基本上 相机将始终将玩家保持在屏幕中央 并且它会移动以正确跟随玩家并在静止时正确绘制所有内容 然而 当玩家移动时 玩家行走的表面瓷砖会出现故障 如下
  • iOS 上 OpenGL ES2.0 中的多纹理点精灵?

    我正在尝试使用 OpenGL ES 2 0 为 iPhone 应用程序制作多纹理点精灵 我在网上找不到任何这样的例子 而且它似乎不起作用 当对点精灵使用 GL POINTS 模式时 是否有一些内置限制使得 gl PointCoord 不能在
  • 减少 OpenGL ES 1.1 中纹理的内存使用

    我在 OpenGL ES 中的场景需要几个大分辨率纹理 但它们是灰度的 因为我仅将它们用于蒙版 我需要减少内存使用 我尝试使用 Bitmap Config ALPHA 8 和 RGB 565 加载这些纹理 ALPHA 8 似乎实际上增加了内
  • 具有 OpenGL ES 3.1 上下文的 GLSurfaceView

    我正在使用 OpenGL 开发 Android 我知道如何使用GLSurfaceView及其自定义派生类 使用以下方法创建 OpenGL ES 2 0 上下文GLSurfaceView setEGLContextClientVersion
  • Android GLSurfaceView 具有可绘制背景

    我有一个带有可绘制对象作为背景的 GLSurfaceView 但是在没有 surfaceView setZOrderOnTop true 的情况下渲染时只有背景可见 我需要避免使用 setZOrderOnTop true 因为在 GLSur
  • Android OpenGLES 渲染到纹理

    我为 iPhone 编写图形应用程序 并且希望将我最新的应用程序 Layers 移植到 Android 平台 Layers 是一款绘画应用程序 允许用户在屏幕上绘画并使用不同的画笔 颜色等创建多层绘画 并导出到 PSD 它有桌面同步 涂抹工
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • libgdx SpriteBatch 渲染到纹理

    是否可以使用 libGdx 适用于 Android 桌面的 Java 引擎 中的 SpriteBatch 渲染到纹理 如果是这样 怎么办 基本上我想将所有内容渲染到 512 x 256 纹理的 320 x 240 区域 然后缩放区域以适合屏
  • presentRenderbuffer :GL_RENDERBUFFER_OES 需要很长时间

    我在游戏中添加了一个分析器并隔离了此功能 有时 它会导致 FPS 下降 这是我的结果 Present buffer time 22 Present buffer time 1 Present buffer time 9 Present bu
  • Cocos2d - 将 GLImageProcessing 效果应用于 CCSprite

    苹果的oplenglGL图像处理 http developer apple com library ios samplecode GLImageProcessing Introduction Intro html加载图像并应用图像调整 亮度
  • 使用 JOGL 和 Android OpenGL 编写可移植 Java 应用程序

    我计划编写一款可以在 PC 和 Android 上运行的 Java 3D 游戏 不幸的是 这两个平台似乎没有通用的 OpenGL API API 是否有显着差异 有没有办法在两个版本中使用相同的 3D 代码 这是不是一个好主意 Androi

随机推荐