aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp')
-rw-r--r--libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp b/libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp
new file mode 100644
index 0000000..3bfbe1e
--- /dev/null
+++ b/libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp
@@ -0,0 +1,320 @@
1//#define ENABLE_LOG_PRINTF
2
3#include <string.h>
4
5#include <d3dx9.h>
6
7#include "evas_direct3d_object_image.h"
8#include "evas_direct3d_image_cache.h"
9#include "evas_direct3d_device.h"
10#include "evas_direct3d_shader_pack.h"
11#include "evas_direct3d_vertex_buffer_cache.h"
12
13TArray<D3DObjectImage *> D3DObjectImage::_cache;
14bool D3DObjectImage::_cache_enabled = false;
15
16D3DObjectImage::D3DObjectImage()
17{
18 _x = _y = _w = _h = 0;
19 _sx = _sy = _sw = _sh = 0;
20 _u = _v = _du = _dv = 0;
21 _image_id = -1;
22 _width = _height = 0;
23 _source[0] = 0;
24 _color = 0xffffffff;
25 _cache_i = 0;
26 _border = D3DXVECTOR4(0, 0, 0, 0);
27 _uvborder = D3DXVECTOR4(0, 0, 0, 0);
28 _with_border = false;
29 _dirty = false;
30 _image_data_updated = false;
31}
32
33D3DObjectImage::~D3DObjectImage()
34{
35 D3DImageCache::Current()->RemoveImageUser(_image_id);
36}
37
38void D3DObjectImage::CopyTo(D3DObjectImage *image)
39{
40 assert(image != NULL);
41 image->_u = _u;
42 image->_v = _v;
43 image->_du = _du;
44 image->_dv = _dv;
45 image->_image_id = _image_id;
46 image->_width = _width;
47 image->_height = _height;
48 CopyMemory(image->_source, _source, sizeof(_source));
49 D3DImageCache::Current()->AddImageUser(image->_image_id);
50}
51
52void D3DObjectImage::BeginCache()
53{
54 _cache.Allocate(0);
55 _cache_enabled = true;
56}
57
58void D3DObjectImage::EndCache(D3DDevice *d3d)
59{
60 if (!_cache_enabled || _cache.Length() == 0)
61 return;
62 D3DShaderPack::Current()->SetVDecl(d3d, D3DShaderPack::VDECL_XYUVC);
63 D3DShaderPack::Current()->SetVS(d3d, D3DShaderPack::VS_COPY_UV_COLOR);
64 D3DShaderPack::Current()->SetPS(d3d, D3DShaderPack::PS_TEX_COLOR_FILTER);
65
66 static TArray<Vertex> sorted;
67 static TArray<GroupDesc> groups;
68 sorted.Allocate(0);
69 groups.Allocate(0);
70
71 bool found = true;
72 while (found)
73 {
74 found = false;
75 int cur_id = -1;
76 int num = 0;
77 for (int i = 0; i < _cache.Length(); i++)
78 {
79 // We have processed this
80 if (_cache[i]->_image_id < 0)
81 continue;
82 found = true;
83 if (cur_id < 0)
84 cur_id = _cache[i]->_image_id;
85 if (_cache[i]->_image_id == cur_id)
86 {
87 if (!_cache[i]->_with_border)
88 {
89 Vertex *data = _cache[i]->MakeData();
90 sorted.Add(data[0]);
91 sorted.Add(data[1]);
92 sorted.Add(data[2]);
93 sorted.Add(data[3]);
94 sorted.Add(data[4]);
95 sorted.Add(data[5]);
96 _cache[i]->_image_id = -_cache[i]->_image_id - 1;
97 num++;
98 }
99 else
100 {
101 Vertex *data = _cache[i]->MakeDataBorder();
102 int last_len = sorted.Length();
103 sorted.Allocate(last_len + 6 * 9);
104 CopyMemory(&sorted[last_len], data, sizeof(Vertex) * 6 * 9);
105 _cache[i]->_image_id = -_cache[i]->_image_id - 1;
106 num += 9;
107 }
108 }
109 }
110 if (num > 0)
111 {
112 GroupDesc gd = {num, cur_id};
113 groups.Add(gd);
114 }
115 }
116
117 // Restore ids
118 for (int i = 0; i < _cache.Length(); i++)
119 _cache[i]->_image_id = -_cache[i]->_image_id - 1;
120
121 D3DVertexBufferCache::CacheEntryInfo ce_info;
122 if (!D3DVertexBufferCache::Current()->InitBuffer(d3d, (BYTE *)sorted.Data(),
123 sorted.Length() * sizeof(Vertex), ce_info))
124 {
125 return;
126 }
127 D3DVertexBufferCache::Current()->SelectBufferToDevice(d3d, ce_info.id, sizeof(Vertex));
128
129 HRESULT hr;
130 for (int i = 0, cur = 0; i < groups.Length(); i++)
131 {
132 if (FAILED(hr = D3DImageCache::Current()->SelectImageToDevice(d3d, groups[i].id)))
133 {
134 Log("Failed to select texture: %X", (DWORD)hr);
135 }
136// d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, groups[i].num * 2,
137// &sorted[cur], sizeof(Vertex));
138 d3d->GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, cur, groups[i].num * 2);
139 cur += groups[i].num * 6;
140 }
141
142 DBG("Image cache drawn: %d items, %d groups", _cache.Length(), groups.Length());
143 _cache_enabled = false;
144}
145
146void D3DObjectImage::Draw(D3DDevice *d3d)
147{
148 _dirty = false;
149
150 DBG("Image draw: (%.3f, %.3f, %.3f, %.3f)", _x, _y, _w, _h);
151
152 if (_cache_enabled)
153 {
154 _cache.Add(this);
155 _cache_i = _cache.Length() - 1;
156 return;
157 }
158
159 D3DShaderPack::Current()->SetVDecl(d3d, D3DShaderPack::VDECL_XYUVC);
160 D3DShaderPack::Current()->SetVS(d3d, D3DShaderPack::VS_COPY_UV_COLOR);
161 D3DShaderPack::Current()->SetPS(d3d, D3DShaderPack::PS_TEX_COLOR_FILTER);
162 D3DImageCache::Current()->SelectImageToDevice(d3d, _image_id);
163
164 if (!_with_border)
165 d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, MakeData(), sizeof(Vertex));
166 else
167 d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 18, MakeDataBorder(), sizeof(Vertex));
168}
169
170void D3DObjectImage::Init(FLOAT u, FLOAT v, FLOAT du, FLOAT dv,
171 int image_id, int width, int height, const char *source)
172{
173 _u = u;
174 _v = v;
175 _du = du;
176 _dv = dv;
177 _image_id = image_id;
178 _width = width;
179 _height = height;
180#ifdef __MINGW32__
181 strncpy(_source, source, sizeof(_source) - 1);
182#else
183 strncpy_s(_source, sizeof(_source), source, sizeof(_source) - 1);
184#endif // ! __MINGW32__
185}
186
187void D3DObjectImage::Setup(FLOAT x, FLOAT y, FLOAT w, FLOAT h,
188 int sx, int sy, int sw, int sh)
189{
190 if (!_dirty)
191 {
192 _x = 1.f;
193 _y = -1.f;
194 _w = _h = 0.f;
195 _sx = _sy = 1.f;
196 _sw = _sh = 0.f;
197 }
198
199 if (!_with_border)
200 {
201 _x = x;
202 _y = y;
203 _w = w;
204 _h = h;
205 _sx = FLOAT(sx) / FLOAT(_width);
206 _sy = FLOAT(sy) / FLOAT(_height);
207 _sw = FLOAT(sw) / FLOAT(_width);
208 _sh = FLOAT(sh) / FLOAT(_height);
209 }
210 else
211 {
212 _x = min(_x, x);
213 _y = max(_y, y);
214 _w += w / 3;
215 _h += h / 3;
216 _sx = min(_sx, FLOAT(sx) / FLOAT(_width));
217 _sy = min(_sy, FLOAT(sy) / FLOAT(_height));
218 _sw += FLOAT(sw) / (3.f * FLOAT(_width));
219 _sh += FLOAT(sh) / (3.f * FLOAT(_height));
220 }
221 _dirty = true;
222
223}
224
225void D3DObjectImage::SetupColorFilter(DWORD color)
226{
227 //_color = ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
228 _color = color;
229}
230
231D3DObjectImage::Vertex *D3DObjectImage::MakeData()
232{
233 //FLOAT z = (FLOAT(_cache_i) + 0.5f) / _cache.Length();
234 Vertex data[6] = {
235 {_x, _y, _u + _sx * _du, _v + _sy * _dv, _color},
236 {_x + _w, _y, _u + (_sx + _sw) * _du, _v + _sy * _dv, _color},
237 {_x, _y + _h, _u + _sx * _du, _v + (_sy + _sh) * _dv, _color},
238 {_x, _y + _h, _u + _sx * _du, _v + (_sy + _sh) * _dv, _color},
239 {_x + _w, _y, _u + (_sx + _sw) * _du, _v + _sy * _dv, _color},
240 {_x + _w, _y + _h, _u + (_sx + _sw) * _du, _v + (_sy + _sh) * _dv, _color}};
241 CopyMemory(_data, data, sizeof(data));
242 return _data;
243}
244
245D3DObjectImage::Vertex *D3DObjectImage::MakeDataBorder()
246{
247 //FLOAT z = (FLOAT(_cache_i) + 0.5f) / _cache.Length();
248 if (_border.x + _border.z > _w)
249 _border.x = _border.z = _w / 2;
250 if (_border.y + _border.w < _h)
251 _border.y = _border.w = _h / 2;
252
253 FLOAT ul, ut, ur, ub;
254 ul = _uvborder.x * _du;
255 ut = _uvborder.y * _dv;
256 ur = _uvborder.z * _du;
257 ub = _uvborder.w * _dv;
258 FLOAT bl, bt, br, bb;
259 bl = _border.x;
260 bt = _border.y;
261 br = _border.z;
262 bb = _border.w;
263
264 const FLOAT half_x = 0.5f * _du / FLOAT(_width);
265 const FLOAT half_y = 0.5f * _dv / FLOAT(_height);
266
267 // Diagonal knots
268 Vertex data[4] = {
269 {_x, _y, _u + _sx * _du + half_x, _v + _sy * _dv + half_y, _color},
270 {_x + bl, _y + bt, _u + ul + _sx * _du, _v + ut + _sy * _dv, _color},
271 {_x + _w - br, _y + _h - bb, _u - ur + (_sx + _sw) * _du, _v - ub + (_sy + _sh) * _dv, _color},
272 {_x + _w, _y + _h, _u + (_sx + _sw) * _du - half_x, _v + (_sy + _sh) * _dv - half_y, _color}};
273
274 static const int yshift[6] = {0, 0, 1, 1, 0, 1};
275 static const int xshift[6] = {0, 1, 0, 0, 1, 1};
276
277 int vi = 0;
278 for (int i = 0; i < 3; i++)
279 {
280 for (int j = 0; j < 3; j++)
281 {
282 for (int v = 0; v < 6; v++)
283 {
284 _data[vi].x = data[xshift[v] + j].x;
285 _data[vi].y = data[yshift[v] + i].y;
286 _data[vi].u = data[xshift[v] + j].u;
287 _data[vi].v = data[yshift[v] + i].v;
288 _data[vi].col = data[0].col;
289 vi++;
290 }
291 }
292 }
293
294 return _data;
295}
296
297void D3DObjectImage::SetupBorder(const D3DXVECTOR4 &world_border, const D3DXVECTOR4 &pix_border)
298{
299 _border = world_border;
300 _uvborder = pix_border;
301 _with_border = (_border.x > 0.0001f || _border.y > 0.0001f ||
302 _border.z > 0.0001f || _border.w > 0.0001f);
303}
304
305bool D3DObjectImage::UpdateImageData(DWORD *image_data)
306{
307 D3DImageCache::CacheEntryInfo info = {_image_id, _width, _height, _u, _v, _du, _dv};
308 _image_data_updated = false;
309 return D3DImageCache::Current()->UpdateImageData(info, image_data);
310}
311
312DWORD *D3DObjectImage::GetImageData()
313{
314 if (_image_data_updated)
315 return _image_data.Data();
316 _image_data_updated = true;
317 D3DImageCache::CacheEntryInfo info = {_image_id, _width, _height, _u, _v, _du, _dv};
318 D3DImageCache::Current()->GetImageData(info, _image_data);
319 return _image_data.Data();
320}