janta
27/11/2005, 18h21
Allo :)
J'ai créé une classe très simple pour encapsuler un Mesh ( cad un pointeur sur ID3DXEffect + les autres pointeurs qui vont bien: materials, textures ainsi que des variables bool ou int, etc.)
Cette classe fonctionne au poil avec les membres:
...
HRESULT LoadFromFile(IDirect3DDevice9* pd3dDevice, LPWSTR fileName);
HRESULT Render(IDirect3DDevice9* pd3dDevice);
VOID Clean();
...
Maintenant j'essaye d'améliorer cette classe (sans héritage, pour commencer) en intégrant la gestion des fichier effets, puisque certains meshes au format .x ont besoin du fichier .fx associé pour être rendu correctement. (En fait j'ai pris pour exemple le mesh dwarf.x fourni dans le sdk directx, que l'on voit notamment dans l'exemple ProgressiveMesh => Mais Pour l'instant je ne cherche pas à gérer les progressive mesh !)
J'ai donc ajouté (essentiellement) les membres suivants: (et modifié un peu la fonction Clean() bien sur)
...
HRESULT LoadEffect(IDirect3DDevice9* pd3dDevice, LPWSTR szFxFileName);
HRESULT SetRenderTechnique(D3DXHANDLE hTechnique);
...
Jusqu'ici pas de souci, c'est du gâteau. Mais la fonction de Rendu !!!
Peut être que ca vient de mon inexpérience, mais voici comment je vois la chose:
Chaque fichier .fx possède ses propres variables globales et doit donc par conséquent avoir un traitement spécifique au moment du rendu du mesh. Il faut notamment:
Connaître le nom des variables globales
Savoir quelles variables doivent être initialisées au début du rendu
Savoir quelles variable doivent être modifiées pour chaque SubSet
Savoir quelles variable doivent être modifiées à chaque passe
Etc.
Par exemple mon fichier .fx commence par les déclarations suivantes:
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4 g_vDiffuse; // Material diffuse color (pour chaque subset)
float4x4 g_mWorld; // World matrix for object (début du rendu du mesh)
float4x4 g_mWorldViewProjection; // World * View * Projection matrix (début du rendu)
texture g_txScene; // Texture, pour chaque subset
...
Mais j'imagine que ce sera différent pour chaque fichier .fx :00000012:
Comment donc imagineriez vous la fonction de rendu ?
Certains paramètres doivent être transmis au moment de l'appel (les matrices de vue, du monde, de projection), d'autres sont "connus" par le mesh (texture, material) mais encore faut il savoir quoi passer et quand, dans un appel du type :
pMesh->SetXxxxx("g_Parameter", parameterValue);
Peut être faire une fonction à liste d'arguments variables ? Hum au niveau des performances je ne suis pas sur que ce soit une bonne idée...
Voila, je ne sais pas si ce thread est susceptible d'intéresser des gens ;) Et désolé pour la longueur mais j'espère au moins avoir exposé clairement mon problème et vous donner envie d'y réfléchir avec moi.
PS: Une autre possibilité à laquelle j'ai pensé serait de raisonner à l'envers avec une "procédure de traitement" définie dans ma classe (voire plusieurs), et de me limiter à des formats de fichier .fx conformes à ces procédures (notamment le nom des variables et à quel moment les définir). Pensez vous que la variabilité des fichier .fx soit trop importante pour ce genre de méthode (qui réduit déjà infiniment trop la flexibilité de ma classe à mon goût, mais bon...)
PS2: Mes objets Mesh ne sont pas des objets physiques, simplement de pures géométrie. Donc pas de propriétés physiques encapsulées (masse, taille, position, orientation, etc.) et par conséquent les différentes matrices liées au rendu (monde, projection, vue) doivent être fournies à la méthode de rendu. (Mais je suis ouvert à la discussion sur cette modélisation bien sur)
EDIT: si vous trouvez ce sujet ininteressant, trop simple, trop compliqué etc. vous pouvez aussi le dire :D (jai l'impression d'être boycotté :p lol)
J'ai créé une classe très simple pour encapsuler un Mesh ( cad un pointeur sur ID3DXEffect + les autres pointeurs qui vont bien: materials, textures ainsi que des variables bool ou int, etc.)
Cette classe fonctionne au poil avec les membres:
...
HRESULT LoadFromFile(IDirect3DDevice9* pd3dDevice, LPWSTR fileName);
HRESULT Render(IDirect3DDevice9* pd3dDevice);
VOID Clean();
...
Maintenant j'essaye d'améliorer cette classe (sans héritage, pour commencer) en intégrant la gestion des fichier effets, puisque certains meshes au format .x ont besoin du fichier .fx associé pour être rendu correctement. (En fait j'ai pris pour exemple le mesh dwarf.x fourni dans le sdk directx, que l'on voit notamment dans l'exemple ProgressiveMesh => Mais Pour l'instant je ne cherche pas à gérer les progressive mesh !)
J'ai donc ajouté (essentiellement) les membres suivants: (et modifié un peu la fonction Clean() bien sur)
...
HRESULT LoadEffect(IDirect3DDevice9* pd3dDevice, LPWSTR szFxFileName);
HRESULT SetRenderTechnique(D3DXHANDLE hTechnique);
...
Jusqu'ici pas de souci, c'est du gâteau. Mais la fonction de Rendu !!!
Peut être que ca vient de mon inexpérience, mais voici comment je vois la chose:
Chaque fichier .fx possède ses propres variables globales et doit donc par conséquent avoir un traitement spécifique au moment du rendu du mesh. Il faut notamment:
Connaître le nom des variables globales
Savoir quelles variables doivent être initialisées au début du rendu
Savoir quelles variable doivent être modifiées pour chaque SubSet
Savoir quelles variable doivent être modifiées à chaque passe
Etc.
Par exemple mon fichier .fx commence par les déclarations suivantes:
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4 g_vDiffuse; // Material diffuse color (pour chaque subset)
float4x4 g_mWorld; // World matrix for object (début du rendu du mesh)
float4x4 g_mWorldViewProjection; // World * View * Projection matrix (début du rendu)
texture g_txScene; // Texture, pour chaque subset
...
Mais j'imagine que ce sera différent pour chaque fichier .fx :00000012:
Comment donc imagineriez vous la fonction de rendu ?
Certains paramètres doivent être transmis au moment de l'appel (les matrices de vue, du monde, de projection), d'autres sont "connus" par le mesh (texture, material) mais encore faut il savoir quoi passer et quand, dans un appel du type :
pMesh->SetXxxxx("g_Parameter", parameterValue);
Peut être faire une fonction à liste d'arguments variables ? Hum au niveau des performances je ne suis pas sur que ce soit une bonne idée...
Voila, je ne sais pas si ce thread est susceptible d'intéresser des gens ;) Et désolé pour la longueur mais j'espère au moins avoir exposé clairement mon problème et vous donner envie d'y réfléchir avec moi.
PS: Une autre possibilité à laquelle j'ai pensé serait de raisonner à l'envers avec une "procédure de traitement" définie dans ma classe (voire plusieurs), et de me limiter à des formats de fichier .fx conformes à ces procédures (notamment le nom des variables et à quel moment les définir). Pensez vous que la variabilité des fichier .fx soit trop importante pour ce genre de méthode (qui réduit déjà infiniment trop la flexibilité de ma classe à mon goût, mais bon...)
PS2: Mes objets Mesh ne sont pas des objets physiques, simplement de pures géométrie. Donc pas de propriétés physiques encapsulées (masse, taille, position, orientation, etc.) et par conséquent les différentes matrices liées au rendu (monde, projection, vue) doivent être fournies à la méthode de rendu. (Mais je suis ouvert à la discussion sur cette modélisation bien sur)
EDIT: si vous trouvez ce sujet ininteressant, trop simple, trop compliqué etc. vous pouvez aussi le dire :D (jai l'impression d'être boycotté :p lol)