【问题标题】:Draw and rotate the text along z axis in opengl/opentk在 opengl/opentk 中沿 z 轴绘制和旋转文本
【发布时间】:2018-05-21 10:48:53
【问题描述】:

我需要在 opengl/opentk 中绘制字符串/文本,然后从文本本身的中心沿 z 轴旋转它。

这是我迄今为止尝试过的:

void drawstring(string text, Font font, float fontsize, SolidBrush brush, float x, float y)
{
    if (text == null || text == "")
        return;
    /*
    OpenTK.Graphics.Begin(); 
    OpenTK.Graphics.OpenGL.GL.PushMatrix(); 
    OpenTK.Graphics.OpenGL.GL.Translate(x, y, 0);
    printer.Print(text, font, c); 
    OpenTK.Graphics.OpenGL.GL.PopMatrix(); printer.End();
    */

    float maxy = 1;

    foreach (char cha in text)
    {
        int charno = (int)cha;
        int charid = charno ^ (int)(fontsize * 1000) ^ brush.Color.ToArgb();

        if (!charDict.ContainsKey(charid))
        {
            charDict[charid] = new character()
            {
                bitmap = new Bitmap(128, 128, System.Drawing.Imaging.PixelFormat.Format32bppArgb),
                size = (int)fontsize
            };

            charDict[charid].bitmap.MakeTransparent(Color.Transparent);

            //charbitmaptexid

            float maxx = this.Width / 150; // for space

            // create bitmap
            using (var gfx = Graphics.FromImage(charDict[charid].bitmap))
            {
                var pth = new GraphicsPath();

                if (text != null)
                    pth.AddString(cha + "", font.FontFamily, 0, fontsize + 5, new Point((int)0, (int)0),
                        StringFormat.GenericTypographic);

                charDict[charid].pth = pth;

                gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                gfx.DrawPath(this._p, pth);

                //Draw the face

                gfx.FillPath(brush, pth);

                if (pth.PointCount > 0)
                {
                    foreach (PointF pnt in pth.PathPoints)
                    {
                        if (pnt.X > maxx)
                            maxx = pnt.X;

                        if (pnt.Y > maxy)
                            maxy = pnt.Y;
                    }
                }
            }

            charDict[charid].width = (int)(maxx + 2);

            //charbitmaps[charid] = charbitmaps[charid].Clone(new RectangleF(0, 0, maxx + 2, maxy + 2), charbitmaps[charid].PixelFormat);

            //charbitmaps[charno * (int)fontsize].Save(charno + " " + (int)fontsize + ".png");

            // create texture
            int textureId;
            OpenTK.Graphics.OpenGL.GL.TexEnv(OpenTK.Graphics.OpenGL.TextureEnvTarget.TextureEnv, OpenTK.Graphics.OpenGL.TextureEnvParameter.TextureEnvMode,
                (float)TextureEnvModeCombine.Replace); //Important, or wrong color on some computers

            Bitmap bitmap = charDict[charid].bitmap;
            OpenTK.Graphics.OpenGL.GL.GenTextures(1, out textureId);
            OpenTK.Graphics.OpenGL.GL.BindTexture(OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, textureId);

            BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

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

            OpenTK.Graphics.OpenGL.GL.TexParameter(OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, OpenTK.Graphics.OpenGL.TextureParameterName.TextureMinFilter,
                (int)TextureMinFilter.Linear);
            OpenTK.Graphics.OpenGL.GL.TexParameter(OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, OpenTK.Graphics.OpenGL.TextureParameterName.TextureMagFilter,
                (int)TextureMagFilter.Linear);

            //    OpenTK.Graphics.OpenGL.GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest);
            //OpenTK.Graphics.OpenGL.GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Nearest);
            OpenTK.Graphics.OpenGL.GL.Flush();
            bitmap.UnlockBits(data);

            charDict[charid].gltextureid = textureId;
        }

        float scale = 1.0f;

        // dont draw spaces
        if (cha != ' ')
        {
            /*
            TranslateTransform(x, y);
            DrawPath(this._p, charDict[charid].pth);

            //Draw the face

            FillPath(brush, charDict[charid].pth);

            TranslateTransform(-x, -y);
            */
            //OpenTK.Graphics.OpenGL.GL.Enable(EnableCap.Blend);
            //OpenTK.Graphics.OpenGL.GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
            OpenTK.Graphics.OpenGL.GL.BlendFunc(OpenTK.Graphics.OpenGL.BlendingFactor.SrcAlpha, OpenTK.Graphics.OpenGL.BlendingFactor.OneMinusSrcAlpha);

            OpenTK.Graphics.OpenGL.GL.Enable(OpenTK.Graphics.OpenGL.EnableCap.Texture2D);
            OpenTK.Graphics.OpenGL.GL.BindTexture(OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, charDict[charid].gltextureid);

            OpenTK.Graphics.OpenGL.GL.Begin(OpenTK.Graphics.OpenGL.PrimitiveType.TriangleFan);
            OpenTK.Graphics.OpenGL.GL.TexCoord2(0, 0);
            OpenTK.Graphics.OpenGL.GL.Vertex2(x, y);
            OpenTK.Graphics.OpenGL.GL.TexCoord2(1, 0);
            OpenTK.Graphics.OpenGL.GL.Vertex2(x + charDict[charid].bitmap.Width * scale, y);
            OpenTK.Graphics.OpenGL.GL.TexCoord2(1, 1);
            OpenTK.Graphics.OpenGL.GL.Vertex2(x + charDict[charid].bitmap.Width * scale, y + charDict[charid].bitmap.Height * scale);
            OpenTK.Graphics.OpenGL.GL.TexCoord2(0, 1);
            OpenTK.Graphics.OpenGL.GL.Vertex2(x + 0, y + charDict[charid].bitmap.Height * scale);
            OpenTK.Graphics.OpenGL.GL.End();

            //OpenTK.Graphics.OpenGL.GL.Disable(EnableCap.Blend);
            OpenTK.Graphics.OpenGL.GL.Disable(OpenTK.Graphics.OpenGL.EnableCap.Texture2D);
        }

        x += charDict[charid].width * scale;
    }
}

