首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我的OpenGL ES应用程序会在glDrawElements上崩溃?

为什么我的OpenGL ES应用程序会在glDrawElements上崩溃?
EN

Stack Overflow用户
提问于 2020-09-02 14:11:52
回答 1查看 825关注 0票数 2

我已经开发了一个移动游戏与OpenGL ES 3在Xamarin (它使用OpenTK)。它在大多数设备上运行良好,但在某些设备上崩溃(华为Y5 lite)。不幸的是,我没有得到详细的错误日志:

代码语言:javascript
运行
复制
  #00  pc 0000000000093d2a  /vendor/lib/egl/libGLESv2_mtk.so
  #01  pc 000000000001c137  /vendor/lib/egl/libGLESv2_mtk.so
  #02  pc 000000000001eddf  /vendor/lib/egl/libGLESv2_mtk.so
  #03  pc 000000000001af75  /vendor/lib/egl/libGLESv2_mtk.so
  #04  pc 000000000001aabf  /vendor/lib/egl/libGLESv2_mtk.so (glDrawElements+54)
  #05  pc 000000000000ca0c  <anonymous>

我猜这与我的抽签代码有关,或者更糟的是与手机的一些司机问题有关。我使用以下代码来呈现四角体:

代码语言:javascript
运行
复制
public void BeforeRender()
{
    // Use shader program.
    GL.UseProgram(shader.Program);

    // Enable transparency
    GL.Enable(EnableCap.Blend);
    GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

    // Use texture
    GL.ActiveTexture(TextureUnit.Texture0);
    GL.Uniform1(shader.UniformTexture, 0);

    // Only bind once for all quads
    GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBufferId);
}

public void Render(Sprite sprite, Vector4 color, Matrix4 modelViewProjection)
{            
    // Set model view projection
    GL.UniformMatrix4(shader.UniformModelViewProjection, false, ref modelViewProjection);

    // Set color
    GL.Uniform4(shader.UniformColor, color);

    // Set texture
    GL.BindTexture(TextureTarget.Texture2D, sprite.TextureId);

    // Update attribute value Position
    GL.BindBuffer(BufferTarget.ArrayBuffer, sprite.Vbo);
    GL.VertexAttribPointer(shader.AttribVertex, 3, VertexAttribPointerType.Float, false, sizeof(float) * 5, IntPtr.Zero); // 3 + 2 = 5
    GL.EnableVertexAttribArray(shader.AttribVertex);

    // Update attribute value TexCoord
    GL.VertexAttribPointer(shader.AttribTexCoord, 2, VertexAttribPointerType.Float, false, sizeof(float) * 5, new IntPtr(sizeof(float) * 3));
    GL.EnableVertexAttribArray(shader.AttribTexCoord);

    // Draw quad
    GL.DrawElements(BeginMode.Triangles, faceIndexes.Length, DrawElementsType.UnsignedShort, IntPtr.Zero); 
}

public void AfterRender()
{
    // Unbind / Disable
    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
    GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
    GL.Disable(EnableCap.Blend);
}

要绘制多个四角体,我只需调用如下方法:

代码语言:javascript
运行
复制
BeforeRender();

foreach(var sprite in sprites)
{
    Render(sprite);
}

AfterRender();

我的代码总体上有什么问题,可能会在其他设备“容忍”的某些设备上造成问题吗?

提前感谢!

更新:

下面是我如何创建缓冲区:

代码语言:javascript
运行
复制
public int Load<T>(T[] data) 
        where T : struct
    {
        int bufferId;

        GL.GenBuffers(1, out bufferId);

        bufferIds.Add(bufferId);

        GL.BindBuffer(BufferTarget.ArrayBuffer, bufferId);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(data.Length * Marshal.SizeOf(default(T))), data, BufferUsage.StaticDraw);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

        return bufferId;
    }

对于索引缓冲区,我使用:

代码语言:javascript
运行
复制
ushort[] faceIndexes =
        {
            0, 1, 2, 1, 3, 2
        };

indexBufferId = bufferManager.Load(faceIndexes);

对于顶点缓冲区,我使用:

代码语言:javascript
运行
复制
float[] vertices =
            {
                0f, 0f, 0f, 0f, ty,
                width, 0f, 0f, tx, ty,
                0f, height, 0f, 0f, 0f,
                width, height, 0f, tx, 0f
            };

int vboId = bufferManager.Load(vertices);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-18 14:40:13

我发现了这个问题,这导致我的应用程序在一些设备上崩溃。显然,有一个项目滑到绘图例程中,它将一个缓冲区id 0传递到GL.BindBuffer中。在某些设备上,当调用Gl.DrawElements时,这会导致以下错误: emuglGLESv2_enc: sendVertexAttributes:坏偏移量/len!当然,每当为id创建缓冲区id为0或没有缓冲区时,解决方案就不再执行此代码。在我的示例中,GL.GenBuffers没有返回0。我有一些应该为空(而不是呈现)的精灵,我的原始解决方案是将缓冲区id设置为0。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63707424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档