mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
6.4 KiB
270 lines
6.4 KiB
#if defined(WIN32) || defined(_WIN32) |
|
# define WIN32_LEAN_AND_MEAN |
|
# include <windows.h> |
|
#elif defined(__linux__) |
|
# include <X11/X.h> |
|
# include <X11/Xlib.h> |
|
# include <X11/Xutil.h> |
|
#endif |
|
|
|
#include <string> |
|
|
|
#include <GL/gl.h> |
|
#if defined(WIN32) || defined(_WIN32) |
|
# include <GL/glu.h> |
|
#elif defined(__linux__) |
|
# include <GL/glx.h> |
|
#endif |
|
|
|
#if defined(WIN32) || defined(_WIN32) |
|
# define WINCLASS "WinAppWnd" |
|
#endif |
|
|
|
#define SAFE_RELEASE(p) if (p) { p->Release(); p = NULL; } |
|
|
|
class Timer |
|
{ |
|
public: |
|
enum UNITS |
|
{ |
|
USEC = 0, |
|
MSEC, |
|
SEC |
|
}; |
|
|
|
Timer() : m_t0(0), m_diff(0) |
|
{ |
|
m_tick_frequency = (float)cv::getTickFrequency(); |
|
|
|
m_unit_mul[USEC] = 1000000; |
|
m_unit_mul[MSEC] = 1000; |
|
m_unit_mul[SEC] = 1; |
|
} |
|
|
|
void clear() |
|
{ |
|
m_t0 = m_diff = 0; |
|
} |
|
|
|
void start() |
|
{ |
|
m_t0 = cv::getTickCount(); |
|
} |
|
|
|
void stop() |
|
{ |
|
m_diff = cv::getTickCount() - m_t0; |
|
} |
|
|
|
float time(UNITS u = MSEC) |
|
{ |
|
float sec = m_diff / m_tick_frequency; |
|
|
|
return sec * m_unit_mul[u]; |
|
} |
|
|
|
public: |
|
float m_tick_frequency; |
|
int64 m_t0; |
|
int64 m_diff; |
|
int m_unit_mul[3]; |
|
}; |
|
|
|
class WinApp |
|
{ |
|
public: |
|
WinApp(int width, int height, std::string& window_name) |
|
{ |
|
m_width = width; |
|
m_height = height; |
|
m_window_name = window_name; |
|
#if defined(WIN32) || defined(_WIN32) |
|
m_hInstance = ::GetModuleHandle(NULL); |
|
#endif |
|
} |
|
|
|
virtual ~WinApp() |
|
{ |
|
#if defined(WIN32) || defined(_WIN32) |
|
::UnregisterClass(WINCLASS, m_hInstance); |
|
#endif |
|
} |
|
|
|
int create() |
|
{ |
|
#if defined(WIN32) || defined(_WIN32) |
|
WNDCLASSEX wcex; |
|
|
|
wcex.cbSize = sizeof(WNDCLASSEX); |
|
wcex.style = CS_HREDRAW | CS_VREDRAW; |
|
wcex.lpfnWndProc = &WinApp::StaticWndProc; |
|
wcex.cbClsExtra = 0; |
|
wcex.cbWndExtra = 0; |
|
wcex.hInstance = m_hInstance; |
|
wcex.hIcon = LoadIcon(0, IDI_APPLICATION); |
|
wcex.hCursor = LoadCursor(0, IDC_ARROW); |
|
wcex.hbrBackground = 0; |
|
wcex.lpszMenuName = 0L; |
|
wcex.lpszClassName = WINCLASS; |
|
wcex.hIconSm = 0; |
|
|
|
ATOM wc = ::RegisterClassEx(&wcex); |
|
|
|
RECT rc = { 0, 0, m_width, m_height }; |
|
::AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false); |
|
|
|
m_hWnd = ::CreateWindow( |
|
(LPCTSTR)wc, m_window_name.c_str(), |
|
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, |
|
rc.right - rc.left, rc.bottom - rc.top, |
|
NULL, NULL, m_hInstance, (void*)this); |
|
|
|
if (!m_hWnd) |
|
return -1; |
|
|
|
::ShowWindow(m_hWnd, SW_SHOW); |
|
::UpdateWindow(m_hWnd); |
|
::SetFocus(m_hWnd); |
|
#elif defined(__linux__) |
|
m_display = XOpenDisplay(NULL); |
|
|
|
if (m_display == NULL) |
|
{ |
|
return -1; |
|
} |
|
|
|
m_WM_DELETE_WINDOW = XInternAtom(m_display, "WM_DELETE_WINDOW", False); |
|
|
|
static GLint visual_attributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; |
|
m_visual_info = glXChooseVisual(m_display, 0, visual_attributes); |
|
|
|
if (m_visual_info == NULL) |
|
{ |
|
XCloseDisplay(m_display); |
|
return -2; |
|
} |
|
|
|
Window root = DefaultRootWindow(m_display); |
|
|
|
m_event_mask = ExposureMask | KeyPressMask; |
|
|
|
XSetWindowAttributes window_attributes; |
|
window_attributes.colormap = XCreateColormap(m_display, root, m_visual_info->visual, AllocNone); |
|
window_attributes.event_mask = m_event_mask; |
|
|
|
m_window = XCreateWindow( |
|
m_display, root, 0, 0, m_width, m_height, 0, m_visual_info->depth, |
|
InputOutput, m_visual_info->visual, CWColormap | CWEventMask, &window_attributes); |
|
|
|
XMapWindow(m_display, m_window); |
|
XSetWMProtocols(m_display, m_window, &m_WM_DELETE_WINDOW, 1); |
|
XStoreName(m_display, m_window, m_window_name.c_str()); |
|
#endif |
|
|
|
return init(); |
|
} |
|
|
|
virtual void cleanup() |
|
{ |
|
#if defined(WIN32) || defined(_WIN32) |
|
::DestroyWindow(m_hWnd); |
|
#elif defined(__linux__) |
|
XDestroyWindow(m_display, m_window); |
|
XCloseDisplay(m_display); |
|
#endif |
|
} |
|
|
|
#if defined(WIN32) || defined(_WIN32) |
|
virtual LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) = 0; |
|
#endif |
|
|
|
int run() |
|
{ |
|
#if defined(WIN32) || defined(_WIN32) |
|
MSG msg; |
|
|
|
::ZeroMemory(&msg, sizeof(msg)); |
|
|
|
while (msg.message != WM_QUIT) |
|
{ |
|
if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) |
|
{ |
|
::TranslateMessage(&msg); |
|
::DispatchMessage(&msg); |
|
} |
|
else |
|
{ |
|
idle(); |
|
} |
|
} |
|
|
|
return static_cast<int>(msg.wParam); |
|
#elif defined(__linux__) |
|
m_end_loop = false; |
|
|
|
do { |
|
XEvent e; |
|
|
|
if (!XCheckWindowEvent(m_display, m_window, m_event_mask, &e) || !handle_event(e)) |
|
{ |
|
idle(); |
|
} |
|
} while (!m_end_loop); |
|
|
|
return 0; |
|
#endif |
|
} |
|
|
|
protected: |
|
|
|
#if defined(WIN32) || defined(_WIN32) |
|
static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
|
{ |
|
WinApp* pWnd; |
|
|
|
if (message == WM_NCCREATE) |
|
{ |
|
LPCREATESTRUCT pCreateStruct = ((LPCREATESTRUCT)lParam); |
|
pWnd = (WinApp*)(pCreateStruct->lpCreateParams); |
|
::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pWnd); |
|
} |
|
|
|
pWnd = GetObjectFromWindow(hWnd); |
|
|
|
if (pWnd) |
|
return pWnd->WndProc(hWnd, message, wParam, lParam); |
|
else |
|
return ::DefWindowProc(hWnd, message, wParam, lParam); |
|
} |
|
|
|
inline static WinApp* GetObjectFromWindow(HWND hWnd) |
|
{ |
|
return (WinApp*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); |
|
} |
|
#endif |
|
|
|
#if defined(__linux__) |
|
virtual int handle_event(XEvent& e) = 0; |
|
#endif |
|
|
|
virtual int init() = 0; |
|
virtual int render() = 0; |
|
|
|
virtual void idle() = 0; |
|
|
|
#if defined(WIN32) || defined(_WIN32) |
|
HINSTANCE m_hInstance; |
|
HWND m_hWnd; |
|
#elif defined(__linux__) |
|
Display* m_display; |
|
XVisualInfo* m_visual_info; |
|
Window m_window; |
|
long m_event_mask; |
|
Atom m_WM_DELETE_WINDOW; |
|
bool m_end_loop; |
|
#endif |
|
int m_width; |
|
int m_height; |
|
std::string m_window_name; |
|
Timer m_timer; |
|
};
|
|
|