From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: 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. --- .../direct3d/evas_direct3d_object_image.cpp | 320 +++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp (limited to 'libraries/evas/src/modules/engines/direct3d/evas_direct3d_object_image.cpp') 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 @@ +//#define ENABLE_LOG_PRINTF + +#include + +#include + +#include "evas_direct3d_object_image.h" +#include "evas_direct3d_image_cache.h" +#include "evas_direct3d_device.h" +#include "evas_direct3d_shader_pack.h" +#include "evas_direct3d_vertex_buffer_cache.h" + +TArray D3DObjectImage::_cache; +bool D3DObjectImage::_cache_enabled = false; + +D3DObjectImage::D3DObjectImage() +{ + _x = _y = _w = _h = 0; + _sx = _sy = _sw = _sh = 0; + _u = _v = _du = _dv = 0; + _image_id = -1; + _width = _height = 0; + _source[0] = 0; + _color = 0xffffffff; + _cache_i = 0; + _border = D3DXVECTOR4(0, 0, 0, 0); + _uvborder = D3DXVECTOR4(0, 0, 0, 0); + _with_border = false; + _dirty = false; + _image_data_updated = false; +} + +D3DObjectImage::~D3DObjectImage() +{ + D3DImageCache::Current()->RemoveImageUser(_image_id); +} + +void D3DObjectImage::CopyTo(D3DObjectImage *image) +{ + assert(image != NULL); + image->_u = _u; + image->_v = _v; + image->_du = _du; + image->_dv = _dv; + image->_image_id = _image_id; + image->_width = _width; + image->_height = _height; + CopyMemory(image->_source, _source, sizeof(_source)); + D3DImageCache::Current()->AddImageUser(image->_image_id); +} + +void D3DObjectImage::BeginCache() +{ + _cache.Allocate(0); + _cache_enabled = true; +} + +void D3DObjectImage::EndCache(D3DDevice *d3d) +{ + if (!_cache_enabled || _cache.Length() == 0) + return; + D3DShaderPack::Current()->SetVDecl(d3d, D3DShaderPack::VDECL_XYUVC); + D3DShaderPack::Current()->SetVS(d3d, D3DShaderPack::VS_COPY_UV_COLOR); + D3DShaderPack::Current()->SetPS(d3d, D3DShaderPack::PS_TEX_COLOR_FILTER); + + static TArray sorted; + static TArray groups; + sorted.Allocate(0); + groups.Allocate(0); + + bool found = true; + while (found) + { + found = false; + int cur_id = -1; + int num = 0; + for (int i = 0; i < _cache.Length(); i++) + { + // We have processed this + if (_cache[i]->_image_id < 0) + continue; + found = true; + if (cur_id < 0) + cur_id = _cache[i]->_image_id; + if (_cache[i]->_image_id == cur_id) + { + if (!_cache[i]->_with_border) + { + Vertex *data = _cache[i]->MakeData(); + sorted.Add(data[0]); + sorted.Add(data[1]); + sorted.Add(data[2]); + sorted.Add(data[3]); + sorted.Add(data[4]); + sorted.Add(data[5]); + _cache[i]->_image_id = -_cache[i]->_image_id - 1; + num++; + } + else + { + Vertex *data = _cache[i]->MakeDataBorder(); + int last_len = sorted.Length(); + sorted.Allocate(last_len + 6 * 9); + CopyMemory(&sorted[last_len], data, sizeof(Vertex) * 6 * 9); + _cache[i]->_image_id = -_cache[i]->_image_id - 1; + num += 9; + } + } + } + if (num > 0) + { + GroupDesc gd = {num, cur_id}; + groups.Add(gd); + } + } + + // Restore ids + for (int i = 0; i < _cache.Length(); i++) + _cache[i]->_image_id = -_cache[i]->_image_id - 1; + + D3DVertexBufferCache::CacheEntryInfo ce_info; + if (!D3DVertexBufferCache::Current()->InitBuffer(d3d, (BYTE *)sorted.Data(), + sorted.Length() * sizeof(Vertex), ce_info)) + { + return; + } + D3DVertexBufferCache::Current()->SelectBufferToDevice(d3d, ce_info.id, sizeof(Vertex)); + + HRESULT hr; + for (int i = 0, cur = 0; i < groups.Length(); i++) + { + if (FAILED(hr = D3DImageCache::Current()->SelectImageToDevice(d3d, groups[i].id))) + { + Log("Failed to select texture: %X", (DWORD)hr); + } +// d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, groups[i].num * 2, +// &sorted[cur], sizeof(Vertex)); + d3d->GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, cur, groups[i].num * 2); + cur += groups[i].num * 6; + } + + DBG("Image cache drawn: %d items, %d groups", _cache.Length(), groups.Length()); + _cache_enabled = false; +} + +void D3DObjectImage::Draw(D3DDevice *d3d) +{ + _dirty = false; + + DBG("Image draw: (%.3f, %.3f, %.3f, %.3f)", _x, _y, _w, _h); + + if (_cache_enabled) + { + _cache.Add(this); + _cache_i = _cache.Length() - 1; + return; + } + + D3DShaderPack::Current()->SetVDecl(d3d, D3DShaderPack::VDECL_XYUVC); + D3DShaderPack::Current()->SetVS(d3d, D3DShaderPack::VS_COPY_UV_COLOR); + D3DShaderPack::Current()->SetPS(d3d, D3DShaderPack::PS_TEX_COLOR_FILTER); + D3DImageCache::Current()->SelectImageToDevice(d3d, _image_id); + + if (!_with_border) + d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, MakeData(), sizeof(Vertex)); + else + d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 18, MakeDataBorder(), sizeof(Vertex)); +} + +void D3DObjectImage::Init(FLOAT u, FLOAT v, FLOAT du, FLOAT dv, + int image_id, int width, int height, const char *source) +{ + _u = u; + _v = v; + _du = du; + _dv = dv; + _image_id = image_id; + _width = width; + _height = height; +#ifdef __MINGW32__ + strncpy(_source, source, sizeof(_source) - 1); +#else + strncpy_s(_source, sizeof(_source), source, sizeof(_source) - 1); +#endif // ! __MINGW32__ +} + +void D3DObjectImage::Setup(FLOAT x, FLOAT y, FLOAT w, FLOAT h, + int sx, int sy, int sw, int sh) +{ + if (!_dirty) + { + _x = 1.f; + _y = -1.f; + _w = _h = 0.f; + _sx = _sy = 1.f; + _sw = _sh = 0.f; + } + + if (!_with_border) + { + _x = x; + _y = y; + _w = w; + _h = h; + _sx = FLOAT(sx) / FLOAT(_width); + _sy = FLOAT(sy) / FLOAT(_height); + _sw = FLOAT(sw) / FLOAT(_width); + _sh = FLOAT(sh) / FLOAT(_height); + } + else + { + _x = min(_x, x); + _y = max(_y, y); + _w += w / 3; + _h += h / 3; + _sx = min(_sx, FLOAT(sx) / FLOAT(_width)); + _sy = min(_sy, FLOAT(sy) / FLOAT(_height)); + _sw += FLOAT(sw) / (3.f * FLOAT(_width)); + _sh += FLOAT(sh) / (3.f * FLOAT(_height)); + } + _dirty = true; + +} + +void D3DObjectImage::SetupColorFilter(DWORD color) +{ + //_color = ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); + _color = color; +} + +D3DObjectImage::Vertex *D3DObjectImage::MakeData() +{ + //FLOAT z = (FLOAT(_cache_i) + 0.5f) / _cache.Length(); + Vertex data[6] = { + {_x, _y, _u + _sx * _du, _v + _sy * _dv, _color}, + {_x + _w, _y, _u + (_sx + _sw) * _du, _v + _sy * _dv, _color}, + {_x, _y + _h, _u + _sx * _du, _v + (_sy + _sh) * _dv, _color}, + {_x, _y + _h, _u + _sx * _du, _v + (_sy + _sh) * _dv, _color}, + {_x + _w, _y, _u + (_sx + _sw) * _du, _v + _sy * _dv, _color}, + {_x + _w, _y + _h, _u + (_sx + _sw) * _du, _v + (_sy + _sh) * _dv, _color}}; + CopyMemory(_data, data, sizeof(data)); + return _data; +} + +D3DObjectImage::Vertex *D3DObjectImage::MakeDataBorder() +{ + //FLOAT z = (FLOAT(_cache_i) + 0.5f) / _cache.Length(); + if (_border.x + _border.z > _w) + _border.x = _border.z = _w / 2; + if (_border.y + _border.w < _h) + _border.y = _border.w = _h / 2; + + FLOAT ul, ut, ur, ub; + ul = _uvborder.x * _du; + ut = _uvborder.y * _dv; + ur = _uvborder.z * _du; + ub = _uvborder.w * _dv; + FLOAT bl, bt, br, bb; + bl = _border.x; + bt = _border.y; + br = _border.z; + bb = _border.w; + + const FLOAT half_x = 0.5f * _du / FLOAT(_width); + const FLOAT half_y = 0.5f * _dv / FLOAT(_height); + + // Diagonal knots + Vertex data[4] = { + {_x, _y, _u + _sx * _du + half_x, _v + _sy * _dv + half_y, _color}, + {_x + bl, _y + bt, _u + ul + _sx * _du, _v + ut + _sy * _dv, _color}, + {_x + _w - br, _y + _h - bb, _u - ur + (_sx + _sw) * _du, _v - ub + (_sy + _sh) * _dv, _color}, + {_x + _w, _y + _h, _u + (_sx + _sw) * _du - half_x, _v + (_sy + _sh) * _dv - half_y, _color}}; + + static const int yshift[6] = {0, 0, 1, 1, 0, 1}; + static const int xshift[6] = {0, 1, 0, 0, 1, 1}; + + int vi = 0; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + for (int v = 0; v < 6; v++) + { + _data[vi].x = data[xshift[v] + j].x; + _data[vi].y = data[yshift[v] + i].y; + _data[vi].u = data[xshift[v] + j].u; + _data[vi].v = data[yshift[v] + i].v; + _data[vi].col = data[0].col; + vi++; + } + } + } + + return _data; +} + +void D3DObjectImage::SetupBorder(const D3DXVECTOR4 &world_border, const D3DXVECTOR4 &pix_border) +{ + _border = world_border; + _uvborder = pix_border; + _with_border = (_border.x > 0.0001f || _border.y > 0.0001f || + _border.z > 0.0001f || _border.w > 0.0001f); +} + +bool D3DObjectImage::UpdateImageData(DWORD *image_data) +{ + D3DImageCache::CacheEntryInfo info = {_image_id, _width, _height, _u, _v, _du, _dv}; + _image_data_updated = false; + return D3DImageCache::Current()->UpdateImageData(info, image_data); +} + +DWORD *D3DObjectImage::GetImageData() +{ + if (_image_data_updated) + return _image_data.Data(); + _image_data_updated = true; + D3DImageCache::CacheEntryInfo info = {_image_id, _width, _height, _u, _v, _du, _dv}; + D3DImageCache::Current()->GetImageData(info, _image_data); + return _image_data.Data(); +} -- cgit v1.1