/* virtual */ MStatus hwPhongShader::glGeometry(const MDagPath & path, int prim, unsigned int writable, int indexCount, const unsigned int * indexArray, int vertexCount, const int * vertexIDs, const float * vertexArray, int normalCount, const float ** normalArrays, int colorCount, const float ** colorArrays, int texCoordCount, const float ** texCoordArrays) { TRACE_API_CALLS("glGeometry"); MStatus stat = MStatus::kSuccess; if (mGeometryShape != 0) drawDefaultGeometry(); else stat = draw( prim, writable, indexCount, indexArray, vertexCount, vertexIDs, vertexArray, normalCount, normalArrays, colorCount, colorArrays, texCoordCount, texCoordArrays); return stat; }
/* virtual */ MStatus hwPhongShader::glUnbind(const MDagPath&) { TRACE_API_CALLS("glUnbind"); // The texture may have been allocated by the draw; it's kept // around for use again. When scene new or open is performed this // texture will be released in releaseEverything(). return MS::kSuccess; }
/* virtual */ MStatus hwPhongShader::glBind(const MDagPath&) { TRACE_API_CALLS("glBind"); if ( mAttributesChanged || (phong_map_id == 0)) { init_Phong_texture (); } return MS::kSuccess; }
/* virtual */ MStatus hwPhongShader::bind(const MDrawRequest& request, M3dView& view) { TRACE_API_CALLS("bind"); if (mAttributesChanged || (phong_map_id == 0)) { init_Phong_texture (); } return MS::kSuccess; }
/* virtual */ int hwPhongShader::normalsPerVertex() { TRACE_API_CALLS("normalsPerVertex"); #if defined(_TEST_CYCLING_NORMALS_PER_VERTEX_) static int normCnt = 1; if (normCnt == 3) normCnt = 1; else normCnt++; return normCnt; #else return 1; #endif }
hwPhongShader::hwPhongShader() { TRACE_API_CALLS("hwPhongShader"); attachSceneCallbacks(); mAmbientColor[0] = mAmbientColor[1] = mAmbientColor[2] = 0.1f; mDiffuseColor[0] = mDiffuseColor[1] = mDiffuseColor[2] = 0.5f; mSpecularColor[0] = mSpecularColor[1] = mSpecularColor[2] = 0.5f; mShininess[0] = mShininess[1] = mShininess[2] = 100.0f; mAttributesChanged = false; phong_map_id = 0; mGeometryShape = 0; }
/* virtual */ int hwPhongShader::texCoordsPerVertex() { TRACE_API_CALLS("texCoordsPerVertex"); #if defined(_TEST_CYCLING_UVSETS_PER_VERTEX_) static int uvCnt = 1; if (uvCnt == 3) uvCnt = 1; else uvCnt++; return uvCnt; #else return 0; #endif }
MStatus uninitializePlugin( MObject obj ) { TRACE_API_CALLS("uninitializePlugin"); MStatus status; MFnPlugin plugin( obj ); // Unregister all chamelion shader nodes plugin.deregisterNode( hwPhongShader::id ); if (!status) { status.perror("deregisterNode"); return status; } plugin.deregisterDragAndDropBehavior("hwPhongShaderBehavior"); return MS::kSuccess; }
// DESCRIPTION: // MStatus hwPhongShader::compute( const MPlug& plug, MDataBlock& block ) { TRACE_API_CALLS("compute"); if ((plug != outColor) && (plug.parent() != outColor)) return MS::kUnknownParameter; MFloatVector & color = block.inputValue( aDiffuseColor ).asFloatVector(); // set output color attribute MDataHandle outColorHandle = block.outputValue( outColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = color; outColorHandle.setClean(); return MS::kSuccess; }
MStatus initializePlugin( MObject obj ) { TRACE_API_CALLS("initializePlugin"); MStatus status; const MString& swatchName = MHWShaderSwatchGenerator::initialize(); const MString UserClassify( "shader/surface/utility/:swatch/"+swatchName ); MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5", "Any"); status = plugin.registerNode( "hwPhongShader", hwPhongShader::id, hwPhongShader::creator, hwPhongShader::initialize, MPxNode::kHwShaderNode, &UserClassify ); if (!status) { status.perror("registerNode"); return status; } plugin.registerDragAndDropBehavior("hwPhongShaderBehavior", hwPhongShaderBehavior::creator); return MS::kSuccess; }
void hwPhongShader::drawTheSwatch( MGeometryData* pGeomData, unsigned int* pIndexing, unsigned int numberOfData, unsigned int indexCount ) { TRACE_API_CALLS("drwaTheSwatch"); MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer(); if( !pRenderer ) return; if ( mAttributesChanged || (phong_map_id == 0)) { init_Phong_texture (); } // Get the default background color float r, g, b, a; MHWShaderSwatchGenerator::getSwatchBackgroundColor( r, g, b, a ); glClearColor( r, g, b, a ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glDisable ( GL_LIGHTING ); glDisable ( GL_TEXTURE_1D ); glDisable ( GL_TEXTURE_2D ); { glEnable ( GL_TEXTURE_CUBE_MAP_EXT ); glBindTexture ( GL_TEXTURE_CUBE_MAP_EXT, phong_map_id ); glEnable ( GL_TEXTURE_GEN_S ); glEnable ( GL_TEXTURE_GEN_T ); glEnable ( GL_TEXTURE_GEN_R ); glTexGeni ( GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexGeni ( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexGeni ( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); // Could modify the texture matrix here to do light tracking... glMatrixMode ( GL_TEXTURE ); glPushMatrix (); glLoadIdentity (); glRotatef( 5.0, -1.0, 0.0, 0.0 ); glRotatef( 10.0, 0.0, 1.0, 0.0 ); glMatrixMode ( GL_MODELVIEW ); } // Draw default geometry { if (pGeomData) { glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ); float *vertexData = (float *)( pGeomData[0].data() ); if (vertexData) { glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer ( 3, GL_FLOAT, 0, vertexData ); } float *normalData = (float *)( pGeomData[1].data() ); if (normalData) { glEnableClientState( GL_NORMAL_ARRAY ); glNormalPointer ( GL_FLOAT, 0, normalData ); } if (vertexData && normalData && pIndexing ) glDrawElements ( GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, pIndexing ); glPopClientAttrib(); // Release data references pRenderer->dereferenceGeometry( pGeomData, numberOfData ); } } { glMatrixMode ( GL_TEXTURE ); glPopMatrix (); glMatrixMode ( GL_MODELVIEW ); glDisable ( GL_TEXTURE_CUBE_MAP_EXT ); glDisable ( GL_TEXTURE_GEN_S ); glDisable ( GL_TEXTURE_GEN_T ); glDisable ( GL_TEXTURE_GEN_R ); } }
void * hwPhongShader::creator() { TRACE_API_CALLS("creator"); return new hwPhongShader(); }
hwPhongShader::~hwPhongShader() { TRACE_API_CALLS("~hwPhongShader"); detachSceneCallbacks(); }
void hwPhongShader::postConstructor( ) { TRACE_API_CALLS("postConstructor"); setMPSafe(false); }
void hwPhongShader::drawDefaultGeometry() { TRACE_API_CALLS("drawDefaultGeometry"); MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer(); if (!pRenderer) return; glPushAttrib ( GL_ENABLE_BIT ); glDisable ( GL_LIGHTING ); glDisable ( GL_TEXTURE_1D ); glDisable ( GL_TEXTURE_2D ); { glEnable ( GL_TEXTURE_CUBE_MAP_EXT ); glBindTexture ( GL_TEXTURE_CUBE_MAP_EXT, phong_map_id ); glEnable ( GL_TEXTURE_GEN_S ); glEnable ( GL_TEXTURE_GEN_T ); glEnable ( GL_TEXTURE_GEN_R ); glTexGeni ( GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexGeni ( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexGeni ( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); glMatrixMode ( GL_TEXTURE ); glPushMatrix (); glLoadIdentity (); glMatrixMode ( GL_MODELVIEW ); } // Get default geometry { unsigned int numberOfData = 0; unsigned int *pIndexing = 0; unsigned int indexCount = 0; MHardwareRenderer::GeometricShape gshape = MHardwareRenderer::kDefaultSphere; if (mGeometryShape == 2) { gshape = MHardwareRenderer::kDefaultCube; } else if (mGeometryShape == 3) { gshape = MHardwareRenderer::kDefaultPlane; } // Get data references MGeometryData * pGeomData = pRenderer->referenceDefaultGeometry( gshape, numberOfData, pIndexing, indexCount); if (pGeomData) { glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ); float *vertexData = (float *)( pGeomData[0].data() ); if (vertexData) { glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer ( 3, GL_FLOAT, 0, vertexData ); } float *normalData = (float *)( pGeomData[1].data() ); if (normalData) { glEnableClientState( GL_NORMAL_ARRAY ); glNormalPointer ( GL_FLOAT, 0, normalData ); } if (vertexData && normalData && pIndexing ) glDrawElements ( GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, pIndexing ); glPopClientAttrib(); // Release data references pRenderer->dereferenceGeometry( pGeomData, numberOfData ); } } { glMatrixMode ( GL_TEXTURE ); glPopMatrix (); glMatrixMode ( GL_MODELVIEW ); glDisable ( GL_TEXTURE_CUBE_MAP_EXT ); glDisable ( GL_TEXTURE_GEN_S ); glDisable ( GL_TEXTURE_GEN_T ); glDisable ( GL_TEXTURE_GEN_R ); glPopAttrib(); } }
MStatus hwPhongShader::initialize() { // Make sure that all attributes are cached internal for // optimal performance ! TRACE_API_CALLS("initialize"); MFnNumericAttribute nAttr; // Create input attributes aColor = nAttr.createColor( "color", "c"); nAttr.setStorable(true); nAttr.setKeyable(true); nAttr.setDefault(0.1f, 0.1f, 0.1f); nAttr.setCached( true ); nAttr.setInternal( true ); aDiffuseColor = nAttr.createColor( "diffuseColor", "dc" ); nAttr.setStorable(true); nAttr.setKeyable(true); nAttr.setDefault(1.f, 0.5f, 0.5f); nAttr.setCached( true ); nAttr.setInternal( true ); aSpecularColor = nAttr.createColor( "specularColor", "sc" ); nAttr.setStorable(true); nAttr.setKeyable(true); nAttr.setDefault(0.5f, 0.5f, 0.5f); nAttr.setCached( true ); nAttr.setInternal( true ); // This is defined as a point, so that users can easily enter // values beyond 1. aShininess = nAttr.createPoint( "shininess", "sh" ); nAttr.setStorable(true); nAttr.setKeyable(true); nAttr.setDefault(100.0f, 100.0f, 100.0f); nAttr.setCached( true ); nAttr.setInternal( true ); aGeometryShape = nAttr.create( "geometryShape", "gs", MFnNumericData::kInt ); nAttr.setStorable(true); nAttr.setKeyable(true); nAttr.setDefault(0); nAttr.setCached( true ); nAttr.setInternal( true ); // create output attributes here // outColor is the only output attribute and it is inherited // so we do not need to create or add it. // // Add the attributes here addAttribute(aColor); addAttribute(aDiffuseColor); addAttribute(aSpecularColor); addAttribute(aShininess); addAttribute(aGeometryShape); attributeAffects (aColor, outColor); attributeAffects (aDiffuseColor, outColor); attributeAffects (aSpecularColor, outColor); attributeAffects (aShininess, outColor); return MS::kSuccess; }
void cgfxPass::bind(const sourceStreamInfo dataSources[], const int sourceCount) const { TRACE_API_CALLS("cgfxPass::bind"); cgfxVaryingParameter* parameter = fParameters; while( parameter) { // Here we only deal with fVertexAttribute. How to do fVertexStructure? if (parameter->fVertexAttribute.isNull() == false) { //find the corresponding data buffer int index = 0; for(index = 0; index < sourceCount; ++index) { // printf( // " Compare param %s (0x%p) [%s] name (type=%d) with data source name [%s] (type=%d)\n", // parameter->fName.asChar(), // parameter, // parameter->fVertexAttribute->fSourceName.asChar(), // parameter->fVertexAttribute->fSourceType, // dataSources[index].fSourceName.asChar(), // dataSources[index].fSourceType); if (dataSources[index].fSourceName == parameter->fVertexAttribute->fSourceName ) { // we find the correct vertex stream break; } } if(index < sourceCount) { // printf(" Binding source name [%s]\n", dataSources[index].fSourceName.asChar()); if(!parameter->bind(dataSources[index])) { // This is a true error. Binding should normally // always succeed here as the geometry // requirements are verified in // cgfxShaderOverride::initialize(). parameter->null(); MString s = "cgfxShader : Couldn't bind source \""; s += dataSources[index].fSourceName; s += "\" for vertex attribute \""; s += parameter->fVertexAttribute->fSourceName;; s +="\"."; MGlobal::displayError(s); } } else { // printf(" Can't find the source for source name [%s] for parameter [%s]\n", // parameter->fVertexAttribute->fSourceName.asChar(), // parameter->fVertexAttribute->fName.asChar()); // There is no matching source for this parameter. We // therefore bind null data for this parameter. Note // that this fact should have already been reported // to the user in cgfxShaderOverride::initialize(). We // don't report it to the user here because it would // get repetitively reported for each redraw. parameter->null(); } } parameter = parameter->fNext; } // printf(" Successfully bound sources\n"); }
MStatus hwPhongShader::draw(int prim, unsigned int writable, int indexCount, const unsigned int * indexArray, int vertexCount, const int * vertexIDs, const float * vertexArray, int normalCount, const float ** normalArrays, int colorCount, const float ** colorArrays, int texCoordCount, const float ** texCoordArrays) { TRACE_API_CALLS("draw"); #if !defined(_MAKE_HWSHADER_NODE_STATICLY_EVALUATE_) if ( prim != GL_TRIANGLES && prim != GL_TRIANGLE_STRIP) { return MS::kFailure; } { // glPushAttrib ( GL_ALL_ATTRIB_BITS ); // This is overkill // Even this is too much as matrices and texture state are restored. // glPushAttrib ( GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_TRANSFORM_BIT ); glPushAttrib ( GL_ENABLE_BIT ); glDisable ( GL_LIGHTING ); glDisable ( GL_TEXTURE_1D ); glDisable ( GL_TEXTURE_2D ); // Setup cube map generation glEnable ( GL_TEXTURE_CUBE_MAP_EXT ); glBindTexture ( GL_TEXTURE_CUBE_MAP_EXT, phong_map_id ); glEnable ( GL_TEXTURE_GEN_S ); glEnable ( GL_TEXTURE_GEN_T ); glEnable ( GL_TEXTURE_GEN_R ); glTexGeni ( GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexGeni ( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexGeni ( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT ); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); // Could modify the texture matrix here to do light tracking... glMatrixMode ( GL_TEXTURE ); glPushMatrix (); glLoadIdentity (); glMatrixMode ( GL_MODELVIEW ); } #endif // Draw the surface. // { glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ); // GL_VERTEX_ARRAY does not necessarily need to be // enabled, as it should be enabled before this routine // is valled. glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_NORMAL_ARRAY ); glVertexPointer ( 3, GL_FLOAT, 0, &vertexArray[0] ); glNormalPointer ( GL_FLOAT, 0, &normalArrays[0][0] ); glDrawElements ( prim, indexCount, GL_UNSIGNED_INT, indexArray ); // The client attribute is already being popped. You // don't need to reset state here. //glDisableClientState( GL_NORMAL_ARRAY ); //glDisableClientState( GL_VERTEX_ARRAY ); glPopClientAttrib(); } #if !defined(_MAKE_HWSHADER_NODE_STATICLY_EVALUATE_) { glMatrixMode ( GL_TEXTURE ); glPopMatrix (); glMatrixMode ( GL_MODELVIEW ); glDisable ( GL_TEXTURE_CUBE_MAP_EXT ); glDisable ( GL_TEXTURE_GEN_S ); glDisable ( GL_TEXTURE_GEN_T ); glDisable ( GL_TEXTURE_GEN_R ); glPopAttrib(); } #endif return MS::kSuccess; }