我在MonoTouch中使用OpenTK在iOS中渲染一些紋理,並且一些紋理出現破裂。這是iPad的屏幕截圖顯示一個正確呈現質感(最上面的一個),並低於二級破碎者的特寫:在iOS中破損的紋理
我沒有做任何事情奇怪。我使用CGImage
- >CGBitmapContext
- >GL.TexImage2D
從半透明PNG加載紋理。我使用兩個三角形渲染每個精靈,而我的片段着色器僅從texture2D()
採樣器中讀取紋理元素,並將其乘以uniform vec4
以爲紋理着色。
自己似乎是好這些文件,並使用單聲道的Android相同的應用程序在Android端口,完全相同的二進制資源使它們完美。正如你所看到的,其他透明紋理工作正常。
如果有幫助,當我在模擬器中運行程序時,幾乎所有的紋理都被破壞。即使我重建程序,這個問題仍然存在。
任何想法如何找出是什麼導致這個問題?
這裏是我的頂點着色器:
attribute vec4 spritePosition;
attribute vec2 textureCoords;
uniform mat4 projectionMatrix;
uniform vec4 color;
varying vec4 colorVarying;
varying vec2 textureVarying;
void main()
{
gl_Position = projectionMatrix * spritePosition;
textureVarying = textureCoords;
colorVarying = color;
}
這裏是我的片段着色器:
varying lowp vec4 colorVarying;
varying lowp vec2 textureVarying;
uniform sampler2D spriteTexture;
void main()
{
gl_FragColor = texture2D(spriteTexture, textureVarying) * colorVarying;
}
我加載這樣的形象:
using (var bitmap = UIImage.FromFile(resourcePath).CGImage)
{
IntPtr pixels = Marshal.AllocHGlobal(bitmap.Width * bitmap.Height * 4);
using (var context = new CGBitmapContext(pixels, bitmap.Width, bitmap.Height, 8, bitmap.Width * 4, bitmap.ColorSpace, CGImageAlphaInfo.PremultipliedLast))
{
context.DrawImage(new RectangleF(0, 0, bitmap.Width, bitmap.Height), bitmap);
int[] textureNames = new int[1];
GL.GenTextures(1, textureNames);
GL.BindTexture(TextureTarget.Texture2D, textureNames[0]);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bitmap.Width, bitmap.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels);
CurrentResources.Add(resourceID, new ResourceData(resourcePath, resourceType, 0, new TextureEntry(textureNames[0], bitmap.Width, bitmap.Height)));
}
}
,並在我的onRenderFrame,我有這個:
GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.UseProgram(RenderingProgram);
GL.VertexAttribPointer((int)ShaderAttributes.SpritePosition, 2, VertexAttribPointerType.Float, false, 0, squareVertices);
GL.VertexAttribPointer((int)ShaderAttributes.TextureCoords, 2, VertexAttribPointerType.Float, false, 0, squareTextureCoords);
GL.EnableVertexAttribArray((int)ShaderAttributes.SpritePosition);
GL.EnableVertexAttribArray((int)ShaderAttributes.TextureCoords);
//...
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, textureEntry.TextureID);
GL.Uniform1(Uniforms[(int)ShaderUniforms.Texture], 0);
// ...
GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);
即三角形帶由出兩個三角形組成的質感,與頂點和紋理座標中設置的地方,我想表明我的精靈。 projectionMatrix
是一個簡單的直接投影矩陣。
正如你所看到的,我並不想在這裏做任何事情。這是所有非常標準的代碼,它適用於某些紋理,所以我認爲通常代碼是可以的。我在Android的Mono中也做了幾乎相同的事情,並且它工作得很好,沒有任何紋理損壞。
損壞的顏色一樣,那味道像某處未初始化的變量,並看到它發生僅在透明部分使我相信,我有地方未初始化的alpha值。然而,GL.Clear(ClearBufferMask.ColorBufferBit)
應清除我的alpha值,即使如此,背景紋理的alpha值爲1,並且當前BlendFunc
應將這些像素的alpha設置爲1.之後,透明紋理的alpha值範圍爲0到1,所以他們應該適當地混合。我在任何地方都看不到未初始化的變量。
......或者......這是CGBitmapContext
所有的過錯。也許通過做DrawImage
,我不是blitting源圖像,而是使用混合繪製它,而垃圾數據來自AllocGlobal
。這並不能解釋爲什麼它始終只有這兩個質地發生,但...(我這個標記爲核心的顯卡,所以也許石英人可以幫之一)
讓我知道如果你想看到一些更多的代碼。
看到一些代碼可能會幫助人們告訴你/如果事情可能出錯。 – poupou
@poupou我想我解釋什麼,怎麼我做的,我相信這是比較有用的不僅僅是複製粘貼一段代碼長列表,但肯定的是,我可以張貼一些代碼。 –
我猜你正在用'CGBitmapContext'在正確的軌道上。它沒有被默認清除。我相信,你需要確保你在繪製精靈之前用透明黑色填充它。 – user1118321