/* virtual */ MStatus hwUnlitShader::bind(const MDrawRequest& request, M3dView& view) { MStatus status; // white, opaque. float bgColor[4] = {1,1,1,1}; // Get path of current object in draw request currentObjectPath = request.multiPath(); MString currentPathName( currentObjectPath.partialPathName() ); updateTransparencyFlags(currentPathName); // Get decal texture name MString decalName = ""; ShadingConnection colorConnection(thisMObject(), currentPathName, "color"); // If the color attribute is ultimately connected to a file texture, find its filename. // otherwise use the default color texture. if (colorConnection.type() == ShadingConnection::TEXTURE && colorConnection.texture().hasFn(MFn::kFileTexture)) { // Get the filename of the texture. MFnDependencyNode textureNode(colorConnection.texture()); MPlug filenamePlug( colorConnection.texture(), textureNode.attribute(MString("fileTextureName")) ); filenamePlug.getValue(decalName); if (decalName == "") getFloat3(color, bgColor); } else { decalName = ""; getFloat3(color, bgColor); } assert(glGetError() == GL_NO_ERROR); view.beginGL(); glPushAttrib( GL_ALL_ATTRIB_BITS ); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); // Set the standard OpenGL blending mode. glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Change the constant alpha value. float alpha = 1.0f - fConstantTransparency; // Set a color (with alpha). This color will be used directly if // the shader is not textured. Otherwise, the texture will get modulated // by the alpha. glColor4f(bgColor[0], bgColor[1], bgColor[2], alpha); // If the shader is textured... if (decalName.length() != 0) { // Enable 2D texturing. glEnable(GL_TEXTURE_2D); assert(glGetError() == GL_NO_ERROR); // Bind the 2D texture through the texture cache. The cache will keep // the texture around, so that it will only be loaded in video // memory once. In this example, the third parameter (mipmapping) is // false, so no mipmaps are generated. Note that mipmaps only work if // the texture has even dimensions. if(m_pTextureCache) m_pTextureCache->bind(colorConnection.texture(), MTexture::RGBA, false); // Set minification and magnification filtering to linear interpolation. // For better quality, you could enable mipmapping while binding and // use GL_MIPMAP_LINEAR_MIPMAP in for minification filtering. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); } // Disable lighting. glDisable(GL_LIGHTING); view.endGL(); return MS::kSuccess; }
// Return a reference to the texture. Need to dereference by calling "release". MTexture* MTextureCache::texture(MObject textureObj, MTexture::Type type /* = MTexture::RGBA */, bool mipmapped /* = true */, GLenum target /* = GL_TEXTURE_2D */) { // Get the name of the texture object. MString textureName = getNameFromObj(textureObj); // If this isn't a file texture node, or if it has no valid name, // return NULL. if (!textureObj.hasFn(MFn::kFileTexture) || textureName == "") return NULL; // Check if we already have a texCacheElement assigned to the given texture name. MTextureCacheElement *texCacheElement = m_textureTable[textureName.asChar()]; bool newTexture = !texCacheElement; bool textureDirty = texCacheElement && texCacheElement->fMonitor.dirty(); if (textureDirty) { texCacheElement->fMonitor.stopWatching(); xr_delete(texCacheElement->m_texture); texCacheElement->m_texture = NULL; } if (newTexture) { texCacheElement = xr_new<MTextureCacheElement>(); texCacheElement->fMonitor.setManager(this); // Add it to the map. m_textureTable[textureName.asChar()] = texCacheElement; } if (textureDirty || newTexture) { // Get the filename of the file texture node. MString textureFilename; MFnDependencyNode textureNode(textureObj); MPlug filenamePlug( textureObj, textureNode.attribute(MString("fileTextureName")) ); filenamePlug.getValue(textureFilename); // Create the MTexture texCacheElement->m_texture = xr_new<MTexture>(); // Monitor the given texture node for "dirty" or "rename" messages. texCacheElement->fMonitor.watch(textureObj); // Attempt to load the texture from disk and bind it in the OpenGL driver. if (texCacheElement->m_texture->load(textureFilename, type, mipmapped, target) == false) { // An error occured. Most likely, it was impossible to // open the given filename. // Clean up and return NULL. xr_delete(texCacheElement); texCacheElement = NULL; m_textureTable.erase(textureName.asChar()); return NULL; } } // Update the last updated timestamp. texCacheElement->lastAccessedTimestamp = m_currentTimestamp; return texCacheElement->texture(); }