Had to switch from OpenGL to Direct3D9 any help with vertex shader/pixel shader construction?

Started by
5 comments, last by Hodgman 10 years, 2 months ago

Hello after having so much hassle getting win32 and OpenGL to work in sync I decided to say screw it and go for Direct3D 9 with HLSL and having a blast but there is a little problem understanding the right functions and the order in which pixel and vertex shaders need to be setup to use,create and code them both, turns out to be a hellish task due to the somewhat "abomination" that is the "MSDN" which doesn't really say exactly what to do or if it does it's so vague that I can't quite grasp the function order and names so with that can someone please ethier tell me what I need to do to use,create and code pixel and vertex shaders or provide me a non-retardedly technical resource for learning Direct3D9 that actually works out of the box so I can learn the hell out of it please.

I will complain to MSDN about the lazy-ness of there writers as well it's proper foul.

From what I've learnt on my own research is I need to setup vertex declaration,constants and the handle for which to reference the shader member functions with.


LPDIRECT3DVERTEXSHADER9 Vertex_Shader ;
LPDIRECT3DVERTEXDECLARATIONS9 Vertex_Declarations;

Then this one line "LPD3DXCONSTANTTABLE" below doesn't have a definition on MSVS 2012 in the d3d9.h file any reasons why would be appreciated and very helpful.


LPD3DXCONSTANTTABLE Vertex_Constants;

Then I need to get the shader file with


D3DXCompileShaderFromFile();

of which I have not much of an idea how to use it if at all and doesn't compile, presume there is a header file I'm missing if so would be nice if someone could tell me which one so I can find it somewhat easily but I doubt anyone will :/ and yea that's about as far as I've gotten and still very confused.. please someone out there help!

EDIT: It also appears that some of these are deprecated so I defiantly need help now sad.png.

OpenGL all the way for Linux and MacOSX though biggrin.png

I'm on Windows!

Any advice or tips is also appreciated !

Advertisement

Don't know which SDK you've got but there should be a Direct3D (or Direct3D9) folder somewhere in the Samples folder, possilbly among others in the C++ folder.

There are several examples using vertex shaders - HDRPipeline, HDRScene, HLSLwithEffects, etc. Microsoft's use of DXUT is sort of a pain but you should easily find examples of D3DXCompileShader.., etc., how to set it up and use it.

LPD3DXCONSTANTTABLE is a define for ID3DXConstantTable* - In the help viewer index (not search), look for ID3DXConstant.. and you should find the documentation.

You may also want to consider using ID3DXEffect inside of shaders. I find that easier to use (it's a tradeoff) because it can contain multiple techniques (different shaders, essentially) all in one file. You can switch among techniques, depending on how you want to handle different objects.

EDIT: With regard to the compile error, make sure you have the correct path set to the shader file. Because of starting in different working directories depending on debug vs release vs running from the menu, it may be best just to use the full path, e.g., "c:\\mystuff\\thisproject\\myshader.vsh" rather than just "myshader.vsh"

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

What a fairly vague answer hmmm but thanks any more help would be appreciated . :D

Why Direct3D 9? 11 works with older hardware via feature levels and it runs on Vista and up (Vista needs SP2, I believe) and the API is _significantly_ cleaner and better. The only reason I can think of to use D3D9 is if you plan to support WinXP, and in that case it's hard to recommended writing a separate renderer if you've already got a GL one. Use SDL/SFML/GLFW/etc. and you can basically ignore the existence of Win32's API and code more or less uniformly across Windows, Mac, and Linux. Even iOS/Android to a degree.

If you want more specific help, post (small) code samples and clearly list the actual errors and problem. "It doesn't work" and 1 or 2 context-less lines are not helpful to any of us. smile.png

The nice thing about D3D11 is that most of the concepts it uses port directly to modern OpenGL. You might have to modify some of your high-level renderer structure if you're using OpenGL "wrong" (fairly common given how terrible most online docs for GL are and how much legacy cruft is in the GL API; it's hard to know what you should or shouldn't do in GL without lots of experience) in order to match the structure D3D11 needs (which is roughly the architecture that _hardware_ needs to be used well) but the result will be a better GL renderer in your game. If anyone has the time for two renderers I usually recommend writing and debugging the D3D11 one first and the GL one second for this reason and a few others (the big one being that the D3D debug tools are _significantly_ more advanced and useful than the GL ones, so it's easier to build a renderer on D3D11 and just use GL for ports of an already written and debugged renderer).

Sean Middleditch – Game Systems Engineer – Join my team!

Have you considered a middleware engine such as Ogre3D? It supports GL, D3D9/11, etc.

www.simulatedmedicine.com - medical simulation software

Looking to find experienced Ogre & shader developers/artists. PM me or contact through website with a contact email address if interested.

many GOOD Games were been maked with dx9

many old videocards not support dx11

