Решил всё-таки сделать через Direct3D. Не поучается отрисовать полупрозрачный прямоугольник :(
Код:
job_t::job_t() : _fps(30)
{
WNDCLASS wcla = {0, _wnd_proc, 0, 4, GetModuleHandle(0),
LoadIcon(0, IDI_APPLICATION), LoadCursor(0, IDC_ARROW),
/*HBRUSH(COLOR_WINDOW + 1)*/0, 0, L"Window"};
_atom = reinterpret_cast<const wchar_t*>(RegisterClass(&wcla));
_window = CreateWindowEx(0, _atom, L"GDI+ Window", WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, 0, 0);
SetTimer(_window, 101, 1000/_fps, 0);
d3d.reset(Direct3DCreate9(D3D_SDK_VERSION));
co_throw_error(d3d.empty());
D3DPRESENT_PARAMETERS d3params = D3DPRESENT_PARAMETERS();
d3params.BackBufferFormat = D3DFMT_A8R8G8B8;
d3params.Windowed = true;
d3params.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3params.hDeviceWindow = _window;
co_throw_error(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, _window,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3params, d3dev.prepare_storage()));
ShowWindow(_window, SW_SHOW);
}
void job_t::_paint()
{
d3dev->Present(0, 0, 0, 0);
}
void job_t::_render()
{
static area_t
_area1(L"test.jpg", 0., 0.),
_area2(L"test2.jpg", 50., 50.);
d3dev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0 );
co_good(d3dev->BeginScene());
// всякие варианты перепробовал:
// co_throw_error(d3dev->SetRenderState(D3DRS_LIGHTING, false));
// d3dev->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
// d3dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
// d3dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
// d3dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
// d3dev->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
d3dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
// d3dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
// co_throw_error(d3dev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1));
_area1.render();
_area2.render();
co_good(d3dev->EndScene());
}
area_t::area_t(const wchar_t* img, float x, float y)
{
co_throw_error(D3DXCreateTextureFromFile(d3dev.get(), img, _texture.prepare_storage()));
co_throw_error(d3dev->CreateVertexBuffer(sizeof(vertex_t)*6, 0, vertex_fvf,
D3DPOOL_DEFAULT, _vertices.prepare_storage(), 0));
vertex_t* vertex_mem;
co_throw_error(_vertices->Lock(0, sizeof(vertex_t)*6, (void**)&vertex_mem, 0));
static float _tryangles[12] =
{0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 1.0, 0.0, 1.0, 1.0};
static long _colors[6] = {
0xffffffff,0xffffffff,0xff80ffff,
0xffffffff,0x80ffffff,0x00ffffff};
for(unsigned p=0; p<6; ++p,++vertex_mem)
{
vertex_mem->x = x + _tryangles[p*2+0]*640;
vertex_mem->y = y + _tryangles[p*2+1]*480;
vertex_mem->z = 1.;
vertex_mem->rhw = 1.;
vertex_mem->color = _colors[p];
vertex_mem->tu = _tryangles[p*2+0];
vertex_mem->tv = _tryangles[p*2+1];
}
co_throw_error(_vertices->Unlock());
}
void area_t::render()
{
co_good(d3dev->SetTexture(0, _texture.get()));
co_good(d3dev->SetStreamSource(0, _vertices.get(), 0, sizeof(vertex_t)));
co_good(d3dev->SetFVF(vertex_fvf));
co_good(d3dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2));
}
перепробовал всякие игры с настройками блендинга, ну непрозрачное, хоть убейся. Хочу, допустим, сделать прямоугольник с плавным уменьшением прозрачности от края к краю.
Код:
// код для разъяснений в предыдущем куске кода
void co_throw_error(HRESULT hr);
bool co_good(HRESULT hr);
void log_message(const wstring&);
wstring wstr(const string&);
//---------------------------------------------------------------------------
template<class Interface>
class co_deleter
{
public:
~co_deleter()
{
reset(0);
}
co_deleter(Interface* ptr=0) throw() : _ptr(ptr)
{
}
co_deleter(const co_deleter& deleter) throw() : _ptr(co_deleter._ptr)
{
if (_ptr) _ptr->AddRef();
}
void reset(Interface* ptr) throw()
{
if(_ptr) _ptr->Release();
_ptr = ptr;
}
Interface** prepare_storage()
{
reset(0);
return &_ptr;
}
bool empty() throw()
{
return _ptr==0;
}
Interface* get() throw()
{
return _ptr;
}
Interface* operator->() throw()
{
return _ptr;
}
private:
Interface* _ptr;
};
//---------------------------------------------------------------------------
class area_t
{
public:
enum {
vertex_fvf = D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1,
vertex_triangles = 2,
vertex_count = 3*vertex_triangles
};
struct vertex_t
{
float x, y, z, rhw;
unsigned color;
float tu, tv;
};
area_t(const wchar_t* img, float x, float y);
void render();
private:
co_deleter<IDirect3DVertexBuffer9> _vertices;
co_deleter<IDirect3DTexture9> _texture;
};
class job_t
{
public:
// ~job_t();
job_t();
void operator()();
private:
const wchar_t* _atom;
HWND _window;
unsigned _fps;
void _render();
void _paint();
void _init_vertex_buffer();
static long __stdcall _wnd_proc(HWND hwnd, unsigned code, unsigned wparam, long lparam);
};
|