What changes per pass?

Started by
1 comment, last by brekehan 15 years, 2 months ago
I am getting more confused. My biggest problem is I am trying to design my engine in such a way that it is open to have new effects added. Yet I do not know what to expect when I try more advanced things. Unlike everyone else, I do not have hardcoded material attributes. I have a system where an effect class creates a material by querying the effect interface for variables. It works. Now I am trying to implement a "RenderMethod" class that will be a member of each object getting rendered to describe what effect to use material to use technique to use passes to apply etc. This render method class is obtained from the renderable object by the render queue. The render queue communicates between the renderable object and the effect manager, binding input layout, binding effect, setting effect variables, etc. Two problems: I am unsure if the material is going to change per pass or per frame. I am unsure if transforms will change per pass or frame. I am unsure if the vertex buffers I bind will change per pass or per frame. Edit: well, actually someone told the vertex buffers and input layout can change per pass, in another post. Can someone list the things that are liable to change per pass? If vertex buffers are going to change per pass, I am at a complete loss on how I can track which vertex buffers to bind on what pass. There are no comparison methods for any of the built in directx stuff for input layout or vertex buffers. I'd have to create some way of knowing what buffer contains what and what pass can use which one. Its harder then it sounds. Right now, I just rely on the author knowing what the vertex buffers contain and knowing what vertex data the effect uses. My renderbale object is capable of creating one hardcoded input layout. To dynmaically create an inout layout is going to drive me nutts. I'd love it if someone knowledgable could take a look at my system. It's small and I can put it up on my ftp site. Hell, I'd pay them for good suggestions. Getting this basic framework to where I am happy with it is taking months and I haven' even done anything but render a few lit and textured cubes :( Short of that here are some snippets:

//----------------------------------------------------------------------------
void TestApp::Render()
{
   //--------
   // TODO - Alot of the following should belong in a renderqueue class

   // These steps only need take place once per frame
      
      // Bind the view and projection matrices from the camera
      m_effectManager->BindCamera(m_camera);
      
      // Bind the lights
      // NOTE - No lights yet in this project

   // These can be skipped for polygon sets that use the same shape as the previous rendered polygon sets

      // Bind the input format
      // NOTE - I haven't written a renderqueue yet to do this, so the input layout is bound once in InitResources()

      // Bind vertex and index buffers
      m_polygonSet->BindBuffers();

   // These steps can be skipped when no transform or other non-tweable effect parameters have changed
      
      // Update the effect's world matrix variable

   // These steps can be skipped for polygon sets that use the same material
 
      // Bind the effect variables
      m_effectManager->BindMaterial(m_polygonSet->GetMaterial());

   // These steps need always take place
      
      // Apply pass
      //
      // TODO - Later, the renderable object should have a render method class that contains information
      //        about what passes to apply, what vertex buffers to use for each, and material to use
      //        for now, the effect only has 1 pass.

      m_effectManager->ApplyPass(m_polygonSet->GetMaterial().GetEffectName(),
                                 m_polygonSet->GetMaterial().GetTechniqueName(),
                                 0);

      // Draw
      m_device->DrawIndexed(m_polygonSet->GetNumIndices(), 0, 0);

}





#ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H

// EngineX Includes
#include "Texture.h"

// DirectX Includes
#include <d3dx10.h>
#include <d3d10.h>

// Standard Includes
#include <string>
#include <map>


class TextureManager
{
public:

   /**
   * Constructor
   *
   * @param device - an intialized Direct3D device to use
   */
   TextureManager(ID3D10Device & device);

   /**
   * Deconstructor
   */
   ~TextureManager();


   /**
   * Creates a texture from a file
   */
   void CreateTextureFromFile(const std::string & textureName, const std::string & filePath);

   /**
   * Sets an effect variable to use a texture
   */
   void SetTextureEffectVariable(const std::string & textureName, 
                                 ID3D10EffectShaderResourceVariable * effectVariable);

protected:

private:

   ID3D10Device & m_device;

   /** 
   * Map of textures where the name of the texture is the key and a pointer to a texture is the value 
   * I use a pointers to textures here, because there should only be one instance of a given texture,
   * so copying and passing by value is not permitted */
   typedef std::map<std::string, Texture *> TextureMap;
   TextureMap m_textures;
};


