2015-06-20 05:44:05 +00:00
|
|
|
struct VideoGDI : Video {
|
2017-07-24 05:23:40 +00:00
|
|
|
VideoGDI() { initialize(); }
|
|
|
|
~VideoGDI() { terminate(); }
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
auto ready() -> bool { return _ready; }
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
auto context() -> uintptr { return _context; }
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
auto setContext(uintptr context) -> bool {
|
|
|
|
if(_context == context) return true;
|
|
|
|
_context = context;
|
|
|
|
return initialize();
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
auto clear() -> void {
|
|
|
|
if(!ready()) return;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2017-05-30 07:48:41 +00:00
|
|
|
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
|
2017-07-24 05:23:40 +00:00
|
|
|
if(!ready()) return false;
|
|
|
|
|
|
|
|
if(!_buffer || _width != width || _height != height) {
|
|
|
|
if(_buffer) delete[] _buffer;
|
|
|
|
if(_bitmap) DeleteObject(_bitmap);
|
|
|
|
if(_dc) DeleteObject(_dc);
|
|
|
|
|
|
|
|
_buffer = new uint32_t[width * height]();
|
|
|
|
_width = width;
|
|
|
|
_height = height;
|
|
|
|
|
|
|
|
HDC hdc = GetDC((HWND)_context);
|
|
|
|
_dc = CreateCompatibleDC(hdc);
|
|
|
|
_bitmap = CreateCompatibleBitmap(hdc, width, height);
|
|
|
|
SelectObject(_dc, _bitmap);
|
|
|
|
ReleaseDC((HWND)_context, hdc);
|
|
|
|
|
|
|
|
memory::fill(&_info, sizeof(BITMAPINFO));
|
|
|
|
_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
_info.bmiHeader.biWidth = width;
|
|
|
|
_info.bmiHeader.biHeight = -height;
|
|
|
|
_info.bmiHeader.biPlanes = 1;
|
|
|
|
_info.bmiHeader.biBitCount = 32;
|
|
|
|
_info.bmiHeader.biCompression = BI_RGB;
|
|
|
|
_info.bmiHeader.biSizeImage = width * height * sizeof(uint32_t);
|
2017-05-30 07:48:41 +00:00
|
|
|
}
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
pitch = _width * sizeof(uint32_t);
|
|
|
|
return data = _buffer;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
auto unlock() -> void {
|
|
|
|
if(!ready()) return;
|
|
|
|
}
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
auto output() -> void {
|
|
|
|
if(!ready()) return;
|
2010-08-09 13:28:56 +00:00
|
|
|
|
|
|
|
RECT rc;
|
2017-07-24 05:23:40 +00:00
|
|
|
GetClientRect((HWND)_context, &rc);
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
SetDIBits(_dc, _bitmap, 0, _height, (void*)_buffer, &_info, DIB_RGB_COLORS);
|
|
|
|
HDC hdc = GetDC((HWND)_context);
|
|
|
|
StretchBlt(hdc, rc.left, rc.top, rc.right, rc.bottom, _dc, 0, 0, _width, _height, SRCCOPY);
|
|
|
|
ReleaseDC((HWND)_context, hdc);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
private:
|
|
|
|
auto initialize() -> bool {
|
|
|
|
terminate();
|
|
|
|
if(!_context) return false;
|
|
|
|
|
|
|
|
_width = 0;
|
|
|
|
_height = 0;
|
|
|
|
return _ready = true;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2017-07-24 05:23:40 +00:00
|
|
|
auto terminate() -> void {
|
|
|
|
_ready = false;
|
|
|
|
if(_buffer) { delete[] _buffer; _buffer = nullptr; }
|
|
|
|
if(_bitmap) { DeleteObject(_bitmap); _bitmap = nullptr; }
|
|
|
|
if(_dc) { DeleteDC(_dc); _dc = nullptr; }
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
2017-07-24 05:23:40 +00:00
|
|
|
|
|
|
|
bool _ready = false;
|
|
|
|
uintptr _context = 0;
|
|
|
|
|
|
|
|
uint32_t* _buffer = nullptr;
|
|
|
|
uint _width = 0;
|
|
|
|
uint _height = 0;
|
|
|
|
|
|
|
|
HBITMAP _bitmap = nullptr;
|
|
|
|
HDC _dc = nullptr;
|
|
|
|
BITMAPINFO _info = {};
|
2010-08-09 13:28:56 +00:00
|
|
|
};
|