//! called during the update of the entity		
	void PelletManager::Update()
	{
		VertexBuffer* pVB = GetComponent<GraphicComponent>()->GetVertexBuffer();
		pVB->SetNumVertices(0);

		if(m_Bullets.size())
		{
			u32 bulletIndex = 0;
			for(std::list<Bullet*>::iterator it = m_Bullets.begin(); it != m_Bullets.end();)
			{
				Vector3 vClosestEnemy = Vector3::Zero;
				f32 fDistToClosestEnemy = Math::Epsilon;
				if(GetClosestEnemy((*it)->vPosition, vClosestEnemy, fDistToClosestEnemy))
				{
					f32 fDistFactor = m_fMinDistToEnemy/fDistToClosestEnemy;
					f32 fInterpolator = m_fHomingFactor*fDistFactor*fDistFactor*g_fDeltaTime;
					fInterpolator = Math::Clamp(fInterpolator, 0.0f, 1.0f);
					Vector3 vDirectionToEnemy = (vClosestEnemy-(*it)->vPosition).Normalize();
					(*it)->vDirection = (vDirectionToEnemy-(*it)->vDirection)*fInterpolator + (*it)->vDirection;
				}
				
				(*it)->vPosition += (*it)->vDirection*(*it)->fSpeed*g_fDeltaTime;
				SetupRendering((*it), bulletIndex++, pVB);

				(*it)->fLife -= g_fDeltaTime;
				if((*it)->fLife > 0.0f)
				{
					++it;
				}
				else
				{
					m_Pool->Free((*it));
					it = m_Bullets.erase(it);
				}
			}

			pVB->SetDirty(true);
		}
	}
int main(int argc, char* argv[]) {
    // Get an OSVR client context to use to access the devices
    // that we need.
    osvr::clientkit::ClientContext context(
        "com.osvr.renderManager.openGLExample");

    // Construct button devices and connect them to a callback
    // that will set the "quit" variable to true when it is
    // pressed.  Use button "1" on the left-hand or
    // right-hand controller.
    osvr::clientkit::Interface leftButton1 =
        context.getInterface("/controller/left/1");
    leftButton1.registerCallback(&myButtonCallback, &quit);

    osvr::clientkit::Interface rightButton1 =
        context.getInterface("/controller/right/1");
    rightButton1.registerCallback(&myButtonCallback, &quit);

    // Open OpenGL and set up the context for rendering to
    // an HMD.  Do this using the OSVR RenderManager interface,
    // which maps to the nVidia or other vendor direct mode
    // to reduce the latency.
    osvr::renderkit::RenderManager* render =
        osvr::renderkit::createRenderManager(context.get(), "OpenGL");

    if ((render == nullptr) || (!render->doingOkay())) {
        std::cerr << "Could not create RenderManager" << std::endl;
        return 1;
    }

    // Set callback to handle setting up rendering in an eye
    render->SetViewProjectionCallback(SetupEye);

    // Set callback to handle setting up rendering in a display
    render->SetDisplayCallback(SetupDisplay);

    // Register callbacks to render things in left hand, right
    // hand, and world space.
    render->AddRenderCallback("/", DrawWorld);
    render->AddRenderCallback("/me/hands/left", DrawHand);
    render->AddRenderCallback("/me/hands/right", DrawHand);

// Set up a handler to cause us to exit cleanly.
#ifdef _WIN32
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
#endif

    // Open the display and make sure this worked.
    osvr::renderkit::RenderManager::OpenResults ret = render->OpenDisplay();
    if (ret.status == osvr::renderkit::RenderManager::OpenStatus::FAILURE) {
        std::cerr << "Could not open display" << std::endl;
        delete render;
        return 2;
    }
    if (ret.library.OpenGL == nullptr) {
        std::cerr << "Attempted to run an OpenGL program with a config file "
                  << "that specified a different rendering library."
                  << std::endl;
        return 3;
    }

    // Set up the rendering state we need.
    if (!SetupRendering(ret.library)) {
        return 3;
    }

    // Continue rendering until it is time to quit.
    while (!quit) {
        // Update the context so we get our callbacks called and
        // update tracker state.
        context.update();

        if (!render->Render()) {
            std::cerr
                << "Render() returned false, maybe because it was asked to quit"
                << std::endl;
            quit = true;
        }
    }

    // Close the Renderer interface cleanly.
    delete render;

    return 0;
}
int main(int argc, char* argv[]) {
    // Parse the command line
    int delayMilliSeconds = 0;
    int realParams = 0;
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-') {
            Usage(argv[0]);
        } else
            switch (++realParams) {
            case 1:
                delayMilliSeconds = atoi(argv[i]);
                break;
            default:
                Usage(argv[0]);
            }
    }
    if (realParams != 1) {
        Usage(argv[0]);
    }

    // Get an OSVR client context to use to access the devices
    // that we need.
    osvr::clientkit::ClientContext context(
        "com.osvr.renderManager.openGLExample");

    // Construct button devices and connect them to a callback
    // that will set the "quit" variable to true when it is
    // pressed.  Use button "1" on the left-hand or
    // right-hand controller.
    osvr::clientkit::Interface leftButton1 =
        context.getInterface("/controller/left/1");
    leftButton1.registerCallback(&myButtonCallback, &quit);

    osvr::clientkit::Interface rightButton1 =
        context.getInterface("/controller/right/1");
    rightButton1.registerCallback(&myButtonCallback, &quit);

    // Open Direct3D and set up the context for rendering to
    // an HMD.  Do this using the OSVR RenderManager interface,
    // which maps to the nVidia or other vendor direct mode
    // to reduce the latency.
    osvr::renderkit::RenderManager* render =
        osvr::renderkit::createRenderManager(context.get(), "OpenGL");

    if ((render == nullptr) || (!render->doingOkay())) {
        std::cerr << "Could not create RenderManager" << std::endl;
        return 1;
    }

