为什么 OpenTK 中的纹理显示不正确? (错误colors/Rotated)
Why does a texture in OpenTK not show properly? (Wrong colors/Rotated)
我列出了我自己的纹理对象,以便我可以相应地访问它们。这些是我正在使用的两个位图图像:
每次我加载我的程序时,它都会从两个位图文件中读取并将它们的纹理数据存储到我的全局纹理列表中。首先加载草方块,然后加载带有 1.0
的棋盘格。草地瓦片纹理渲染。这是它在我的程序中的样子:
看起来像是旋转了180度并水平翻转了。我检查了我的 2d 投影、坐标,它们没问题。向上朝向正 Y,向右朝向正 X,这很好。还有,颜色不错,质感不错!
然而,如果我选择渲染第二个纹理,即 black/magenta 棋盘,它在我的程序中看起来像这样:
它也进行了旋转和翻转,但颜色也没有正确渲染。为什么会这样?这是我的代码:
从位图加载纹理:
Private Function LoadFromBitmap(ByVal Bitmap As Bitmap) As Integer
Dim Tex As Integer
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest)
GL.GenTextures(1, Tex)
GL.BindTexture(TextureTarget.Texture2D, Tex)
Dim Data As BitmapData = Bitmap.LockBits(New Rectangle(0, 0, Bitmap.Width, Bitmap.Height), ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb)
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Data.Width, Data.Height, 0, OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, Data.Scan0)
Bitmap.UnlockBits(Data)
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureMagFilter.Nearest)
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureMinFilter.Nearest)
Return Tex
End Function
渲染:
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()
GL.Viewport(0, 0, ControlWidth, ControlHeight)
For X As Byte = 0 To EZSize(0) - 1
For Y As Byte = 0 To EZSize(1) - 1
GL.Enable(EnableCap.Texture2D)
GL.BindTexture(TextureTarget.Texture2D, TextureList.Item(1).IntData)
GL.Begin(PrimitiveType.Quads)
GL.TexCoord2(X, Y) : GL.Vertex2(X, Y)
GL.TexCoord2(X + 1, Y) : GL.Vertex2(X + 1, Y)
GL.TexCoord2(X + 1, Y + 1) : GL.Vertex2(X + 1, Y + 1)
GL.TexCoord2(X, Y + 1) : GL.Vertex2(X, Y + 1)
GL.End()
GL.Disable(EnableCap.Texture2D)
Next
Next
GL.LoadIdentity()
GL.Flush()
GraphicsContext.CurrentContext.SwapInterval = True
GlControl1.SwapBuffers()
如果启用纹理,则默认情况下纹理元素的颜色乘以当前颜色,因为默认情况下纹理环境模式 (GL_TEXTURE_ENV_MODE
) 为 GL_MODULATE
。参见 glTexEnv
。
这会导致纹理的纹素颜色 "mixed" 是您通过 glColor
设置的最后一种颜色。
在渲染纹理之前设置 "white" 颜色,以解决您的问题:
GL.Color3(Color.White)
贴图被翻转了,因为左下window坐标是(0,0),而贴图中右上坐标是(0, 0)。您必须通过翻转纹理坐标的 v-component 来补偿它:
例如:
GL.Enable(EnableCap.Texture2D)
GL.BindTexture(TextureTarget.Texture2D, TextureList.Item(1).IntData)
GL.Color3(Color.White)
GL.Begin(PrimitiveType.Quads)
GL.TexCoord2(X, Y + 1) : GL.Vertex2(X, Y)
GL.TexCoord2(X + 1, Y + 1) : GL.Vertex2(X + 1, Y)
GL.TexCoord2(X + 1, Y) : GL.Vertex2(X + 1, Y + 1)
GL.TexCoord2(X, Y) : GL.Vertex2(X, Y + 1)
GL.End()
GL.Disable(EnableCap.Texture2D)
同样,您可以将环境模式更改为 GL_REPLACE
,而不是 glTexEnv
:
GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, GL_REPLACE)
我列出了我自己的纹理对象,以便我可以相应地访问它们。这些是我正在使用的两个位图图像:
每次我加载我的程序时,它都会从两个位图文件中读取并将它们的纹理数据存储到我的全局纹理列表中。首先加载草方块,然后加载带有 1.0
的棋盘格。草地瓦片纹理渲染。这是它在我的程序中的样子:
看起来像是旋转了180度并水平翻转了。我检查了我的 2d 投影、坐标,它们没问题。向上朝向正 Y,向右朝向正 X,这很好。还有,颜色不错,质感不错!
然而,如果我选择渲染第二个纹理,即 black/magenta 棋盘,它在我的程序中看起来像这样:
它也进行了旋转和翻转,但颜色也没有正确渲染。为什么会这样?这是我的代码:
从位图加载纹理:
Private Function LoadFromBitmap(ByVal Bitmap As Bitmap) As Integer
Dim Tex As Integer
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest)
GL.GenTextures(1, Tex)
GL.BindTexture(TextureTarget.Texture2D, Tex)
Dim Data As BitmapData = Bitmap.LockBits(New Rectangle(0, 0, Bitmap.Width, Bitmap.Height), ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb)
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Data.Width, Data.Height, 0, OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, Data.Scan0)
Bitmap.UnlockBits(Data)
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureMagFilter.Nearest)
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureMinFilter.Nearest)
Return Tex
End Function
渲染:
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()
GL.Viewport(0, 0, ControlWidth, ControlHeight)
For X As Byte = 0 To EZSize(0) - 1
For Y As Byte = 0 To EZSize(1) - 1
GL.Enable(EnableCap.Texture2D)
GL.BindTexture(TextureTarget.Texture2D, TextureList.Item(1).IntData)
GL.Begin(PrimitiveType.Quads)
GL.TexCoord2(X, Y) : GL.Vertex2(X, Y)
GL.TexCoord2(X + 1, Y) : GL.Vertex2(X + 1, Y)
GL.TexCoord2(X + 1, Y + 1) : GL.Vertex2(X + 1, Y + 1)
GL.TexCoord2(X, Y + 1) : GL.Vertex2(X, Y + 1)
GL.End()
GL.Disable(EnableCap.Texture2D)
Next
Next
GL.LoadIdentity()
GL.Flush()
GraphicsContext.CurrentContext.SwapInterval = True
GlControl1.SwapBuffers()
如果启用纹理,则默认情况下纹理元素的颜色乘以当前颜色,因为默认情况下纹理环境模式 (GL_TEXTURE_ENV_MODE
) 为 GL_MODULATE
。参见 glTexEnv
。
这会导致纹理的纹素颜色 "mixed" 是您通过 glColor
设置的最后一种颜色。
在渲染纹理之前设置 "white" 颜色,以解决您的问题:
GL.Color3(Color.White)
贴图被翻转了,因为左下window坐标是(0,0),而贴图中右上坐标是(0, 0)。您必须通过翻转纹理坐标的 v-component 来补偿它:
例如:
GL.Enable(EnableCap.Texture2D)
GL.BindTexture(TextureTarget.Texture2D, TextureList.Item(1).IntData)
GL.Color3(Color.White)
GL.Begin(PrimitiveType.Quads)
GL.TexCoord2(X, Y + 1) : GL.Vertex2(X, Y)
GL.TexCoord2(X + 1, Y + 1) : GL.Vertex2(X + 1, Y)
GL.TexCoord2(X + 1, Y) : GL.Vertex2(X + 1, Y + 1)
GL.TexCoord2(X, Y) : GL.Vertex2(X, Y + 1)
GL.End()
GL.Disable(EnableCap.Texture2D)
同样,您可以将环境模式更改为 GL_REPLACE
,而不是 glTexEnv
:
GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, GL_REPLACE)