我可以用它写文字,但无法旋转。而且对于某些字符来说,它占用了太多空间,从而导致文本之间出现间隙。

【问题讨论】:

  • 我已经用我当前的代码编辑了这个问题。请检查。谢谢

标签: c# opengl opentk coordinate-transformation


【解决方案1】:

我可以用这个写文字,但无法旋转

您必须将旋转矩阵应用于模型视图矩阵。

选择模型视图矩阵堆栈glMatrixMode(GL_MODELVIEW)

将当前矩阵推入矩阵栈glPushMatrix

将当前矩阵乘以围绕z轴的旋转矩阵glRotate

OpenTK.Graphics.OpenGL.GL.MatrixMode(OpenTK.Graphics.OpenGL.MatrixMode.ModelView);
OpenTK.Graphics.OpenGL.GL.PushMatrix();
OpenTK.Graphics.OpenGL.GL.Rotated( angle_degree, 0.0, 0.0, 1.0);

OpenTK.Graphics.OpenGL.GL.Begin(OpenTK.Graphics.OpenGL.PrimitiveType.TriangleFan);
OpenTK.Graphics.OpenGL.GL.TexCoord2(0, 0);
OpenTK.Graphics.OpenGL.GL.Vertex2(x, y);
OpenTK.Graphics.OpenGL.GL.TexCoord2(1, 0);
OpenTK.Graphics.OpenGL.GL.Vertex2(x + charDict[charid].bitmap.Width * scale, y);
OpenTK.Graphics.OpenGL.GL.TexCoord2(1, 1);
OpenTK.Graphics.OpenGL.GL.Vertex2(x + charDict[charid].bitmap.Width * scale, y + charDict[charid].bitmap.Height * scale);
OpenTK.Graphics.OpenGL.GL.TexCoord2(0, 1);
OpenTK.Graphics.OpenGL.GL.Vertex2(x + 0, y + charDict[charid].bitmap.Height * scale);
OpenTK.Graphics.OpenGL.GL.End();

OpenTK.Graphics.OpenGL.GL.PopMatrix();

注意,如果你想“重置”当前矩阵,那么这可以通过 glLoadIdentity.


如果你想改变旋转点,那么你必须平移到旋转点,然后旋转,最后从旋转点平移回来。 翻译可以通过glTranslate完成。可能TranslateTransform 可以用于您的情况,但由于我无法“看到”它在做什么,我无法确定。

OpenTK.Graphics.OpenGL.GL.PushMatrix();
OpenTK.Graphics.OpenGL.GL.Translate( rotate_center_x, rotate_center_y, 0.0);
OpenTK.Graphics.OpenGL.GL.Rotated( angle_degree, 0.0, 0.0, 1.0);
OpenTK.Graphics.OpenGL.GL.Translate( -rotate_center_x, -rotate_center_y, 0.0);

.....

OpenTK.Graphics.OpenGL.GL.PopMatrix();

【讨论】:

  • 感谢您的第一时间回复。我对这个 OpenGL 库完全陌生。如果你能让我知道我必须在哪里专门添加这些行,那将是一个很大的帮助。谢谢
  • 我试过这个。它的作用是旋转我正在编写这些文本的面板。我可以猜想我错过了 GL.Translate(x, y, z) 语句,但我不确定我应该将什么作为坐标 (x, y) 传递。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
相关资源
最近更新 更多