//! 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( ®isterBufferState))) { 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; }
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; }