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

Using ImGui-SFML with OpenGL 3.0 and SFML 2.5.1 #109

Closed
PuscasuRobert opened this issue Oct 5, 2019 · 3 comments
Closed

Using ImGui-SFML with OpenGL 3.0 and SFML 2.5.1 #109

PuscasuRobert opened this issue Oct 5, 2019 · 3 comments
Labels

Comments

@PuscasuRobert
Copy link

PuscasuRobert commented Oct 5, 2019

I think a bug in your ImGui-SFML implementation. Since i dont understand the code 100% there is a slight chance that my solution is not 100% correct. Lets begin:

I want to build a project that uses OpenGL 3.0, ImGui-SFML and SFML 2.5.1. I wanted to draw the widgets with ImGui-SFML, but i want the scene to be rendered with OpenGL 3.0, not with SFML draw functions. I managed to make install all these libraries and compile the project. But at runtime something weird happened. It crashed. This is a small example of the code:

#include "pch.h"
#include "imgui.h"
#include "imgui-SFML.h"

#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Graphics/CircleShape.hpp>

#include <iostream>
using namespace std;

int main()
{
	sf::ContextSettings settings;
	settings.depthBits = 24;
	settings.stencilBits = 8;
	settings.antialiasingLevel = 8;
	settings.majorVersion = 3;
	settings.minorVersion = 0;
	
	sf::RenderWindow window(sf::VideoMode(640, 480), "ImGui + SFML = <3",sf::Style::Close,settings);
	window.setFramerateLimit(60); 
	window.setActive(); 
	
	ImGui::SFML::Init(window); 

	glewExperimental = GL_TRUE; 
	GLenum errorCode = glewInit(); 

	unsigned int VBO, VAO = -1; 
	glGenVertexArrays(1, &VAO); 
	glGenBuffers(1, &VBO); 
	glBindVertexArray(VAO); 
	glBindVertexArray(0);//THIS LINE FIXES THE BUG. Without it, the function RenderDrawLists() crashes. I dont fully understand why, i just know that this line fixes it, after spending 7 hours trying to make this work. You should add this line at the end of RenderDrawLists() function.

	sf::Clock deltaClock; 
	int i;
	for(i=0;i<3;i++) 
	{
		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(); 
		ImGui::SFML::Render(window); 
		window.display(); 
	}

	ImGui::SFML::Shutdown();
}

I was able to make the program not crash when it was using only OpenGL 3.0 draw calls and i managed to make it not crash when it was only using ImGui draw calls. So i realised that these 2 things affect each other. I managed to find the exact line at which the code crashes. Its at line "glBindVertexArray(VAO); ". Read that again, its "gl BIND vertex array" , not "glGenVertexArray".
After some hours of debugging, i figured out that the function "void RenderDrawLists ( ImDrawData* draw_data )" doesnt unbind the vertex array after it draws it. So i wrote "glBindVertexArray(0);" my code, and it stopped crashing. Normally, its my job to make sure i call that line after I'm done with a draw call, but i think it would be better for the library to also call that line, because today i lost 7 hours trying to fix this bug. If you want, i can send you a code repository with my example to show you that it crashes. Anyway, i hope this helps.

@eliasdaler
Copy link
Contributor

Hello
Sorry it took you so long to debug this - I'm not very good at OpenGL and when I started to work on imgui-sfml I just copied the implementation from previous ImGui+SFML thing and I don't fully understand which OpenGL state it modifies and restores.

Look at how complicated ImGui's OpenGL renderer example is: https://github.com/ocornut/imgui/blob/f0f5301612dbaa2caeede3091df6aee1c872dbdf/examples/imgui_impl_opengl3.cpp
... and it's different from OpenGL2 example: https://github.com/ocornut/imgui/blob/f0f5301612dbaa2caeede3091df6aee1c872dbdf/examples/imgui_impl_opengl2.cpp

SFML uses OpenGL 2, so ImGui-SFML should use this OpenGL2 implementation by default, which is discussed in #79 - unfortunately I didn't have time to work on that.

For now, I recommend trying not to call ImGui::SFML::Render, but to use imgui_impl_opengl3.cpp with your program somehow - I'm still not sure how to embed it into ImGui-SFML.

@PuscasuRobert
Copy link
Author

From my knowledge, OpenGL 3.0 is just OpenGL 2.0 with extra steps. You have to load at runtime the functions your GPU uses, using the function glewInit() (see my code above). So as long as you write the necessary lines of code that set up the variables OpenGL 3.0 needs, it will work the same way as OpenGL 2.0. By adding that line, the project works now. That line tells the GPU the index of the object that will be drawn in the next draw call. It stores this index in a variable. The exception is the value 0. If you give 0 as a parameter, it wont draw anything. Somehow, if you call RenderDrawLists() without having that variable be 0, it crashes.

I learned everything i know of OpenGL 3.0 from here: https://learnopengl.com/Getting-started/Hello-Triangle. Maybe this will help one day.

@eliasdaler
Copy link
Contributor

Caused by #159 - closing

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