void ToMayaImageConverter::writeChannel( MImage &image, typename TypedData< std::vector<T> >::Ptr channelData, unsigned channelOffset, unsigned numChannels ) const { assert( channelOffset < numChannels ); ConstImagePrimitivePtr toConvert = runTimeCast<const ImagePrimitive>( srcParameter()->getValidatedValue() ); assert( toConvert ); unsigned width, height; image.getSize( width, height ); const Imath::Box2i &dataWindow = toConvert->getDataWindow(); const Imath::Box2i &displayWindow = toConvert->getDisplayWindow(); unsigned int dataWidth = dataWindow.size().x + 1; unsigned int dataHeight = dataWindow.size().y + 1; Imath::V2i dataOffset = dataWindow.min - displayWindow.min ; boost::multi_array_ref< const T, 2 > src( &channelData->readable()[0], boost::extents[dataHeight][dataWidth] ); boost::multi_array_ref< T, 3 > dst( MImageAccessor<T>::getPixels( image ), boost::extents[ height ][ width ][ numChannels ] ); for ( unsigned x = 0; x < dataWidth; x++ ) { for ( unsigned y = 0; y < dataHeight; y++ ) { /// Vertical flip, to match Maya dst[ ( height - 1 ) - ( y + dataOffset.y ) ][ x + dataOffset.x ][channelOffset] = src[y][x]; } } }
void vixo_clumpFreq::init(string fileName,float baseValue,float noiseAmp,int noiseFreq) { this->baseValue=baseValue; this->noiseAmp=noiseAmp; this->noiseFreq=noiseFreq; this->filename=fileName; if(fileName!=""||this->baseValue!=0) { hasEffect=true; } else hasEffect=false; if(fileName!="") { MImage img; img.readFromFile(MString(fileName.c_str())); img.getSize(width,height); pixels=img.pixels(); /*TIFF* tif = TIFFOpen(fileName.c_str(), "r"); if (tif) { size_t npixels; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); npixels = width * height; pixels.resize(npixels); TIFFReadRGBAImage(tif, width, height, &pixels[0], 0); //abgr TIFFClose(tif); }*/ } }
virtual MStatus renderSwatchImage( MImage & image ) { unsigned int width, height; image.getSize(width, height); unsigned char *p = image.pixels(); for(unsigned int i=0; i<width*height; i++){ *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 255; } return MS::kSuccess; }
void ToMayaImageConverter::writeAlpha( MImage &image, const T &alpha ) const { const int numChannels = 4; const int channelOffset = 3; unsigned width, height; image.getSize( width, height ); boost::multi_array_ref< T, 3 > dst( MImageAccessor<T>::getPixels( image ), boost::extents[ height ][ width ][ numChannels ] ); for ( unsigned x = 0; x < width; x++ ) { for ( unsigned y = 0; y < height; y++ ) { dst[y][x][channelOffset] = alpha; } } }
void ToMayaImageConverter::writeDepth( MImage &image, FloatVectorDataPtr channelData ) const { assert( channelData ); ConstImagePrimitivePtr toConvert = runTimeCast<const ImagePrimitive>( srcParameter()->getValidatedValue() ); assert( toConvert ); unsigned width, height; MStatus s = image.getSize( width, height ); assert( s ); const Imath::Box2i &dataWindow = toConvert->getDataWindow(); const Imath::Box2i &displayWindow = toConvert->getDisplayWindow(); unsigned int dataWidth = dataWindow.size().x + 1; unsigned int dataHeight = dataWindow.size().y + 1; Imath::V2i dataOffset = dataWindow.min - displayWindow.min ; boost::multi_array_ref< const float, 2 > src( &channelData->readable()[0], boost::extents[dataHeight][dataWidth] ); std::vector<float> depth; depth.resize( height * width, 0 ); boost::multi_array_ref< float, 2 > dst( &depth[0], boost::extents[ height ][ width ] ); for ( unsigned x = 0; x < dataWidth; x++ ) { for ( unsigned y = 0; y < dataHeight; y++ ) { /// Vertical flip, to match Maya dst[ ( height - 1 ) - ( y + dataOffset.y ) ][ x + dataOffset.x ] = src[y][x]; } } s = image.setDepthMap( &depth[0], width, height ); assert( s ); assert( image.depth() ); #ifndef NDEBUG unsigned depthWidth = 0, depthHeight = 0; s = image.getDepthMapSize( depthWidth, depthHeight ); assert( s ); assert( depthWidth == width ); assert( depthHeight == height ); #endif }
bool M_loadImage(const char * filename, void * data) { DevILInit(); // gen image ILuint ImgId = 0; ilGenImages(1, &ImgId); // bind image ilBindImage(ImgId); // load image if(! ilLoadImage(filename)) { ilDeleteImages(1, &ImgId); DevILShutDown(); return false; } // get properties int bytePerPix = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); int width = ilGetInteger(IL_IMAGE_WIDTH); int height = ilGetInteger(IL_IMAGE_HEIGHT); if(bytePerPix == 4) ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); else ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); // create image MImage * image = (MImage *)data; image->create(M_UBYTE, (unsigned int)width, (unsigned int)height, (unsigned int)bytePerPix); // copy data unsigned int size = image->getSize(); memcpy(image->getData(), ilGetData(), size); ilDeleteImages(1, &ImgId); DevILShutDown(); return true; }
void hwColorPerVertexShader::drawTheSwatch( MGeometryData* pGeomData, unsigned int* pIndexing, unsigned int numberOfData, unsigned int indexCount ) { MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer(); if( !pRenderer ) return; // Set 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); { // Enable the blending to get the transparency to work // glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // Load in a sample background image if (mSampleImageId == 0) { mSampleImage = new MImage; MStatus rstatus = mSampleImage->readFromFile("C:\\temp\\maya.gif"); if (rstatus == MStatus::kSuccess) { unsigned int w, h; mSampleImage->getSize( w, h ); if (w > 2 && h > 2 ) { glGenTextures( 1, &mSampleImageId ); if (mSampleImageId > 0) { glEnable(GL_TEXTURE_2D); glBindTexture ( GL_TEXTURE_2D, mSampleImageId ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) mSampleImage->pixels() ); } } } if (mSampleImage) { delete mSampleImage; } } // Overlay the background checker board // bool drawBackGround = ( mTranspBias > 0.0f ); bool drawBackGroundTexture = (mSampleImageId != 0); if (drawBackGround) { if (drawBackGroundTexture) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glBindTexture(GL_TEXTURE_2D, mSampleImageId ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); } unsigned int numberOfRepeats = 8; MColor quadColor( 0.5f, 0.5f, 0.5f, 1.0f ); pRenderer->drawSwatchBackGroundQuads( quadColor, drawBackGroundTexture, numberOfRepeats ); if (drawBackGroundTexture) glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); } { // Set some example material // float ambient[4] = { 0.1f, 0.1f, 0.1f, 1.0f }; float diffuse[4] = { 0.7f, 0.7f, 0.7f, 1.0f }; float specular[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; float emission[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission ); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular ); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f); // Track diffuse color float swatchColor[4]; float biasT = 1.0f - mTranspGain - mTranspBias; swatchColor[0] = (diffuse[0] * mColorGain[0]) + mColorBias[0]; swatchColor[1] = (diffuse[1] * mColorGain[1]) + mColorBias[1]; swatchColor[2] = (diffuse[2] * mColorGain[2]) + mColorBias[2]; swatchColor[3] = (diffuse[3] * mTranspGain) + biasT; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, swatchColor ); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glColor4fv( swatchColor ); } if (pGeomData) { glPushClientAttrib ( GL_CLIENT_VERTEX_ARRAY_BIT ); if (mNormalsPerVertex >= 1) { glDisable(GL_LIGHTING); float *normalData = (float *)( pGeomData[1].data() ); float * tangentData = (float *)( pGeomData[3].data() ); float * binormalData = (float *)( pGeomData[4].data() ); if (normalData && mNormalsPerVertex == 1) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, normalData); } else if (tangentData && mNormalsPerVertex == 2) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, tangentData); } else if (binormalData) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_FLOAT, 0, binormalData); } } 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 (mSampleImageId > 0) { float *uvData = (float *) (pGeomData[2].data() ); if (uvData) { glBindTexture ( GL_TEXTURE_2D, mSampleImageId ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glTexCoordPointer( 2, GL_FLOAT, 0, uvData ); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef( 0.5f, 0.5f, 1 ); //glTranslatef(0.5f, 0.5f, 0.0f); glRotatef( mTexRotateX, 1.0f, 0.0f, 0.0f); glRotatef( mTexRotateY, 0.0, 1.0f, 0.0f); glRotatef( mTexRotateZ, 0.0, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); } } if (vertexData && normalData && pIndexing ) glDrawElements ( GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, pIndexing ); glPopClientAttrib(); // Release data references pRenderer->dereferenceGeometry( pGeomData, numberOfData ); } glDisable( GL_COLOR_MATERIAL ); glDisable( GL_LIGHTING ); }
/* virtual */ MStatus hwColorPerVertexShader::renderSwatchImage( MImage& outImage ) { MStatus status = MStatus::kFailure; // Get the hardware renderer utility class MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer(); if (pRenderer) { const MString& backEndStr = pRenderer->backEndString(); // Get geometry // ============ unsigned int* pIndexing = 0; unsigned int numberOfData = 0; unsigned int indexCount = 0; MHardwareRenderer::GeometricShape gshape = MHardwareRenderer::kDefaultSphere; //MHardwareRenderer::GeometricShape gshape = MHardwareRenderer::kDefaultPlane; MGeometryData* pGeomData = pRenderer->referenceDefaultGeometry( gshape, numberOfData, pIndexing, indexCount ); if( !pGeomData ) { return MStatus::kFailure; } // Make the swatch context current // =============================== // unsigned int width, height; outImage.getSize( width, height ); unsigned int origWidth = width; unsigned int origHeight = height; MStatus status2 = pRenderer->makeSwatchContextCurrent( backEndStr, width, height ); if( status2 != MS::kSuccess ) { pRenderer->dereferenceGeometry( pGeomData, numberOfData ); return MStatus::kFailure; } glPushAttrib(GL_ALL_ATTRIB_BITS); // Get the light direction from the API, and use it // ============================================= { float light_pos[4]; pRenderer->getSwatchLightDirection( light_pos[0], light_pos[1], light_pos[2], light_pos[3] ); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glLightfv(GL_LIGHT0, GL_POSITION, light_pos ); glPopMatrix(); float light_ambt[4] = {1.0f, 1.0f, 1.0f, 1.0}; float light_diff[4] = {1.0f, 1.0f, 1.0f, 1.0}; float light_spec[4] = {1.0f, 1.0f, 1.0f, 1.0}; glLightfv( GL_LIGHT0, GL_AMBIENT, light_ambt ); glLightfv( GL_LIGHT0, GL_DIFFUSE, light_diff ); glLightfv( GL_LIGHT0, GL_SPECULAR, light_spec ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); } // Get camera // ========== { // Get the camera frustum from the API double l, r, b, t, n, f; pRenderer->getSwatchOrthoCameraSetting( l, r, b, t, n, f ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho( l, r, b, t, n, f ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } // Draw The Swatch // =============== drawTheSwatch( pGeomData, pIndexing, numberOfData, indexCount ); // Read pixels back from swatch context to MImage // ============================================== pRenderer->readSwatchContextPixels( backEndStr, outImage ); // Double check the outing going image size as image resizing // was required to properly read from the swatch context outImage.getSize( width, height ); if (width != origWidth || height != origHeight) { status = MStatus::kFailure; } else { status = MStatus::kSuccess; } glPopAttrib(); } return status; }
bool MTexture::set(MImage &image, Type type, bool mipmapped /* = true */, GLenum target /* = GL_TEXTURE_2D) */) { unsigned int i; // used as a temporary index. // Store the type of texture, and derive other parameters. // (Depth is assumed to be 4 bytes per pixel RGBA. // MImage always returns that pixel format anyway.) m_type = type; if ( (m_type == RGBA) || (m_type == NMAP) ) { m_internalFormat = GL_RGBA8; m_format = GL_RGBA; m_componentFormat = GL_UNSIGNED_BYTE; } else if (m_type == HILO) { #if NVIDIA_SPECIFIC m_internalFormat = GL_SIGNED_HILO_NV; m_format = GL_HILO_NV; m_componentFormat = GL_SHORT; #endif } else assert(0); // Get the dimension of the texture. MStatus stat = image.getSize(m_width, m_height); assert(stat); m_mipmapped = mipmapped; unsigned int maxWidthLevels = highestPowerOf2(m_width); unsigned int maxHeightLevels = highestPowerOf2(m_height); // Standard OpenGL doesn't accept width or height that are not power of 2. // If that's the case we resize the picture to the closest larger valid rectangle. bool widthIsExponent = (m_width == (unsigned int) (1 << maxWidthLevels)); bool heightIsExponent = (m_height == (unsigned int) (1 << maxHeightLevels)); if (!widthIsExponent || !heightIsExponent) { // Calculate the new width/height. if (!widthIsExponent) maxWidthLevels++; if (!heightIsExponent) maxHeightLevels++; // Resize the image, without bothering to preserve the aspect ratio. m_width = 1 << maxWidthLevels; m_height = 1 << maxHeightLevels; image.resize(m_width, m_height, false); } // Deallocate any existing levels if (m_levels != NULL) { for (i=0; i < m_numLevels; i++) { if (m_levels[i]) { xr_free(m_levels[i]); m_levels[i] = NULL; } } xr_free(m_levels); } // The number of mipmap levels cannot be greater than the exponent of width or height. // The number of mipmap levels is 1 for a non-mipmapped texture. // For mipmapped textures, m_numLevels = max level + 1. m_numLevels = mipmapped ? _max(maxWidthLevels, maxHeightLevels) + 1 : 1; // Allocate the proper amount of memory, for the base level and the mipmaps. m_levels = xr_alloc<unsigned char*>(m_numLevels); for (i=0; i < m_numLevels; i++) { m_levels[i] = xr_alloc<unsigned char>(width(i) * height(i) * 4); } // Copy the base level. (the actual file texture) Memory.mem_copy(m_levels[0], image.pixels(), m_width * m_height * 4); // Create the mipmapped levels. // NOTE REGARDING THE width_ratio and height_ratio: // The smallest mipmap levels of non-square textures must be handled // carefully. Say we have a 8x2 texture. Mipmap levels will be // 4x1, 2x1, 1x1. We cannot simply multiply the current st coordinate by // 2 like we do for square textures to find the source st coordinates, // or we'll end up fetching outside of the source level. Instead, we // multiply the target s, t coordinates by the width and height ratio respectively. for (unsigned int current_level = 1; current_level < m_numLevels; current_level++) { unsigned int width_ratio = width(i-1) / width(i); unsigned int height_ratio = height(i-1) / height(i-1); unsigned int previous_level = current_level - 1; for (unsigned int target_t = 0; target_t < height(current_level); target_t++) { for (unsigned int target_s = 0; target_s < width(current_level); target_s++) { // The st coordinates from the source level. unsigned int source_s = target_s * width_ratio; unsigned int source_t = target_t * height_ratio; unsigned int source_s2 = source_s + ((width_ratio == 2) ? 1 : 0); unsigned int source_t2 = source_t + ((height_ratio == 2) ? 1 : 0); unsigned char *destination = internalFetch(target_s, target_t, current_level); unsigned char *source1 = internalFetch(source_s, source_t, previous_level); unsigned char *source2 = internalFetch(source_s2, source_t, previous_level); unsigned char *source3 = internalFetch(source_s, source_t2, previous_level); unsigned char *source4 = internalFetch(source_s2, source_t2, previous_level); // Average byte per byte. unsigned int average1 = (*source1++ + *source2++ + *source3++ + *source4++) / 4; *destination++ = average1; unsigned int average2 = (*source1++ + *source2++ + *source3++ + *source4++) / 4; *destination++ = average2; unsigned int average3 = (*source1++ + *source2++ + *source3++ + *source4++) / 4; *destination++ = average3; unsigned int average4 = (*source1++ + *source2++ + *source3++ + *source4++) / 4; *destination++ = average4; } } } if( type == NMAP ) { // Convert each level to the NORMAL map format // MNormalMapConverter mapConverter; for (unsigned int i = 0; i < m_numLevels; i++) { mapConverter.convertToNormalMap( m_levels[i], width(i), height(i), MNormalMapConverter::RGBA, 2.0f ); } } specify(target); return true; }
void vixo_hairStyleMaya::getTextureInfo(MString attrName,vector<float>& uvs,vector<follicleColor>& res,MDataBlock& data) { MPlug plug(thisMObject(),this->densityMap); if(attrName=="tipColor") plug.setAttribute(tipColor); else if(attrName=="baseColor") plug.setAttribute(baseColor); else if(attrName=="tipOpacity") plug.setAttribute(tipOpacity); else if(attrName=="baseOpacity") plug.setAttribute(baseOpacity); MPlugArray arr; plug.connectedTo(arr,true,false); if(arr.length()!=1) { MFloatVector color=data.inputValue(plug).asFloatVector(); if(attrName=="densityMap") for(int i=0;i<uvs.size()/2;i++) res[i].density=color.x; else if(attrName=="tipOpacity") { float noiseAmp=data.inputValue(tipOpacityNoiseAmp).asFloat(); float noiseFreq=data.inputValue(tipOpacityNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { float ton=noise::atPointUV(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq)*2-1; res[i].tipOpa=min(max(color.x+ton*noiseAmp,0.0),1.0); } } else if(attrName=="baseOpacity") { float noiseAmp=data.inputValue(baseOpacityNoiseAmp).asFloat(); float noiseFreq=data.inputValue(baseOpacityNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { float bon=noise::atPointUV(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq)*2-1; res[i].baseOpa=min(max(color.x+bon*noiseAmp,0.0),1.0); } } else if(attrName=="baseColor") { float noiseAmp=data.inputValue(baseColorNoiseAmp).asFloat(); float noiseFreq=data.inputValue(baseColorNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { pnt bcn=noise::atPointUVColor(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq); bcn.x=(bcn.x*2-1)*noiseAmp; bcn.y=(bcn.y*2-1)*noiseAmp; bcn.z=(bcn.z*2-1)*noiseAmp; res[i].baseColorR=min(max(color.x+bcn.x,0.0),1.0); res[i].baseColorG=min(max(color.y+bcn.y,0.0),1.0); res[i].baseColorB=min(max(color.z+bcn.z,0.0),1.0); } } else if(attrName=="tipColor") { float noiseAmp=data.inputValue(tipColorNoiseAmp).asFloat(); float noiseFreq=data.inputValue(tipColorNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { pnt tcn=noise::atPointUVColor(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq); tcn.x=(tcn.x*2-1)*noiseAmp; tcn.y=(tcn.y*2-1)*noiseAmp; tcn.z=(tcn.z*2-1)*noiseAmp; res[i].tipColorR=min(max(color.x+tcn.x,0.0),1.0); res[i].tipColorG=min(max(color.y+tcn.y,0.0),1.0); res[i].tipColorB=min(max(color.z+tcn.z,0.0),1.0); } } return; } MFnDependencyNode dgFn(arr[0].node()); MPlug fnFile=dgFn.findPlug("fileTextureName"); if(fnFile.asString()=="") { MFloatVector color=data.inputValue(plug).asFloatVector(); if(attrName=="densityMap") for(int i=0;i<uvs.size()/2;i++) res[i].density=color.x; else if(attrName=="tipOpacity") { float noiseAmp=data.inputValue(tipOpacityNoiseAmp).asFloat(); float noiseFreq=data.inputValue(tipOpacityNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { float ton=noise::atPointUV(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq)*2-1; res[i].tipOpa=min(max(color.x+ton*noiseAmp,0.0),1.0); } } else if(attrName=="baseOpacity") { float noiseAmp=data.inputValue(baseOpacityNoiseAmp).asFloat(); float noiseFreq=data.inputValue(baseOpacityNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { float bon=noise::atPointUV(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq)*2-1; res[i].baseOpa=min(max(color.x+bon*noiseAmp,0.0),1.0); } } else if(attrName=="baseColor") { float noiseAmp=data.inputValue(baseColorNoiseAmp).asFloat(); float noiseFreq=data.inputValue(baseColorNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { pnt bcn=noise::atPointUVColor(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq); bcn.x=(bcn.x*2-1)*noiseAmp; bcn.y=(bcn.y*2-1)*noiseAmp; bcn.z=(bcn.z*2-1)*noiseAmp; res[i].baseColorR=min(max(color.x+bcn.x,0.0),1.0); res[i].baseColorG=min(max(color.y+bcn.y,0.0),1.0); res[i].baseColorB=min(max(color.z+bcn.z,0.0),1.0); } } else if(attrName=="tipColor") { float noiseAmp=data.inputValue(tipColorNoiseAmp).asFloat(); float noiseFreq=data.inputValue(tipColorNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { pnt tcn=noise::atPointUVColor(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq); tcn.x=(tcn.x*2-1)*noiseAmp; tcn.y=(tcn.y*2-1)*noiseAmp; tcn.z=(tcn.z*2-1)*noiseAmp; res[i].tipColorR=min(max(color.x+tcn.x,0.0),1.0); res[i].tipColorG=min(max(color.y+tcn.y,0.0),1.0); res[i].tipColorB=min(max(color.z+tcn.z,0.0),1.0); } } return; } MImage imgFn; imgFn.readFromTextureNode(arr[0].node()); unsigned int imageWidth,imageHeight,imageDepth; imgFn.getSize(imageWidth,imageHeight); imageDepth=4; unsigned char * pixels=imgFn.pixels(); if(attrName=="densityMap") for(int i=0;i<uvs.size()/2;i++) { int pixelW=uvs[2*i]*imageWidth; int pixelH=uvs[2*i+1]*imageHeight; res[i].density=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)])/255.0; } else if(attrName=="tipOpacity") { float noiseAmp=data.inputValue(tipOpacityNoiseAmp).asFloat(); float noiseFreq=data.inputValue(tipOpacityNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { float ton=noise::atPointUV(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq)*2-1; int pixelW=uvs[2*i]*imageWidth; int pixelH=uvs[2*i+1]*imageHeight; res[i].tipOpa=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)])/255.0; res[i].tipOpa=min(max(res[i].tipOpa+ton*noiseAmp,0.0),1.0); } } else if(attrName=="baseOpacity") { float noiseAmp=data.inputValue(baseOpacityNoiseAmp).asFloat(); float noiseFreq=data.inputValue(baseOpacityNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { float bon=noise::atPointUV(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq)*2-1; int pixelW=uvs[2*i]*imageWidth; int pixelH=uvs[2*i+1]*imageHeight; res[i].baseOpa=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)])/255.0; res[i].baseOpa=min(max(res[i].baseOpa+bon*noiseAmp,0.0),1.0); } } else if(attrName=="baseColor") { float noiseAmp=data.inputValue(baseColorNoiseAmp).asFloat(); float noiseFreq=data.inputValue(baseColorNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { pnt bcn=noise::atPointUVColor(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq); bcn.x=(bcn.x*2-1)*noiseAmp; bcn.y=(bcn.y*2-1)*noiseAmp; bcn.z=(bcn.z*2-1)*noiseAmp; int pixelW=uvs[2*i]*imageWidth; int pixelH=uvs[2*i+1]*imageHeight; res[i].baseColorR=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)])/255.0; res[i].baseColorG=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)+1])/255.0; res[i].baseColorB=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)+2])/255.0; res[i].baseColorR=min(max(res[i].baseColorR+bcn.x,0.0),1.0); res[i].baseColorG=min(max(res[i].baseColorG+bcn.y,0.0),1.0); res[i].baseColorB=min(max(res[i].baseColorB+bcn.z,0.0),1.0); } } else if(attrName=="tipColor") { float noiseAmp=data.inputValue(tipColorNoiseAmp).asFloat(); float noiseFreq=data.inputValue(tipColorNoiseFreq).asFloat(); for(int i=0;i<uvs.size()/2;i++) { pnt tcn=noise::atPointUVColor(uvs[2*i]*noiseFreq,uvs[2*i+1]*noiseFreq); tcn.x=(tcn.x*2-1)*noiseAmp; tcn.y=(tcn.y*2-1)*noiseAmp; tcn.z=(tcn.z*2-1)*noiseAmp; int pixelW=uvs[2*i]*imageWidth; int pixelH=uvs[2*i+1]*imageHeight; res[i].tipColorR=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)])/255.0; res[i].tipColorG=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)+1])/255.0; res[i].tipColorB=((unsigned int)pixels[imageDepth*(pixelH*imageWidth+pixelW)+2])/255.0; res[i].tipColorR=min(max(res[i].tipColorR+tcn.x,0.0),1.0); res[i].tipColorG=min(max(res[i].tipColorG+tcn.y,0.0),1.0); res[i].tipColorB=min(max(res[i].tipColorB+tcn.z,0.0),1.0); } } }
bool M_loadFont(const char * filename, void * data, void * arg) { MFont * font = (MFont *)data; int pen_x, pen_y, max_y; unsigned int n, max_code = 4096; unsigned int size = font->getFontSize(); unsigned int space = 2; unsigned int width = 1024; unsigned int height = 0; MImage image; FT_GlyphSlot slot; FT_Library library; FT_Face face; FT_Byte * file_base; FT_Long file_size; // init FT_Error error = FT_Init_FreeType(&library); if(error){ printf("ERROR Load Font : unable to init FreeType\n"); return false; } // open file MFile * file = M_fopen(filename, "rb"); if(! file) { FT_Done_FreeType(library); printf("ERROR Load Font : can't read file %s\n", filename); return false; } M_fseek(file, 0, SEEK_END); file_size = M_ftell(file); M_rewind(file); file_base = new FT_Byte[file_size]; if(file_size != M_fread(file_base, sizeof(FT_Byte), file_size, file)) { M_fclose(file); FT_Done_FreeType(library); delete [] file_base; return false; } // read font error = FT_New_Memory_Face(library, file_base, file_size, 0, &face); M_fclose(file); if(error) { printf("ERROR Load Font : unable to read data %s\n", filename); FT_Done_FreeType(library); delete [] file_base; return false; } // set font size error = FT_Set_Pixel_Sizes(face, 0, size); if(error) { printf("ERROR Load Font : unable to size font\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // parse characters max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > width) { pen_x = space; pen_y += max_y + space; height += max_y + space; max_y = 0; } // increment pen position pen_x += slot->bitmap.width + space; } if(height == 0) { printf("ERROR Load Font : unable to create font texture\n"); FT_Done_FreeType(library); delete [] file_base; return false; } // create image height = getNextPowerOfTwo(height); image.create(M_UBYTE, width, height, 4); memset(image.getData(), 0, image.getSize()*sizeof(char)); // init font font->setTextureWidth(width); font->setTextureHeight(height); // create font texture max_y = 0; slot = face->glyph; pen_x = space; pen_y = space; for(n = 0; n<max_code; n++) { // load glyph image into the slot (erase previous one) error = FT_Load_Char(face, n, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); if(error) continue; if(FT_Get_Char_Index(face, n) == 0) continue; // max y max_y = MAX(max_y, slot->bitmap.rows); if((pen_x + slot->bitmap.width + space) > (int)image.getWidth()){ pen_x = space; pen_y += max_y + space; } // get character properties float xAdvance = (slot->advance.x >> 6) / ((float)size); MVector2 offset = MVector2((float)slot->bitmap_left - 1, - (float)slot->bitmap_top - 1) / ((float)size); MVector2 pos = MVector2((float)(pen_x-1) / (float)width, (float)(pen_y-1) / (float)height); MVector2 scale = MVector2((float)(slot->bitmap.width+2) / (float)width, (float)(slot->bitmap.rows+2) / (float)height); // set character font->setCharacter(n, MCharacter(xAdvance, offset, pos, scale)); // draw to image drawBitmap(&image, &slot->bitmap, pen_x, pen_y); // increment pen position pen_x += slot->bitmap.width + space; } // send texture MEngine * engine = MEngine().getInstance(); MRenderingContext * render = engine->getRenderingContext(); // gen texture id unsigned int textureId = font->getTextureId(); if(textureId == 0) { render->createTexture(&textureId); font->setTextureId(textureId); } // send texture image render->bindTexture(textureId); render->setTextureUWrapMode(M_WRAP_REPEAT); render->setTextureVWrapMode(M_WRAP_REPEAT); render->sendTextureImage(&image, 0, 1, 0); // finish FT_Done_FreeType(library); delete [] file_base; return true; }
/* virtual */ MStatus hwPhongShader::renderSwatchImage( MImage & outImage ) { MStatus status = MStatus::kFailure; // Get the hardware renderer utility class MHardwareRenderer *pRenderer = MHardwareRenderer::theRenderer(); if (pRenderer) { const MString& backEndStr = pRenderer->backEndString(); // Get geometry // ============ unsigned int* pIndexing = 0; unsigned int numberOfData = 0; unsigned int indexCount = 0; MHardwareRenderer::GeometricShape gshape = MHardwareRenderer::kDefaultSphere; if (mGeometryShape == 2) { gshape = MHardwareRenderer::kDefaultCube; } else if (mGeometryShape == 3) { gshape = MHardwareRenderer::kDefaultPlane; } MGeometryData* pGeomData = pRenderer->referenceDefaultGeometry( gshape, numberOfData, pIndexing, indexCount ); if( !pGeomData ) { return MStatus::kFailure; } // Make the swatch context current // =============================== // unsigned int width, height; outImage.getSize( width, height ); unsigned int origWidth = width; unsigned int origHeight = height; MStatus status2 = pRenderer->makeSwatchContextCurrent( backEndStr, width, height ); if( status2 == MS::kSuccess ) { glPushAttrib ( GL_ALL_ATTRIB_BITS ); // Get camera // ========== { // Get the camera frustum from the API double l, r, b, t, n, f; pRenderer->getSwatchOrthoCameraSetting( l, r, b, t, n, f ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho( l, r, b, t, n, f ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Rotate the cube a bit so we don't see it head on if (gshape == MHardwareRenderer::kDefaultCube) glRotatef( 45, 1.0, 1.0, 1.0 ); else if (gshape == MHardwareRenderer::kDefaultPlane) glScalef( 1.5, 1.5, 1.5 ); else glScalef( 1.0, 1.0, 1.0 ); } // Draw The Swatch // =============== drawTheSwatch( pGeomData, pIndexing, numberOfData, indexCount ); // Read pixels back from swatch context to MImage // ============================================== pRenderer->readSwatchContextPixels( backEndStr, outImage ); // Double check the outing going image size as image resizing // was required to properly read from the swatch context outImage.getSize( width, height ); if (width != origWidth || height != origHeight) { status = MStatus::kFailure; } else { status = MStatus::kSuccess; } glPopAttrib(); } else { pRenderer->dereferenceGeometry( pGeomData, numberOfData ); } } return status; }
// Post-render callback // void refreshCompute::postRenderCB(const MString& panelName, void * data) { refreshCompute *thisCompute = (refreshCompute *) data; if (!thisCompute) return; // Get the view if any for the panel M3dView view; MStatus status = M3dView::getM3dViewFromModelPanel(panelName, view); if (status != MS::kSuccess) return; view.popViewport(); if (thisCompute->mBufferOperation == kDrawDepthBuffer) { int width = 0, height = 0; width = view.portWidth( &status ) / 2 ; if (status != MS::kSuccess || (width < 2)) return; height = view.portHeight( &status ) / 2 ; if (status != MS::kSuccess || (height < 2)) return; unsigned int numPixels = width * height; float *depthPixels = new float[numPixels]; if (!depthPixels) return; unsigned char *colorPixels = new unsigned char[numPixels * 4]; if (!colorPixels) { delete depthPixels; delete colorPixels; } // Read into a float buffer status = view.readDepthMap( 0,0, width, height, (unsigned char *)depthPixels, M3dView::kDepth_Float ); if (status != MS::kSuccess) { delete depthPixels; delete colorPixels; return; } // Find depth range and remap normalized depth range (-1 to 1) into 0...255 // for color. float *dPtr = depthPixels; unsigned int i = 0; float zmin = 100.0f; // *dPtr; float zmax = -100.0f; // *dPtr; for(i=0; i<numPixels; i++) { float val = *dPtr; // * 2.0f - 1.0f; if(val < zmin) { zmin = *dPtr; } if(val > zmax) { zmax = *dPtr; } dPtr++; } float zrange = zmax - zmin; //printf("depth values = (%g, %g). Range = %g\n", zmin, zmax, zrange); unsigned char *cPtr = colorPixels; dPtr = depthPixels; for(i=0; i < numPixels; i++) { float val = *dPtr; // * 2.0f - 1.0f; //unsigned char depth = (unsigned char)(255.0f * (( (*dPtr)-zmin) / zrange) + zmin ); unsigned char depth = (unsigned char)(255.0f * (( (val)-zmin) / zrange) ); //unsigned char depth = (unsigned char)(255.0f * val); *cPtr = depth; cPtr++; *cPtr = depth; cPtr++; *cPtr = depth; cPtr++; *cPtr = 0xff; cPtr++; dPtr++; } MImage image; image.setPixels( colorPixels, width, height ); // Uncomment next line to test writing buffer to file. //image.writeToFile( "C:\\temp\\dumpDepth.iff" ); // Write all pixels back. The origin of the image (lower left) // is used status = view.writeColorBuffer( image, 5, 5 ); if (depthPixels) delete depthPixels; if (colorPixels) delete colorPixels; } // Do a simple color invert operation on all pixels // else if (thisCompute->mBufferOperation == kInvertColorBuffer) { // Optional to read as RGBA. Note that this will be slower // since we must swizzle the bytes around from the default // BGRA format. bool readAsRGBA = true; // Read the RGB values from the color buffer MImage image; status = view.readColorBuffer( image, readAsRGBA ); if (status != MS::kSuccess) return; status = view.writeColorBuffer( image, 5, 5 ); unsigned char *pixelPtr = (unsigned char*)image.pixels(); if (pixelPtr) { unsigned int width, height; image.getSize( width, height ); MImage image2; image2.create( width, height ); unsigned char *pixelPtr2 = (unsigned char*)image2.pixels(); unsigned int numPixels = width * height; for (unsigned int i=0; i < numPixels; i++) { *pixelPtr2 = (255 - *pixelPtr); pixelPtr2++; pixelPtr++; *pixelPtr2 = (255 - *pixelPtr); pixelPtr2++; pixelPtr++; *pixelPtr2 = (255 - *pixelPtr); pixelPtr2++; pixelPtr++; *pixelPtr2 = 255; pixelPtr2++; pixelPtr++; } // Write all pixels back. The origin of the image (lower left) // is used status = view.writeColorBuffer( image2, 5, short(5+height/2) ); } } }