I've pushed an update to the Addons plugin for Ashita v3 which enables addons to directly access the Direct3D device(s). This allows addons to directly interact with the graphics device giving them much more power to render custom things. (ie. the Minimap plugin could be done fully in an addon now.)
Here is a quick example of what this looks like in use:

And the addon to do it:
- _addon.author = 'atom0s';
- _addon.version = '1.0';
- _addon.name = 'test';
- require 'common';
- require 'd3d8';
- local rot_x = 0;
- local rot_y = 0;
- local MOOGLEVERTEX = 0x102; -- (D3DFVF_XYZ | D3DFVF_TEX1)
- local MOOGLEVERTEX_SIZE = 0x24; -- (sizeof(vertices) / sizeof(t_MoogleVertex)) = (720 / 20)
- local MOOGLEVERTEX_TOTAL= 0x2D0; -- MOOGLEVERTEX_SIZE * sizeof(t_MoogleVertex)) = (36 * 20)
- local vertices =
- {
- { -1.0, -1.0, -1.0, 0.0, 1.0 }, -- Front face
- { -1.0, 1.0, -1.0, 0.0, 0.0 },
- { 1.0, 1.0, -1.0, 1.0, 0.0 },
- { 1.0, 1.0, -1.0, 1.0, 0.0 },
- { 1.0, -1.0, -1.0, 1.0, 1.0 },
- { -1.0, -1.0, -1.0, 0.0, 1.0 },
- { 1.0, -1.0, 1.0, 0.0, 1.0 }, -- Back face
- { 1.0, 1.0, 1.0, 0.0, 0.0 },
- { -1.0, 1.0, 1.0, 1.0, 0.0 },
- { -1.0, 1.0, 1.0, 1.0, 0.0 },
- { -1.0, -1.0, 1.0, 1.0, 1.0 },
- { 1.0, -1.0, 1.0, 0.0, 1.0 },
- { -1.0, 1.0, -1.0, 0.0, 1.0 }, -- Top face
- { -1.0, 1.0, 1.0, 0.0, 0.0 },
- { 1.0, 1.0, 1.0, 1.0, 0.0 },
- { 1.0, 1.0, 1.0, 1.0, 0.0 },
- { 1.0, 1.0, -1.0, 1.0, 1.0 },
- { -1.0, 1.0, -1.0, 0.0, 1.0 },
- { 1.0, -1.0, -1.0, 0.0, 1.0 }, -- Bottom face
- { 1.0, -1.0, 1.0, 0.0, 0.0 },
- { -1.0, -1.0, 1.0, 1.0, 0.0 },
- { -1.0, -1.0, 1.0, 1.0, 0.0 },
- { -1.0, -1.0, -1.0, 1.0, 1.0 },
- { 1.0, -1.0, -1.0, 0.0, 1.0 },
- { -1.0, -1.0, 1.0, 0.0, 1.0 }, -- Left face
- { -1.0, 1.0, 1.0, 0.0, 0.0 },
- { -1.0, 1.0, -1.0, 1.0, 0.0 },
- { -1.0, 1.0, -1.0, 1.0, 0.0 },
- { -1.0, -1.0, -1.0, 1.0, 1.0 },
- { -1.0, -1.0, 1.0, 0.0, 1.0 },
- { 1.0, -1.0, -1.0, 0.0, 1.0 }, -- Right face
- { 1.0, 1.0, -1.0, 0.0, 0.0 },
- { 1.0, 1.0, 1.0, 1.0, 0.0 },
- { 1.0, 1.0, 1.0, 1.0, 0.0 },
- { 1.0, -1.0, 1.0, 1.0, 1.0 },
- { 1.0, -1.0, -1.0, 0.0, 1.0 },
- };
- -- Load the texture from a local file..
- local hres, moogleTexture = ashita.d3dx.CreateTextureFromFileA(_addon.path .. '\\moogle.bmp');
- if (hres ~= 0) then
- error('Failed to load moogle.bmp into a texture.');
- end
- -- Create the moogle vertex buffer..
- local hres, moogleVertexBuffer = ashita.d3d8dev.CreateVertexBuffer(MOOGLEVERTEX_TOTAL, D3DUSAGE_WRITEONLY, MOOGLEVERTEX, D3DPOOL_MANAGED);
- if (hres ~= 0) then
- error('Failed to create the moogle vertex buffer.');
- end
- -- Lock the vertex buffer for writing..
- local hres, ptr = moogleVertexBuffer:Lock(0, 0, 0);
- if (hres ~= 0) then
- error('Failed to lock the moogle vertex buffer.');
- end
- -- Write the vertices to the vertex buffer..
- for k, v in pairs(vertices) do
- -- Loop the entries data members..
- for kk, vv in pairs(v) do
- -- Write to the vertex buffer pointer..
- -- This vertex buffer is just float data, so we can just write each value directly as a float
- -- and step the pointer as we go..
- ashita.memory.write_float(ptr, vv);
- ptr = ptr + 4;
- end
- end
- -- Unlock the vertex buffer..
- moogleVertexBuffer:Unlock();
- ----------------------------------------------------------------------------------------------------
- -- func: unload
- -- desc: Event called when the addon is being unloaded.
- ----------------------------------------------------------------------------------------------------
- ashita.register_event('unload', function()
- if (moogleTexture ~= nil) then
- moogleTexture:Release();
- end
- if (moogleVertexBuffer ~= nil) then
- moogleVertexBuffer:Release();
- end
- end)
- ----------------------------------------------------------------------------------------------------
- -- func: render
- -- desc: Event called when the addon is being rendered.
- ----------------------------------------------------------------------------------------------------
- ashita.register_event('render', function()
- if (moogleTexture == nil or moogleVertexBuffer == nil) then
- return;
- end
- -- Step the rotations to make the box spin..
- rot_x = rot_x + 0.01;
- rot_y = rot_y + 0.01;
- -- Prepare the render states for our box..
- ashita.d3d8dev.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- ashita.d3d8dev.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- ashita.d3d8dev.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
- ashita.d3d8dev.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- ashita.d3d8dev.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
- ashita.d3d8dev.SetRenderState(D3DRS_LIGHTING, 0);
- ashita.d3d8dev.SetRenderState(D3DRS_ZENABLE, 0);
- ashita.d3d8dev.SetVertexShader(MOOGLEVERTEX);
- ashita.d3d8dev.SetStreamSource(0, moogleVertexBuffer:Get(), 0x14); -- 0x14 = sizeof(t_MoogleVertex)
- ashita.d3d8dev.SetTexture(0, moogleTexture:Get());
- -- Set the world transform..
- local m = ashita.d3dx.MatrixIdentity(D3DXMATRIX());
- local x = ashita.d3dx.MatrixIdentity(D3DXMATRIX());
- local y = ashita.d3dx.MatrixIdentity(D3DXMATRIX());
- x = ashita.d3dx.MatrixRotationX(x, rot_x);
- y = ashita.d3dx.MatrixRotationY(y, rot_y);
- m = ashita.d3dx.MatrixMultiply(m, x, y);
- ashita.d3d8dev.SetTransform(D3DTS_WORLD, m);
- -- Draw the moogle box..
- ashita.d3d8dev.DrawPrimitive(D3DPT_TRIANGLELIST, 0, 0x0C); -- 0x0C = MOOGLEVERTEX_SIZE / 3
- end);
IDirect3DDevice8 can be accessed via: ashita.d3d8dev.
d3dx8 extensions can be accessed via: ashita.d3dx.
More info / docs coming soon for this as we are working on moving some of our site things around and such.
A new Lua lib was added for this as well named 'd3d8.lua'. It holds all of the D3D8 macro definitions from the .h files of the d3d8 sdk for C++. You can use either the direct values or the macro names in Lua as they are seen in the d3d8.lua file.