You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-11 13:10:58 +00:00
[DisplayServer] Implement screen_get_image method for LinuxBSD/X11, macOS and Windows.
This commit is contained in:
@@ -643,15 +643,87 @@ Color DisplayServerWindows::screen_get_pixel(const Point2i &p_position) const {
|
||||
win81p_LogicalToPhysicalPointForPerMonitorDPI(0, &p);
|
||||
}
|
||||
HDC dc = GetDC(0);
|
||||
COLORREF col = GetPixel(dc, p.x, p.y);
|
||||
if (col != CLR_INVALID) {
|
||||
return Color(float(col & 0x000000FF) / 256.0, float((col & 0x0000FF00) >> 8) / 256.0, float((col & 0x00FF0000) >> 16) / 256.0, 1.0);
|
||||
if (dc) {
|
||||
COLORREF col = GetPixel(dc, p.x, p.y);
|
||||
if (col != CLR_INVALID) {
|
||||
ReleaseDC(NULL, dc);
|
||||
return Color(float(col & 0x000000FF) / 256.0, float((col & 0x0000FF00) >> 8) / 256.0, float((col & 0x00FF0000) >> 16) / 256.0, 1.0);
|
||||
}
|
||||
ReleaseDC(NULL, dc);
|
||||
}
|
||||
ReleaseDC(NULL, dc);
|
||||
|
||||
return Color();
|
||||
}
|
||||
|
||||
Ref<Image> DisplayServerWindows::screen_get_image(int p_screen) const {
|
||||
ERR_FAIL_INDEX_V(p_screen, get_screen_count(), Ref<Image>());
|
||||
|
||||
switch (p_screen) {
|
||||
case SCREEN_PRIMARY: {
|
||||
p_screen = get_primary_screen();
|
||||
} break;
|
||||
case SCREEN_OF_MAIN_WINDOW: {
|
||||
p_screen = window_get_current_screen(MAIN_WINDOW_ID);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Point2i pos = screen_get_position(p_screen) + _get_screens_origin();
|
||||
Size2i size = screen_get_size(p_screen);
|
||||
|
||||
POINT p1;
|
||||
p1.x = pos.x;
|
||||
p1.y = pos.y;
|
||||
|
||||
POINT p2;
|
||||
p2.x = pos.x + size.x;
|
||||
p2.y = pos.y + size.y;
|
||||
if (win81p_LogicalToPhysicalPointForPerMonitorDPI) {
|
||||
win81p_LogicalToPhysicalPointForPerMonitorDPI(0, &p1);
|
||||
win81p_LogicalToPhysicalPointForPerMonitorDPI(0, &p2);
|
||||
}
|
||||
|
||||
Ref<Image> img;
|
||||
HDC dc = GetDC(0);
|
||||
if (dc) {
|
||||
HDC hdc = CreateCompatibleDC(dc);
|
||||
int width = p2.x - p1.x;
|
||||
int height = p2.y - p1.y;
|
||||
if (hdc) {
|
||||
HBITMAP hbm = CreateCompatibleBitmap(dc, width, height);
|
||||
if (hbm) {
|
||||
SelectObject(hdc, hbm);
|
||||
BitBlt(hdc, 0, 0, width, height, dc, p1.x, p1.y, SRCCOPY);
|
||||
|
||||
BITMAPINFO bmp_info = { 0 };
|
||||
bmp_info.bmiHeader.biSize = sizeof(bmp_info.bmiHeader);
|
||||
bmp_info.bmiHeader.biWidth = width;
|
||||
bmp_info.bmiHeader.biHeight = -height;
|
||||
bmp_info.bmiHeader.biPlanes = 1;
|
||||
bmp_info.bmiHeader.biBitCount = 32;
|
||||
bmp_info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
Vector<uint8_t> img_data;
|
||||
img_data.resize(width * height * 4);
|
||||
GetDIBits(hdc, hbm, 0, height, img_data.ptrw(), &bmp_info, DIB_RGB_COLORS);
|
||||
|
||||
uint8_t *wr = (uint8_t *)img_data.ptrw();
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
SWAP(wr[i * 4 + 0], wr[i * 4 + 2]);
|
||||
}
|
||||
img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, img_data);
|
||||
|
||||
DeleteObject(hbm);
|
||||
}
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
ReleaseDC(NULL, dc);
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
float DisplayServerWindows::screen_get_refresh_rate(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user