redistributing directx
-
- KVRAF
- Topic Starter
- 2256 posts since 29 May, 2012
Hi all
Does anybody use directx for GUI's? I have recently used directx 9 for an application, considering that it was the oldest relevant version and probably compatible with even ancient versions of windows, but no version of windows seems to have it preinstalled. It would be nice to know if any specific version is already preinstalled, say dx 10 on windows 8 and dx 11 on windows 10 and so on:)
Found some info, but not a complete list yet
DirectX 11.1 is preinstalled on windows 8
DirectX 10.? is probably preinstalled on windows vista
p.s. Google is fast, I have posted this half an hour ago but now it's among the web search results when I still look for information about the subject:) It isn't much fun to find only your own post in a thread, though:)
Does anybody use directx for GUI's? I have recently used directx 9 for an application, considering that it was the oldest relevant version and probably compatible with even ancient versions of windows, but no version of windows seems to have it preinstalled. It would be nice to know if any specific version is already preinstalled, say dx 10 on windows 8 and dx 11 on windows 10 and so on:)
Found some info, but not a complete list yet
DirectX 11.1 is preinstalled on windows 8
DirectX 10.? is probably preinstalled on windows vista
p.s. Google is fast, I have posted this half an hour ago but now it's among the web search results when I still look for information about the subject:) It isn't much fun to find only your own post in a thread, though:)
~stratum~
-
- KVRAF
- Topic Starter
- 2256 posts since 29 May, 2012
-
- KVRist
- 34 posts since 22 Sep, 2013
If you want to use Direct3D9 that works from XP up to Windows 10.
Don't use the DirectX wrapper but only the d3d9.lib (d3d9.dll is available on all XP up to Windows 10 computers.)
I use the d3d9.lib from 2003 and never had any problems.
But, you have to write your own image/texture loader. ( just use GDIplus for this )
And make your own Math library for the needed trig functions etc.
This way it doesn't matter which version of DirectX9 is installed on the users PC, it will always work and your .exe will be very small.
If you make use of the DirectX wrapper d3dx9.lib then the user need to have installed the same version of your wrapper and that it rarely the case. ( it will report a missing d3dx9_XX.dll )
Don't use the DirectX wrapper but only the d3d9.lib (d3d9.dll is available on all XP up to Windows 10 computers.)
I use the d3d9.lib from 2003 and never had any problems.
But, you have to write your own image/texture loader. ( just use GDIplus for this )
And make your own Math library for the needed trig functions etc.
This way it doesn't matter which version of DirectX9 is installed on the users PC, it will always work and your .exe will be very small.
If you make use of the DirectX wrapper d3dx9.lib then the user need to have installed the same version of your wrapper and that it rarely the case. ( it will report a missing d3dx9_XX.dll )
- KVRAF
- 7890 posts since 12 Feb, 2006 from Helsinki, Finland
Ignoring the question of redistributable, I've found in the past that Direct3D windows (and this applies to both Direct3D9 and the later versions; I know the problem exists on Win7 at least, no idea if later versions of Windows share the issue) don't really play well with GDI windows in certain hosts, namely if the host wants to embed your plugin editor into a window containing other stuff that is drawn using GDI, you will most likely experience all kinds of synchronisation problems with repaints, learning to artifacts in the GDI drawing. YMMV, but you might want to use OpenGL instead which works perfectly fine everywhere and can even support modern goodies on WinXP as long as the user has hardware to deal with it.
-
- KVRAF
- Topic Starter
- 2256 posts since 29 May, 2012
Hi,
Thanks for the responses so far. It's nice to know that if I had used directx for a plugin I wouldn't need to include a directx setup.
This question isn't about plugins, though, I've just thought that this community is probably familiar with directx because I seen a few plugins with nice multisampled/antialiased gui's. I have no chance of using OpenGL because this is about hardware accelerated video decoding and the related sdk uses DirectX9/11.
The problem with GDI is interesting. I have seen similar drawing conflicts with QT too, but I haven't really investigated the issue and had to leave that to work on something more urgent, and meanwhile people started asking, do we really need to install directx, what the hell is it for, we have no business with game development
Thanks for the responses so far. It's nice to know that if I had used directx for a plugin I wouldn't need to include a directx setup.
This question isn't about plugins, though, I've just thought that this community is probably familiar with directx because I seen a few plugins with nice multisampled/antialiased gui's. I have no chance of using OpenGL because this is about hardware accelerated video decoding and the related sdk uses DirectX9/11.
The problem with GDI is interesting. I have seen similar drawing conflicts with QT too, but I haven't really investigated the issue and had to leave that to work on something more urgent, and meanwhile people started asking, do we really need to install directx, what the hell is it for, we have no business with game development
~stratum~
- KVRAF
- 7890 posts since 12 Feb, 2006 from Helsinki, Finland
I believe QT is internally using GDI or OpenGL, so it's most likely the very same issue. It's also worth noting that it has something to do with GDI redirection under DWM that uses some kind of implicit synchronization (while Direct3D back-buffers are available to DWM directly; the problem also affects Direct2D that uses the same interfaces I guess). I've never seen the issue happen with DWM disable, but that's not really realistic these days.stratum wrote: The problem with GDI is interesting. I have seen similar drawing conflicts with QT too, but I haven't really investigated the issue and had to leave that to work on something more urgent, and meanwhile people started asking, do we really need to install directx, what the hell is it for, we have no business with game development
One thing to keep in mind is that (if I'm not mistaken) the Direct3D9 shader compiler is not installed by default either, so if you need to compile shaders on the fly (rather than distribute precompiled shader bytecode) then you'll also need to install the redistributable. I personally don't see why adding the redistributables "just in case" to an installer would be a problem, but if you don't have an installer otherwise then that might obviously be a problem.
-
- KVRAF
- Topic Starter
- 2256 posts since 29 May, 2012
QT has many options, but the default on windows is probably trying to use OpenGL first, and if that fails, there is an OpenGL emulation called ANGLE which forwards OpenGL calls to DirectX, and if that fails too, I don't know what it does. Which means, it could actually be using anything, or, it is necessary to compile it from the sources and specify exactly what you want. Given the issue about DWM, perhaps configuring it to always use ANGLE would solve the problem.I believe QT is internally using GDI or OpenGL,
I've seen more amusing problems which prevent people to remember making an installerbut if you don't have an installer otherwise then that might obviously be a problem.
~stratum~
-
- KVRist
- 34 posts since 22 Sep, 2013
Why compile shader-files on the fly when precompiled shader-files are often much smaller ?
And you need no shader-compiler on the users computer ?
If it's not for games but only for GUI's, do you realy need a shader ?
Without a shader you can do most of the effects with just plain coding.
Why does someone want to mix different types of graphics renderers ?
You can do everything with only the d3d9.lib, even shaders. (d3d9.dll is available on all windows computers with XP and up)
The only reason I use GDIplus is to make use of the picture/image encoder/decoders and not for drawing.
I copy the raw picture/image data to Direct9 texture buffers and shut down GDIplus.
Just keep it simple and don't mix things that will bite each other.
Timing issues can easily be solved if programmed smart and simple if you know what you are doing.
Synchronise it all to 1 timer and everything will run in pace.
So, no need for any kind of an installer to create a Directx 9 GUI program.
And you need no shader-compiler on the users computer ?
If it's not for games but only for GUI's, do you realy need a shader ?
Without a shader you can do most of the effects with just plain coding.
Why does someone want to mix different types of graphics renderers ?
You can do everything with only the d3d9.lib, even shaders. (d3d9.dll is available on all windows computers with XP and up)
The only reason I use GDIplus is to make use of the picture/image encoder/decoders and not for drawing.
I copy the raw picture/image data to Direct9 texture buffers and shut down GDIplus.
Just keep it simple and don't mix things that will bite each other.
Timing issues can easily be solved if programmed smart and simple if you know what you are doing.
Synchronise it all to 1 timer and everything will run in pace.
So, no need for any kind of an installer to create a Directx 9 GUI program.
-
- KVRAF
- Topic Starter
- 2256 posts since 29 May, 2012
Hi Siekmanski,
This stuff is a mess for a number of different reasons. Using QT in a scenario in which fastest possible graphics performance is needed is one. That fact that Microsoft created directx at a time when opengl had already existed is another.
No a shader is not needed and yes we could distribute this app without a setup program if I had rendered the textures the way you had described. Thanks for that info.
This stuff is a mess for a number of different reasons. Using QT in a scenario in which fastest possible graphics performance is needed is one. That fact that Microsoft created directx at a time when opengl had already existed is another.
No a shader is not needed and yes we could distribute this app without a setup program if I had rendered the textures the way you had described. Thanks for that info.
Last edited by stratum on Tue Mar 07, 2017 2:48 pm, edited 1 time in total.
~stratum~
- KVRAF
- 7890 posts since 12 Feb, 2006 from Helsinki, Finland
The most common reason to compile shaders on the fly is when you want to choose some of the shader details at run-time and/or adapt it depending on hardware. If you only have a couple of shaders without many variations then obviously precompiling is not an issue.Siekmanski wrote:Why compile shader-files on the fly when precompiled shader-files are often much smaller ?
-
- KVRist
- 34 posts since 22 Sep, 2013
Hi mystran,
I just send different parameters to the shader code to make those changes.
Hi stratum,
You can include for example the .jpg .png files etc. in the resource section of your exe and decode them on the fly in the startup of your program using the GDIplus api and copy them to the texture buffers.
I just started coding a GUI for a picture crucher program written with Directx9 as I described here, it's still in its first stage ( only the textures and the alpha blending ) and uses only the d3d9.dll and GDIplus for the decoding of the textures/pictures.
The GUI graphics ( font, background and window borders ) are included in the resource section of the executable and the alpha handpointer.png is loaded from the Media folder. The rest is not finished yet, but just to show you it can be done without the need of the DirectX9 redistributables installed.
http://members.home.nl/siekmanski/GUI_directx9.zip "Hit F1 for full screen"
I just send different parameters to the shader code to make those changes.
Hi stratum,
You can include for example the .jpg .png files etc. in the resource section of your exe and decode them on the fly in the startup of your program using the GDIplus api and copy them to the texture buffers.
I just started coding a GUI for a picture crucher program written with Directx9 as I described here, it's still in its first stage ( only the textures and the alpha blending ) and uses only the d3d9.dll and GDIplus for the decoding of the textures/pictures.
The GUI graphics ( font, background and window borders ) are included in the resource section of the executable and the alpha handpointer.png is loaded from the Media folder. The rest is not finished yet, but just to show you it can be done without the need of the DirectX9 redistributables installed.
http://members.home.nl/siekmanski/GUI_directx9.zip "Hit F1 for full screen"
-
- KVRAF
- Topic Starter
- 2256 posts since 29 May, 2012
Hi,
What I do is this:
According to the info you had given, probably missing dll's are due to calls like D3DXCreateTexture/D3DXCreateTextureFromFile (there is also a D3DXCreateTextureFromFile call somewhere else)
What I do is this:
Code: Select all
//to create:
D3DFORMAT fmt = D3DFMT_A8B8G8R8
HRESULT hr = D3DXCreateTexture(m_Target,
m_TxWidth,
m_TxHeight,
0,
D3DUSAGE_DYNAMIC,
fmt,
D3DPOOL_DEFAULT,
&m_Texture);
if (FAILED(hr))
return hr;
return S_OK;
//// when data needs to be refreshed:
HRESULT Update()
{
if (!m_Texture)
return E_FAIL;
D3DLOCKED_RECT r;
HRESULT hr = m_Texture->LockRect(0, &r, NULL, D3DLOCK_DISCARD);
if (FAILED(hr))
return hr;
unsigned char* target = (unsigned char*)r.pBits;
unsigned char* src = (unsigned char*)m_Data;// m_Data holds the image (logo, etc)
for (int i = 0; i < m_TxHeight; i++)
{
memcpy(target, src, 4 * m_TxWidth);
target += r.Pitch;
src += m_Pitch; // source row size in bytes
}
hr = m_Texture->UnlockRect(0);
if (FAILED(hr))
return hr;
return hr;
}
~stratum~
-
- KVRist
- 34 posts since 22 Sep, 2013
D3DXCreateTextureFromFile function is from a d3dx9_XX.dll which is part of the DirectX9 redistributables you don't want to use.
So, you have to write your own D3DXCreateTextureFromFile function.
This is my DirectX9 texture loader routine.
It's written in Masm assembler ( my mother language )
You could try to translate it to C++
So, you have to write your own D3DXCreateTextureFromFile function.
This is my DirectX9 texture loader routine.
It's written in Masm assembler ( my mother language )
You could try to translate it to C++
Code: Select all
LoadTexture proc uses ebx esi edi PictureName:DWORD,ColorKey:DWORD,pTexture:DWORD
LOCAL GdiplusToken:dword
LOCAL PictureBuffer:dword
LOCAL RsrcSize:dword
LOCAL hRsrc:dword
LOCAL pStream:dword
LOCAL pImage:dword
LOCAL pLockedRect:D3DLOCKED_RECT
LOCAL ReturnMessage:dword
mov ReturnMessage,E_FAIL
mov esi,pTexture
SAFE_RELEASE dword ptr [esi]
invoke GdiplusStartup,addr GdiplusToken,addr GdiplusSInput,NULL
test eax,eax
jnz Exit_LoadTexture
mov PictureBuffer,NULL
mov pStream,NULL
invoke FindResource,NULL,PictureName,TEXT_("PICTURE")
test eax,eax
jnz Picture_In_Resource ; Picture found in the resource ?
; Try to load Picture from file.
invoke MultiByteToWideChar,CP_ACP,0,PictureName,-1,addr FilenameW,MAX_PATH-1
invoke GdipCreateBitmapFromFile,addr FilenameW,addr pImage
test eax,eax
jnz ShutdownGDIplus
jmp LockBitmap
Picture_In_Resource:
mov hRsrc,eax
invoke SizeofResource,NULL,eax
mov RsrcSize,eax
invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,eax
test eax,eax
jz ShutdownGDIplus
mov PictureBuffer,eax
invoke LoadResource,NULL,hRsrc
invoke LockResource,eax
invoke RtlMoveMemory,PictureBuffer,eax,RsrcSize
invoke CreateStreamOnHGlobal,PictureBuffer,TRUE,addr pStream
test eax,eax
jnz Close_Gdiplus
invoke GdipCreateBitmapFromStream,pStream,addr pImage
test eax,eax
jnz Close_Gdiplus
LockBitmap:
invoke GdipBitmapLockBits,pImage,NULL,ImageLockModeRead,PixelFormat32bppARGB,addr GDIplusBitmapData
test eax,eax
jnz Close_Image
coinvoke g_pD3DDevice,IDirect3DDevice9,CreateTexture,GDIplusBitmapData.dwWidth,GDIplusBitmapData.dwHeight,\
1,D3DUSAGE_DYNAMIC,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,pTexture,NULL
cmp eax,D3D_OK
jne UnlockBitmap
coinvoke g_pPictureTexture,IDirect3DTexture9,LockRect,0,addr pLockedRect,NULL,D3DLOCK_DISCARD
cmp eax,D3D_OK
jne UnlockBitmap
mov esi,GDIplusBitmapData.Scan0 ; pointer to the bitmap data
mov edi,pLockedRect.pBits ; pointer to the texture data
mov ecx,GDIplusBitmapData.dwHeight
Height_lp:
mov edx,GDIplusBitmapData.dwWidth
xor ebx,ebx
Width_lp:
mov eax,dword ptr [esi+ebx]
cmp ColorKey,NULL
jz NoColorKey
or eax,D3DCOLOR_ARGB(255,0,0,0)
cmp ColorKey,eax
jne NoColorKey
xor eax,eax
NoColorKey:
mov dword ptr [edi+ebx],eax
add ebx,4
dec edx
jnz Width_lp
add esi,GDIplusBitmapData.Stride
add edi,pLockedRect.Pitch
dec ecx
jnz Height_lp
coinvoke g_pPictureTexture,IDirect3DTexture9,UnlockRect,0
mov ReturnMessage,D3D_OK
UnlockBitmap:
invoke GdipBitmapUnlockBits,pImage,addr GDIplusBitmapData
Close_Image:
invoke GdipDisposeImage,pImage
Close_Gdiplus:
SAFE_RELEASE pStream
cmp PictureBuffer,NULL
jz ShutdownGDIplus
invoke GlobalFree,PictureBuffer
ShutdownGDIplus:
invoke GdiplusShutdown,GdiplusToken
Exit_LoadTexture:
mov eax,ReturnMessage
ret
LoadTexture endp
-
- KVRAF
- Topic Starter
- 2256 posts since 29 May, 2012
I always knew that the probability of finding someone sane among software engineers wasn't high, but the place where you find people who claim the ability to save the world, or code an whole app in masm, is probably the best of the best and I guess these people smoke something more interesting than the zillion cups of turkish coffee I daily consumeIt's written in Masm assembler ( my mother language )
https://www.youtube.com/watch?v=vBzY7F2lMNo
~stratum~
- KVRAF
- 7890 posts since 12 Feb, 2006 from Helsinki, Finland
Right, so essentially what you want to do is call IDirect3dDevice9::CreateTexture to create the texture, then call texture->GetSurfaceLevel to get the level 0 (highest resolution mip) surface and then surface->LockRect to get a pointer where you can upload the image data (which you can load using whatever image loader floats your boat). Then UnlockRect and release the surface.
The complication is that you need the texture surface to be lockable to upload data which doesn't work for default pool (which you'd probably want to use), so what I normally do is first CreatePlainOffscreenSurface in D3DPOOL_SYSTEMMEM (or you can also create another texture, if you need a pixel format that doesn't work with plain offscreen.. not a problem with normal ARGB though), then do LockRect on that and write the data, then create the actual final texture into D3DPOOL_DEFAULT, use GetSurfaceLevel() to get the top MIP and copy the data over using IDirect3DSurface9::UpdateSurface or StretchRect or some such, then throw away the system memory surface afterwards.
The complication is that you need the texture surface to be lockable to upload data which doesn't work for default pool (which you'd probably want to use), so what I normally do is first CreatePlainOffscreenSurface in D3DPOOL_SYSTEMMEM (or you can also create another texture, if you need a pixel format that doesn't work with plain offscreen.. not a problem with normal ARGB though), then do LockRect on that and write the data, then create the actual final texture into D3DPOOL_DEFAULT, use GetSurfaceLevel() to get the top MIP and copy the data over using IDirect3DSurface9::UpdateSurface or StretchRect or some such, then throw away the system memory surface afterwards.