1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
#include "texture_d3d9.h"
#include <stdexcept>
#include <cassert>
#include "graphics_interface.h"
#include "context_d3d9.h"
#include "d3d9_util.h"
#include "leak_dumper.h"
using namespace std;
using namespace Shared::Graphics;
namespace Shared{ namespace Graphics{ namespace D3d9{
// ===============================================
// class Texture2DD3d9
// ===============================================
D3DFORMAT toFormatD3d(Texture::Format format, int components){
switch(format){
case Texture::fAuto:
switch(components){
case 1:
return D3DFMT_L8;
case 3:
return D3DFMT_X8R8G8B8;
case 4:
return D3DFMT_A8R8G8B8;
default:
assert(false);
return D3DFMT_A8R8G8B8;
}
break;
case Texture::fLuminance:
return D3DFMT_L8;
case Texture::fAlpha:
return D3DFMT_A8;
case Texture::fRgb:
return D3DFMT_X8R8G8B8;
case Texture::fRgba:
return D3DFMT_A8R8G8B8;
default:
assert(false);
return D3DFMT_A8R8G8B8;
}
}
void fillPixels(uint8 *texturePixels, const Pixmap2D *pixmap){
for(int i=0; i<pixmap->getW(); ++i){
for(int j=0; j<pixmap->getH(); ++j){
int k= j*pixmap->getW()+i;
Vec4<uint8> pixel;
pixmap->getPixel(i, j, pixel.ptr());
switch(pixmap->getComponents()){
case 1:
texturePixels[k]= pixel.x;
break;
case 3:
texturePixels[k*4]= pixel.z;
texturePixels[k*4+1]= pixel.y;
texturePixels[k*4+2]= pixel.x;
break;
case 4:
texturePixels[k*4]= pixel.z;
texturePixels[k*4+1]= pixel.y;
texturePixels[k*4+2]= pixel.x;
texturePixels[k*4+3]= pixel.w;
break;
default:
assert(false);
}
}
}
}
void Texture2DD3d9::init(Filter textureFilter, int maxAnisotropy){
if(!inited){
//get device
GraphicsInterface &gi= GraphicsInterface::getInstance();
ContextD3d9 *context= static_cast<ContextD3d9*>(gi.getCurrentContext());
IDirect3DDevice9 *d3dDevice= context->getD3dDevice();
bool mipmapCaps= (context->getCaps()->TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP) != 0;
bool autogenMipmap= mipmapCaps && mipmap;
int w= pixmapInit? pixmap.getW(): defaultSize;
int h= pixmapInit? pixmap.getH(): defaultSize;
//create texture
D3DCALL(d3dDevice->CreateTexture(
w,
h,
autogenMipmap? 0: 1,
autogenMipmap? D3DUSAGE_AUTOGENMIPMAP: 0,
toFormatD3d(format, pixmap.getComponents()),
D3DPOOL_MANAGED,
&d3dTexture,
NULL));
if(pixmapInit){
//lock
D3DLOCKED_RECT lockedRect;
D3DCALL(d3dTexture->LockRect(0, &lockedRect, NULL, 0));
//copy
fillPixels(reinterpret_cast<uint8*>(lockedRect.pBits), &pixmap);
//unlock
D3DCALL(d3dTexture->UnlockRect(0));
}
inited= true;
}
}
void Texture2DD3d9::end(){
if(inited){
d3dTexture->Release();
}
}
// ===============================================
// class TextureCubeD3d9
// ===============================================
void TextureCubeD3d9::init(Filter textureFilter, int maxAnisotropy){
//get device
if(!inited){
GraphicsInterface &gi= GraphicsInterface::getInstance();
ContextD3d9 *context= static_cast<ContextD3d9*>(gi.getCurrentContext());
IDirect3DDevice9 *d3dDevice= context->getD3dDevice();
const Pixmap2D *face0= pixmap.getFace(0);
int l= pixmapInit? face0->getW(): defaultSize;
int components= face0->getComponents();
//check dimensions and face components
if(pixmapInit){
for(int i=0; i<6; ++i){
const Pixmap2D *currentFace= pixmap.getFace(i);
if(currentFace->getW()!=l || currentFace->getH()!=l){
throw runtime_error("Can't create Direct3D cube texture: dimensions don't agree");
}
if(currentFace->getComponents()!=components){
throw runtime_error("Can't create Direct3D cube texture: components don't agree");
}
}
}
bool mipmapCaps= (context->getCaps()->TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP) != 0;
bool autogenMipmap= mipmapCaps && mipmap;
//create texture
D3DCALL(d3dDevice->CreateCubeTexture(
l,
autogenMipmap? 0: 1,
autogenMipmap? D3DUSAGE_AUTOGENMIPMAP: 0,
toFormatD3d(format, components),
D3DPOOL_MANAGED,
&d3dCubeTexture,
NULL));
if(pixmapInit){
for(int i=0; i<6; ++i){
//lock
D3DLOCKED_RECT lockedRect;
D3DCALL(d3dCubeTexture->LockRect(static_cast<D3DCUBEMAP_FACES>(i), 0, &lockedRect, NULL, 0));
//copy
fillPixels(reinterpret_cast<uint8*>(lockedRect.pBits), pixmap.getFace(i));
//unlock
D3DCALL(d3dCubeTexture->UnlockRect(static_cast<D3DCUBEMAP_FACES>(i), 0));
}
}
inited= true;
}
}
void TextureCubeD3d9::end(){
if(inited){
d3dCubeTexture->Release();
}
}
}}}//end namespace
|