简体   繁体   English

在opengl / opentk中沿z轴绘制并旋转文本

[英]Draw and rotate the text along z axis in opengl/opentk

I need to draw string/text in opengl/opentk and then rotate it along z axis from the center of text itself. 我需要在opengl / opentk中绘制字符串/文本,然后从文本本身的中心沿z轴旋转它。

This is what I have tried so far: 到目前为止,这是我尝试过的:

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;
    }
}

I am able to write text with this but unable to rotate. 我可以用它来写文本,但是不能旋转。 And also for some characters it is taking too much space which causes a gap between texts. 而且对于某些字符来说,它占用了太多空间,从而导致文本之间出现间隙。

I am able to write text with this but unable to rotate 我可以用它来写文字,但无法旋转

You have to apply a rotation matrix to the model view matrix. 您必须将旋转矩阵应用于模型视图矩阵。

Choose the model view matrix stack glMatrixMode(GL_MODELVIEW) . 选择模型视图矩阵堆栈glMatrixMode(GL_MODELVIEW)

Push the current matrix on the matrix stack glPushMatrix . 将当前矩阵推入矩阵堆栈glPushMatrix

Multiply the current matrix by a rotation matrix around the z-axis glRotate 将当前矩阵乘以围绕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();

Note, if you want to "reset" the current matrix, then this can be done by glLoadIdentity . 注意,如果要“重置”当前矩阵,则可以通过glLoadIdentity来完成。


If you want to change the rotation point, then you have to translate to the rotation point, then rotate and finally translated back from the rotation point. 如果要更改旋转点,则必须平移到旋转点,然后旋转,最后从旋转点平移回去。 The translation can be done by glTranslate . 翻译可以通过glTranslate Possibly TranslateTransform can be used in your case, but since I can't "see" what it is doing, I can't be sure. 可能会在您的情况下使用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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM