Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.
How to create a DirectX texture with a picture
This article explains how to create a DirectX texture with a picture loaded using a .NET API.
This article explains how you can create the texture by loading the picture into a buffer in C# and passing it to C++ code (where it can be loaded into a texture).
Solution has four parts :
Read a picture to get its buffer data
To load a picture you must use BitmapImage class. This class can decode different image formats but it doesn't give an access to pixel.
You must convert this bitmap to a WritableBitmap class.
WriteableBitmap have three interesting properties :
- PixelWidth : picture width.
- PixelHeight : picture height.
- Pixels : pixels buffer.
Warning: Picture orientation of pixel buffer could be wrong. You can find a solution to get the true picture orientation of pixel buffer here: Ensuring correct orientation of loaded image.
Give Buffer to C++ code
Once you load a picture and create a WriteableBitmap, you must give picture size and pixel buffer to C++ code. C# array is compatible with the C++/CX Platform::Array class.
First you must add a public function to your WinPRT component with equivalent parameters:
void func (const Platform::Array<int>^ buffer, int with, int height);
In the C++ code, the buffer pointer is accessible from the Platform::Array::Data property.
To call this function from your C# code, you just need to give the pixels array.
m_d3dInterop.CreateTexture(bmp.Pixels, bmp.PixelWidth, bmp.PixelHeight);
Create a DirectX texture
DXGI_FORMAT_B8G8R8A8_UNORM, // Texture use ARGB pixel
static_cast<UINT>(width), //picture width
static_cast<UINT>(height), //picture height
When you create a texture you can give pixel data. To do it, you must initialize a D3D11_SUBRESOURCE_DATA structure with pixel buffer and its memory organisation.
int pixelSize = sizeof(int);//pixel size. Each pixels are represented by a int 32bits.
data.pSysMem = buffer; //pixel buffer
data.SysMemPitch = pixelSize *width;// line size in byte
data.SysMemSlicePitch = pixelSize *width*height ;// total buffer size in byte
&textureDesc, //texture format
&data, // pixel buffer use to fill the texture
&m_Texture // created texture
Image with alpha layer
WritableBitmap use premultiplied_ARGB format, i.e. RGB values are ever multiplied by alpha coefficient. This format is used to seep-up blending computation.
If you load a picture with an alpha layer you must remove alpha compensation on RGB values.
//use uint32 buffer
uint32 * uBuffer = (uint32 *)buffer;
//for each pixel
for (int i =0; i <width*height;++i)
//extract alpha value
uint8 a = uBuffer[i] >>24;
//alpha = 0 => can't compensate RGB value
//alpha = 255 => ARGB == premultiplied_ARGB
if(a ==0 || a ==255)
ARGBBuffer[i] = uBuffer[i];
//compute alpha coefficient
double aCoef = (uBuffer[i] >>24)/255.;
//extract RGB value and remove alpha compensation with alpha coeficient
uint8 r = (uBuffer[i] >>16 & 0xFF) /aCoef +.5;
uint8 g = (uBuffer[i] >>8 & 0xFF) /aCoef +.5;
uint8 b = (uBuffer[i] & 0xFF) /aCoef +.5;
//recreate ARGB value to uint32
ARGBBuffer[i] = (a <<24) + (r <<16) + (g <<8) + b;
A code example/test code can be downloaded from here: Media:DisplayPictureDX.zip
The example app uses previous functions to generate a texture and displays a cube. A button is used to select a picture from your photo gallery.