Subversion Repositories seema-scanner

Rev

Blame | Last modification | View Log | RSS feed

#include "OpenGLContext.h"

#include <windows.h>
#include <winuser.h>
#include <tchar.h>
#include <ShObjIdl.h>
#include <GL/gl.h>

#include <stdio.h>

BOOL CALLBACK monitorEnumerator(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData){

    MONITORINFOEX monitorInfo;
    ZeroMemory(&monitorInfo, sizeof(MONITORINFOEX));
    monitorInfo.cbSize = sizeof(MONITORINFOEX);

    GetMonitorInfo(hMonitor, &monitorInfo);

    ScreenInfo screen;
    char deviceName[32];
    wcstombs((char *)deviceName, (wchar_t*)monitorInfo.szDevice, 32);
    screen.name = std::string(deviceName);

    RECT rect = monitorInfo.rcMonitor;
    screen.resX = rect.right - rect.left;
    screen.resY = rect.bottom - rect.top;

    screen.posX = rect.left;
    screen.posY = rect.top;

    std::vector<ScreenInfo> *ret = reinterpret_cast<std::vector<ScreenInfo>*>(dwData);
    ret->push_back(screen);

    return true;
}


std::vector<ScreenInfo> OpenGLContext::GetScreenInfo(){

    std::vector<ScreenInfo> ret;

    EnumDisplayMonitors(NULL, NULL, monitorEnumerator, (LPARAM)&ret);


//    DISPLAY_DEVICE dd;
//    ZeroMemory(&dd, sizeof(DISPLAY_DEVICE));
//    dd.cb = sizeof(dd);

//    for(int i=0; EnumDisplayDevices(NULL, i, &dd, 0); i++){

//        if ((dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) || !(dd.StateFlags & DISPLAY_DEVICE_ACTIVE))
//            continue;

//        // Get additional info
//        DISPLAY_DEVICE display;
//        ZeroMemory(&display, sizeof(DISPLAY_DEVICE));
//        display.cb = sizeof(DISPLAY_DEVICE);

//        EnumDisplayDevices(dd.DeviceName, 0, &display, 0);
//        HDC dc = CreateDC(L"DISPLAY", display.DeviceString, NULL, NULL);

//        ScreenInfo screen;

//        char deviceName[32];
//        wcstombs(deviceName, display.DeviceName, 32);
//        screen.name = std::string(deviceName);

//        screen.resX = GetDeviceCaps(dc, HORZRES);
//        screen.resY = GetDeviceCaps(dc, VERTRES);

//        ret.push_back(screen);


//        DEVMODE settings;
//        ZeroMemory(&settings, sizeof(DEVMODE));
//        settings.dmSize = sizeof(DEVMODE);

//        EnumDisplaySettings(display.DeviceName, ENUM_CURRENT_SETTINGS, &settings);

//        int xpos = settings.dmPosition.x;
//        int ypos = settings.dmPosition.y;

//        DeleteDC(dc);
//    }

    return ret;
}

// Window Function
LONG WINAPI MainWndProc (
    HWND    hWnd,
    UINT    uMsg,
    WPARAM  wParam,
    LPARAM  lParam)
{
    LONG lRet = 1;
    PAINTSTRUCT ps;

    switch (uMsg) {

    case WM_PAINT:
        BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;
    default:
        lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
        break;
    }

    return lRet;
}

struct OpenGLContext::OpenGLContextInfo{
    HDC hdc;     // device OpenGLContext handle
    HGLRC hglrc; // OpenGL rendering OpenGLContext
    HWND hwnd;   // window handle
    HINSTANCE hinstance; // application instance handle

    OpenGLContextInfo() : hdc(NULL), hglrc(NULL), hwnd(NULL){}
};

