OpenGL糟糕的表现

时间:2017-12-24 12:10:39

标签: c# performance opengl opentk

当我最终认为我的游戏引擎完成时,会发生这种情况:rx480,i3 7100以29 fps呈现40 * 25四边形。我正在使用OpenTK,这是​​我的渲染引擎代码:

public static void Render(Entity model, int x = 0, int y = 0, int sx = 0, int sy = 0)
    {
        if (sx == 0 || sy == 0)
        { 
        sx = model.texture.Width;
        sy = model.texture.Height;
        }
        Bind(model.texture, x, y, sx, sy);
        GL.Rotate(model.rX, 0, 0, 1);
        GL.Begin(PrimitiveType.Quads);
        GL.TexCoord2(0f, 0f);
        GL.Vertex2(model.vertices[0] + model.position);
        GL.TexCoord2(1f, 0f);
        GL.Vertex2(model.vertices[1] + model.position);
        GL.TexCoord2(1f, 1f);
        GL.Vertex2(model.vertices[3] + model.position);
        GL.TexCoord2(0f, 1f);
        GL.Vertex2(model.vertices[2] + model.position);
        GL.End();
        GL.Rotate(0 - model.rX, 0, 0, 1);
    }

    private static void Bind(Bitmap bitmap, int X, int Y, int SizeX, int SizeY)
    {

        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);

        BitmapData data = bitmap.LockBits(new Rectangle(X, Y, SizeX, SizeY),
       ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
            OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);

        bitmap.UnlockBits(data);
    }

    public static void Render(TextElement text)
    {
        Render(new Entity(text.verts, text.pos, text.rot, text.prerender));

    }

    public static void Render(Sprite sprite, int state, Display disp)
    {
        Vector2[] vec = {
            Vector2.Zero,
            new Vector2(((float) sprite.spriteSize.Width / disp.w.Width), 0),
            new Vector2(0,((float) sprite.spriteSize.Height / disp.w.Height)),
            new Vector2(((float)sprite.spriteSize.Width / disp.w.Width), ((float)sprite.spriteSize.Height / disp.w.Height)),
        };
        Entity ent = new Entity(vec, sprite.position, sprite.rot, sprite.texture);

        Render(ent,(int) sprite.states[state].X, (int) sprite.states[state].Y, sprite.spriteSize.Width, sprite.spriteSize.Height);
    }

    public static void Render(TerrainCamera cam, Tile[] tiles, Scene scene, Size size, Display d, Scene[] LightScene)
    {
        Vector2[] states = {Vector2.Zero };
        for (int x = 0; x < size.Width; x++)
        {
            for (int y = 0; y < size.Height; y++)
            {

                Vector2 pos = new Vector2((float)(x * tiles[0].Textures[0].Width) / d.w.Width, (float)(y * tiles[0].Textures[0].Height) / d.w.Height);
                Sprite ent = new Sprite(tiles[cam.GetTile(x, y, scene)].Textures[tiles[cam.GetTile(x, y, scene)].animState], new Size(tiles[0].Textures[0].Width, tiles[0].Textures[0].Height), states, 0, pos);
               Shader(pos.X, pos.Y, tiles[0].Textures[0].Width / d.w.Width, tiles[0].Textures[0].Height / d.w.Height, Color.FromArgb(254, LightScene[0].Level[x, y], LightScene[1].Level[x, y], LightScene[2].Level[x, y]));
                Render(ent, 0, d);
                GL.Color4(1f, 1f, 1f, 1f);
            }
        }
    }

    public static void Shader(float X, float Y, float SizeX, float SizeY, Color ShaderColor)
    {
        GL.Color4(ShaderColor);
        GL.Begin(PrimitiveType.Quads);
        GL.Vertex2(X, Y);
        GL.Vertex2(X + SizeX, Y);
        GL.Vertex2(X + SizeX, Y + SizeY);
        GL.Vertex2(X, Y + SizeY);
        GL.End();

    }

VSync已关闭。我想我正在重载cpu创建新的精灵。即使关闭了ShaderQuads,fps仍然很糟糕。我应该使用纹理坐标吗?我也用GDI +渲染文本(不是最好的表现)。我的旧瓷砖映射游戏使用相同数量的四边形和着色器(200 fps)做得很好。我可以节省时间绑定纹理吗?

你能帮我吗?

1 个答案:

答案 0 :(得分:0)

您正在使用即时模式绘图命令,即glBegin(…), glVertex(…), glEnd()。性能被函数调用开销占用。开始使用顶点数组,理想情况下包含在缓冲区对象(VBO)中,并将绘制批处理为尽可能少的glDraw…(…)调用。

另一个问题是,您的Bind方法会为每个绘图调用重新创建纹理对象(glTexImage为每个绘图调用创建一个全新的纹理对象)。 创建纹理对象非常昂贵!只需创建一次纹理对象,然后在需要时绑定它(glBindTexture)。