// Set up a handler to cause us to exit cleanly.
#ifdef _WIN32
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
#endif

    // Open the display and make sure this worked.
    osvr::renderkit::RenderManager::OpenResults ret = render->OpenDisplay();
    if (ret.status == osvr::renderkit::RenderManager::OpenStatus::FAILURE) {
        std::cerr << "Could not open display" << std::endl;
        delete render;
        return 2;
    }

    // Set up the rendering state we need.
    if (!SetupRendering(ret.library)) {
        return 3;
    }

    // Do a call to get the information we need to construct our
    // color and depth render-to-texture buffers.
    std::vector<osvr::renderkit::RenderInfo> renderInfo;
    context.update();
    renderInfo = render->GetRenderInfo();
    std::vector<osvr::renderkit::RenderBuffer> colorBuffers;
    std::vector<GLuint> depthBuffers; //< Depth/stencil buffers to render into

    // Construct the buffers we're going to need for our render-to-texture
    // code.
    GLuint frameBuffer; //< Groups a color buffer and a depth buffer
    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

    for (size_t i = 0; i < renderInfo.size(); i++) {

        // The color buffer for this eye.  We need to put this into
        // a generic structure for the Present function, but we only need
        // to fill in the OpenGL portion.
        //  Note that this must be used to generate a RenderBuffer, not just
        // a texture, if we want to be able to present it to be rendered
        // via Direct3D for DirectMode.  This is selected based on the
        // config file value, so we want to be sure to use the more general
        // case.
        //  Note that this texture format must be RGBA and unsigned byte,
        // so that we can present it to Direct3D for DirectMode
        GLuint colorBufferName = 0;
        glGenRenderbuffers(1, &colorBufferName);
        osvr::renderkit::RenderBuffer rb;
        rb.OpenGL = new osvr::renderkit::RenderBufferOpenGL;
        rb.OpenGL->colorBufferName = colorBufferName;
        colorBuffers.push_back(rb);

        // "Bind" the newly created texture : all future texture
        // functions will modify this texture glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, colorBufferName);

        // Determine the appropriate size for the frame buffer to be used for
        // this eye.
        int width = static_cast<int>(renderInfo[i].viewport.width);
        int height = static_cast<int>(renderInfo[i].viewport.height);

        // Give an empty image to OpenGL ( the last "0" means "empty" )
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, 0);

        // Bilinear filtering
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // The depth buffer
        GLuint depthrenderbuffer;
        glGenRenderbuffers(1, &depthrenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width,
                              height);
        depthBuffers.push_back(depthrenderbuffer);
    }

    // Register our constructed buffers so that we can use them for
    // presentation.
    if (!render->RegisterRenderBuffers(colorBuffers)) {
        std::cerr << "RegisterRenderBuffers() returned false, cannot continue"
                  << std::endl;
        quit = true;
    }

    // Continue rendering until it is time to quit.
    while (!quit) {

        // Update the context so we get our callbacks called and
        // update tracker state.
        context.update();

        renderInfo = render->GetRenderInfo();

        // Render into each buffer using the specified information.
        for (size_t i = 0; i < renderInfo.size(); i++) {
            RenderView(renderInfo[i], frameBuffer,
                       colorBuffers[i].OpenGL->colorBufferName,
                       depthBuffers[i]);
        }

        // Delay the requested length of time.
        // Busy-wait so we don't get swapped out longer than we wanted.
        auto end = std::chrono::high_resolution_clock::now() +
                   std::chrono::milliseconds(delayMilliSeconds);
        do {
        } while (std::chrono::high_resolution_clock::now() < end);

        // Send the rendered results to the screen
        if (!render->PresentRenderBuffers(colorBuffers, renderInfo)) {
            std::cerr << "PresentRenderBuffers() returned false, maybe because "
                         "it was asked to quit"
                      << std::endl;
            quit = true;
        }
    }

    // Clean up after ourselves.
    glDeleteFramebuffers(1, &frameBuffer);
    for (size_t i = 0; i < renderInfo.size(); i++) {
        glDeleteTextures(1, &colorBuffers[i].OpenGL->colorBufferName);
        delete colorBuffers[i].OpenGL;
        glDeleteRenderbuffers(1, &depthBuffers[i]);
    }

    // Close the Renderer interface cleanly.
    delete render;

    return 0;
}
int main(int argc, char* argv[]) {
    // Get an OSVR client context to use to access the devices
    // that we need.
    osvr::clientkit::ClientContext context(
        "com.osvr.renderManager.openGLExample");

    // Construct button devices and connect them to a callback
    // that will set the "quit" variable to true when it is
    // pressed.  Use button "1" on the left-hand or
    // right-hand controller.
    osvr::clientkit::Interface leftButton1 =
        context.getInterface("/controller/left/1");
    leftButton1.registerCallback(&myButtonCallback, &quit);

    osvr::clientkit::Interface rightButton1 =
        context.getInterface("/controller/right/1");
    rightButton1.registerCallback(&myButtonCallback, &quit);

    // Open OpenGL and set up the context for rendering to
    // an HMD.  Do this using the OSVR RenderManager interface,
    // which maps to the nVidia or other vendor direct mode
    // to reduce the latency.
    OSVR_GraphicsLibraryOpenGL library;
    library.toolkit = nullptr;
    OSVR_RenderManager render;
    OSVR_RenderManagerOpenGL renderOGL;
    if (OSVR_RETURN_SUCCESS != osvrCreateRenderManagerOpenGL(
        context.get(), "OpenGL", library, &render, &renderOGL)) {
        std::cerr << "Could not create the RenderManager" << std::endl;
        return 1;
    }

    // Set up a handler to cause us to exit cleanly.
#ifdef _WIN32
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
#endif

    // Open the display and make sure this worked.
    OSVR_OpenResultsOpenGL openResults;
    if ((OSVR_RETURN_SUCCESS != osvrRenderManagerOpenDisplayOpenGL(
        renderOGL, &openResults)) ||
        (openResults.status == OSVR_OPEN_STATUS_FAILURE)) {

        std::cerr << "Could not open display" << std::endl;
        delete render;
        return 2;
    }

    // Set up the rendering state we need.
    if (!SetupRendering()) {
        return 3;
    }

    // Do a call to get the information we need to construct our
    // color and depth render-to-texture buffers.
    context.update();

    OSVR_RenderParams renderParams;
    osvrRenderManagerGetDefaultRenderParams(&renderParams);
    OSVR_RenderInfoCollection renderInfoCollection;
    if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoCollection(
        render, renderParams, &renderInfoCollection))) {
        std::cerr << "Could not get render info" << std::endl;
        return 5;
    }

    OSVR_RenderInfoCount numRenderInfo;
    osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, &numRenderInfo);

    std::vector<OSVR_RenderBufferOpenGL> colorBuffers;
    std::vector<GLuint> depthBuffers; //< Depth/stencil buffers to render into

    // Construct the buffers we're going to need for our render-to-texture
    // code.
    GLuint frameBuffer; //< Groups a color buffer and a depth buffer
    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

    OSVR_RenderManagerRegisterBufferState registerBufferState;
    if ((OSVR_RETURN_SUCCESS != osvrRenderManagerStartRegisterRenderBuffers(
        &registerBufferState))) {
        std::cerr << "Could not start registering render buffers" << std::endl;
        return -4;
    }

    for (size_t i = 0; i < numRenderInfo; i++) {
        // Get the current render info
        OSVR_RenderInfoOpenGL renderInfo = { 0 };

        if (OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoFromCollectionOpenGL(
            renderInfoCollection, i, &renderInfo)) {
            std::cerr << "Could not get render info " << i << std::endl;
            return 1;
        }

        // The color buffer for this eye.  We need to put this into
        // a generic structure for the Present function, but we only need
        // to fill in the OpenGL portion.
        //  Note that this must be used to generate a RenderBuffer, not just
        // a texture, if we want to be able to present it to be rendered
        // via Direct3D for DirectMode.  This is selected based on the
        // config file value, so we want to be sure to use the more general
        // case.
        //  Note that this texture format must be RGBA and unsigned byte,
        // so that we can present it to Direct3D for DirectMode
        GLuint colorBufferName = 0;
        glGenRenderbuffers(1, &colorBufferName);

        OSVR_RenderBufferOpenGL rb;
        rb.colorBufferName = colorBufferName;
        colorBuffers.push_back(rb);

        // "Bind" the newly created texture : all future texture
        // functions will modify this texture glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, colorBufferName);

        // Determine the appropriate size for the frame buffer to be used for
        // this eye.
        int width = static_cast<int>(renderInfo.viewport.width);
        int height = static_cast<int>(renderInfo.viewport.height);

        // Give an empty image to OpenGL ( the last "0" means "empty" )
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
            GL_UNSIGNED_BYTE, 0);

        // Bilinear filtering
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // The depth buffer
        GLuint depthrenderbuffer;
        glGenRenderbuffers(1, &depthrenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width,
            height);
        depthBuffers.push_back(depthrenderbuffer);

        if (OSVR_RETURN_SUCCESS != osvrRenderManagerRegisterRenderBufferOpenGL(
            registerBufferState, rb)) {
            std::cerr << "Could not register render buffer " << i << std::endl;
            return -5;
        }
    }

    // Register our constructed buffers so that we can use them for
    // presentation.
    if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishRegisterRenderBuffers(
        render, registerBufferState, false))) {
        std::cerr << "Could not start finish registering render buffers" << std::endl;
        quit = true;
    }

    // Continue rendering until it is time to quit.
    while (!quit) {

        // Update the context so we get our callbacks called and
        // update tracker state.
        context.update();

        //renderInfo = render->GetRenderInfo();

        OSVR_RenderInfoCollection renderInfoCollection = { 0 };
        if (OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoCollection(
            render, renderParams, &renderInfoCollection)) {
            std::cerr << "Could not get render info in the main loop" << std::endl;
            return -1;
        }

        osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, &numRenderInfo);

        // Render into each buffer using the specified information.
        for (size_t i = 0; i < numRenderInfo; i++) {
            OSVR_RenderInfoOpenGL renderInfo = { 0 };
            osvrRenderManagerGetRenderInfoFromCollectionOpenGL(
                renderInfoCollection, i, &renderInfo);

            RenderView(renderInfo, frameBuffer,
                colorBuffers[i].colorBufferName,
                depthBuffers[i]);
        }

        OSVR_RenderManagerPresentState presentState;
        if ((OSVR_RETURN_SUCCESS != osvrRenderManagerStartPresentRenderBuffers(
            &presentState))) {
            std::cerr << "Could not start presenting render buffers" << std::endl;
            return 201;
        }
        OSVR_ViewportDescription fullView;
        fullView.left = fullView.lower = 0;
        fullView.width = fullView.height = 1;
        for (size_t i = 0; i < numRenderInfo; i++) {
            OSVR_RenderInfoOpenGL renderInfo = { 0 };
            osvrRenderManagerGetRenderInfoFromCollectionOpenGL(
                renderInfoCollection, i, &renderInfo);

            if ((OSVR_RETURN_SUCCESS != osvrRenderManagerPresentRenderBufferOpenGL(
                presentState, colorBuffers[i], renderInfo, fullView))) {
                std::cerr << "Could not present render buffer " << i << std::endl;
                return 202;
            }
        }

        if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishPresentRenderBuffers(
            render, presentState, renderParams, false))) {
            std::cerr << "Could not finish presenting render buffers" << std::endl;
            quit = true;
        }
    }

    // Clean up after ourselves.
    glDeleteFramebuffers(1, &frameBuffer);
    for (size_t i = 0; i < colorBuffers.size(); i++) {
        glDeleteTextures(1, &colorBuffers[i].colorBufferName);
        glDeleteRenderbuffers(1, &depthBuffers[i]);
    }

    // Close the Renderer interface cleanly.
    osvrDestroyRenderManager(render);

    return 0;
}
Exemplo n.º 5
0
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_LCDUISAMPLE, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_LCDUISAMPLE));

    /*
    Here we initialize our connection
    */

    //Create a connection context and connect to LCDMon
    lgLcdConnectContextEx ConnectCtx;
    ConnectCtx.appFriendlyName = g_AppletTitle;

    //This part tells LCDMon what you want to display on.
    //Use LGLCD_APPLET_CAP_BW for monochrome, and
    //LGLCD_APPLET_CAP_QVGA for color.  Or them together
    //to be dual mode.  See the lgcd.h documentation
    //for more details on dual mode applets.
    ConnectCtx.dwAppletCapabilitiesSupported = LGLCD_APPLET_CAP_BW | LGLCD_APPLET_CAP_QVGA;

    //We don't want to autostart a sample
    ConnectCtx.isAutostartable = FALSE;

    //Persistence has been deprecated, so we will skip that field
    //ConnectCtx.isPersistent = doesn't matter

    //This example does not cover the configure callback, but it
    //is very similar to setting up notifications.
    ConnectCtx.onConfigure.configCallback = NULL;
    ConnectCtx.onConfigure.configContext = NULL;

    //In this sample, we are using the default notification
    ConnectCtx.onNotify.notificationCallback = NULL;
    ConnectCtx.onNotify.notifyContext = NULL;

    //Let's use our softbutton callback
    g_SBContext.softbuttonsChangedCallback = OnButtonCB;
    g_SBContext.softbuttonsChangedContext = g_hwnd;

    //Initialize your connection
    //We are using our own softbutton callback
    if( FALSE == g_Connection.Initialize(ConnectCtx, &g_SBContext) )
    {
        return -1;
    }

    

    //Add your monochrome page
    CLCDOutput* pMonoOutput = g_Connection.MonoOutput();
    CLCDPage m_MonoPage;

    pMonoOutput->ShowPage(&m_MonoPage);

    //For monochrome, let's just display some text
    g_MonoText.SetText( _T("Hello monochrome display.\n") );
    g_MonoText.SetOrigin(0,0);
    g_MonoText.SetSize(160, 16);
    g_MonoText.SetFontPointSize(8);
    m_MonoPage.AddObject(&g_MonoText);
      
    
    //Add your color page
    CLCDOutput* pColorOutput = g_Connection.ColorOutput();
    CLCDPage m_ColorPage;

    pColorOutput->ShowPage(&m_ColorPage);

    //Add our new OpenGL object
    //We're going to take up the entire screen with it
    g_OGLObj.Initialize(320,240);
    m_ColorPage.AddObject(&g_OGLObj);


    //Let's setup some OpenGL stuff in this function
    g_OGLObj.MakeCurrent();
    SetupRendering();

	// Main message loop:
	BOOL Done = FALSE;
    DWORD timestamp;



    while(!Done)									
	{
		if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) )	
		{
			if (msg.message==WM_QUIT)				
			{
				Done = TRUE;							
			}
			else									
			{
				TranslateMessage(&msg);				
				DispatchMessage(&msg);				
			}
		}
        else
        {
            timestamp = GetTickCount();
            g_OGLObj.BeginDraw();
            //Do OpenGL rendering here
            //One perk of OpenGL is that we do not have to put this rendering code
            //inside of COGLObject's OnDraw class.
            DoRendering(timestamp);
            g_OGLObj.EndDraw();

            //The update will do the rendering of any LCDUI objects we added to pages
            g_Connection.Update();

            //This loop goes very fast, so let's throttle it a bit
            Sleep(33);
        }
    }

    //Shutdown the connection
    //(also called in the destructor)
    g_Connection.Shutdown();

	return (int) msg.wParam;
}
int main(int argc, char* argv[]) {
    // Get an OSVR client context to use to access the devices
    // that we need.
    osvr::clientkit::ClientContext context(
        "com.osvr.renderManager.openGLExample");

    // Construct button devices and connect them to a callback
    // that will set the "quit" variable to true when it is
    // pressed.  Use button "1" on the left-hand or
    // right-hand controller.
    osvr::clientkit::Interface leftButton1 =
        context.getInterface("/controller/left/1");
    leftButton1.registerCallback(&myButtonCallback, &quit);

    osvr::clientkit::Interface rightButton1 =
        context.getInterface("/controller/right/1");
    rightButton1.registerCallback(&myButtonCallback, &quit);

    // Use SDL to open a window and then get an OpenGL context for us.
    // Note: This window is not the one that will be used for rendering
    // the OSVR display, but one that will be cleared to a slowly-changing
    // constant color so we can see that we're able to render to both
    // contexts.
    if (!osvr::renderkit::SDLInitQuit()) {
      std::cerr << "Could not initialize SDL"
        << std::endl;
      return 100;
    }
    SDL_Window *myWindow = SDL_CreateWindow(
      "Test window, not used", 30, 30, 300, 100,
      SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
    if (myWindow == nullptr) {
      std::cerr << "SDL window open failed: Could not get window"
        << std::endl;
      return 101;
    }
    SDL_GLContext myGLContext;
    myGLContext = SDL_GL_CreateContext(myWindow);
    if (myGLContext == 0) {
      std::cerr << "RenderManagerOpenGL::addOpenGLContext: Could not get "
        "OpenGL context" << std::endl;
      return 102;
    }

    // Open OpenGL and set up the context for rendering to
    // an HMD.  Do this using the OSVR RenderManager interface,
    // which maps to the nVidia or other vendor direct mode
    // to reduce the latency.
    osvr::renderkit::RenderManager* render =
        osvr::renderkit::createRenderManager(context.get(), "OpenGL");

    if ((render == nullptr) || (!render->doingOkay())) {
        std::cerr << "Could not create RenderManager" << std::endl;
        return 1;
    }

// Set up a handler to cause us to exit cleanly.
#ifdef _WIN32
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
#endif

    // Open the display and make sure this worked.
    osvr::renderkit::RenderManager::OpenResults ret = render->OpenDisplay();
    if (ret.status == osvr::renderkit::RenderManager::OpenStatus::FAILURE) {
        std::cerr << "Could not open display" << std::endl;
        delete render;
        return 2;
    }

    // Set up the rendering state we need.
    if (!SetupRendering(ret.library)) {
        return 3;
    }

    // Do a call to get the information we need to construct our
    // color and depth render-to-texture buffers.
    std::vector<osvr::renderkit::RenderInfo> renderInfo;
    context.update();
    renderInfo = render->GetRenderInfo();
    std::vector<osvr::renderkit::RenderBuffer> colorBuffers;
    std::vector<GLuint> depthBuffers; //< Depth/stencil buffers to render into

    // Initialize the textures with our window's context open,
    // so that they will be associated with it.
    SDL_GL_MakeCurrent(myWindow, myGLContext);

    // Construct the buffers we're going to need for our render-to-texture
    // code.
    GLuint frameBuffer; //< Groups a color buffer and a depth buffer
    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

    for (size_t i = 0; i < renderInfo.size(); i++) {

        // The color buffer for this eye.  We need to put this into
        // a generic structure for the Present function, but we only need
        // to fill in the OpenGL portion.
        //  Note that this must be used to generate a RenderBuffer, not just
        // a texture, if we want to be able to present it to be rendered
        // via Direct3D for DirectMode.  This is selected based on the
        // config file value, so we want to be sure to use the more general
        // case.
        //  Note that this texture format must be RGBA and unsigned byte,
        // so that we can present it to Direct3D for DirectMode
        GLuint colorBufferName = 0;
        glGenTextures(1, &colorBufferName);
        osvr::renderkit::RenderBuffer rb;
        rb.OpenGL = new osvr::renderkit::RenderBufferOpenGL;
        rb.OpenGL->colorBufferName = colorBufferName;
        colorBuffers.push_back(rb);

        // "Bind" the newly created texture : all future texture
        // functions will modify this texture glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, colorBufferName);

        // Determine the appropriate size for the frame buffer to be used for
        // this eye.
        int width = static_cast<int>(renderInfo[i].viewport.width);
        int height = static_cast<int>(renderInfo[i].viewport.height);

        // Give an empty image to OpenGL ( the last "0" means "empty" )
        // Note that whether or not the second GL_RGBA is turned into
        // GL_BGRA, the first one should remain GL_RGBA -- it is specifying
        // the size.  If the second is changed to GL_RGB or GL_BGR, then
        // the first should become GL_RGB.
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, 0);

        // Bilinear filtering
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // The depth buffer
        GLuint depthrenderbuffer;
        glGenRenderbuffers(1, &depthrenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width,
                              height);
        depthBuffers.push_back(depthrenderbuffer);
    }

    // Register our constructed buffers so that we can use them for
    // presentation.
    if (!render->RegisterRenderBuffers(colorBuffers)) {
        std::cerr << "RegisterRenderBuffers() returned false, cannot continue"
                  << std::endl;
        quit = true;
    }

    // Continue rendering until it is time to quit.
    while (!quit) {

        // Update the context so we get our callbacks called and
        // update tracker state.
        context.update();

        renderInfo = render->GetRenderInfo();

        // Render into each buffer using the specified information.
        for (size_t i = 0; i < renderInfo.size(); i++) {
            RenderView(renderInfo[i], frameBuffer,
                       colorBuffers[i].OpenGL->colorBufferName,
                       depthBuffers[i]);
        }

        // Send the rendered results to the screen
        if (!render->PresentRenderBuffers(colorBuffers, renderInfo)) {
            std::cerr << "PresentRenderBuffers() returned false, maybe because "
                         "it was asked to quit"
                      << std::endl;
            quit = true;
        }

        // Draw something in our window, just looping the background color
        // Render to the standard framebuffer in our own window
        // Because we bind a different frame buffer in our draw routine, we
        // need to put this back here.
        SDL_GL_MakeCurrent(myWindow, myGLContext);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        static GLfloat bg = 0;
        glViewport(static_cast<GLint>(0),
          static_cast<GLint>(0),
          static_cast<GLint>(300),
          static_cast<GLint>(100));
        glClearColor(bg, bg, bg, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        SDL_GL_SwapWindow(myWindow);
        bg += 0.003f;
        if (bg > 1) { bg = 0; }
    }

    // Clean up after ourselves.
    glDeleteFramebuffers(1, &frameBuffer);
    for (size_t i = 0; i < renderInfo.size(); i++) {
        glDeleteTextures(1, &colorBuffers[i].OpenGL->colorBufferName);
        delete colorBuffers[i].OpenGL;
        glDeleteRenderbuffers(1, &depthBuffers[i]);
    }

    // Close the Renderer interface cleanly.
    delete render;

    return 0;
}