-1

Im new to C++ and what im working on the docs tell me to look at the example code only it doesnt explain anything so im trying to decipher it.

i came a across this declaration of a function but i dont fully understand it.

just the first function

i get underneath part what i dont get is after the MHWRender::MPxShaderOverride(obj) and then it starts as a list of arguments(or what its called i dont know)

and i guess where i would find what the specified inputs would be.

again i have no idea what this is doing so im a bit lost in how to explain it.

full code can be found here: http://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__cpp_ref_hw_phong_shader_2hw_phong_shader_8cpp_example_html

    hwPhongShaderOverride(const MObject& obj)
: MHWRender::MPxShaderOverride(obj)
, fShaderNode(NULL)
, fTextureData(NULL)
, fDrawUsingShader(true) // Disabling this will use fixed-function which only has an OpenGL implementation
, fShaderBound(false)
, fTexture(NULL)
, fInColorPass(false)
, fColorShaderInstance(NULL)
, fInShadowPass(false)
, fShadowShaderInstance(NULL)
, fTransparency(0.0f)
{
    // Create a shader instance to use for drawing
    //
    if (fDrawUsingShader)
    {
        createShaderInstance();
    }
    fAmbient[0] = fAmbient[1] = fAmbient[2] = 0.0f;
    fDiffuse[0] = fDiffuse[1] = fDiffuse[2] = fDiffuse[3] = 0.0f;
    fSpecular[0] = fSpecular[1] = fSpecular[2] = 0.0f;
    fShininess[0] = fShininess[1] = fShininess[2] = 500.0f;
}

// override blend state when there is blending
static const MHWRender::MBlendState *sBlendState;

// Current hwPhongShader node associated with the shader override.
// Updated during doDG() time.
hwPhongShader *fShaderNode;
// Shader inputs values including transparency
float fTransparency;
float fAmbient[3];
float fDiffuse[4];
float fSpecular[3];
float fShininess[3];

// Temporary system buffer for creating textures
unsigned char* fTextureData;

// Pass tracking
bool fInColorPass;
bool fInShadowPass;

// Draw with texture or shader flag
bool fDrawUsingShader;
// VP2 texture
MHWRender::MTexture *fTexture;
// VP2 color shader
MHWRender::MShaderInstance *fColorShaderInstance;
// VP2 shadow shader
MHWRender::MShaderInstance *fShadowShaderInstance;
mutable bool fShaderBound;
cronicryo
  • 437
  • 1
  • 4
  • 15

2 Answers2

6

This is a class constructor. The class is named hwPhongShaderOverrideMObject, and it derives from MHWRender::MPxShaderOverride, eg:

class hwPhongShaderOverrideMObject : public MHWRender::MPxShaderOverride
{
    ...
};

hwPhongShaderOverride(const MObject& obj) specifies that this constructor takes one argument as input, a const reference to a MObject instance. The constructor is being declared and implemented inline inside the class declaration itself, rather than being implemented separately from its declaration. Both approaches are allowed in C++.

Everything between : and { is the initialization list for the constructor. It initializes members of the class.

: begins the initialization list.

MHWRender::MPxShaderOverride(obj) is passing the input object to the base class constructor. Base classes must always be constructed first.

, fShaderNode(NULL) is initializing the fShaderNode member to NULL.

, fTextureData(NULL) is initializing the fTextureData member to NULL.

And so on until { is reached to end the initialization list. Then the body of the constructor is entered, like any other function, after the class members have been initialized first.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • So then my next question would be why not just do that inside of the constructor.(I come from a background of Python and JavaScript so to me this makes more sense) – cronicryo Dec 03 '15 at 04:55
  • It is more efficient to initialize class members in the constructor's initialization list than inside the constructor's body. Not as big a deal for POD types (integers, booleans, pointers, etc), but can be a big deal for other types. The initialization list allows data to be passed to class member constructors. If you do the initializations in the constructor body instead, the compiler has to default-construct the members first, then you are performing assignments afterwards. It is better to initialize the members via their own constructors when available. – Remy Lebeau Dec 03 '15 at 17:51
2

Below is a constructor.

hwPhongShaderOverride(const MObject& obj)
: MHWRender::MPxShaderOverride(obj)
, fShaderNode(NULL)
, fTextureData(NULL)
, fDrawUsingShader(true) // Disabling this will use fixed-function which only has an OpenGL implementation
, fShaderBound(false)
, fTexture(NULL)
, fInColorPass(false)
, fColorShaderInstance(NULL)
, fInShadowPass(false)
, fShadowShaderInstance(NULL)
, fTransparency(0.0f)
{
    // Create a shader instance to use for drawing
    //
    if (fDrawUsingShader)
    {
        createShaderInstance();
    }
    fAmbient[0] = fAmbient[1] = fAmbient[2] = 0.0f;
    fDiffuse[0] = fDiffuse[1] = fDiffuse[2] = fDiffuse[3] = 0.0f;
    fSpecular[0] = fSpecular[1] = fSpecular[2] = 0.0f;
    fShininess[0] = fShininess[1] = fShininess[2] = 500.0f;
}

It is using an initializer list to initialize its member variables by calling their constructors. hwPhongShaderOverride inherits from MHWRender::MPxShaderOverride, so it calls MHWRender::MPxShaderOverride's constructor as the first element in the initializer list (i.e., MHWRender::MPxShaderOverride(obj).

You can toggle fDrawUsingShader to create an instance of a shader (as seen in the body of the constructor). After that it adds some initial values to the four arrays fAmbient, fDiffuse, fSpecular, and fShininess.

erip
  • 16,374
  • 11
  • 66
  • 121