Original Post
Hello all. I'm doing something very simple: mapping a texture to a quad using MDX(9) with transformed coordinates and rendering it to the screen. The textured quad appears in the correct screen space and everything looks good... except the texture seems to render incorrectly. It's as if the texture image histogram has been modified and is drawn to the screen in a strangely sharpened/contrasty state. I'm loading the texture with values from a byte array (that corresponds initially to an 8-bit grayscale image) so I saved the array to a bitmap, saved it, opened it and looked at it. It appears exactly as I would expect, so I know the source array contains the correct values. The texture is properly positioned and everything, it's just the appearance of the texture itself that looks different by a not-insignificant degree. The byte array is exactly the same dimensions as the quad so there should be a straight 1:1 mapping with no interpolation. Here's the simple source code I'm using...can anyone see what I've done wrong? Thanks in advance!
//Values have been loaded into pixelBuffer[,]. Save to a bitmap just
// to make sure the values look correct:
Bitmap checkImage = new Bitmap(pixelBuffer.GetLength(1), pixelBuffer.GetLength(0), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
for (int x = 0; x < pixelBuffer.GetLength(0); x++)
{
for (int y = 0; y < pixelBuffer.GetLength(1); y++)
{
byte grayVal = pixelBuffer[x,y];
checkImage.SetPixel(y, x, Color.FromArgb(grayVal, grayVal, grayVal));
}
}
checkImage.Save("C:\\Users\\Me\\Check Image.bmp");
// Image looks good.
// Instantiate a Texture, write to it:
Bitmap texBitmap = new Bitmap(renderRectangle.Width, renderRectangle.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
backgroundTexture = new Texture(device, texBitmap, 0, Pool.Managed);
Surface texSurface = backgroundTexture.GetSurfaceLevel(0);
SurfaceDescription description = backgroundTexture.GetLevelDescription(0);
// Note: "PixelColor" is a struct containing 4 bytes (a,r,g,b):
PixelColor[] textureData = (PixelColor[])texSurface.LockRectangle(typeof(PixelColor), LockFlags.None, description.Width * description.Height);
int CurrentTexturePosition = 0;
for (int row = 0; row < renderRectangle.Height; row++)
{
for (int column = 0; column < renderRectangle.Width; column++)
{
textureData[CurrentTexturePosition].a = 255;
textureData[CurrentTexturePosition].r = pixelBuffer[row, column];
textureData[CurrentTexturePosition].g = pixelBuffer[row, column];
textureData[CurrentTexturePosition].b = pixelBuffer[row, column];
CurrentTexturePosition++;
}
}
// Unlock surface:
textSurface.UnlockRectangle();
// Setup device and parameters:
presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
device =
new Device(0, DeviceType.Hardware, ParentForm, CreateFlags.HardwareVertexProcessing, presentParams);
device.RenderState.Lighting = false;
device.RenderState.AlphaBlendEnable = true;
device.RenderState.SourceBlend = Blend.SourceColor;
device.RenderState.DestinationBlend = Blend.InvSourceAlpha;
// Initialize the vertices used for the triangles that form
// the background quad. Used transformed coordinates.
// "renderRectangle" is exactly the same dimensions
// as the "pixelBuffer" array:
float Left = (float)renderRectangle.Left;
float Top = (float)renderRectangle.Top;
float Right = (float)renderRectangle.Right;
float Bottom = (float)renderRectangle.Bottom;
// Use default (clockwise) winding order:
backgroundVertices[0].Position = new Vector4(Left, Top, 1.0f, 1.0f);
backgroundVertices[0].Tu = 0.0f;
backgroundVertices[0].Tv = 0.0f;
backgroundVertices[1].Position = new Vector4(Right, Top, 1.0f, 1.0f);
backgroundVertices[1].Tu = 1.0f;
backgroundVertices[1].Tv = 0.0f;
backgroundVertices[2].Position = new Vector4(Right, Bottom, 1.0f, 1.0f);
backgroundVertices[2].Tu = 1.0f;
backgroundVertices[2].Tv = 1.0f;
backgroundVertices[3].Position = new Vector4(Left, Top, 1.0f, 1.0f);
backgroundVertices[3].Tu = 0.0f;
backgroundVertices[3].Tv = 0.0f;
backgroundVertices[4].Position = new Vector4(Right, Bottom, 1.0f, 1.0f);
backgroundVertices[4].Tu = 1.0f;
backgroundVertices[4].Tv = 1.0f;
backgroundVertices[5].Position = new Vector4(Left, Bottom, 1.0f, 1.0f);
backgroundVertices[5].Tu = 0.0f;
backgroundVertices[5].Tv = 1.0f;
// Now loop through the vertices and offset by -0.5 to correctly map the
// texels with the pixels:
for (int x = 0; x < 6; x++)
{
backgroundVertices[x].X -= 0.5f;
backgroundVertices[x].Y -= 0.5f;
}
// Clear the DirectX device and render:
device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
device.BeginScene();
device.SetTexture(0, backgroundTexture);
device.VertexFormat = CustomVertex.TransformedTextured.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 2, backgroundVertices);
device.EndScene();
device.Present();