@@ -381,8 +381,8 @@ void Update(sf::Window& window, sf::RenderTarget& target, sf::Time dt) {
381
381
382
382
void Update (const sf::Vector2i& mousePos, const sf::Vector2f& displaySize, sf::Time dt) {
383
383
ImGuiIO& io = ImGui::GetIO ();
384
- io.DisplaySize = ImVec2 (displaySize.x , displaySize.y );
385
384
385
+ io.DisplaySize = ImVec2 (displaySize.x , displaySize.y );
386
386
io.DeltaTime = dt.asSeconds ();
387
387
388
388
if (s_windowHasFocus) {
@@ -440,8 +440,10 @@ void Update(const sf::Vector2i& mousePos, const sf::Vector2f& displaySize, sf::T
440
440
441
441
void Render (sf::RenderTarget& target) {
442
442
target.resetGLStates ();
443
+ target.pushGLStates ();
443
444
ImGui::Render ();
444
445
RenderDrawLists (ImGui::GetDrawData ());
446
+ target.popGLStates ();
445
447
}
446
448
447
449
void Render () {
@@ -450,7 +452,7 @@ void Render() {
450
452
}
451
453
452
454
void Shutdown () {
453
- ImGui::GetIO ().Fonts ->TexID = (ImTextureID) NULL ;
455
+ ImGui::GetIO ().Fonts ->SetTexID ( 0 ) ;
454
456
455
457
if (s_fontTexture) { // if internal texture was created, we delete it
456
458
delete s_fontTexture;
@@ -480,7 +482,8 @@ void UpdateFontTexture() {
480
482
texture.create (width, height);
481
483
texture.update (pixels);
482
484
483
- io.Fonts ->TexID = convertGLTextureHandleToImTextureID (texture.getNativeHandle ());
485
+ ImTextureID texID = convertGLTextureHandleToImTextureID (texture.getNativeHandle ());
486
+ io.Fonts ->SetTexID (texID);
484
487
}
485
488
486
489
sf::Texture& GetFontTexture () {
@@ -705,6 +708,51 @@ GLuint convertImTextureIDToGLTextureHandle(ImTextureID textureID) {
705
708
return glTextureHandle;
706
709
}
707
710
711
+ // copied from imgui/backends/imgui_impl_opengl2.cpp
712
+ void SetupRenderState (ImDrawData* draw_data, int fb_width, int fb_height) {
713
+ // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor
714
+ // enabled, vertex/texcoord/color pointers, polygon fill.
715
+ glEnable (GL_BLEND);
716
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
717
+ // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); //
718
+ // In order to composite our output buffer we need to preserve alpha
719
+ glDisable (GL_CULL_FACE);
720
+ glDisable (GL_DEPTH_TEST);
721
+ glDisable (GL_STENCIL_TEST);
722
+ glDisable (GL_LIGHTING);
723
+ glDisable (GL_COLOR_MATERIAL);
724
+ glEnable (GL_SCISSOR_TEST);
725
+ glEnableClientState (GL_VERTEX_ARRAY);
726
+ glEnableClientState (GL_TEXTURE_COORD_ARRAY);
727
+ glEnableClientState (GL_COLOR_ARRAY);
728
+ glDisableClientState (GL_NORMAL_ARRAY);
729
+ glEnable (GL_TEXTURE_2D);
730
+ glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
731
+ glShadeModel (GL_SMOOTH);
732
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
733
+
734
+ // Setup viewport, orthographic projection matrix
735
+ // Our visible imgui space lies from draw_data->DisplayPos (top left) to
736
+ // draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single
737
+ // viewport apps.
738
+ glViewport (0 , 0 , (GLsizei)fb_width, (GLsizei)fb_height);
739
+ glMatrixMode (GL_PROJECTION);
740
+ glPushMatrix ();
741
+ glLoadIdentity ();
742
+ #ifdef GL_VERSION_ES_CL_1_1
743
+ glOrthof (draw_data->DisplayPos .x , draw_data->DisplayPos .x + draw_data->DisplaySize .x ,
744
+ draw_data->DisplayPos .y + draw_data->DisplaySize .y , draw_data->DisplayPos .y , -1 .0f ,
745
+ +1 .0f );
746
+ #else
747
+ glOrtho (draw_data->DisplayPos .x , draw_data->DisplayPos .x + draw_data->DisplaySize .x ,
748
+ draw_data->DisplayPos .y + draw_data->DisplaySize .y , draw_data->DisplayPos .y , -1 .0f ,
749
+ +1 .0f );
750
+ #endif
751
+ glMatrixMode (GL_MODELVIEW);
752
+ glPushMatrix ();
753
+ glLoadIdentity ();
754
+ }
755
+
708
756
// Rendering callback
709
757
void RenderDrawLists (ImDrawData* draw_data) {
710
758
ImGui::GetDrawData ();
@@ -715,86 +763,115 @@ void RenderDrawLists(ImDrawData* draw_data) {
715
763
ImGuiIO& io = ImGui::GetIO ();
716
764
assert (io.Fonts ->TexID != (ImTextureID)NULL ); // You forgot to create and set font texture
717
765
718
- // scale stuff (needed for proper handling of window resize)
719
- int fb_width = static_cast <int >(io.DisplaySize .x * io.DisplayFramebufferScale .x );
720
- int fb_height = static_cast <int >(io.DisplaySize .y * io.DisplayFramebufferScale .y );
721
- if (fb_width == 0 || fb_height == 0 ) {
722
- return ;
723
- }
766
+ // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates !=
767
+ // framebuffer coordinates)
768
+ int fb_width = (int )(draw_data->DisplaySize .x * draw_data->FramebufferScale .x );
769
+ int fb_height = (int )(draw_data->DisplaySize .y * draw_data->FramebufferScale .y );
770
+ if (fb_width == 0 || fb_height == 0 ) return ;
724
771
draw_data->ScaleClipRects (io.DisplayFramebufferScale );
725
772
726
- #ifdef GL_VERSION_ES_CL_1_1
727
- GLint last_program, last_texture, last_array_buffer, last_element_array_buffer;
773
+ // Backup GL state
774
+ // Backup GL state
775
+ GLint last_texture;
728
776
glGetIntegerv (GL_TEXTURE_BINDING_2D, &last_texture);
777
+ GLint last_polygon_mode[2 ];
778
+ glGetIntegerv (GL_POLYGON_MODE, last_polygon_mode);
779
+ GLint last_viewport[4 ];
780
+ glGetIntegerv (GL_VIEWPORT, last_viewport);
781
+ GLint last_scissor_box[4 ];
782
+ glGetIntegerv (GL_SCISSOR_BOX, last_scissor_box);
783
+ GLint last_shade_model;
784
+ glGetIntegerv (GL_SHADE_MODEL, &last_shade_model);
785
+ GLint last_tex_env_mode;
786
+ glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
787
+
788
+ #ifdef GL_VERSION_ES_CL_1_1
789
+ GLint last_array_buffer;
729
790
glGetIntegerv (GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
791
+ GLint last_element_array_buffer;
730
792
glGetIntegerv (GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
731
793
#else
732
794
glPushAttrib (GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
733
795
#endif
734
796
735
- glEnable (GL_BLEND);
736
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
737
- glDisable (GL_CULL_FACE);
738
- glDisable (GL_DEPTH_TEST);
739
- glEnable (GL_SCISSOR_TEST);
740
- glEnable (GL_TEXTURE_2D);
741
- glDisable (GL_LIGHTING);
742
- glEnableClientState (GL_VERTEX_ARRAY);
743
- glEnableClientState (GL_COLOR_ARRAY);
744
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
745
-
746
- glViewport (0 , 0 , (GLsizei)fb_width, (GLsizei)fb_height);
797
+ // Setup desired GL state
798
+ SetupRenderState (draw_data, fb_width, fb_height);
747
799
748
- glMatrixMode (GL_TEXTURE);
749
- glLoadIdentity ();
800
+ // Will project scissor/clipping rectangles into framebuffer space
801
+ ImVec2 clip_off = draw_data->DisplayPos ; // (0,0) unless using multi-viewports
802
+ ImVec2 clip_scale = draw_data->FramebufferScale ; // (1,1) unless using retina display which are
803
+ // often (2,2)
750
804
751
- glMatrixMode (GL_PROJECTION);
752
- glLoadIdentity ();
753
-
754
- #ifdef GL_VERSION_ES_CL_1_1
755
- glOrthof (0 .0f , io.DisplaySize .x , io.DisplaySize .y , 0 .0f , -1 .0f , +1 .0f );
756
- #else
757
- glOrtho (0 .0f , io.DisplaySize .x , io.DisplaySize .y , 0 .0f , -1 .0f , +1 .0f );
758
- #endif
759
-
760
- glMatrixMode (GL_MODELVIEW);
761
- glLoadIdentity ();
762
-
763
- for (int n = 0 ; n < draw_data->CmdListsCount ; ++n) {
805
+ // Render command lists
806
+ for (int n = 0 ; n < draw_data->CmdListsCount ; n++) {
764
807
const ImDrawList* cmd_list = draw_data->CmdLists [n];
765
- const unsigned char * vtx_buffer = (const unsigned char *)&cmd_list->VtxBuffer .front ();
766
- const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer .front ();
767
-
808
+ const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer .Data ;
809
+ const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer .Data ;
768
810
glVertexPointer (2 , GL_FLOAT, sizeof (ImDrawVert),
769
- (void *)(vtx_buffer + offsetof (ImDrawVert, pos)));
811
+ (const GLvoid *)(( const char *) vtx_buffer + IM_OFFSETOF (ImDrawVert, pos)));
770
812
glTexCoordPointer (2 , GL_FLOAT, sizeof (ImDrawVert),
771
- (void *)(vtx_buffer + offsetof (ImDrawVert, uv)));
813
+ (const GLvoid *)(( const char *) vtx_buffer + IM_OFFSETOF (ImDrawVert, uv)));
772
814
glColorPointer (4 , GL_UNSIGNED_BYTE, sizeof (ImDrawVert),
773
- (void *)(vtx_buffer + offsetof (ImDrawVert, col)));
815
+ (const GLvoid *)(( const char *) vtx_buffer + IM_OFFSETOF (ImDrawVert, col)));
774
816
775
- for (int cmd_i = 0 ; cmd_i < cmd_list->CmdBuffer .size (); ++cmd_i ) {
817
+ for (int cmd_i = 0 ; cmd_i < cmd_list->CmdBuffer .Size ; cmd_i++ ) {
776
818
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer [cmd_i];
777
819
if (pcmd->UserCallback ) {
778
- pcmd->UserCallback (cmd_list, pcmd);
820
+ // User callback, registered via ImDrawList::AddCallback()
821
+ // (ImDrawCallback_ResetRenderState is a special callback value used by the user to
822
+ // request the renderer to reset render state.)
823
+ if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
824
+ SetupRenderState (draw_data, fb_width, fb_height);
825
+ else
826
+ pcmd->UserCallback (cmd_list, pcmd);
779
827
} else {
780
- GLuint textureHandle = convertImTextureIDToGLTextureHandle (pcmd->TextureId );
781
- glBindTexture (GL_TEXTURE_2D, textureHandle);
782
- glScissor ((int )pcmd->ClipRect .x , (int )(fb_height - pcmd->ClipRect .w ),
783
- (int )(pcmd->ClipRect .z - pcmd->ClipRect .x ),
784
- (int )(pcmd->ClipRect .w - pcmd->ClipRect .y ));
785
- glDrawElements (GL_TRIANGLES, (GLsizei)pcmd->ElemCount , GL_UNSIGNED_SHORT,
786
- idx_buffer);
828
+ // Project scissor/clipping rectangles into framebuffer space
829
+ ImVec4 clip_rect;
830
+ clip_rect.x = (pcmd->ClipRect .x - clip_off.x ) * clip_scale.x ;
831
+ clip_rect.y = (pcmd->ClipRect .y - clip_off.y ) * clip_scale.y ;
832
+ clip_rect.z = (pcmd->ClipRect .z - clip_off.x ) * clip_scale.x ;
833
+ clip_rect.w = (pcmd->ClipRect .w - clip_off.y ) * clip_scale.y ;
834
+
835
+ if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0 .0f &&
836
+ clip_rect.w >= 0 .0f ) {
837
+ // Apply scissor/clipping rectangle
838
+ glScissor ((int )clip_rect.x , (int )(fb_height - clip_rect.w ),
839
+ (int )(clip_rect.z - clip_rect.x ), (int )(clip_rect.w - clip_rect.y ));
840
+
841
+ // Bind texture, Draw
842
+ GLuint textureHandle = convertImTextureIDToGLTextureHandle (pcmd->TextureId );
843
+ glBindTexture (GL_TEXTURE_2D, textureHandle);
844
+ glDrawElements (GL_TRIANGLES, (GLsizei)pcmd->ElemCount , GL_UNSIGNED_SHORT,
845
+ idx_buffer);
846
+ }
787
847
}
788
848
idx_buffer += pcmd->ElemCount ;
789
849
}
790
850
}
851
+
852
+ // Restore modified GL state
853
+ glDisableClientState (GL_COLOR_ARRAY);
854
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
855
+ glDisableClientState (GL_VERTEX_ARRAY);
856
+ glBindTexture (GL_TEXTURE_2D, (GLuint)last_texture);
857
+ glMatrixMode (GL_MODELVIEW);
858
+ glPopMatrix ();
859
+ glMatrixMode (GL_PROJECTION);
860
+ glPopMatrix ();
861
+ glPopAttrib ();
862
+ glPolygonMode (GL_FRONT, (GLenum)last_polygon_mode[0 ]);
863
+ glPolygonMode (GL_BACK, (GLenum)last_polygon_mode[1 ]);
864
+ glViewport (last_viewport[0 ], last_viewport[1 ], (GLsizei)last_viewport[2 ],
865
+ (GLsizei)last_viewport[3 ]);
866
+ glScissor (last_scissor_box[0 ], last_scissor_box[1 ], (GLsizei)last_scissor_box[2 ],
867
+ (GLsizei)last_scissor_box[3 ]);
868
+ glShadeModel (last_shade_model);
869
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
870
+
791
871
#ifdef GL_VERSION_ES_CL_1_1
792
- glBindTexture (GL_TEXTURE_2D, last_texture);
793
872
glBindBuffer (GL_ARRAY_BUFFER, last_array_buffer);
794
873
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
795
874
glDisable (GL_SCISSOR_TEST);
796
- #else
797
- glPopAttrib ();
798
875
#endif
799
876
}
800
877
0 commit comments