Here an example of code used to listen for UDP trame. As C language is not my programming language my code can be far from best. This code works in 32bit and 64bit (Use VC++ 2012 express - much easier to build DLL for 32bits and 64bits than VC++ 2010) Notes: - This example take the ISI example plugin as code base - In C when a variable is declared, it is not initialized with classical values (so if you do not explicitly set a variable default value in the constructor, a new created variable will have a random value) -> Main source of issue for JAVA, C#, ... developpers rF2 Plugin API notes There are two main methods, in the rF2 plugin API, allowing you to add your rendering code. - void RenderScreenBeforeOverlays( const ScreenInfoV01 &info ); // This method is called after the track/car rendering but before the rF2 overlays (like virtual mirrors) - void RenderScreenAfterOverlays( const ScreenInfoV01 &info ); // this method is called after rF2 overlays DirectX prerequisite To be able to use DirectX primitive, you need have DirectX SDK installed. You can download the "Microsoft DirectX SDK 28 June 2010" In you VC++ properties you need to set: - Project Properties > Configuration > VC++ Directories >> Include Directories : C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) - Project Properties > Configuration > VC++ Directories >> Librairy Directories : ..... For 32bits: C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath) ..... For 64bits: C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) DirectX includes In the Example.hpp, add the following includes: Code: #include <d3d9.h> #include <d3dx9.h> #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") Retrieve the DirectX device To be able to draw any kind of DirectX primitive, you need to retrieve the DirectX device from the rF2 API parameter "ScreenInfoV01 &info" Code: LPDIRECT3DDEVICE9 dev = static_cast<LPDIRECT3DDEVICE9>(info.mDevice); Draw a text First, you need to create the DirectX font to use. Code: int fontSize = 16; int fontWeight = 400; // 400=Normal, 700=Bold (For all values, [URL="http://msdn.microsoft.com/en-us/library/windows/desktop/dd183499(v=vs.85).aspx"]see FW_xxxx constant for D3DXCreateFont[/URL]) char fontName[] = "Arial"; LPD3DXFONT font; D3DXCreateFont( dev, fontSize, 0, fontWeight, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT(fontName), &font ); Now, to draw a Text, you need to specify the rectangle in which the text will be drawn (and clipped), the text, alignment and the color. Code: RECT tmpRect; tmpRect.left = 100; tmpRect.top = 100; tmpRect.right = 400; tmpRect.bottom = 150; int alignment = 1; // 0=left, 1=center, 2=right D3DCOLOR color= D3DCOLOR_ARGB( 255, 255, 0, 255 ); // alpha, r, g, b font->DrawTextA(NULL, "Your text", -1, &tmpRect, alignment, color); Draw an image First you need to create the DirectX sprite object. Code: LPD3DXSPRITE sprite; D3DXCreateSprite(dev, &sprite); Then you need to create the texture object. You can create a texture from a file using Code: LPDIRECT3DTEXTURE9 texture; D3DXCreateTextureFromFileEx(dev, "c:/myImage.png", D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0xFFFF00FF, NULL, NULL, &texture); or from a byte array "char buf[]" of length "int bufsize" Code: D3DXCreateTextureFromFileInMemory(device, &buf[0], bufsize, &texture); If you need to retrieve the width and height of the image, you can use for a file Code: D3DXIMAGE_INFO imageInfo; D3DXGetImageInfoFromFile("c:/myImage.png", &imageInfo); float height = (float)imageInfo.Height; float width = (float)imageInfo.Width; or from a buffer Code: D3DXIMAGE_INFO imageInfo; D3DXGetImageInfoFromFileInMemory(&buf[0] , bufsize, &imageInfo); float height = (float)imageInfo.Height; float width = (float)imageInfo.Width; Now, you can render the sprite using matrix transformation for positioning, scaling, ... Code: D3DXMATRIX scaleMatrix; D3DXMATRIX transMatrix; D3DXMatrixScaling(&scaleMatrix, 1, 1, 0); // x, y, z scale (z is not used as it is a 2D rendering) D3DXMatrixTranslation(&transMatrix, 350, 500, 0); // x, y, z (z is not used as it is a 2D rendering) D3DXMatrixMultiply(&transMatrix, &scaleMatrix, &transMatrix); sprite->SetTransform(&transMatrix); sprite->Begin(D3DXSPRITE_ALPHABLEND); sprite->Draw(texture, NULL, NULL, NULL, color); //D3DCOLOR_RGBA(255,255,255,alpha)); sprite->End(); Note : You can use the color to alter the original image color. For example, if you need several identical images but with different images (like colored rectangle, or colored spot), you can create you image as black/grey/white and apply a colored filter.
Thanks a lot, that was really helpful! An important thing to note (might be obvious for people who often program in c++, but I had to find it out the hard way): You have to call Release() on LPD3DXFONT and LPDIRECT3DDEVICE9 or you will have a memory leak and your game will crash fairly soon So something like: Code: if (font != NULL) font->Release(); if (dev == NULL) dev = static_cast<LPDIRECT3DDEVICE9>(info.mDevice); before the text is drawn.
In a real plugin, you will not create a font or a sprite/texture before each draw call. You create it and store it to enhance performance. So you will release them only when necessary.