#endif // TEXTUREMANAGER_H






#ifndef TEXTURE_H
#define TEXTURE_H

// Common Lib Includes
#include "BaseException.h"

// DirectX Includes
#include <d3d10.h>
#include <d3dx10.h>

// Standard Includes
#include <string>

//------------------------------------------------------------------------------------------
/**
* Wrapper around the Direct3D texture resource
*/
class Texture
{
public:

   /**
   * Constructor
   *
   * @param device - Direct3D device
   * @param filePath - Path to the texture file to load
   *
   * @throws BaseException - if the texture cannot be loaded
   */
   Texture(ID3D10Device & device, const std::string & filePath);

   /**
   * Deconstructor
   */
   ~Texture();

   /**
   * Sets an effect variable to use this texture
   */
   void SetTextureEffectVariable(ID3D10EffectShaderResourceVariable * effectVariable);

private:

   /**
   * Copy Constructor
   *
   * You cannot copy this class, there should only be one instance of a particular texture
   * in video memory. There are ways to get an manupulate data and create a new resource
   * from it, which might be added later.
   */
   Texture(const Texture & rhs);


   ID3D10Device &              m_device;
   ID3D10ShaderResourceView *  m_texture;
   bool                        m_transparent;
   unsigned                    m_width;
   unsigned                    m_height;
};

#endif





#ifndef EFFECTMANAGER_H
#define EFFECTMANAGER_H

// EngineX Includes
#include "Graphics/Textures/TextureManager.h"
#include "Effect.h"
#include "Material.h"
#include "Graphics/3D/PolygonSet3D.h"
#include "Graphics/Cameras/BaseCamera.h"

// DirectX Includes
#include <d3dx10.h>
#include <d3d10.h>

// Standard Includes
#include <string>
#include <map>

//----------------------------------------------------------------------------
/**
* Manages the DirectX effects, which contain techniques for rendering
*/
class EffectManager
{
public:

   /**
   * Constructor
   *
   * @param device - an intialized Direct3D device to use
   * @param effectsDirectory - Directory that contains the .fx and .fxh files for the DirectX effects
   */
   EffectManager(ID3D10Device & device, TextureManager & textureManager, const std::string & effectDirectory);

   /**
   * Deconstructor
   */
   ~EffectManager();


   /**
   * Creates an effect from a file
   */
   void CreateEffectFromFile(const std::string & effectName, const std::string & filePath);

   /**
   * Removes a loaded effect
   */
   void RemoveEffect(const std::string & effectName);

   /**
   * Gets a Material from an effect
   */
   const Material & GetMaterial(const std::string & effectName) const;

   /**
   * Gets the input description of a pass which must be verified with the description of the vertex buffers
   * that will be bound during rendering of that pass
   */
   const D3D10_PASS_DESC GetPassDesc(const std::string effectName,
                                     const std::string techniqueName, 
                                     const unsigned passIndex) const;


   /**
   * Binds the camera's view and projection matrices to the effect
   */
   void BindCamera(BaseCamera * camera);

   /**
   * Binds material attributes to the effect variables
   */
   void BindMaterial(const Material & material);

   /**
   * Applys a technique pass
   */
   void ApplyPass(std::string effectName, std::string techniqueName, unsigned passIndex);

private:

   ID3D10Device &     m_device;
   TextureManager &   m_textureManager;

   const std::string  m_effectDirectory;
   ID3D10EffectPool * m_effectPool;

   // Shared effect variables
   ID3D10EffectMatrixVariable * m_effectVariable_view;
   ID3D10EffectMatrixVariable * m_effectVariable_projection;

   typedef struct AmbientLight
   {
      AmbientLight()
         :
         m_effectVariable_intensity(0),
         m_effectVariable_color(0)
      {}

      ID3D10EffectVectorVariable * m_effectVariable_intensity;
      ID3D10EffectVectorVariable * m_effectVariable_color;
   };              
   
   AmbientLight m_ambientLight;

