// // Window and input event handling // #include #include #include #include "events.h" // #define EVENTS_DEBUG void EventHandler::windowResizeEvent(int width, int height) { if(width<=0 || height<=0) { return; } printf("windowResizeEvnet: %d, %d\n", width, height); glViewport(0, 0, width, height); mCamera.setWindowSize(width, height); m_InteractionMode = (int)MODE_PAN; } SDL_Renderer* EventHandler::GetRenderer() { return m_pRenderer; } void EventHandler::SetInteractionMode(int mode) { m_InteractionMode = mode; } void EventHandler::initWindow(const char* title) { // Create SDL window /* mpWindow = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, mCamera.windowSize().width, mCamera.windowSize().height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE| SDL_WINDOW_SHOWN); */ SDL_CreateWindowAndRenderer(mCamera.windowSize().width, mCamera.windowSize().height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE| SDL_WINDOW_SHOWN, &mpWindow, &m_pRenderer); mWindowID = SDL_GetWindowID(mpWindow); printf("Window Created!!!! Width:%d, Height: %d\n", mCamera.windowSize().width, mCamera.windowSize().height); // Create OpenGLES 2 context on SDL window SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetSwapInterval(1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GLContext glc = SDL_GL_CreateContext(mpWindow); // Set clear color to black glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Initialize viewport windowResizeEvent(mCamera.windowSize().width, mCamera.windowSize().height); m_nEventType = 0; m_fDeltaX = 0; m_fDeltaY = 0; } void EventHandler::swapWindow() { SDL_GL_SwapWindow(mpWindow); } void EventHandler::zoom(float fDelta) { //float zoomDelta = mouseWheelDown ? -cMouseWheelZoomDelta : cMouseWheelZoomDelta; float zoomDelta = 0.0f; if(fDelta>0) { zoomDelta = -cMouseWheelZoomDelta; } else { zoomDelta = cMouseWheelZoomDelta; } mCamera.setZoomDelta(zoomDelta); } void EventHandler::zoomEventMouse(bool mouseWheelDown, int x, int y) { float preZoomWorldX, preZoomWorldY; mCamera.windowToWorldCoords(mMousePositionX, mMousePositionY, preZoomWorldX, preZoomWorldY); // Zoom by scaling up/down in 0.05 increments float zoomDelta = mouseWheelDown ? -cMouseWheelZoomDelta : cMouseWheelZoomDelta; mCamera.setZoomDelta(zoomDelta); // Zoom to point: Keep the world coords under mouse position the same before and after the zoom float postZoomWorldX, postZoomWorldY; mCamera.windowToWorldCoords(mMousePositionX, mMousePositionY, postZoomWorldX, postZoomWorldY); Vec2 deltaWorld = { postZoomWorldX - preZoomWorldX, postZoomWorldY - preZoomWorldY }; mCamera.setPanDelta (deltaWorld); } void EventHandler::zoomEventPinch (float pinchDist, float pinchX, float pinchY) { float preZoomWorldX, preZoomWorldY; mCamera.normWindowToWorldCoords(pinchX, pinchY, preZoomWorldX, preZoomWorldY); // Zoom in/out by positive/negative mPinch distance float zoomDelta = pinchDist * cPinchScale; mCamera.setZoomDelta(zoomDelta); // Zoom to point: Keep the world coords under pinch position the same before and after the zoom float postZoomWorldX, postZoomWorldY; mCamera.normWindowToWorldCoords(pinchX, pinchY, postZoomWorldX, postZoomWorldY); Vec2 deltaWorld = { postZoomWorldX - preZoomWorldX, postZoomWorldY - preZoomWorldY }; mCamera.setPanDelta (deltaWorld); } void EventHandler::SetMouseButtonDownPosition(int x, int y) { mMouseButtonDownX = x; mMouseButtonDownY = y; mMouseButtonDown = true; mCamera.setBasePan(); } void EventHandler::SetMouseButtonUpPosition(int x, int y) { m_nEventType = 3; mMouseButtonDown = false; } void EventHandler::panEventMouse(int x, int y) { m_nEventType = 1; int deltaX = mCamera.windowSize().width / 2 + (x - mMouseButtonDownX), deltaY = mCamera.windowSize().height / 2 + (y - mMouseButtonDownY); if(m_InteractionMode&InteractionMode::MODE_WIDTHLEVEL) { m_fDeltaX = x - mMouseButtonDownX; m_fDeltaY = y - mMouseButtonDownY; return; } float deviceX, deviceY; mCamera.windowToDeviceCoords(deltaX, deltaY, deviceX, deviceY); Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(), mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() }; mCamera.setPan(pan); /* int deltaX = mCamera.windowSize().width / 2 + (x - mMouseButtonDownX), deltaY = mCamera.windowSize().height / 2 + (y - mMouseButtonDownY); m_nEventType = 1; m_fDeltaX = x - mMouseButtonDownX; m_fDeltaY = y - mMouseButtonDownY; return; float deviceX, deviceY; mCamera.windowToDeviceCoords(deltaX, deltaY, deviceX, deviceY); Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(), mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() }; mCamera.setPan(pan); */ } void EventHandler::panEventFinger(float x, float y) { m_nEventType = 2; if(m_InteractionMode&InteractionMode::MODE_WIDTHLEVEL) { int nWidth = mCamera.windowSize().width; int nHeight = mCamera.windowSize().height; m_fDeltaX = (x - mFingerDownX)*nWidth; m_fDeltaY = (y - mFingerDownY)*nHeight; return; } float deltaX = 0.5f + (x - mFingerDownX), deltaY = 0.5f + (y - mFingerDownY); float deviceX, deviceY; mCamera.normWindowToDeviceCoords(deltaX, deltaY, deviceX, deviceY); Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(), mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() }; mCamera.setPan(pan); /* float deltaX = 0.5f + (x - mFingerDownX), deltaY = 0.5f + (y - mFingerDownY); m_nEventType = 2; int nWidth = mCamera.windowSize().width; int nHeight = mCamera.windowSize().height; m_fDeltaX = (x - mFingerDownX)*nWidth; m_fDeltaY = (y - mFingerDownY)*nHeight; return; float deviceX, deviceY; mCamera.normWindowToDeviceCoords(deltaX, deltaY, deviceX, deviceY); Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(), mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() }; mCamera.setPan(pan); */ } int EventHandler::GetEventType() { return m_nEventType; } float EventHandler::GetDeltaX() { return m_fDeltaX; } float EventHandler::GetDeltaY() { return m_fDeltaY; } void EventHandler::processEvents() { // Handle events SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: std::terminate(); break; case SDL_WINDOWEVENT: { if (event.window.windowID == mWindowID && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { int width = event.window.data1, height = event.window.data2; windowResizeEvent(width, height); } break; } case SDL_MOUSEWHEEL: { // SDL_MOUSEWHEEL regression? // m->y no longer reliable (often y is 0 when mouse wheel is spun up or down), use m->preciseY instead SDL_MouseWheelEvent *m = (SDL_MouseWheelEvent*)&event; #ifdef EVENTS_DEBUG printf ("SDL_MOUSEWHEEL= x,y=%d,%d preciseX,preciseY=%f,%f\n", m->x, m->y, m->preciseX, m->preciseY); #endif bool mouseWheelDown = (m->preciseY < 0.0); if(m_InteractionMode&InteractionMode::MODE_SCROLL) { zoomEventMouse(mouseWheelDown, mMousePositionX, mMousePositionY); } break; } case SDL_MOUSEMOTION: { SDL_MouseMotionEvent *m = (SDL_MouseMotionEvent*)&event; mMousePositionX = m->x; mMousePositionY = m->y; if (mMouseButtonDown && !mFingerDown && !mPinch) panEventMouse(mMousePositionX, mMousePositionY); break; } case SDL_MOUSEBUTTONDOWN: { SDL_MouseButtonEvent *m = (SDL_MouseButtonEvent*)&event; if (m->button == SDL_BUTTON_LEFT && !mFingerDown && !mPinch) { mMouseButtonDown = true; mMouseButtonDownX = m->x; mMouseButtonDownY = m->y; mCamera.setBasePan(); } if (m->button == SDL_BUTTON_RIGHT && !mFingerDown && !mPinch) { printf("C++: 오른쪽 마우스 버튼이 눌렸습니다! 좌표: x=%d, y=%d\n", m->x, m->y); //mMouseButtonDown = true; //mMouseButtonDownX = m->x; //mMouseButtonDownY = m->y; //mCamera.setBasePan(); } break; } case SDL_MOUSEBUTTONUP: { SDL_MouseButtonEvent *m = (SDL_MouseButtonEvent*)&event; if (m->button == SDL_BUTTON_LEFT) { mMouseButtonDown = false; m_nEventType = 3; } break; } case SDL_FINGERMOTION: if (mFingerDown) { SDL_TouchFingerEvent *m = (SDL_TouchFingerEvent*)&event; // Finger down and finger moving must match if (m->fingerId == mFingerDownId) panEventFinger(m->x, m->y); } else { } break; case SDL_FINGERDOWN: if (!mPinch) { // Finger already down means multiple fingers, which is handled by multigesture event if (mFingerDown) mFingerDown = false; else { SDL_TouchFingerEvent *m = (SDL_TouchFingerEvent*)&event; mFingerDown = true; mFingerDownX = m->x; mFingerDownY = m->y; mFingerDownId = m->fingerId; mCamera.setBasePan(); } } break; case SDL_MULTIGESTURE: { SDL_MultiGestureEvent *m = (SDL_MultiGestureEvent*)&event; if (m->numFingers == 2 && fabs(m->dDist) >= cPinchZoomThreshold) { mPinch = true; mFingerDown = false; mMouseButtonDown = false; if(m_InteractionMode&InteractionMode::MODE_SCROLL) { zoomEventPinch(m->dDist, m->x, m->y); } } break; } case SDL_FINGERUP: m_nEventType = 4; mFingerDown = false; mPinch = false; break; } #ifdef EVENTS_DEBUG printf ("event=%d mousePos=%d,%d mouseButtonDown=%d fingerDown=%d pinch=%d aspect=%f window=%dx%d\n", event.type, mMousePositionX, mMousePositionY, mMouseButtonDown, mFingerDown, mPinch, mCamera.aspect(), mCamera.windowSize().width, mCamera.windowSize().height); printf (" zoom=%f pan=%f,%f\n", mCamera.zoom(), mCamera.pan()[0], mCamera.pan()[1]); #endif } }