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 "LampBasic.h"
00026 #include "Graphics/Picture/PictureRGBA8.h"
00027 #include "Graphics/Scene/Scene.h"
00028 #include "Graphics/Picture/PictureManager.h"
00029 #include "Graphics/Renderer/RenderingDevice.h"
00030 #include "Core/Codec/LinearMinificationFilter/LinearMinificationFilter.h"
00031
00032 namespace Lamp{
00033
00034
00035
00036 PictureRGBA8::PictureRGBA8(const String& name, Scene* scene) :
00037 Picture(name, scene), d3dTexture_(NULL), image_(NULL){
00038 }
00039
00040
00041 PictureRGBA8::~PictureRGBA8(){
00042 SafeArrayDelete(image_);
00043 SafeRelease(d3dTexture_);
00044 }
00045
00046
00047 PictureRGBA8* PictureRGBA8::copyPictureRGBA8() const{
00048 PictureManager* manager = scene_->getPictureManager();
00049 PictureRGBA8* copyPicture =
00050 manager->createPictureRGBA8(manager->rename(name_));
00051 copyPictureValue(copyPicture);
00052 copyPicture->setImage(getImage());
00053 return copyPicture;
00054 }
00055
00056
00057 Direct3DTexture* PictureRGBA8::getD3DTexture(){
00058 if(d3dTexture_ == NULL){
00059 if(!compile()){ return NULL; }
00060 }
00061 return d3dTexture_;
00062 }
00063
00064
00065 bool PictureRGBA8::compile(){
00066 if(getImage() == NULL){
00067 ErrorOut("PictureRGBA8::compile() image is null");
00068 return false;
00069 }
00070 SafeRelease(d3dTexture_);
00071
00072 DimensionI size = getSize();
00073 d3dTexture_ = RenderingDevice::getInstance()->createTexture(
00074 D3DFMT_A8R8G8B8, size.width, size.height);
00075
00076 if(!compileMipmap(getImage(), size, 0)){ return false; }
00077 return true;
00078 }
00079
00080
00081 bool PictureRGBA8::compileImage(
00082 const Color4c* image, const DimensionI& size, int mipmapLevel){
00083 RenderingDevice* device = RenderingDevice::getInstance();
00084 D3DLOCKED_RECT lockedRect = device->lockTexture(d3dTexture_, mipmapLevel);
00085 u_char* lineAddr = (u_char*)lockedRect.pBits;
00086 for(int i = 0; i < size.height; i++){
00087 u_int* writeAddr = (u_int*)lineAddr;
00088 int offset = i * size.width;
00089 for(int j = 0; j < size.width; j++){
00090 (*writeAddr) = image[offset + j].getARGB();
00091 writeAddr++;
00092 }
00093 lineAddr += lockedRect.Pitch;
00094 }
00095 device->unlockTexture(d3dTexture_, mipmapLevel);
00096 return true;
00097 }
00098
00099
00100 bool PictureRGBA8::compileMipmap(
00101 const Color4c* image, const DimensionI& size, int mipmapLevel){
00102
00103 if(!compileImage(image, size, mipmapLevel)){ return false; }
00104
00105 mipmapLevel++;
00106 if((size.width == 1) && (size.height == 1)){
00107 Assert(d3dTexture_->GetLevelCount() == mipmapLevel);
00108 return true;
00109 }
00110 DimensionI nextSize = LinearMinificationFilter::getNextSize(size);
00111 Color4c* nextImage = new Color4c[nextSize.width * nextSize.height];
00112
00113 LinearMinificationFilter::filter(image, size, nextImage, nextSize);
00114 bool nextLevelResult = compileMipmap(nextImage, nextSize, mipmapLevel);
00115 delete[] nextImage;
00116 return nextLevelResult;
00117 }
00118
00119
00120 void PictureRGBA8::setSize(const DimensionI& size){
00121 Picture::setSize(size);
00122 Assert(size.width > 0);
00123 Assert(size.height > 0);
00124 int pixelCount = size.width * size.height;
00125 SafeArrayDelete(image_);
00126 image_ = new Color4c[pixelCount];
00127 stateChanged();
00128 }
00129
00130
00131 void PictureRGBA8::setImage(const Color4c* image){
00132 DimensionI size = getSize();
00133 Assert(size.width > 0);
00134 Assert(size.height > 0);
00135 std::memcpy(image_, image, sizeof(Color4c) * size.width * size.height);
00136 stateChanged();
00137 }
00138
00139 }
00140