Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An issue using modern OpenGL and Imgui-SFML ? #55

Closed
fteppe opened this issue May 31, 2018 · 4 comments
Closed

An issue using modern OpenGL and Imgui-SFML ? #55

fteppe opened this issue May 31, 2018 · 4 comments
Labels

Comments

@fteppe
Copy link

fteppe commented May 31, 2018

Hello,

I tried using your work since I already use a SFML window for my openGL project.

For now it pretty much crashes as soon as I try to display the GUI calling:
ImGui::SFML::Render(window)

Before that I get a lot of errors during my openGL operations
An internal OpenGL call failed in Texture.cpp(667). Expression: glMatrixMode(GL_MODELVIEW) Error description: GL_INVALID_OPERATION The specified operation is not allowed in the current state.

I'm not sure which "texture.cpp" this is, I have such a class but it is not 667 lines long. But it seems there is some state conflict between my openGL operations and the ones done by IMGUI-SFML.

I know that the othaur of Imgui advised against mixing modern and old openGL and I also noticed that the imgui-sfml.cpp file had the following lines:
` glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();`

as well as :
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, pos))); glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, uv))); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + offsetof(ImDrawVert, col)));

which look like 1.2 openGL. could it be that your openGL code is at odds with mine? Is there a way around it?

The init of my window and openGL context is this:

` std::cout << "starting application" << std::endl;
/*
WINDOW OPENGL INIT
*/
const std::string title = "openGL";
sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.antialiasingLevel = 2; // Optional
// Request OpenGL version 3.2 (optional but recommended)
settings.majorVersion = 4;
settings.minorVersion = 5;
settings.attributeFlags = sf::ContextSettings::Core;

unsigned width = WIDTH;
unsigned height = HEIGHT;


window.create(sf::VideoMode(width, height), "Tetra Engine", sf::Style::Close, settings);
ImGui::SFML::Init(window);

glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glewExperimental = GL_TRUE;
glewInit();
//apparently an old implementation bug tends to raise an error on startup. We call geterror to remove it.
glGetError();`

I do the following in my main loop:

` tetraRender::EventHandler handler(scene);
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop

	sf::Event event;
	int time = clock.getElapsedTime().asMilliseconds();
	int frameTime = sf::milliseconds(16).asMilliseconds();
	bool needNewFrame = time >= frameTime;
	//It would seem that without this sync, there is a fall in performance. Not sure why yet. Also the application takes way more resources without it;
	//std::cout << '\r' << std::setw(4) << std::setfill(' ');
	if (needNewFrame)
	{


		//Render time.

		std::cout << '\r' << std::setw(4) << std::setfill(' ') << time;
		clock.restart();

		scene->renderScene();
		
	}
	if (window.pollEvent(event))
	{

		handler.handle(event);
		// "close requested" event: we close the window
		if (event.type == sf::Event::Closed)
		{
			window.close();

		}
	}
	ImGui::SFML::ProcessEvent(event);
	ImGui::SFML::Update(window, deltaClock.restart());


	if (ImGui::Button("Update window title")) {
		// this code gets if user clicks on the button
		// yes, you could have written if(ImGui::InputText(...))
		// but I do this to show how buttons work :)
	}
	ImGui::End(); // end window

	ImGui::SFML::Render(window);
	window.display();

}`

in scene->renderScene() I do a lot of opengl state calls to render my scenes using multiple framebuffers and shaders using opengl 4.3.

I would like to add that the system crashes during a call to Imgui::End() because g.currentWindow is null. And the many openGL errors appear during the call of window.resetGLStates();

@eliasdaler
Copy link
Contributor

Hello

The "Texture.cpp" is SFML's sf::Texture. Which probably means that you're messing SFML's internal state of OpenGL by calling OpenGL where SFML doesn't expect you to do so. Try calling push/pop/resetGLStates around the code where you use OpenGL. I'm not sure about the order in your case, check out the guide here: https://www.sfml-dev.org/tutorials/2.5/window-opengl.php#using-opengl-together-with-the-graphics-module

You can also try doing this: (You'll also need to remove resetGLStates from ImGui::SFML::Render)

window.pushGLStates();
ImGui::SFML::Render(window);
window.popGLStates();

I would like to add that the system crashes during a call to Imgui::End() because g.currentWindow is null

On what line exactly does it crash?

@fteppe
Copy link
Author

fteppe commented May 31, 2018

Hey, so in tinkered around for a while and I tried to remove everything unnecessary to see what was going on.

so when I don't initialize openGL I have this:
image

To do this I started a RenderWindows WITHOUT settings, leaving them to default I believe.
std::cout << "starting application" << std::endl;
/*
WINDOW OPENGL INIT
*/
const std::string title = "openGL";
sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.antialiasingLevel = 2; // Optional
// Request OpenGL version 3.2 (optional but recommended)
settings.majorVersion = 4;
settings.minorVersion = 3;
settings.attributeFlags = sf::ContextSettings::Core;

unsigned width = WIDTH;
unsigned height = HEIGHT;


sf::RenderWindow window(sf::VideoMode(width, height), "Tetra Engine", sf::Style::Default, settings);
window.setFramerateLimit(60);

window.setActive();

glewExperimental = GL_TRUE;
glewInit();
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
ImGui::CreateContext();
ImGui::SFML::Init(window);

sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);

sf::Clock deltaClock;
while (window.isOpen()) {
	sf::Event event;
	while (window.pollEvent(event)) {
		ImGui::SFML::ProcessEvent(event);

		if (event.type == sf::Event::Closed) {
			window.close();
		}
	}

	ImGui::SFML::Update(window, deltaClock.restart());


	ImGui::Begin("Hello, world!");
	ImGui::Button("Look at this pretty button");
	ImGui::End();

	window.clear();
	window.draw(shape);
	window.pushGLStates();
	ImGui::SFML::Render(window);
	window.popGLStates();
	window.display();
}

ImGui::SFML::Shutdown();


	return 0;`

So this is pretty much all of my code, and from window.clear() to window.display() it seems each line will raise errors from SFML. And this is pretty much only Imgui code that is beeing executed here, I don't do any openGL code of my own.

I am not sure what is causing this because I removed pretty much all of my code and it is still breaking. So you'll notice that one way for it to work is to remove settings from the constructor but of course it means no openGL context.

EDIT: I moved to SDL since I used very little of SFML. So if you have other questions I'll try to go back to older versions of my code if necessary but apparently since I wanted a core context and SFML doesn't work that well with them it caused issues.

@eliasdaler
Copy link
Contributor

Thanks! This is close to a minimal reproducible example, so I'll try to reproduce it and see what I can do.

@eliasdaler
Copy link
Contributor

Closing, #159.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants