00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "System/stdafx.h"
00026 #include "Texture/MayaTexture.h"
00027 #include "Texture/MayaTextureManager.h"
00028 #include "Core/Codec/LinearMinificationFilter/LinearMinificationFilter.h"
00029
00030 namespace LampForMaya{
00031
00032
00033
00034 MayaTexture::MayaTexture(const MObject& node, const String& name) :
00035 node_(node), name_(name), textureID_(0), images_(NULL), mipmapLevel_(0),
00036 width_(0), height_(0), renameCallbackID_(0), dirtyCallbackID_(0),
00037 loaded_(false){
00038 MStatus result;
00039
00040 glGenTextures(1, &textureID_);
00041 MayaOpenGLCheck();
00042
00043 renameCallbackID_ = MNodeMessage::addNameChangedCallback(
00044 node_, MayaTextureManager::renameCallback, this, &result);
00045 MayaStatusCheck(result);
00046 dirtyCallbackID_ = MNodeMessage::addNodeDirtyCallback(
00047 node_, MayaTextureManager::dirtyCallback, this, &result);
00048 MayaStatusCheck(result);
00049 }
00050
00051
00052 MayaTexture::~MayaTexture(){
00053 clear();
00054
00055 MayaStatusCheck(MMessage::removeCallback(dirtyCallbackID_));
00056 MayaStatusCheck(MMessage::removeCallback(renameCallbackID_));
00057
00058 glDeleteTextures(1, &textureID_);
00059 MayaOpenGLCheck();
00060 }
00061
00062
00063 void MayaTexture::clear(){
00064 if(images_ != NULL){
00065 for(int i = 0; i < mipmapLevel_; i++){
00066 SafeArrayDelete(images_[i]);
00067 }
00068 mipmapLevel_ = 0;
00069 SafeArrayDelete(images_);
00070 }
00071 }
00072
00073
00074 bool MayaTexture::load(){
00075 if(loaded_){ return true; }
00076 MStatus result;
00077
00078 MImage image;
00079 String fileName =
00080 MayaAttributeUtility::getString(node_, "fileTextureName");
00081 if(fileName.isEmpty()){ return false; }
00082 MayaStatusCheck(image.readFromFile(fileName.getBytes()));
00083 MayaStatusCheck(image.getSize(width_, height_));
00084
00085 u_int widthLevel = highestPowerOf2(width_);
00086 bool widthResize = (width_ != (1 << widthLevel));
00087 u_int heightLevel = highestPowerOf2(height_);
00088 bool heightResize = (height_ != (1 << heightLevel));
00089 if(widthResize || heightResize){
00090 if(widthResize){
00091 widthLevel++;
00092 width_ = (1 << widthLevel);
00093 }
00094 if(heightResize){
00095 heightLevel++;
00096 height_ = (1 << heightLevel);
00097 }
00098 MayaStatusCheck(image.resize(width_, height_, false));
00099 }
00100
00101
00102 mipmapLevel_ = Math::maximum(widthLevel, heightLevel) + 1;
00103
00104
00105 Assert(images_ == NULL);
00106 images_ = new u_char*[mipmapLevel_];
00107 for(int i = 0; i < mipmapLevel_; i++){
00108 images_[i] = new u_char[getWidth(i) * getHeight(i) * bytesPerPixel_];
00109 }
00110
00111
00112 ::memcpy(images_[0], image.pixels(), width_ * height_ * bytesPerPixel_);
00113
00114
00115 for(int level = 1; level < mipmapLevel_; level++){
00116 int sourceLevel = level - 1;
00117 DimensionI sourceSize(getWidth(sourceLevel), getHeight(sourceLevel));
00118 DimensionI targetSize(getWidth(level), getHeight(level));
00119 LinearMinificationFilter::filter(
00120 (Color4c*)images_[sourceLevel], sourceSize,
00121 (Color4c*)images_[level], targetSize);
00122 }
00123
00124
00125 for(int i = 0; i < mipmapLevel_; i++){
00126 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA8, getWidth(i), getHeight(i), 0,
00127 GL_RGBA, GL_UNSIGNED_BYTE, images_[i]);
00128 MayaOpenGLCheck();
00129 }
00130
00131 loaded_ = true;
00132 return true;
00133 }
00134
00135
00136 bool MayaTexture::bind(){
00137 glEnable(GL_TEXTURE_2D);
00138 glBindTexture(GL_TEXTURE_2D, textureID_);
00139 MayaOpenGLCheck();
00140
00141
00142 if(!load()){ return false; }
00143
00144 glTexParameteri(GL_TEXTURE_2D,
00145 GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00149 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00150 MayaOpenGLCheck();
00151 return true;
00152 }
00153
00154 }
00155