   typedef struct DirectionalLight
   {
      DirectionalLight()
         :
         m_effectVariable_enabled(0),
         m_effectVariable_direction(0),
         m_effectVariable_color(0)
      {}

      ID3D10EffectScalarVariable * m_effectVariable_enabled;
      ID3D10EffectVectorVariable * m_effectVariable_direction;
      ID3D10EffectVectorVariable * m_effectVariable_color;
   };
   
   DirectionalLight m_directionalLights[8];

   // Child effects
   typedef std::map<std::string, Effect *> EffectMap;
   EffectMap m_effects;
};

#endif // EFFECTMANAGER_H





#ifndef EFFECT_H
#define EFFECT_H

// EngineX Includes
#include "Graphics/Effects/Material.h"
#include "Graphics/Textures/TextureManager.h"
#include "Graphics/3D/PolygonSet3D.h"

// Common Lib Includes
#include "BaseException.h"

// DirectX Includes
#include <d3d10.h>
#include <d3dx10.h>

// Standard Includes
#include <string>

//----------------------------------------------------------------------------
/**
*
*/
class Effect
{
public:

   /**
   * Constructor
   */
   Effect(ID3D10Device & device, 
          ID3D10EffectPool & effectPool,
          TextureManager & textureManager,
          const std::string & effectName, 
          const std::string & filePath);

   /**
   * Deconstructor
   */
   ~Effect();


   /**
   * Gets the description of a pass within a technique
   */
   const D3D10_PASS_DESC GetPassDesc(const std::string & techniqueName, unsigned index) const; 

   /**
   * Applies the state contained in a pass to the DirectX device
   */
   void ApplyPass(const std::string techniqueName, unsigned passIndex);


   /**
   * Sets the world matrix effect variable
   */
   void SetWorldMatrix(const D3DXMATRIX & worldMatrix);


   /**
   * Gets the current material.
   */
   const Material & GetMaterial() const;

   /**
   * Sets the current material
   * Sets tweakable effect parameters to those values contained within the material.
   */
   void SetMaterial(const Material & material);


private:
   
   /**
   * Updates tweakable parameters by obtaining the values from a supplied material
   */
   void UpdateMatrices(const Material & material);
   void UpdateFloats(const Material & material);
   void UpdateTextures(const Material & material);


   /** Reference to the D3D graphics device */
   ID3D10Device &   m_device;

   /** Reference to the texture manager from which texturesd will be obtained */
   TextureManager & m_textureManager;

   /** Each Effect creates and maintains its own copy of a DirectX effect interface */
   ID3D10Effect *   m_effect;

   /** Current Material */
   Material m_material;


   // Non- Tweakable effect parameters
   //
   // These values are communicated directly through the public interface to this class
   
   ID3D10EffectMatrixVariable * m_worldMatrix;


   // Tweakable effect parameters
   //
   // These values are encapsulated by a material and communicated to the effect through the material

   typedef std::map<std::string, ID3D10EffectMatrixVariable *> EffectMatrixVariables;
   EffectMatrixVariables m_effectMatrixVariables;

   typedef std::map<std::string, ID3D10EffectScalarVariable *> EffectFloatVariables;
   EffectFloatVariables m_effectFloatVariables;

   typedef std::map<std::string, ID3D10EffectShaderResourceVariable *> EffectTextureVariables;
   EffectTextureVariables m_effectTextureVariables;
};

#endif // EFFECT_H







#ifndef MATERIAL_H
#define MATERIAL_H

// EngineX Includes
#include "Graphics\3D\Vertices3D.h"

// Common Lib Includes
#include "BaseException.h"

// DirectX Includes
#include <d3d10.h>
#include <d3dx10.h>

// Standard Includes
#include <string>
#include <map>

class Effect;

//----------------------------------------------------------------------------
/**
* Material
*
* Dynamic container of variables used by an Effect.
*
* A Material first has to be created by an Effect in order to allocate the differant
* types of attributes the Effect uses. It can then be obtained from and given back to 
* the Effect, which will use the attributes of the Material to set the variables of 
* the Effect.
*/
class Material
{
public:

   friend class Effect;

   /**
   * Copy Constructor
   */
   Material(const Material & rhs);

