2014-11-18 3 views
1

Я схожу с ума, пытаясь нарисовать текст поверх окна OpenGL с помощью OpenTK! Я следил за некоторыми учебниками, но я не могу заставить его работать, когда я включаю текстуру, где текст нарисован, тогда у меня просто белое окно, и QUAD, который я рисую для теста, просто исчезает. Если у кого-то есть время, чтобы проверить код, это ниже. Я также могу отправить свою тестовую программу, чтобы проверить ее быстрее. Заранее спасибо за любую помощь по этому поводу.Нарисуйте текст, используя OpenTK

using System; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Windows.Forms; 

using OpenTK.Graphics.OpenGL; 

using System.Diagnostics; 


namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     Bitmap textBmp; 
     int textTexture = -1; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      if (!glControl1.Context.IsCurrent) 
      { 
       glControl1.MakeCurrent(); 
      } 

      GL.MatrixMode(MatrixMode.Projection); 
      GL.LoadIdentity(); 

      GL.Ortho(0, glControl1.Width, 0, glControl1.Height, -1000, 1000); 

      GL.Scale(1, 1, 1); 

      GL.Viewport(0, 0, glControl1.Width, glControl1.Height); 

      GL.ClearColor(Color.White); 

      // Better point and line drawing 
      GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest); 
      GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest); 

      GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha); 

      GL.Enable(EnableCap.PointSmooth); 
      GL.Enable(EnableCap.LineSmooth); 

      GL.Enable(EnableCap.Blend); 

      // Hide stuff behind in 3D 
      GL.Enable(EnableCap.DepthTest); 

      // Enable the texture 
      GL.Enable(EnableCap.Texture2D); 

      // Create Bitmap and OpenGL texture 
      textBmp = new Bitmap((int)glControl1.Width, (int)glControl1.Height); 

      textTexture = GL.GenTexture(); 
      GL.BindTexture(TextureTarget.Texture2D, textTexture); 

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

      GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, textBmp.Width, textBmp.Height, 0, 
          OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); 

      ErrorCode errorCode = GL.GetError(); 
      Debug.Assert(errorCode == ErrorCode.NoError, "OpenTK error!"); 
     } 

     private void glControl1_Paint(object sender, PaintEventArgs e) 
     { 
      ErrorCode errorCode; 

      GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); 

      GL.PushMatrix(); 

      GL.Color3(Color.Black); 

      GL.Begin(PrimitiveType.Quads); 

      GL.Vertex3(10, 10, 10); 
      GL.Vertex3(40, 10, 10); 
      GL.Vertex3(40, 50, 10); 
      GL.Vertex3(10, 50, 10); 

      GL.End(); 

      if (textBmp != null) 
      { 
       using (Graphics gfx = Graphics.FromImage(textBmp)) 
       { 
        gfx.Clear(Color.Transparent); 
        gfx.DrawString("text", new Font("Arial", 10), Brushes.Black, new PointF(textBmp.Width/2, textBmp.Height)); 
       } 

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

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

       textBmp.UnlockBits(data); 

       errorCode = GL.GetError(); 
       Debug.Assert(errorCode == ErrorCode.NoError, "OpenTK error!"); 

       GL.Begin(PrimitiveType.Quads); 
       GL.TexCoord2(0f, 1f); GL.Vertex2(0f, 0f); 
       GL.TexCoord2(1f, 1f); GL.Vertex2(1f, 0f); 
       GL.TexCoord2(1f, 0f); GL.Vertex2(1f, 1f); 
       GL.TexCoord2(0f, 0f); GL.Vertex2(0f, 1f); 
       GL.End(); 
      } 

      errorCode = GL.GetError(); 
      Debug.Assert(errorCode == ErrorCode.NoError, "OpenTK error!"); 

      glControl1.SwapBuffers(); 
     } 
    } 
} 
+0

Вы хотите, чтобы обычный 2D-текст GDI или текст текстуры помещался на трехмерную поверхность? – ja72

+0

Просто регулярный 2D-текст, чтобы поставить вокруг оси и пару легенд, никаких причудливых вещей. –

+0

Посмотрите на добавление счетчика FPS на 'OpenTK'. Я думаю, это показывает, как добавить текстовое оверлей. – ja72

ответ

2

Хорошо, мне, наконец, удалось заставить его работать.

На инициализации я только что сделал:

if (!control.Context.IsCurrent) 
{ 
    control.MakeCurrent(); 
} 

GL.Ortho(0, controlWidth, 0, controlHeight, -1000, 1000); 
GL.Scale(1, -1, 1); // I work with a top/left image and openGL is bottom/left 
GL.Viewport(0, 0, controlWidth, controlHeight); 
GL.ClearColor(Color.White); 
GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest); 
GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest); 
GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha); 
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); 
GL.PolygonMode(MaterialFace.Front, PolygonMode.Line); 
GL.Enable(EnableCap.PointSmooth); 
GL.Enable(EnableCap.LineSmooth); 
GL.Enable(EnableCap.Blend); 
GL.Enable(EnableCap.DepthTest); 
GL.ShadeModel(ShadingModel.Smooth); 
GL.Enable(EnableCap.AutoNormal); 

bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 
gfx = Graphics.FromImage(bmp); 
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 

texture = GL.GenTexture(); 
GL.BindTexture(TextureTarget.Texture2D, texture); 
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); 
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); 
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, 
OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); 

Затем написать текст в растровом изображении:

gfx.DrawString(text, font, brush, new PointF(x, y)); 

И чтобы сделать:

if (!control.Context.IsCurrent) 
{ 
    control.MakeCurrent(); 
} 

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 

GL.MatrixMode(MatrixMode.Modelview); 

GL.Enable(EnableCap.Texture2D); 
GL.BindTexture(TextureTarget.Texture2D, Texture); 

GL.Begin(PrimitiveType.Quads); 

GL.TexCoord3(0.0f, 0.0f, 0f); GL.Vertex3(0f, 0f, 0f); 
GL.TexCoord3(1.0f, 0.0f, 0f); GL.Vertex3(realWidth, 0f, 0f); 
GL.TexCoord3(1.0f, 1.0f, 0f); GL.Vertex3(realWidth, realHeight, 0f); 
GL.TexCoord3(0.0f, 1.0f, 0f); GL.Vertex3(0f, realHeight, 0f); 

GL.End(); 

GL.Disable(EnableCap.Texture2D); 

control.SwapBuffers(); 

Это сделал трюк.
Очень важно (по крайней мере, я думаю):
- GL.Enable (EnableCap.Texture2D) непосредственно перед рендерингом quad с текстурой и GL.Disable (EnableCap.Texture2D) послесловия.
- GL.BindTexture (TextureTarget.Texture2D, Texture) после включения GL.Enable (EnableCap.Texture2D).

Надеюсь, это поможет кому-то. Если мне удастся провести некоторое время, я сделаю с ним класс C# и отправлю его здесь.

Смежные вопросы