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