   /**
   * Deconstructor
   */
   ~Material();
   
   /**
   * Assignment Operator
   */
   Material & operator = (const Material & rhs);



   /**
   * Get the name of the effect that created this material and to which this material provides attributes to 
   */
   const std::string & GetEffectName() const;

   /**
   * Get the name of the effect's technique that will render this material
   */
   const std::string & GetTechniqueName() const;

   

   

   
   /**
   * Gets an existing matrix attribute
   *
   * @param variableName - Name of the matrix effect variable as it appears in the effect that created this material
   *
   * @return - The current value that will be used to set the matrix effect variable
   **/
   const D3DXMATRIX & GetMatrix(const std::string & variableName) const;

   /**
   * Sets an existing matrix attribute
   *
   * @param variableName - Name of the matrix effect variable as it appears in the effect that created this material
   * @param value - The current value that will be used to set the matrix effect variable
   */
   void SetMatrix(const std::string & variableName, const D3DXMATRIX & value);



   /**
   * Gets an existing float attribute
   *
   * @param variableName - Name of the float effect variable as it appears in the effect that created this material
   *
   * @return - The current value that will be used to set the float effect variable
   **/
   const float GetFloat(const std::string & varibaleName) const;

   /**
   * Sets an existing float attribute
   *
   * @param variableName - Name of the float effect variable as it appears in the effect that created this material
   * @param value - The current value that will be used to set the float effect variable
   */
   void SetFloat(const std::string & variableName, const float value);

   

   /**
   * Gets an existing texture name attribute
   *
   * @param variableName - Name of the texture effect variable as it appears in the effect that created this material
   *
   * @return - The current name of the texture, as it appears in the TextureManager, that will be used to set the
   *           texture effect variable
   **/
   const std::string GetTextureName(const std::string & variableName) const;

   /**
   * Sets an existing texture name attribute
   *
   * @param variableName - Name of the texture effect variable as it appears in the effect that created this material
   * @param textureName - The name of the texture, as it appears in the TextureManager, that will be used to set the
   *                      texture effect variable
   */
   void SetTextureName(const std::string & variableName, const std::string & textureName);

private:

   /**
   * Constructor
   */
   Material(const std::string & effectName, const std::string & techniqueName);

   /**
   * Creates an unitialized matrix attribute
   *
   * @param variableName - Name of the matrix effect variable as it appears in the effect that created this material
   */
   void CreateMatrix(const std::string & variableName);

   /**
   * Creates an unitialized float attribute
   *
   * @param variableName - Name of the float effect variable as it appears in the effect that created this material
   */
   void CreateFloat(const std::string & variableName);

   /**
   * Creates an unitialized texture name attribute
   *
   * @param variableName - Name of the texture effect variable as it appears in the effect that created this material
   */
   void CreateTextureName(const std::string & variableName);



   /** Name of the effect that created this material and to whom it provides attributes to */
   std::string m_effectName;

   /** Name of the effect's technique that will be used to render this material */
   std::string m_techniqueName;

   /**
   * Material attribute value data structure
   *
   * Each attribute is first created by the effect that creates the material.
   * However, the attributes are not initialized by the effect, but are initialized
   * after the material has been created. This data structure adds a flag to the 
   * attribute value to determine if it has been initialized. 
   */
   template <class T>
   struct Attribute
   {
      bool m_initialized;
      T    m_value;
   };

   /** 
   * Map of matrix attributes
   * 
   * key - matrix variable name as it appears in the DirectX effect
   * value - Attribute structure containing the matrix 
   */
   typedef std::map<std::string, Attribute<D3DXMATRIX> > Matrices;
   Matrices m_matrices;

   /** 
   * Map of float attributes
   * 
   * key - float variable name as it appears in the DirectX effect
   * value - Attribute structure containing the float
   */
   typedef std::map<std::string, Attribute<float> > Floats;
   Floats m_floats;

   /** 
   * Map of the texture name attributes
   * 
   * key - texture variable name as it appears in the DirectX effect
   * value - Attribute structure containing the texture name as it appears in the texture manager 
   */
   typedef std::map<std::string, Attribute<std::string> > TextureNames;
   TextureNames m_textureNames;


};

