14
14
15
15
// CHANGELOG
16
16
// (minor and older changes stripped away, please see git history for details)
17
+ // 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'.
17
18
// 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127).
18
19
// 2022-05-13: OpenGL: Fix state corruption on OpenGL ES 2.0 due to not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states.
19
20
// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
178
179
#define IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
179
180
#endif
180
181
182
+ // [Debugging]
183
+ // #define IMGUI_IMPL_OPENGL_DEBUG
184
+ #ifdef IMGUI_IMPL_OPENGL_DEBUG
185
+ #include < stdio.h>
186
+ #define GL_CALL (_CALL ) do { _CALL; GLenum gl_err = glGetError (); if (gl_err != 0 ) fprintf (stderr, " GL error 0x%x returned from '%s'.\n " , gl_err, #_CALL); } while (0 ) // Call with error check
187
+ #else
188
+ #define GL_CALL (_CALL ) _CALL // Call without error check
189
+ #endif
190
+
181
191
// OpenGL Data
182
192
struct ImGui_ImplOpenGL3_Data
183
193
{
@@ -270,11 +280,14 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
270
280
if (strncmp (vendor, " Intel" , 5 ) == 0 )
271
281
bd->UseBufferSubData = true ;
272
282
#endif
273
- // printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
274
283
#else
275
284
bd->GlVersion = 200 ; // GLES 2
276
285
#endif
277
286
287
+ #ifdef IMGUI_IMPL_OPENGL_DEBUG
288
+ printf (" GL_MAJOR_VERSION = %d\n GL_MINOR_VERSION = %d\n GL_VENDOR = '%s'\n GL_RENDERER = '%s'\n " , major, minor, (const char *)glGetString (GL_VENDOR), (const char *)glGetString (GL_RENDERER)); // [DEBUG]
289
+ #endif
290
+
278
291
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
279
292
if (bd->GlVersion >= 320 )
280
293
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
@@ -373,7 +386,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
373
386
374
387
// Setup viewport, orthographic projection matrix
375
388
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
376
- glViewport (0 , 0 , (GLsizei)fb_width, (GLsizei)fb_height);
389
+ GL_CALL ( glViewport (0 , 0 , (GLsizei)fb_width, (GLsizei)fb_height) );
377
390
float L = draw_data->DisplayPos .x ;
378
391
float R = draw_data->DisplayPos .x + draw_data->DisplaySize .x ;
379
392
float T = draw_data->DisplayPos .y ;
@@ -403,14 +416,14 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
403
416
#endif
404
417
405
418
// Bind vertex/index buffers and setup attributes for ImDrawVert
406
- glBindBuffer (GL_ARRAY_BUFFER, bd->VboHandle );
407
- glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, bd->ElementsHandle );
408
- glEnableVertexAttribArray (bd->AttribLocationVtxPos );
409
- glEnableVertexAttribArray (bd->AttribLocationVtxUV );
410
- glEnableVertexAttribArray (bd->AttribLocationVtxColor );
411
- glVertexAttribPointer (bd->AttribLocationVtxPos , 2 , GL_FLOAT, GL_FALSE, sizeof (ImDrawVert), (GLvoid*)IM_OFFSETOF (ImDrawVert, pos));
412
- glVertexAttribPointer (bd->AttribLocationVtxUV , 2 , GL_FLOAT, GL_FALSE, sizeof (ImDrawVert), (GLvoid*)IM_OFFSETOF (ImDrawVert, uv));
413
- glVertexAttribPointer (bd->AttribLocationVtxColor , 4 , GL_UNSIGNED_BYTE, GL_TRUE, sizeof (ImDrawVert), (GLvoid*)IM_OFFSETOF (ImDrawVert, col));
419
+ GL_CALL ( glBindBuffer (GL_ARRAY_BUFFER, bd->VboHandle ) );
420
+ GL_CALL ( glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, bd->ElementsHandle ) );
421
+ GL_CALL ( glEnableVertexAttribArray (bd->AttribLocationVtxPos ) );
422
+ GL_CALL ( glEnableVertexAttribArray (bd->AttribLocationVtxUV ) );
423
+ GL_CALL ( glEnableVertexAttribArray (bd->AttribLocationVtxColor ) );
424
+ GL_CALL ( glVertexAttribPointer (bd->AttribLocationVtxPos , 2 , GL_FLOAT, GL_FALSE, sizeof (ImDrawVert), (GLvoid*)IM_OFFSETOF (ImDrawVert, pos) ));
425
+ GL_CALL ( glVertexAttribPointer (bd->AttribLocationVtxUV , 2 , GL_FLOAT, GL_FALSE, sizeof (ImDrawVert), (GLvoid*)IM_OFFSETOF (ImDrawVert, uv) ));
426
+ GL_CALL ( glVertexAttribPointer (bd->AttribLocationVtxColor , 4 , GL_UNSIGNED_BYTE, GL_TRUE, sizeof (ImDrawVert), (GLvoid*)IM_OFFSETOF (ImDrawVert, col) ));
414
427
}
415
428
416
429
// OpenGL3 Render function.
@@ -470,7 +483,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
470
483
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
471
484
GLuint vertex_array_object = 0 ;
472
485
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
473
- glGenVertexArrays (1 , &vertex_array_object);
486
+ GL_CALL ( glGenVertexArrays (1 , &vertex_array_object) );
474
487
#endif
475
488
ImGui_ImplOpenGL3_SetupRenderState (draw_data, fb_width, fb_height, vertex_array_object);
476
489
@@ -494,20 +507,20 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
494
507
if (bd->VertexBufferSize < vtx_buffer_size)
495
508
{
496
509
bd->VertexBufferSize = vtx_buffer_size;
497
- glBufferData (GL_ARRAY_BUFFER, bd->VertexBufferSize , NULL , GL_STREAM_DRAW);
510
+ GL_CALL ( glBufferData (GL_ARRAY_BUFFER, bd->VertexBufferSize , NULL , GL_STREAM_DRAW) );
498
511
}
499
512
if (bd->IndexBufferSize < idx_buffer_size)
500
513
{
501
514
bd->IndexBufferSize = idx_buffer_size;
502
- glBufferData (GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize , NULL , GL_STREAM_DRAW);
515
+ GL_CALL ( glBufferData (GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize , NULL , GL_STREAM_DRAW) );
503
516
}
504
- glBufferSubData (GL_ARRAY_BUFFER, 0 , vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer .Data );
505
- glBufferSubData (GL_ELEMENT_ARRAY_BUFFER, 0 , idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer .Data );
517
+ GL_CALL ( glBufferSubData (GL_ARRAY_BUFFER, 0 , vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer .Data ) );
518
+ GL_CALL ( glBufferSubData (GL_ELEMENT_ARRAY_BUFFER, 0 , idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer .Data ) );
506
519
}
507
520
else
508
521
{
509
- glBufferData (GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer .Data , GL_STREAM_DRAW);
510
- glBufferData (GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer .Data , GL_STREAM_DRAW);
522
+ GL_CALL ( glBufferData (GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer .Data , GL_STREAM_DRAW) );
523
+ GL_CALL ( glBufferData (GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer .Data , GL_STREAM_DRAW) );
511
524
}
512
525
513
526
for (int cmd_i = 0 ; cmd_i < cmd_list->CmdBuffer .Size ; cmd_i++)
@@ -531,23 +544,23 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
531
544
continue ;
532
545
533
546
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
534
- glScissor ((int )clip_min.x , (int )((float )fb_height - clip_max.y ), (int )(clip_max.x - clip_min.x ), (int )(clip_max.y - clip_min.y ));
547
+ GL_CALL ( glScissor ((int )clip_min.x , (int )((float )fb_height - clip_max.y ), (int )(clip_max.x - clip_min.x ), (int )(clip_max.y - clip_min.y ) ));
535
548
536
549
// Bind texture, Draw
537
- glBindTexture (GL_TEXTURE_2D, (GLuint)(intptr_t )pcmd->GetTexID ());
550
+ GL_CALL ( glBindTexture (GL_TEXTURE_2D, (GLuint)(intptr_t )pcmd->GetTexID () ));
538
551
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
539
552
if (bd->GlVersion >= 320 )
540
- glDrawElementsBaseVertex (GL_TRIANGLES, (GLsizei)pcmd->ElemCount , sizeof (ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void *)(intptr_t )(pcmd->IdxOffset * sizeof (ImDrawIdx)), (GLint)pcmd->VtxOffset );
553
+ GL_CALL ( glDrawElementsBaseVertex (GL_TRIANGLES, (GLsizei)pcmd->ElemCount , sizeof (ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void *)(intptr_t )(pcmd->IdxOffset * sizeof (ImDrawIdx)), (GLint)pcmd->VtxOffset ) );
541
554
else
542
555
#endif
543
- glDrawElements (GL_TRIANGLES, (GLsizei)pcmd->ElemCount , sizeof (ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void *)(intptr_t )(pcmd->IdxOffset * sizeof (ImDrawIdx)));
556
+ GL_CALL ( glDrawElements (GL_TRIANGLES, (GLsizei)pcmd->ElemCount , sizeof (ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void *)(intptr_t )(pcmd->IdxOffset * sizeof (ImDrawIdx) )));
544
557
}
545
558
}
546
559
}
547
560
548
561
// Destroy the temporary VAO
549
562
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
550
- glDeleteVertexArrays (1 , &vertex_array_object);
563
+ GL_CALL ( glDeleteVertexArrays (1 , &vertex_array_object) );
551
564
#endif
552
565
553
566
// Restore modified GL state
@@ -600,21 +613,21 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
600
613
// Upload texture to graphics system
601
614
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
602
615
GLint last_texture;
603
- glGetIntegerv (GL_TEXTURE_BINDING_2D, &last_texture);
604
- glGenTextures (1 , &bd->FontTexture );
605
- glBindTexture (GL_TEXTURE_2D, bd->FontTexture );
606
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
607
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
616
+ GL_CALL ( glGetIntegerv (GL_TEXTURE_BINDING_2D, &last_texture) );
617
+ GL_CALL ( glGenTextures (1 , &bd->FontTexture ) );
618
+ GL_CALL ( glBindTexture (GL_TEXTURE_2D, bd->FontTexture ) );
619
+ GL_CALL ( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
620
+ GL_CALL ( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
608
621
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
609
- glPixelStorei (GL_UNPACK_ROW_LENGTH, 0 );
622
+ GL_CALL ( glPixelStorei (GL_UNPACK_ROW_LENGTH, 0 ) );
610
623
#endif
611
- glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA, width, height, 0 , GL_RGBA, GL_UNSIGNED_BYTE, pixels);
624
+ GL_CALL ( glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA, width, height, 0 , GL_RGBA, GL_UNSIGNED_BYTE, pixels) );
612
625
613
626
// Store our identifier
614
627
io.Fonts ->SetTexID ((ImTextureID)(intptr_t )bd->FontTexture );
615
628
616
629
// Restore state
617
- glBindTexture (GL_TEXTURE_2D, last_texture);
630
+ GL_CALL ( glBindTexture (GL_TEXTURE_2D, last_texture) );
618
631
619
632
return true ;
620
633
}
0 commit comments