mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-04 10:07:58 +00:00
SDL2 SDL_Renderer + OpenGL context issues with example code #1116
Labels
No labels
accidentally closed
android
backends
bug
building
clipper
coloredit
color spaces
cplusplus
data types
demo
disabled
doc
docking
dpi
drag drop
drawing/drawlist
dropped
dx12
enhancement
focus
font/text
gallery
help wanted
idle/power saving
ime
in progress
inputs
inputtext
internals
label/id and id stack
language bindings
layout
linux/bsd
menus
multi-contexts
multi-threading
multi-viewports
nav
news/info
opengl
optimization
osx/ios
overlap
plot/graph
popups
question
scrolling
selection
settings
sliders/drags
style
tables/columns
tabs
test wanted
tools
tooltips
tree
tricks & tips
useful widgets
vulkan
web
window pos/depth
window sizing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ocornut/imgui#1116
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Environment: sdl2, sdlgfx, glew 2.0.0, OpenGL 4.1 INTEL-10.14.73, GLSL 4.10
I almost integrated imgui in my project but got one little problem. I use the 2 source file out of the examples/sdl_opengl2_example directory As long as i only use imgui methods everything works fine.
Without imgui my project works too.
When i call SDL_RenderCopyEx or something else from sdl_gfx to draw rectangles my ui looks like this.
The code for my rendering looks like this
Perhaps something about current active, aka
glActiveTexture(). Will investigate. Try callingglActiveTexture(GL_TEXTURE0);Maybe related to this PR:
https://github.com/ocornut/imgui/pull/1087
(which was an incorrect fix, but linking for reference)
Hello @maluramichael,
Please use the
sdl_opengl3_examplecode as a base. Mixing GL2 style code with newer GL3 isn't well supported by all drivers. You may also want to get the version with the latest fix I have just made.Ill try this later and report back.
Ok now i know how to recreate this error. I used the latest examples/sdl_opengl3_example code. Imgui works as long as i leave the example as it is. But when i create a SDL_Renderer it does not work anymore and i really need the renderer.
Check those references:
https://github.com/ocornut/imgui/search?q=SDL_Renderer&type=Issues&utf8=%E2%9C%93
I am sure there might be a fix but not using SDL myself I can't tell. Maybe I'll try to repro with your code later if I have time.
There is something wrong with the SDL_Renderer. In your sdl2_opengl3 the following line,
prints
OpenGL 4.1 INTEL-10.14.73, GLSL 4.10and everything works.When i create the renderer with
the line above prints
OpenGL 2.1 INTEL-10.14.73, GLSL 1.20and no ui is rendered.Ok this is crazy. Your example works in this case when i split the SetAttribute calls. It has something to do with this link: http://stackoverflow.com/a/23858884/1407823
Adding reference to https://github.com/ocornut/imgui/issues/935
I am looking at those three issues, #1116, #935, #1110, they seem all related and incredibly confusing for someone not running Linux/OSX (I cannot repro issues on Windows) and not using SDL_Renderer.
Closing the 2 other issues and merging it. Please also refer to them they contains useful information.
@ebachard @maluramichael @slidingboar @kuhaut
There is an issue related to OpenGL context versions, the imgui example renderer codes and SDL_Renderer.
This is the OpenGL SDL_Renderer code in SDL:
http://hg.libsdl.org/SDL/file/d49da5f38a14/src/render/opengl/SDL_render_gl.c
And basically it does this:
So basically SDL_Renderer enforces a 2.1 context and recreate if needed.
I don't know why it does that, it looks like a limitation of SDL_Renderer.
So the old style OpenGL code in
sdl_opengl2_exampleworks better with it.According to Michael latest post (just above, https://github.com/ocornut/imgui/issues/1116#issuecomment-297701113) he is being successful resetting the render context version AFTER creating the SDL_Renderer. This is rather dubious but it may work for you.
It would be nice if you Linux/OSX users could experiment further with small repro being posted, while providing exact OS type + SDL version. So we can decide what to do on with
sdl_opengl2_example/andsdl_opengl3_example. If we should add comments to them etc.As SDL_Renderer tries to be its own platform (wrapping OpenGL, DirectX, etc.) it would also make sense to render imgui only with SDL_Renderer calls, but it doesn't seem to provide many useful calls. At least it doesn't seem possible to render textures triangles with it. Looking from the outside, I don't really understand what SDL_Renderer is for or is trying to provide, it seems like a very poor/outdated library for modern 3D era.
I think I've said this before in other issues, but yeah @ocornut you are exactly right. Mixing SDL render and GL/DX anything else goes wrong. I've attempted this in the past and the upshot is that it is not supported. Change everything to GL.
@paulsapps This is not what I'm saying and this is not what is written above!! What's written is that SDL_Renderer enforces an OpenGL 2.1 context. We have to be more cautious with our wording and assumptions to not make this issue more confusing that it is. There are various possible actions to take, maybe the workaround of changing context version after creating the SDL_Renderer works perfectly well. Maybe we can add more examples to direct users of SDL_Renderer to the old-GL style example etc.
Thing is though it might not even be OpenGL, it can be any of these:
https://wiki.libsdl.org/SDL_HINT_RENDER_DRIVER
direct3d
opengl
opengles2
opengles
software
Which is why its just a bad idea in general.
It's a bit clunky, but it's a not a bad idea if you are targeting OpenGL, it's similar to just writing an GL application. That said, with the small number of features SDL_Renderer supports I don't quite understand why people would want to use that at all instead of OpenGL.
( If SDL_Renderer is in active development, may I suggest its users to push toward it getting enough features implemented so that SDL_Renderer API can render imgui )
The thing with the renderer is that you can easily render stuff like textures and primitives (sdl_gfx) without wrapping shader and vertex buffer.
This is probably caused by SDL's shaders not being unbound after rendering. Try calling
glUseProgramObjectARB (0)beforeImGui::Render(). That fixed the problem for me.@Svennny Are you using the SDL+GL2 or SDL+GL3 example?
AFAIK
glUseProgramObjectARBis a super old function and got replaced byglUseProgram().We already called glUseProgram in the GL3 example.
In the GL2 examples there is a comment in the render function that says:
May include this comment in the main.cpp file of the example as well.
I am using SDL+GL2 example. Uncommenting the line with
glUseProgram(0)works too. I use GLEW instead of gl3w, but I don't think that makes any difference.This code based on GL2 example works properly:
@Svennny Ok so your problem is a different one that the one discussed above in the thread, and you probably should be using the GL3 code anyway (every comments and README suggests so, any reason you used this one?)
I think it would be incredibly useful that I copied the
// gluseProgram(0);line with comment also in the main.cpp functions of the GL2 example. Will do that.I've changed to GL3 code and it still works fine.
Environment: ImGui 1.53, SDL2, sdlgfx, gl3w, OpenGL 4.1, macOS 10.13, MacMini Late 2012 (Intel HD Graphics 4000)
Hey, guys, I met exactly the same issue. I really need a GL3 environment, unfortunately maluramichael's trick doesn't work for me.
I figured out that SDL sets the
SDL_GLContextautomatically when modifying some render states of anSDL_Rendererby callingGL_ActivateRendererinSDL_render_gl.c. This makes it more difficult to tell when and which context you are working on. So my current solution is:SDL_RENDERER_SOFTWARErenderer instead ofSDL_RENDERER_ACCELERATEDfor other stuffUntil now this works fine for me, except:
((SDL_Surface*)sur)->format->Amask = 1;to tell SDL using alpha channel for palette indexed software surfaceIt won't be a problem for my case, because I only use the renderer to generate low resolution surfaces when loading assets, (pixel style). I'd read the source over to find out if it's possible to use multiple accelerated contexts when I get time. SDL is poor at documenting on some of its dark corners, this is not the first time that I have to read its source for clues :/
For the record, I solved #1110 (see the last comment). If ever the information is not enough, feel free to ask.
I ran into a related issue with making SDL2's
SDL_Textures work nicely with ImGui.Turns out SDL's abstraction is a little too rigid that you can't get the underlying
GLuint(orLPDIRECT3DTEXTURE9) butSDL_GL_BindTexturedoes the right thing if you're willing to use/editimgui_impl_opengl2.cpp:This is obviously a hacky fix and would benefit from converting the font texture management to remove that
ifbut I'd rather not spend time on that unless it was worth having animgui_impl_sdlrenderer.Frustratingly, SDL2's D3D9 backend could also implement
SDL_GL_BindTexturewith the equivalent forwarding ontod3dDevice->SetTexturebut it doesn't.Admittedly the API name would be misleading in a D3D context but it would allow a hypothetical
impl_sdlrendererto use either the GL2 or D3D9 ImGui backends depending on which driver was used.(Ignoring the bigger problem of potentially encouraging continued use of either backends)
This is tricky.
I don't think it is even possible to implement a imgui_impl_sdlrenderer without poking in either DX9/GL, SDL_Renderer doesn't seem to expose nearly enough functions. I may be wrong but every time I look at the SDL_Renderer I felt it was a very lacking API.. I'm not sure I understand to what purpose it can be used.
Would using SDL_Texture be typically tied to using SDL_Renderer or does it have uses even without SDL_Renderer? How and why you are using it?
The texture binding is the part that is more likely to need customization, so I was thinking perhaps we should make it a standard thing in renderer code that we can override the texture binding function?
And user would be responsible with overriding the font atlas TexId as well if the type they use doesn't match the default renderer type. This is just a rough idea, haven't come up with a fuller design for that yet.
An SDL_Texture is tied to a specific instance of SDL_Renderer, it's roughly a cross-backend abstraction for the underlying device texture managed by a specific SDL_Renderer.
Generally you create a new renderer for a given SDL_Window and SDL picks a suitable backend (but you can override with the
SDL_Hintsystem).These notes on updating from SDL1 to SDL2 might provide some better context: https://wiki.libsdl.org/MigrationGuide#If_your_game_just_wants_to_get_fully-rendered_frames_to_the_screen
In the code I've been using this hack, the usage looks something like
ImGui::Image((ImTextureID)screenTexture, size);which is quite pleasant.Here's a couple of examples of how SDL manages textures on the backends:
See how the GL backend unpacks the internal
GLuintto emit the relevant bind call: https://hg.libsdl.org/SDL/file/5b6f649b6488/src/render/opengl/SDL_render_gl.c#l1630Here's a like for like comparison of a texture operation implemented by both backends:
https://hg.libsdl.org/SDL/file/5b6f649b6488/src/render/direct3d/SDL_render_d3d.c#l1462
https://hg.libsdl.org/SDL/file/5b6f649b6488/src/render/opengl/SDL_render_gl.c#l1377
I would definitely agree that SDL's rendering API leaves a lot to be desired, I imagine most complex projects only use SDL for its input and window management and entirely do their own thing with GL3/4/D3D11 etc.
OS: Ubuntu 18.04
Example code: examples/sdl_opengl3_example
OpenGL loader: default gl3w
Damn it. After about 2 hours of trying, I finally got a workable code mix usage of sdl2 and img-ui with opengl3 exmaple code:
Note theres lines:
These four lines are from the sdl openg3 exmaple. To make mix sdl renderer and imgui work correct, I have to comment the three lines, or imgui will not show or keep blinking.
And most importantly, sdl renderer graphic draws must come before imgui draw.
And
SDL_RenderPresent(renderer);must be called afterImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());Hope these help anyone want to use imgui in their sdl2 game.
I've created a full runnable example here: https://github.com/ryancheung/imgui-mix-sdl2
@ryancheung : thanks a lot for sharing your code. Indeed, it works on Linux, but there is a strange issue I have no clue on how to solve it ...
More precisely, your code (mixing SDL_Renderer AND ImGui) is working successfuly using:
The error is either "missing main" in fragment shader, or both Pixel and Fragment cannot be compiled.
Test have been made with a Linux Intel machine able to use GLSL 450 core (x86_64 Intel HD620 + i7 8550 ). The software is the one I checked out for the repository you mentionned above.
In fact, I cannot expain to myself why #version 150 (same for 330, 330 core, and superior), refuses to work with SDL_Renderer ? Is it an SDL2 limitation ?
Without using the SDL_Renderer, glsl versions until 450 work very well so far (you can e.g. test using : https://github.com/willis7/OpenGL-SDL ).
@ebachard I have not tested the glsl shader yet. And I found the glsl version init code is from the imgui example: https://github.com/ocornut/imgui/blob/master/examples/example_sdl_opengl3/main.cpp#L43
I don't know if imgui with sdl2 limit the
glsl versionto130 only. In the example code, it is.Or the issue you put can be related the three lines of code from the example I commented. You could put back the three commented code lines, which disable the mix, and test if the glsl shader work correctly.
Actually, I don't know much about opengl or glsl, I may not be able to help you a lot.
This seems like tons of effort and hacks to get something working that isn't really going to continue to work well with future SDL2 updates. Also consider the back-end can be software implementation too.
Even if you only allow DX9 or GL2/3 then it seems odd to use library that abstracts the backend but your goal is the smash down the abstraction.. there are other libs that abstract DX/GL/VK and do allow lower level access which seems to be the goal here?
@ocornut
Today, I was testing SDL 2.0.9 with my software, to verify nothing is broken, and I had the idea to do the following changes:
In $SDL2_ROOT_DIR/src/render/opengl/SDL_render_gl.c
And rebuilding the SDL2 libs + linking again everytime, I tested X=2,Y=1 then X=3,Y=0, and finaly X=3,Y=1 with @ryancheung code.
The result is : using OpenGL 2.1 and OpenGL 3.0 contexts, it works as expected, but when using 3,1 it stopped working (SDL2 objects are no longer rendered e.g.)
IMHO, the issue is definitely an SDL2 limitation, unable to enforce a 3.1 or superior OpenGL context, and this could explain the issues with glsl limited to version 130.
I'll try to find the time to ask on libsdl forum. Waiting I'll try to understand in the SDL2 source code why we are stuck with 3.0
Update: I was able to make glsl 3.30 version + OpenGL 4.5 work on Linux using both SDL2 renderer AND imgui OpenGL context !
Still searching for further information, but this is probably the current max we can reach on Linux (with open drivers I mean).The trick was to define some environment variables, e.g. in your ~/.bashrc file, as wrtten below:
Reference link: https://old.reddit.com/r/archlinux/comments/8stpmt/how_can_i_get_opengl_33_with_glsl_33_support/e128v1f/
For the complete explanation, read mesa/src/mesa/main/version.c file in mesa sources (https://gitlab.freedesktop.org/mesa/mesa)
Or in C++ code (don't forget to #include <stdlib.h>), and as example, what I did on my Linux box, using @ryancheung imgui-mix-sdl2 code:
@ryancheung or any other tester:
Using the change above, the two triangles + the imgui winow appear together in the SDL2 window, as expected. Can you confirm it works for you too ?
Second update: got GLSL version working until 4.50, using the right value in the .bashrc (got MESA_GL_VERSION_OVERRIDE=4.5 in my ~/.bashrc).
Means the environment variables seems to work very well. Disclaimer : I'm using mesa 19.1.0 dev, and maybe it will not work with an older version.
Verification : glxinfo -B now reports :
Tested on Linux x86_64 + Intel GPU + OpenGL 3.1 (from 3.1 to 4.5 work)
To confirm my previous post, watching at the recent mesa commits, I've learned that the issue is known since a while, and the same workaround is proposed i965: Fix allow_higher_compat_version workaround limited by OpenGL 3.0
The link is : https://bugs.freedesktop.org/show_bug.cgi?id=107052
Back to the issue : it seems to be tricky, but with some precautions, it seems to be possible to mix SDL2 renderer + OpenGL3+ + glsl version > 130 on Linux (Intel GPU at least)
Closing this for two reasons.
This has been discussed in various places and is confusing the exact interop it may depends on OS/drivers.
See e.g.
https://github.com/ocornut/imgui/issues/4264#issuecomment-868560023
We have a new imgui_impl_sdlrenderer.cpp backend!
FYI, although I personally recommend using native-backends, SDL 2.0.18 (tentative scheduled in 52 days) will add support for a new
SDL_RenderGeometry()function which allowed a SDL_Renderer backend to be created.This is now available on master (currently requires building SDL from latest sources)
https://github.com/ocornut/imgui/pull/3926#issuecomment-924204079
(Note the backend currently doesn't support multi-viewports.)