#endif








#ifndef POLYGONSET3D_H
#define POLYGONSET3D_H

// EngineX Includes
#include "Graphics\3D\Transformable.h"
#include "Graphics\3D\Vertices3D.h"
#include "Graphics\Effects\Material.h"

// DirectX Includes
#include <d3d10.h>
#include <d3dx10.h>

// Standard Includes
#include <vector>

//------------------------------------------------------------------------------------------
/**
* A set of polygons that are typically rendered as one group of triangles sharing the
* same transform, material, and shader.
*/
class PolygonSet3D : public Transformable
{
public:
   
   /**
   * Describes the vertex buffers this object will use 
   */
   typedef std::vector<D3D10_INPUT_ELEMENT_DESC> InputDesc;

   /**
   * Constructor
   */
   PolygonSet3D::PolygonSet3D(ID3D10Device & device,
                              std::vector<Position> positions,
                              std::vector<Normal> normals,
                              std::vector<UV> texCoords,
                              std::vector<Index> indices,
                              const Material & material);
   
   /**
   * Deconstructor
   */
   ~PolygonSet3D();

   
   /**
   * Gets the description of the vertex buffers that will be bound to render this object
   */
   const InputDesc & GetInputDesc() const;

   /**
   * Gets the number of indices in the index buffer
   */
   const unsigned GetNumIndices() const;
   
   /**
   * Gets the material
   */
   const Material & GetMaterial();

   /**
   * Sets the material
   */
   void SetMaterial(const Material & material);

   /**
   * Binds the vertex and index buffers for rendering
   */
   void BindBuffers();

private:

   ID3D10Device &             m_device;

   typedef std::vector<ID3D10Buffer *> VertexBuffers;
   VertexBuffers              m_vertexBuffers;
   
   typedef std::vector<unsigned> Strides;
   Strides                    m_strides;

   InputDesc                  m_inputDesc;
   unsigned                   m_numVertices;

   ID3D10Buffer *             m_indexBuffer;
   unsigned                   m_numIndices;
   
   Material                   m_material;
};

#endif // POLYGONSET3D_H






#ifndef TRANSFORMABLE_H
#define TRANSFORMABLE_H

// DirectX Includes
#include <d3dx10.h>



//--------------------------------------------------------------------------------
class Transformable
{
public:

   /**
   * Constructor
   */
	Transformable();

   /**
   * Deconstructor
   */
	virtual ~Transformable();


   /**
   * Updates and obtains the current transform matrix
   */
   virtual const D3DXMATRIX & GetTransform();

   /**
   * Moves the the object
   *
   * @param distance - number of units to move the object in the given direction
   * @param direction - direction vector in which to move the object
   * @pram objectSpace - If true, then the direction is in object space, otherwise the direction is in world space
   */
	virtual void ApplyTranslation(const float distance, const D3DXVECTOR3 & direction, const bool objectSpace = false);

   /**
   * Rotates the object
   *
   * @param angle - radians to rotate clockwise when looking down the axis toward the origin in object space
   * @param objectAxis - specifies the axis to rotate around
   */
   virtual void ApplyRotation(const float angle, const D3DXVECTOR3 & objectAxis);


   /**
   * Get the object's current postion
   */
	virtual const D3DXVECTOR3 & GetPosition() const;

   /**
   * Sets the object's postion
   */
	virtual void SetPosition(const D3DXVECTOR3 & position);
	

   /**
   * Get the object's current orientation
   */
   virtual const D3DXQUATERNION & GetOrientation() const;

   /**
   * Sets the object's orientation
   */
   virtual void SetOrientation(const D3DXQUATERNION & orientation);


   /**
   * Gets the object's scaling factor
   */
   virtual const float GetScale() const;

   /**
   * Sets the object's scaling factor
   */
   virtual void SetScale(float scale);


   /**
   * Set the 3D object's orientation using an interpolated rotation from the 
   * current orientation to a specified orientation, given a rotation speed
   *
   * @param target_orientation - orientation of the object at speed = 1
   * @param speed - How far along the interpolated curve to rotate. A number between 0 and 1, 
   *                where 0 rotates to the current orientation and 1 rotates to the target orientation 
   */
	virtual void Slerp(const D3DXQUATERNION & target_orientation, float speed);

protected:

   /**
   * Updates the transform matrix to reflect the object's current position, orientation, and scale
   */
   virtual void Update();

   /**
   * Transforms an axis from object space to world space
   */
   D3DXVECTOR3 ObjectAxisToWorld(const D3DXVECTOR3 & objectAxis);


   /**
   * The position, orientation, and scale in matrix form
   */
   D3DXMATRIX     m_transform;

   /**
   * Seperate components of the total transform
   *
   * These are seperate components change when the various methods are called 
   * The transform matrix is updated when needed, to reflect those changes
   */
   D3DXVECTOR3    m_position;
   D3DXQUATERNION m_orientation;
   float          m_scale;

   /**
   * Whether or not the transform matrix needs to be updated to reflect changes
   * to position, orientation, or scale.
   */
   bool           m_needUpdated;


private:


};

#endif






#ifndef RENDERMETHOD_H
#define RENDERMETHOD_H


//------------------------------------------------------------------------------------------
class PassDescription
{
   // ????????????????????????
};

//------------------------------------------------------------------------------------------

class RenderMethod
{
public:




private:

   std::string effectName;
   std::string techniqueName;

   std::vector<PassDesc> PassDescriptions;
   PassDescriptions m_passDescriptions;
};


#endif




As you can see, effectName, technqiqueName, Material, world matrix, and the like appear a few places they shouldn't. I am hoping to sort all this out with the render method class and updating the portion that will become the renderqueue. I am trying to seperate things while keeping it as open ended as I can. Unfortunatly, my brain cannot keep track of all these relationships! I've poored through other peoples engines, but they have half the problems I have, because they set in stone all thier effect varibale names, what uses them , etc. If you always render an object the same way everything is easy! I don't forsee rendering things the same way. I want to be able to add effects, shadows, and all the advanced trimmings down the road with minimal effort. [Edited by - brekehan on January 24, 2009 4:59:02 AM]
Advertisement
Hi,

Looks like you're most of the way there with your system - good work [smile]. A few thoughts from reading your post...

Quote:Now I am trying to implement a "RenderMethod" class that will be a member of each object getting rendered to describe what

effect to use
material to use
technique to use
passes to apply
etc.
You may find it useful to better define this list. Whilst there aren't any hard rules, in my experience I'd bundle "effect" and "material" together as with D3D10 they're not really seperable except for bound resources (e.g. binding a different input texture) and "techniques" are the high-level container for "passes" such that the client code should only specify the technique name/handle and be ignorant of passes.

Quote:Edit: well, actually someone told the vertex buffers and input layout can change per pass, in another post.

Can someone list the things that are liable to change per pass?
Resources bound for input and output cannot change from within an FX file as far as I remember - only the state of the pipeline (of which there are 6 in D3D10 iirc). So you are correct that the VB can change between passes, but only if the application does it - so if you're going down the data/script route you need to expose this ability, if you don't then you don't need to worry about it!

Quote:I am at a complete loss on how I can track which vertex buffers to bind on what pass
You can use the DXSAS annotations to allow a pass/technique to describe pipeline binding. You can then publish a limited number of subsets ("position_only", "position_texcoords", "position_with_tangents" etc..) and switch accordingly.

Quote:I just rely on the author knowing what the vertex buffers contain and knowing what vertex data the effect uses
As with any data driven architecture you shouldn't assume anything about the quality of inputs. Script writers, even if its you, make mistakes and then all sorts of craziness can ensue [evil].

FX10 has quite solid reflection capabilities so you can build up a "compatability map" for a technique and enumerate its expected inputs/outputs and if your engine doesn't support it you throw it out with an error.

As per my previous example the author can select one of N published vertex formats and if they deviate from that and/or the vertex declaration doesn't match the format they've declared you can fail with suitable error messages.