OpenGLContext::OpenGLContext(unsigned int _screenNum) : screenNum(_screenNum){

    std::vector<ScreenInfo> screenInfo = OpenGLContext::GetScreenInfo();
    screenResX = screenInfo[screenNum].resX;
    screenResY = screenInfo[screenNum].resY;

    // New object for OpenGLContext information
    contextInfo = new OpenGLContextInfo();

    // Create and register window class
    WNDCLASS wndclass;

    wndclass.style = CS_VREDRAW;
    wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = contextInfo->hinstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_NO);
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = L"ProjectorGLClass";
    RegisterClass(&wndclass);

    // create the fullscreen window
    contextInfo->hwnd = CreateWindowEx(WS_EX_TOPMOST,L"ProjectorGLClass", L"Projector",
                                     WS_POPUP|WS_CLIPCHILDREN,
                                     screenInfo[screenNum].posX, screenInfo[screenNum].posY, screenResX, screenResY,
                                     NULL, NULL, contextInfo->hinstance, NULL);

//    contextInfo->hwnd = CreateWindow(L"ProjectorGLClass", L"Projector",
//                                     WS_POPUP|WS_EX_TOOLWINDOW,
//                                     screenInfo[screenNum].posX, screenInfo[screenNum].posY, screenResX, screenResY,
//                                     GetDesktopWindow(), NULL, contextInfo->hinstance, NULL);

    if(!contextInfo->hwnd)
        std::cerr << "Could not create window!" << std::endl;

    //CoTaskbarList list = CoTaskbarList();
    // Get window device OpenGLContext
    if ((contextInfo->hdc = GetDC(contextInfo->hwnd)) == NULL)
        std::cerr << "Could not get window device OpenGLContext!" << std::endl;

    // Select pixel format description
    PIXELFORMATDESCRIPTOR pfd, *ppfd;
    int pixelformat;

    ppfd = &pfd;

    ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
    ppfd->nVersion = 1;
    ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    ppfd->dwLayerMask = PFD_MAIN_PLANE;
    ppfd->iPixelType = PFD_TYPE_COLORINDEX;
    ppfd->cColorBits = 8;
    ppfd->cDepthBits = 16;
    ppfd->cAccumBits = 0;
    ppfd->cStencilBits = 0;

    pixelformat = ChoosePixelFormat(contextInfo->hdc, ppfd);

    if ( (pixelformat = ChoosePixelFormat(contextInfo->hdc, ppfd)) == 0 )
        std::cerr << "Failed to choose pixel format!" << std::endl;

    if (SetPixelFormat(contextInfo->hdc, pixelformat, ppfd) == FALSE)
        std::cerr << "Failed to set pixel format!" << std::endl;

    // Create the OpenGL rendering OpenGLContext
    if ((contextInfo->hglrc = wglCreateContext(contextInfo->hdc)) == NULL)
        std::cerr << "Could not create OpenGL rendering OpenGLContext!" << std::endl;

    // Set swap interval
    //wglSwapIntervalEXT(1);

    // Make OpenGLContext current
    wglMakeCurrent(contextInfo->hdc, contextInfo->hglrc);

    // Show window
    ShowWindow(contextInfo->hwnd, SW_SHOW);
    UpdateWindow(contextInfo->hwnd);

    // Adjust gamma to one
    setGamma(1.0);
}

void OpenGLContext::setGamma(float gamma){
    // Adjust gamma

}

void OpenGLContext::makeContextCurrent(){
    wglMakeCurrent(contextInfo->hdc, contextInfo->hglrc);
}

void OpenGLContext::flush(){
    // Swap buffers
    SwapBuffers(contextInfo->hdc);
    // Synchronize CPU with vsync buffer swap
    glFinish();
}

OpenGLContext::~OpenGLContext(){
    DestroyWindow(contextInfo->hwnd);
    wglMakeCurrent(contextInfo->hdc, NULL);     // release device OpenGLContext in use by rc
    wglDeleteContext(contextInfo->hglrc);       // delete rendering OpenGLContext

    delete contextInfo;
}