diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
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.cpp | 320 |
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 | |||
13 | TArray<D3DObjectImage *> D3DObjectImage::_cache; | ||
14 | bool D3DObjectImage::_cache_enabled = false; | ||
15 | |||
16 | D3DObjectImage::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 | |||
33 | D3DObjectImage::~D3DObjectImage() | ||
34 | { | ||
35 | D3DImageCache::Current()->RemoveImageUser(_image_id); | ||
36 | } | ||
37 | |||
38 | void 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 | |||
52 | void D3DObjectImage::BeginCache() | ||
53 | { | ||
54 | _cache.Allocate(0); | ||
55 | _cache_enabled = true; | ||
56 | } | ||
57 | |||
58 | void 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 | |||
146 | void 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 | |||
170 | void 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 | |||
187 | void 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 | |||
225 | void D3DObjectImage::SetupColorFilter(DWORD color) | ||
226 | { | ||
227 | //_color = ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); | ||
228 | _color = color; | ||
229 | } | ||
230 | |||
231 | D3DObjectImage::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 | |||
245 | D3DObjectImage::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 | |||
297 | void 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 | |||
305 | bool 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 | |||
312 | DWORD *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 | } | ||