我已經撞了近3天,現在已經碰到了一件奇怪的事情。GL.BindTexture表演奇怪
我基本上試圖創建一個地圖應用程序,本質上首先繪製地圖紋理到OpenTK.GLControl,然後在這個地圖上創建幾個「點」來表示實體,然後最後打印出實體旁邊的實體名稱每個點。
我終於設法做到了,看到這個image here。
這裏是實現這一目標的paint方法:
private void glControl_Paint(object sender, PaintEventArgs e)
{
if (!glControlLoaded)
return;
GL.Clear(ClearBufferMask.ColorBufferBit);
if (currentMapImage != null)
{
GL.BindTexture(TextureTarget.Texture2D, mapTextureId);
GL.Enable(EnableCap.Texture2D);
GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Decal);
GL.Begin(PrimitiveType.Quads);
GL.TexCoord2(currentZoomRectangle.Left, currentZoomRectangle.Top); GL.Vertex3(0, 0, 0.0f);
GL.TexCoord2(currentZoomRectangle.Right, currentZoomRectangle.Top); GL.Vertex3(glControl.Width, 0, 0.0f);
GL.TexCoord2(currentZoomRectangle.Right, currentZoomRectangle.Bottom); GL.Vertex3(glControl.Width, glControl.Height, 0.0f);
GL.TexCoord2(currentZoomRectangle.Left, currentZoomRectangle.Bottom); GL.Vertex3(0, glControl.Height, 0.0f);
GL.End();
GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate);
GL.Disable(EnableCap.Texture2D);
}
GL.Begin(PrimitiveType.Points);
foreach (Entity entity in entityList)
{
if (filtersForm.getShowEntity(entity.Name))
{
if (filtersForm.getShowDot(entity.TypeConverted))
{
Color dotColor = settingsForm.getDotColor(entity.TypeConverted);
GL.Color3(dotColor);
PointF? dotGlControlPos = getGlControlPos(entity.ZeroToOnePosition);
if (dotGlControlPos != null)
{
GL.Vertex3(dotGlControlPos.Value.X, dotGlControlPos.Value.Y, 0.0);
}
}
}
}
GL.End();
using (Graphics gfx = Graphics.FromImage(textBitmap))
{
gfx.Clear(Color.Transparent);
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
foreach (Entity entity in entityList)
{
if (filtersForm.getShowEntity(entity.Name))
{
if (filtersForm.getShowDot(entity.TypeConverted))
{
if (filtersForm.getShowName(entity.TypeConverted))
{
PointF? nameGlControlPos = getGlControlPos(entity.ZeroToOnePosition);
if (nameGlControlPos != null)
{
Color nameColor = nameColor = settingsForm.getNameColor(entity.TypeConverted);
nameGlControlPos = new PointF(nameGlControlPos.Value.X + 5, nameGlControlPos.Value.Y - settingsForm.EntityFontHeightInPixels - 5);
gfx.DrawString(entity.Name, settingsForm.EntityFont, new SolidBrush(nameColor), nameGlControlPos.Value);
}
}
}
}
}
}
GL.BindTexture(TextureTarget.Texture2D, textTextureId);
System.Drawing.Imaging.BitmapData data = textBitmap.LockBits(new Rectangle(0, 0, textBitmap.Width, textBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, glControl.Width, glControl.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
textBitmap.UnlockBits(data);
GL.Enable(EnableCap.Texture2D);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
GL.Begin(PrimitiveType.Quads);
GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0, 0, -0.1f);
GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(glControl.Width, 0, -0.1f);
GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(glControl.Width, glControl.Height, -0.1f);
GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0, glControl.Height, -0.1f);
GL.End();
GL.BindTexture(TextureTarget.Texture2D, mapTextureId);
glControl.SwapBuffers();
}
現在有趣的事情是,如果我刪除最後GL.BindTexture() - 調用上述方法(即前一glControl.SwapBuffers() - 調用),像這樣:
private void glControl_Paint(object sender, PaintEventArgs e)
{
...
...
...
//GL.BindTexture(TextureTarget.Texture2D, mapTextureId);
glControl.SwapBuffers();
}
我得到this as a result。
我不知道我是如何想出添加該電話的想法。它對我來說沒有任何意義......我想我實際上只需要調用它一次(在開始時我實際繪製地圖紋理時)。
所以我想我的問題是,誰能告訴我這裏發生了什麼?
我確實將地圖貼圖綁定到了每個paint上(參見第10行,包括空行)。順便說一句,「currentMapImage」測試是假的(它從不爲空,甚至在if範圍內都沒有使用)。刪除了。然而,正確的你是關於OpenGL的所有**狀態**。我開始調查,當你把我的思想放在正確的軌道上。原來是另一個函數替換了未綁定它的貼圖紋理,導致它覆蓋了文本紋理(因爲這是Paint-callback的最後綁定紋理)。無論如何,感謝一堆尼科爾。保存了我的第四天! – Greenshoe