and it will be funny if your LITTLE game will work only on top hardware ;[

turns out to be a hellish task due to the somewhat "abomination" that is the "MSDN" which doesn't really say exactly what to do or if it does it's so vague that I can't quite grasp the function order and names so with that can someone please ethier tell me what I need to do to use,create and code pixel and vertex shaders or provide me a non-retardedly technical resource for learning Direct3D9 that actually works out of the box so I can learn the hell out of it please.

All the info on the MSDN should also be available in your SDK installation, in a file named something like windows_graphics.chm. As well as the reference pages, that just give you the vague descriptions, there will also be guides, tutorials and sample programs.


Instead of using D3DXCompileShaderFromFile, etc, I would recommend using fxc.exe, which is a shader compiler that comes with the SDK that allows you to compile your shaders ahead of time.
See here: http://msdn.microsoft.com/en-us/library/windows/desktop/bb509710(v=vs.85).aspx

The compiler will produce binary "object" files, containing your compiled shader code. You then load these files at runtime, and pass the contents of the file to CreatePixelShader/CreateVertexShader, e.g.


IDirect3DPixelShader9* result = 0;
char* data = /*load your compiled shader file*/;
bool everythingIsOk = SUCCEEDED( device->CreatePixelShader( (DWORD*)data, &result ) );


The overall pipeline looks like:
5VCS8Lj.png


To bind a vertex buffer to the device, for use by any vertex shader, you use SetStreamSource( slot, buffer, offset, stride ).
To bind an index buffer to the device, for use by any vertex shader, you use SetIndices.

To configure the input assembler stage, you bind a "vertex declaration" with SetVertexDeclaration.
This object defines how streams (VBO's) are read and turned into an input vertex, which is passed to the vertex shader. It is the "glue" between vertex buffers and vertex shaders.
To create one, you make an array of D3DVERTEXELEMENT9 elements, describing each 'varying' variable to be input to the vertex shader. This array must contain one extra entry at the end, which is set to D3DDECL_END to signify the end of the array. You then pass this array to CreateVertexDeclaration.

To set the pixel/vertex shader code that will be used, you use SetPixelShader and SetVertexShader.

To configure the rasterization stage, you use SetRenderState with D3DRS_CULLMODE, D3DRS_FILLMODE, D3DRS_DEPTHBIAS and D3DRS_SLOPESCALEDEPTHBIAS.

To configure the depth-stencil test, you use SetRenderState with D3DRS_ZENABLE, D3DRS_ZWRITEENABLE, D3DRS_ZFUNC, D3DRS_STENCILENABLE, D3DRS_STENCILREF, D3DRS_STENCILMASK, D3DRS_STENCILWRITEMASK, D3DRS_STENCILFUNC, D3DRS_STENCILPASS, D3DRS_STENCILFAIL and D3DRS_STENCILZFAIL.

To bind a texture to the device for use by any pixel shader, you use SetTexture( slot, texture )
To bind a texture to the device for use by any vertex shader, you use SetTexture( D3DVERTEXTEXTURESAMPLER0+slot, texture )

To configure how textures are sampled, you use SetSamplerState( slot, type, value ), where type is D3DSAMP_ADDRESSU, D3DSAMP_ADDRESSV, D3DSAMP_ADDRESSW, D3DSAMP_MAGFILTER, D3DSAMP_MINFILTER, D3DSAMP_MIPFILTER, D3DSAMP_MIPMAPLODBIAS, D3DSAMP_MAXMIPLEVEL, D3DSAMP_MAXANISOTROPY and D3DSAMP_BORDERCOLOR.

To set a uniform variable, for use by any pixel shader, you use SetPixelShaderConstantF( slot, data, numberOfFloat4sInData ).
To set a uniform variable, for use by any vertex shader, you use SetVertexShaderConstantF( slot, data, numberOfFloat4sInData ).
Unlike GL 1.x/2.x, uniform variables are set on the device, not on a shader program. Shader programs and uniform values are completely independent.
Once you set a uniform variable, it will remain in that slot (for any bound shader) until a new uniform variable is set.

To configure the output merger stage, you use SetRenderState with D3DRS_COLORWRITEENABLE, D3DRS_ALPHABLENDENABLE, D3DRS_SRCBLEND, D3DRS_DESTBLEND, D3DRS_BLENDOP, D3DRS_ALPHAFUNC and D3DRS_ALPHAREF.

To change your render-targets (frame buffer objects), you use SetDepthStencilSurface and SetRenderTarget.
To set the viewport rect you use SetViewport.
To set the scissor rect you use SetScissorRect.

You can then draw primitives with DrawPrimitive and DrawIndexedPrimitive.

If you've got specific, non-vague questions, ask away.

many GOOD Games were been made with dx9
many old video-cards not support dx11
and it will be funny if your LITTLE game will work only on top hardware ;[

The Dx11 API can be used to write games for SM2 (~2003), SM4 (~2006) and SM5 (~2010) class hardware.
You do this via "feature levels". i.e. you can use the Dx11 API, but select the "D3D9 feature level" so that your game works on old hardware.
The only catch is that your users require Win Vista/7/8...

The Dx9 API can be used to write games for SM2 and SM3 (~2005) class hardware.
The good thing about this is that your users only require Win XP.

This topic is closed to new replies.

Advertisement