//static void DrawSprite(IFramePainterInfo frame, int index) //{ // //prepare // var sprite = frame.spriteList[index]; // var settings = SpriteList.All[sprite.Item1]; // GL.Enable(EnableCap.Texture2D); // GL.BindTexture(TextureTarget.Texture2D, settings.OpenglTexture); // //opacity // { // var opacity = sprite.Item5 == null || sprite.Item5.opacity == null? settings.Opacity : sprite.Item5.opacity.Value; // GL.Enable(EnableCap.Blend); // GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); // GL.Color4(opacity, opacity, opacity, opacity); // } // //go to position // { // GL.MatrixMode(MatrixMode.Modelview); // GL.PushMatrix(); // GL.Translate(new Vector3d(sprite.Item3)); // GL.Rotate(sprite.Item4, 0, 0, 1); // } // //select texture part by frame and draw it // { // var frameNumber = sprite.Item5 == null || sprite.Item5.frame == null ? 0 : sprite.Item5.frame.Value; // if(frameNumber < 0) // frameNumber = 0; // if(frameNumber > settings.FrameCountVertical * settings.FrameCountHorizontal - 1) // frameNumber = settings.FrameCountHorizontal*settings.FrameCountVertical -1; // int hor = settings.FrameCountHorizontal; // int vert = settings.FrameCountVertical; // double horPart = 1d / hor, vertPart = 1d / vert; // double bottom = 1 - (frameNumber / hor + 1) * vertPart; // double top = 1 - frameNumber / hor * vertPart; // double right = (frameNumber % hor + 1) * horPart; // double left = frameNumber % hor * horPart; // Vector2d? size = null; // if(size == null && sprite.Item5 != null && sprite.Item5.size != null) // size = sprite.Item5.size; // if(size == null && settings.Size != null) // size = settings.Size; // if(size == null && settings.ScaleFromOriginal != null) // size = settings.InitialSize.MultEach(settings.ScaleFromOriginal.Value); // if(size == null) // size = settings.InitialSize; // //здесь размер точно не null // if(sprite.Item5 != null && sprite.Item5.scaleSize != null) // size = size.Value.MultEach(sprite.Item5.scaleSize.Value); // var topLeft = -size.Value.MultEach(sprite.Item2); // GL.Begin(PrimitiveType.Quads); // // указываем поочередно вершины и текстурные координаты // GL.TexCoord2(left, top); // GL.Vertex2(topLeft); // GL.TexCoord2(right, top); // GL.Vertex2(topLeft.X + size.Value.X, topLeft.Y); // GL.TexCoord2(right, bottom); // GL.Vertex2(topLeft.X + size.Value.X, topLeft.Y + size.Value.Y); // GL.TexCoord2(left, bottom); // GL.Vertex2(topLeft.X, topLeft.Y + size.Value.Y); // GL.End(); // //draw rect to brighten sprite // if (brightenFactor.Equal(1) == false) // { // double bright = Math.Min(2, brightenFactor) - 1; // GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.One); // GL.Color4(ColorByBright(bright)); // GL.Begin(PrimitiveType.Quads); // // указываем поочередно вершины и текстурные координаты // GL.Vertex2(topLeft); // GL.Vertex2(topLeft.X + size.Value.X, topLeft.Y); // GL.Vertex2(topLeft.X + size.Value.X, topLeft.Y + size.Value.Y); // GL.Vertex2(topLeft.X, topLeft.Y + size.Value.Y); // GL.End(); // if (brightenFactor > 2) // { // GL.Color4(ColorByBright((BrightenFactor - 2) / 2)); // GL.Begin(PrimitiveType.Quads); // // указываем поочередно вершины и текстурные координаты // GL.Vertex2(topLeft); // GL.Vertex2(topLeft.X + size.Value.X, topLeft.Y); // GL.Vertex2(topLeft.X + size.Value.X, topLeft.Y + size.Value.Y); // GL.Vertex2(topLeft.X, topLeft.Y + size.Value.Y); // GL.End(); // } // } // } // GL.PopMatrix(); // GL.Disable(EnableCap.Texture2D); //} #endregion static void DrawText(IFramePainterInfo frame, int index) { QFont.Begin(); var text = frame.textList[index]; var font = FontList.All[text.Item1]; //загружаем все шрифты размером 40 (для достаточной четкости), а потом растягиваем перед выводом float defaultEmSize = 40.0f; var fontState = _textManager.LoadOrCheckFont(font.fontFamily, defaultEmSize /*(float)font.emSize*/, font.fontStyle, text.Item2); fontState.QFont.Options.Colour = font.color; double maxWidth = text.Item6 == null ? double.MaxValue : text.Item6.Value; var fontInfo = new Font(font.fontFamily, defaultEmSize, font.fontStyle, GraphicsUnit.Pixel); var fontHeight = fontInfo.Height; double userWantsHeightInPixels = font.emSize; //in pixels?? double scale = userWantsHeightInPixels / fontInfo.Height; double userWantsMaxWidthInPixels = maxWidth / scale; //* weHavePerPixel.X; var sizeOnbitmap = fontState.QFont.Measure(text.Item2, (float)userWantsMaxWidthInPixels, text.Item5); //todo размер шрифта , если выбираем маленький вьюпорт, не тот var realSize = (new Vector2d(sizeOnbitmap.Width, sizeOnbitmap.Height)) * scale; // rect.size //.DivEach(new Vector2d(control.Width, control.Height)) //.MultEach(new Vector2d(sizeOnbitmap.Width, sizeOnbitmap.Height)); // if (maxWidth != null) // maxWidth *= (rect.size.X / control.Width); // GL.Scale() GL.PushMatrix(); var pos = (text.Item4 - text.Item3.MultEach(realSize)); GL.Translate(pos.X, pos.Y, 0); GL.Scale(scale, scale, 1); fontState.QFont.Print(text.Item2, (float)userWantsMaxWidthInPixels, text.Item5); GL.PopMatrix(); QFont.End(); }
public static void DrawFrame(Control control, IFramePainterInfo frame) { var stopwatch = new Stopwatch(); stopwatch.Start(); //camera GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); var rect = frame.cameraViewport; GL.Ortho(rect.left, rect.right, rect.bottom, rect.top, -1, 1); // Bottom-left corner pixel has coordinate (0, 0) GL.Rotate(frame.cameraRotationDeg, 0, 0, 1); //-- GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); //тут отвечаем только за глубину //глубина, тип, индекс var everything = new List <Tuple <double, int, int> >(); for (int i = 0; i < frame.spriteList.Count; i++) { var x = frame.spriteList[i]; if (SpriteList.All.ContainsKey(x.SpriteEnum) == false) { SpriteList.Load(x.SpriteEnum); Initializer.LoadTextures(new Dictionary <Enum, SpriteList> { { x.SpriteEnum, SpriteList.All[x.SpriteEnum] } }); //решил разрешить подгружать спрайты на лету //throw new Exception("Спрайт с именем " + x.SpriteEnum.ToString() + " не добавлен при инициализации"); } everything.Add(Tuple.Create(x.depth ?? SpriteList.All[x.SpriteEnum].DefaultDrawSettings.depth ?? 0.0, 0, i)); } for (int i = 0; i < frame.textList.Count; i++) { var x = frame.textList[i]; everything.Add( Tuple.Create(x.Item7 ?? FontList.All[x.Item1].depth, 1, i)); } for (int i = 0; i < frame.polygonList.Count; i++) { var x = frame.polygonList[i]; everything.Add( Tuple.Create(x.Item3, 2, i)); } for (int i = 0; i < frame.pathList.Count; i++) { var x = frame.pathList[i]; everything.Add( Tuple.Create(x.Item3, 3, i)); } everything.Sort((a, b) => { if (a.Item1 == b.Item1) { if (a.Item2 == b.Item2) { return(a.Item3.CompareTo(b.Item3)); } else { return(a.Item2.CompareTo(b.Item2)); } } else { return(a.Item1.CompareTo(b.Item1)); } }); foreach (var item in everything) { if (item.Item2 == 0) { DrawSprite(frame.spriteList[item.Item3]); } else if (item.Item2 == 1) { DrawText(frame, item.Item3); } else if (item.Item2 == 2) { DrawPolygon(frame.polygonList[item.Item3].Item1, frame.polygonList[item.Item3].Item2); } else if (item.Item2 == 3) { DrawLineStrip(frame.pathList[item.Item3].Item1, frame.pathList[item.Item3].Item2, frame.pathList[item.Item3].Item4); } } GL.Finish(); double ms = stopwatch.ElapsedMilliseconds; double ticks = stopwatch.ElapsedTicks; }