Почему этот SpriteBatch работает в C#, а не в Java?

У меня есть версии SpriteBatch, написанные на двух разных языках:

Java: http://pastebin.com/7gwHBTXi C#: http://pastebin.com/cTFn26H8

У них одинаковый код, и оба они выполняют следующие вызовы в простой программе:

Джава:

    GL11.glViewport(0, 0, game.getWidth(), game.getHeight());
    GL11.glClearColor(0, 1, 0, 1);
    GL11.glClearDepth(1.0);
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

    sb.Begin();
    sb.Draw(tex, new Vector2(-0.5f, 0.5f), new Vector2(1, -1), Color.White, 0);
    sb.End(SpriteSortMode.None);
    sb.RenderBatch(new Matrix4(), new Matrix4(), BlendState.Opaque, SamplerState.PointWrap, DepthState.None, RasterizerState.CullNone);

C#:

    GL.Viewport(0, 0, game.Width, game.Height);
    GL.ClearColor(0, 1, 0, 1);
    GL.ClearDepth(1.0);
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    sb.Begin();
    sb.Draw(tex, new Vector2(-0.5f, 0.5f), new Vector2(1, -1), Color.White);
    sb.End(SpriteSortMode.None);
    sb.RenderBatch(Matrix4.Identity, Matrix4.Identity, BlendState.Opaque, SamplerState.PointWrap, DepthState.None, RasterizerState.CullNone);

Контекст OpenGL для них одинаков (3.3).

Тем не менее, версия C# делает то, что должна (рисовать белый прямоугольник), а версия Java ничего не делает (только зеленый фон). Может кто-нибудь сказать, пожалуйста, в чем разница? Что не работает? Спасибо. Я застрял на этом в течение трех недель.

1 ответ

Решение

Итак, я нашел проблему на самом деле. Это связано с тем, как Java управляет памятью, и с тем фактом, что Java в этом отношении является кучей мусора. Причина, по которой он работает в C#, а не в Java, заключается в том, что C# предоставляет доступ к указателям, в то время как в Java наиболее близки буферы NIO. Чтобы звонки OpenGL работали, необходимо указывать физические указатели, но буферы могут предоставлять физические или виртуальные указатели в зависимости от их конструкции. Короче говоря, замена "ByteBuffer.allocateDirect" на "BufferUtils.createByteBuffer" решает проблему. Хотя я бы предпочел вместо этого исправить Java:P.

    private void GenerateBatches() {
        if(glyphs.size() < 1) return;

        // Create Arrays
        ByteBuffer bb = BufferUtils.createByteBuffer(6 * glyphs.size() * VertexSpriteBatch.Size);
        SpriteBatchCall call = new SpriteBatchCall(0, glyphs.get(0).Texture, batches);
        glyphs.get(0).VTL.AppendToBuffer(bb);
        glyphs.get(0).VTR.AppendToBuffer(bb);
        glyphs.get(0).VBL.AppendToBuffer(bb);
        glyphs.get(0).VBL.AppendToBuffer(bb);
        glyphs.get(0).VTR.AppendToBuffer(bb);
        glyphs.get(0).VBR.AppendToBuffer(bb);
        emptyGlyphs.add(glyphs.get(0));

        int gc = glyphs.size();
        for(int i = 1; i < gc; i++) {
            SpriteGlyph glyph = glyphs.get(i);
            call = call.Append(glyph, batches);
            glyph.VTL.AppendToBuffer(bb);
            glyph.VTR.AppendToBuffer(bb);
            glyph.VBL.AppendToBuffer(bb);
            glyph.VBL.AppendToBuffer(bb);
            glyph.VTR.AppendToBuffer(bb);
            glyph.VBR.AppendToBuffer(bb);
            emptyGlyphs.add(glyphs.get(i));
        }
        bb.flip();
        glyphs = null;

        // Set The Buffer Data
        glBindBuffer(BufferTarget.ArrayBuffer, vbo);
        if(gc > glyphCapacity) {
            glyphCapacity = gc * 2;
            glBufferData(
                    BufferTarget.ArrayBuffer,
                    (glyphCapacity * 6) * VertexSpriteBatch.Size,
                    bufUsage
                    );
        }
        glBufferSubData(BufferTarget.ArrayBuffer, 0, bb);
        GLBuffer.Unbind(BufferTarget.ArrayBuffer);
    }
Другие вопросы по тегам