Quote:I've poored through other peoples engines, but they have half the problems I have, because they set in stone all thier effect varibale names, what uses them , etc. If you always render an object the same way everything is easy! I don't forsee rendering things the same way. I want to be able to add effects, shadows, and all the advanced trimmings down the road with minimal effort.
You need to decide where your cut-off is. The engines you've seen with hard-coded variables have obviously chosen a very rigid (lazy?)specification for their inputs, but you obviously want more flexibility. You'll find that you can get 75% of the way with a generic system without much hassle - I suspect this is where you're at now - but that last little bit can involve a huge amount of work and you end up almost building your own entire rendering API on top of D3D10. Set some limitations on how expressive your engine can be and allow FX writers work within those constraints.

If you follow the declarative nature of having FX files use DXSAS annotations to describe themselves you can easily fire off "Sorry, <x> is not supported". If <x> comes from a list then whats stopping you adding <x> to the published list of vertex/texture (etc..) declarations in the next release of your engine?? It can still be quite modular in that regard.


hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by jollyjeffers
Whilst there aren't any hard rules, in my experience I'd bundle "effect" and "material" together as with D3D10 they're not really seperable except for bound resources (e.g. binding a different input texture)



Well, that is exactly what my material class is for. It holds all the values of effect variables that may change per object. At render time, my queue, will pass those values to the effect and the effect will bind them to the appropriate variables with matching names.

The values to feed the effect variables have to live somewhere. If they live in the effect how is one going to change them per object? They would still have to make some container for the values to give the effect since those values change per object, not per effect. The values have to be seperated as far as I can tell, in order to allow for different objects to have different values for the effect variables.

If object A and B both use effect X, A might want to bind "redbrick.png" to X's texture, while B might want to bind "fuzzy.jpg". My material holds those values.

Otherwise I'd be creating values and binding, for every object being rendered, whether they used the same values or not.

I guess the name "material" might be misleading. I don't know what else to call it... TweakableEffectVariableValuesGroup? EffectVariableValues?...isn't that what the classic "material" is anyway? A collection of values to feed to the effect?


Quote:Original post by jollyjeffers
"techniques" are the high-level container for "passes" such that the client code should only specify the technique name/handle and be ignorant of passes.


That is my goal, I am trying to come up with a way to handle all the per pass details internally in the engine.

What is stopping me is that I see no way to query the pass for the input layout it is expecting. I can only tell the pass what input layout I am going to give it and see if it accepts it or not. The pass description gives me a pointer to an IAInputSignature , but that does not give me anything I can use in the program to ID what input layouts are acceptable as far as I can tell. It appears to just be an array of BYTES. There is no doc I can find on what the IAInputSigniture is or how to query it for inofrmation. Only that it exists.

Quote:Original post by jollyjeffers
You can use the DXSAS annotations to allow a pass/technique to describe pipeline binding. You can then publish a limited number of subsets ("position_only", "position_texcoords", "position_with_tangents" etc..) and switch accordingly.


Quote:Original post by jollyjeffers
the author can select one of N published vertex formats and if they deviate from that and/or the vertex declaration doesn't match the format they've declared you can fail with suitable error messages.


There doesn't seem to be any resources describing how to do this? Do you have any?

You mentioned this "DXSAS", however a search only provided me with a dx9 doc that really doesn't tell me anything about it at all. It is just syntax. It appeared to again, have hardcoded effect attributes you could use and wants to pair with values of that hardcoded set of attributes in the application. All other google results were just questions about it and whether or not it is still even supported.
I don't see how it will solve this problem yet. How can I use this to query a pass for the input layout it expects?

If I could query the pass for acceptable input layouts, I could dynamically create the appropriate vertex buffers from the app provided data and everything would be dandy.

Quote:Original post by jollyjeffers
data/script route you need to expose this ability, if you don't then you don't need to worry about it!


Eventually, I will be going down that road.

Quote:Original post by jollyjeffers
FX10 has quite solid reflection capabilities so you can build up a "compatability map" for a technique and enumerate its expected inputs/outputs and if your engine doesn't support it you throw it out with an error.


That is exactly what I do for the material-effect relationship. Or rather all the tweakable effect parameters. However, I don't see how to do it for input layouts.

[Edited by - brekehan on January 24, 2009 5:34:20 PM]

This topic is closed to new replies.

Advertisement