Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>1.) I think the problem you are experience is due to trying to put too much in the base class. Since the Model needs to know what particular material type it is working with when it is calling the SetPerFrameInfo function, why not just give each Material-derived class its own Set..() function that takes the proper type instead of void*? Because the Material base class has no way to interact with its per-frame info (it is void*), then why generalize it into the base class?</p> <p><strike>2.) Just put the material-specific datamembers into the derived material classes. I assume each Material instance corresponds to a unique Model, so the material-specific information for the Model should be in its Material-derived class.</strike></p> <h3>In response to your clarification:</h3> <p>Okay, I misunderstood the relationship between the two classes. Basically you want, in the ideal scenario, a set of Materials classes that don't know the details of a Model, and a set of Models that can work with any Material, without knowing the details of the Material. So you may want to apply a Rough material instance to six different models.</p> <p>I don't think there's any question that, if each Material instance is shared by several Models and each Model instance knows nothing about the different Materials, a third per-Model object is needed to store the timers or whatever instance data is needed for drawing. So each Model receives its own AppliedMaterial object which points to a shared Material instance as well as the data members needed to apply the material to that model. There would have to be a different AppliedMaterial subclass for each Material type, storing the data values pertinent to each material. Example of using a third context object:</p> <pre><code>struct GlossMaterialContext { Timer t; int someContextValue; }; class GlossMaterial : Material { void * NewApplicator() { return new GlossMaterialContext; } void FreeApplicator(void *applicator) { delete (GlossMaterialContext*)applicator; } void ApplyMaterial(void *applicator) { // Set up shader... // Apply texture... } }; class 3DModel { Material *material; void *materialContext; void SetMaterial(Material *m) { material = m; materialContext = m-&gt;NewApplicator(); } void Draw() { material-&gt;ApplyMaterial(materialContext); } }; </code></pre> <p>It is not an incredibly clean technique. I always feel like dealing with void* pointers is a kludge. You could also have the 3rd context object be based on a class, like:</p> <pre><code>class AppliedGlossMaterial : AppliedMaterial </code></pre> <p>and:</p> <pre><code>class GlossMaterial : Material { AppliedMaterial * NewApplicator() { return new AppliedGlossMaterial; } ... </code></pre> <p>If the datamembers depend on <em>both</em> the Model type and the Material type, then your models and materials are way too tightly coupled to make them into separate classes that are supposed to know nothing about each other. You would have to create subclasses of your Model: Glossy3DModel, Rough3DModel, etc.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload