@@ -198,6 +198,19 @@ int VRInterface::load(SimulationModel* model) {
198198 std::cout << " glDeleteRenderbuffers not available" << std::endl;
199199 return 1 ;
200200 }
201+
202+ glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)wglGetProcAddress (" glRenderbufferStorageMultisample" );
203+ if (glRenderbufferStorageMultisample == 0 ) {
204+ std::cout << " glRenderbufferStorageMultisample not available" << std::endl;
205+ return 1 ;
206+ }
207+
208+ glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)wglGetProcAddress (" glBlitFramebuffer" );
209+ if (glBlitFramebuffer == 0 ) {
210+ std::cout << " glBlitFramebuffer not available" << std::endl;
211+ return 1 ;
212+ }
213+
201214 #elif defined __linux__
202215 // glXGetProcAddress never returns Null, so no point in checking
203216 glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glXGetProcAddress ((const GLubyte *)" glGenFramebuffers" );
@@ -210,6 +223,8 @@ int VRInterface::load(SimulationModel* model) {
210223 glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glXGetProcAddress ((const GLubyte *)" glFramebufferRenderbuffer" );
211224 glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glXGetProcAddress ((const GLubyte *)" glDeleteFramebuffers" );
212225 glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glXGetProcAddress ((const GLubyte *)" glDeleteRenderbuffers" );
226+ glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glXGetProcAddress ((const GLubyte*)" glRenderbufferStorageMultisample" );
227+ glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glXGetProcAddress ((const GLubyte*)" glBlitFramebuffer" );
213228 #endif
214229
215230 // Changing to HANDHELD_DISPLAY or a future form factor may work, but has not been tested.
@@ -231,7 +246,6 @@ int VRInterface::load(SimulationModel* model) {
231246
232247 // each graphics API requires the use of a specialized struct
233248#ifdef _WIN32
234- // XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl = { 0 };
235249 XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl;
236250 graphics_binding_gl.type = XR_TYPE_UNKNOWN;
237251 graphics_binding_gl.next = NULL ;
@@ -316,7 +330,6 @@ int VRInterface::load(SimulationModel* model) {
316330 return 1 ;
317331 }
318332
319- // XrExtensionProperties* ext_props = malloc(sizeof(XrExtensionProperties) * ext_count);
320333 XrExtensionProperties* ext_props = new XrExtensionProperties[ext_count];
321334
322335 for (uint16_t i = 0 ; i < ext_count; i++) {
@@ -344,7 +357,6 @@ int VRInterface::load(SimulationModel* model) {
344357 depth.supported = true ;
345358 }
346359 }
347- // free(ext_props);
348360 delete[] ext_props;
349361
350362 // A graphics extension like OpenGL is required to draw anything in VR
@@ -412,7 +424,6 @@ int VRInterface::load(SimulationModel* model) {
412424 if (!xr_check (instance, result, " Failed to get view configuration view count!" ))
413425 return 1 ;
414426
415- // viewconfig_views = malloc(sizeof(XrViewConfigurationView) * view_count);
416427 viewconfig_views = new XrViewConfigurationView[view_count];
417428
418429 for (uint32_t i = 0 ; i < view_count; i++) {
@@ -506,11 +517,8 @@ int VRInterface::load(SimulationModel* model) {
506517 // --- Create swapchain for main VR rendering
507518
508519 // In the frame loop we render into OpenGL textures we receive from the runtime here.
509- // swapchains = malloc(sizeof(XrSwapchain) * view_count);
510520 swapchains = new XrSwapchain[view_count];
511- // swapchain_lengths = malloc(sizeof(uint32_t) * view_count);
512521 swapchain_lengths = new uint32_t [view_count];
513- // images = malloc(sizeof(XrSwapchainImageOpenGLKHR*) * view_count);
514522 images = new XrSwapchainImageOpenGLKHR*[view_count];
515523 for (uint32_t i = 0 ; i < view_count; i++) {
516524 XrSwapchainCreateInfo swapchain_create_info;
@@ -536,7 +544,6 @@ int VRInterface::load(SimulationModel* model) {
536544 if (!xr_check (instance, result, " Failed to enumerate swapchains" ))
537545 return 1 ;
538546
539- // images[i] = malloc(sizeof(XrSwapchainImageOpenGLKHR) * swapchain_lengths[i]);
540547 images[i] = new XrSwapchainImageOpenGLKHR[swapchain_lengths[i]];
541548 for (uint32_t j = 0 ; j < swapchain_lengths[i]; j++) {
542549 images[i][j].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR;
@@ -551,19 +558,89 @@ int VRInterface::load(SimulationModel* model) {
551558 // Store image width and height, assumed to be same for both views
552559 swapchainImageWidth = swapchain_create_info.width ;
553560 swapchainImageHeight = swapchain_create_info.height ;
561+ }
554562
563+ // Create framebuffers
564+ framebuffers = new GLuint * [view_count];
565+ depthbuffers = new GLuint * [view_count];
566+ for (uint32_t i = 0 ; i < view_count; i++) {
567+ framebuffers[i] = new GLuint[swapchain_lengths[i]];
568+ depthbuffers[i] = new GLuint[swapchain_lengths[i]];
569+ }
570+
571+ for (uint32_t i = 0 ; i < view_count; i++) {
572+ // ---------------------------------------------------------
573+ // Create per-swapchain-image FBO (attach once!)
574+ // ---------------------------------------------------------
575+ for (uint32_t j = 0 ; j < swapchain_lengths[i]; ++j)
576+ {
577+ glGenFramebuffers (1 , &framebuffers[i][j]);
578+ glBindFramebuffer (GL_FRAMEBUFFER, framebuffers[i][j]);
579+
580+ glFramebufferTexture2D (
581+ GL_FRAMEBUFFER,
582+ GL_COLOR_ATTACHMENT0,
583+ GL_TEXTURE_2D,
584+ images[i][j].image ,
585+ 0
586+ );
587+
588+ if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
589+ std::cerr << " Swapchain FBO incomplete!" << std::endl;
590+ }
591+ }
592+
593+ glBindFramebuffer (GL_FRAMEBUFFER, 0 );
594+
595+ // ---------------------------------------------------------
596+ // Create MSAA framebuffer for this eye
597+ // ---------------------------------------------------------
598+ int width = viewconfig_views[i].recommendedImageRectWidth ;
599+ int height = viewconfig_views[i].recommendedImageRectHeight ;
600+
601+ glGenFramebuffers (1 , &msaaFBO[i]);
602+ glBindFramebuffer (GL_FRAMEBUFFER, msaaFBO[i]);
603+
604+ // --- Multisample color ---
605+ glGenRenderbuffers (1 , &msaaColor[i]);
606+ glBindRenderbuffer (GL_RENDERBUFFER, msaaColor[i]);
607+ glRenderbufferStorageMultisample (
608+ GL_RENDERBUFFER,
609+ MSAA_SAMPLES,
610+ color_format,
611+ width,
612+ height
613+ );
614+ glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
615+ GL_RENDERBUFFER, msaaColor[i]);
616+
617+ // --- Multisample depth ---
618+ glGenRenderbuffers (1 , &msaaDepth[i]);
619+ glBindRenderbuffer (GL_RENDERBUFFER, msaaDepth[i]);
620+ glRenderbufferStorageMultisample (
621+ GL_RENDERBUFFER,
622+ MSAA_SAMPLES,
623+ GL_DEPTH24_STENCIL8,
624+ width,
625+ height
626+ );
627+ glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
628+ GL_RENDERBUFFER, msaaDepth[i]);
629+
630+ if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
631+ std::cerr << " MSAA FBO incomplete!" << std::endl;
632+ }
633+
634+ glBindFramebuffer (GL_FRAMEBUFFER, 0 );
555635 }
556636
557637 // Do not allocate these every frame to save some resources
558- // views = (XrView*)malloc(sizeof(XrView) * view_count);
559638 views = new XrView[view_count];
560639 for (uint32_t i = 0 ; i < view_count; i++) {
561640 views[i].type = XR_TYPE_VIEW;
562641 views[i].next = NULL ;
563642 }
564643
565- // projection_views = (XrCompositionLayerProjectionView*)malloc(
566- // sizeof(XrCompositionLayerProjectionView) * view_count);
567644 projection_views = new XrCompositionLayerProjectionView[view_count];
568645 for (uint32_t i = 0 ; i < view_count; i++) {
569646 projection_views[i].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
@@ -581,15 +658,7 @@ int VRInterface::load(SimulationModel* model) {
581658 // projection_views[i].{pose, fov} have to be filled every frame in frame loop
582659 };
583660
584- // Create framebuffers
585- framebuffers = new GLuint* [view_count];
586- depthbuffers = new GLuint * [view_count];
587- for (uint32_t i = 0 ; i < view_count; i++) {
588- framebuffers[i] = new GLuint[swapchain_lengths[i]];
589- depthbuffers[i] = new GLuint[swapchain_lengths[i]];
590- glGenFramebuffers (swapchain_lengths[i], framebuffers[i]);
591- glGenRenderbuffers (swapchain_lengths[i], depthbuffers[i]);
592- }
661+
593662
594663 // Set up controllers
595664 // --- Set up input (actions)
@@ -1347,29 +1416,34 @@ int VRInterface::update() {
13471416 int w = viewconfig_views[i].recommendedImageRectWidth ;
13481417 int h = viewconfig_views[i].recommendedImageRectHeight ;
13491418
1350- // Render into swapchain images here (for left or right eye), into images[i][acquired_index].image
1351- glBindFramebuffer (GL_FRAMEBUFFER, framebuffers[i][acquired_index]);
1419+ // ---------------------------------------------------------
1420+ // 1) Render scene into MSAA buffer
1421+ // ---------------------------------------------------------
1422+ glBindFramebuffer (GL_FRAMEBUFFER, msaaFBO[i]);
13521423
1353- glBindRenderbuffer (GL_RENDERBUFFER, depthbuffers[i][acquired_index]);
1354- glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
1355- glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffers[1 ][acquired_index]);
1356-
13571424 glViewport (0 , 0 , w, h);
1358- glScissor (0 , 0 , w, h);
1359- glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, images[i][acquired_index].image , 0 );
1360- glClearColor (0 .0f , 0 .0f , 0 .2f , 1 .0f );
1425+
13611426 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1362-
1363- // Check
1364- if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
1365- std::cout << " glCheckFramebufferStatus: " << glCheckFramebufferStatus (GL_FRAMEBUFFER) << std::endl;
1366- }
1367-
1368- // Render
13691427 smgr->drawAll ();
13701428
1371- // Return to framebuffer
1372- glBindFramebuffer (GL_FRAMEBUFFER, 0 );
1429+ // ---------------------------------------------------------
1430+ // 2) Resolve MSAA -> swapchain image
1431+ // ---------------------------------------------------------
1432+
1433+ glBindFramebuffer (GL_READ_FRAMEBUFFER, msaaFBO[i]);
1434+ glBindFramebuffer (GL_DRAW_FRAMEBUFFER,
1435+ framebuffers[i][acquired_index]);
1436+
1437+ glBlitFramebuffer (
1438+ 0 , 0 ,
1439+ viewconfig_views[i].recommendedImageRectWidth ,
1440+ viewconfig_views[i].recommendedImageRectHeight ,
1441+ 0 , 0 ,
1442+ viewconfig_views[i].recommendedImageRectWidth ,
1443+ viewconfig_views[i].recommendedImageRectHeight ,
1444+ GL_COLOR_BUFFER_BIT,
1445+ GL_NEAREST
1446+ );
13731447
13741448 XrSwapchainImageReleaseInfo release_info;
13751449 release_info.type = XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO;
@@ -1412,6 +1486,9 @@ int VRInterface::update() {
14121486 if (!xr_check (instance, result, " failed to end frame!" ))
14131487 return 1 ;
14141488
1489+ // Return to normal framebuffer
1490+ glBindFramebuffer (GL_FRAMEBUFFER, 0 );
1491+
14151492 // Do ray/mesh intersection here if 'select' is active and HUD is shown
14161493 if (showHUD) {
14171494 if (selectState[HAND_LEFT_INDEX] || selectState[HAND_RIGHT_INDEX]) {
@@ -1712,7 +1789,6 @@ void VRInterface::print_api_layers()
17121789 if (count == 0 )
17131790 return ;
17141791
1715- // XrApiLayerProperties* props = malloc(count * sizeof(XrApiLayerProperties));
17161792 XrApiLayerProperties* props = new XrApiLayerProperties[count];
17171793 for (uint32_t i = 0 ; i < count; i++) {
17181794 props[i].type = XR_TYPE_API_LAYER_PROPERTIES;
@@ -1728,7 +1804,6 @@ void VRInterface::print_api_layers()
17281804 printf (" \t %s v%d: %s\n " , props[i].layerName , props[i].layerVersion , props[i].description );
17291805 }
17301806
1731- // free(props)
17321807 delete[] props;
17331808#else
17341809 std::cout << " VR interface not implemented" << std::endl;
@@ -1809,7 +1884,6 @@ int64_t VRInterface::get_swapchain_format(XrInstance instance,
18091884 return -1 ;
18101885
18111886 printf (" Runtime supports %d swapchain formats\n " , swapchain_format_count);
1812- // int64_t* swapchain_formats = malloc(sizeof(int64_t) * swapchain_format_count);
18131887 int64_t * swapchain_formats = new int64_t [swapchain_format_count];
18141888 result = xrEnumerateSwapchainFormats (session, swapchain_format_count, &swapchain_format_count,
18151889 swapchain_formats);
@@ -1830,7 +1904,6 @@ int64_t VRInterface::get_swapchain_format(XrInstance instance,
18301904 printf (" Falling back to non preferred swapchain format %#lx\n " , chosen_format);
18311905 }
18321906
1833- // free(swapchain_formats);
18341907 delete[] swapchain_formats;
18351908
18361909 return chosen_format;
0 commit comments