Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED] Exception when static linking SFML  (Read 3032 times)

0 Members and 2 Guests are viewing this topic.

ranseur

  • Newbie
  • *
  • Posts: 5
    • View Profile
[SOLVED] Exception when static linking SFML
« on: October 29, 2015, 10:43:11 am »
When I started to use a header file that uses opengl my project started to throw this exception:




Curios thing is that it does that only when I am both static linking SFML AND using opengl, in every other case it works fine.

Here is my main.cpp:

#include "imgui.h"
#include "imgui-events-SFML.h"
#include "imgui-rendering-SFML.h"
#include <SFML/Graphics.hpp>

int main() {
        sf::RenderWindow win{ { 800, 600 }, "window" };
        win.setFramerateLimit(60);
        while (win.isOpen()) {
                sf::Event e;
                while (win.pollEvent(e)) {
                        if (e.type == sf::Event::Closed) {
                                win.close();
                        }
                }
                win.clear(sf::Color::Blue);
                win.display();
        }
}
 

Here is the header that makes use of opengl:

#ifndef IMGUI_SFML_RENDERING_BACKEND
#define IMGUI_SFML_RENDERING_BACKEND
#include <vector>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <iostream>
namespace ImGui
{
        namespace ImImpl
        {
                static sf::RenderTarget* ImImpl_rtarget;
                static sf::Texture ImImpl_fontTex;

                static void ImImpl_RenderDrawLists(ImDrawData* draw_data)
                {
                        if (draw_data->CmdListsCount == 0)
                                return;

                        ImImpl_rtarget->pushGLStates();

                        GLint last_texture;
                        glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
                        glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                        glDisable(GL_CULL_FACE);
                        glDisable(GL_DEPTH_TEST);
                        glEnable(GL_SCISSOR_TEST);
                        glEnableClientState(GL_VERTEX_ARRAY);
                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                        glEnableClientState(GL_COLOR_ARRAY);
                        glEnable(GL_TEXTURE_2D);

                        glMatrixMode(GL_PROJECTION);
                        glPushMatrix();
                        glLoadIdentity();
                        glOrtho(0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
                        glMatrixMode(GL_MODELVIEW);
                        glPushMatrix();
                        glLoadIdentity();

                        sf::RenderStates states;
                        states.blendMode = sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::OneMinusSrcAlpha);

#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
                        for (int n = 0; n < draw_data->CmdListsCount; n++)
                        {
                                const ImDrawList* cmd_list = draw_data->CmdLists[n];
                                const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front();
                                const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
                                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)));

                                for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
                                {
                                        const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
                                        if (pcmd->UserCallback)
                                        {
                                                pcmd->UserCallback(cmd_list, pcmd);
                                        }
                                        else
                                        {
                                                sf::Vector2u win_size = ImImpl_rtarget->getSize();
                                                sf::Texture::bind(&ImImpl::ImImpl_fontTex);
                                                glScissor((int)pcmd->ClipRect.x, (int)(win_size.y - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
                                                glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer);
                                        }
                                        idx_buffer += pcmd->ElemCount;
                                }
                        }
#undef OFFSETOF

                        // Restore modified state
                        glDisableClientState(GL_COLOR_ARRAY);
                        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                        glDisableClientState(GL_VERTEX_ARRAY);
                        glBindTexture(GL_TEXTURE_2D, last_texture);
                        glMatrixMode(GL_MODELVIEW);
                        glPopMatrix();
                        glMatrixMode(GL_PROJECTION);
                        glPopMatrix();
                        glPopAttrib();

                        ImImpl_rtarget->popGLStates();
                }
        }
        namespace SFML
        {
                static void SetRenderTarget(sf::RenderTarget& target) { ImImpl::ImImpl_rtarget = &target; }
                static void InitImGuiRendering()
                {
                        ImGuiIO& io = ImGui::GetIO();
                        io.DisplaySize = ImVec2(ImImpl::ImImpl_rtarget->getSize().x, ImImpl::ImImpl_rtarget->getSize().y);
                        io.RenderDrawListsFn = ImImpl::ImImpl_RenderDrawLists;
                        unsigned char* pixels;
                        int width, height;
                        io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
                        ImImpl::ImImpl_fontTex.create(width, height);
                        ImImpl::ImImpl_fontTex.update(pixels);
                        io.Fonts->TexID = (void*)&ImImpl::ImImpl_fontTex;
                        io.Fonts->ClearInputData();
                        io.Fonts->ClearTexData();
                }
                static void UpdateImGuiRendering()
                {
                        ImGuiIO& io = ImGui::GetIO();
                        io.DisplaySize = ImVec2(ImImpl::ImImpl_rtarget->getSize().x, ImImpl::ImImpl_rtarget->getSize().y);
                }
        }
}
#endif
 

(I am trying to get imgui to work  within sfml, and I am 99% there)

My project settings:



(I have added SFML_STATIC to the preprocessor, the projects runs fine with static linking sfml if I am not using opengl)

I'm quite new to both cpp and sfml, and I have no clue on how I could go about resolving this issue.

Thanks.
« Last Edit: October 31, 2015, 12:35:27 pm by ranseur »

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: Exception when static linking SFML and using opengl
« Reply #1 on: October 29, 2015, 10:49:56 am »
You mistyped sfml-system-s-d.

ranseur

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Exception when static linking SFML and using opengl
« Reply #2 on: October 29, 2015, 10:55:02 am »
You mistyped sfml-system-s-d.

Sorry, that came about when pressing win+S to bring up the screenshot program. It's not that. I have corrected the image.
« Last Edit: October 29, 2015, 10:56:39 am by ranseur »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10901
    • View Profile
    • development blog
    • Email
Exception when static linking SFML and using opengl
« Reply #3 on: October 29, 2015, 11:07:23 am »
Show the call stack.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ranseur

  • Newbie
  • *
  • Posts: 5
    • View Profile
« Last Edit: October 29, 2015, 01:02:09 pm by ranseur »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10901
    • View Profile
    • development blog
    • Email
Exception when static linking SFML and using opengl
« Reply #5 on: October 29, 2015, 11:23:05 am »
Ah, you have a static (i.e. global) sf::Texture. Don't do that.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ranseur

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Exception when static linking SFML and using opengl
« Reply #6 on: October 29, 2015, 11:39:17 am »
Ah, you have a static (i.e. global) sf::Texture. Don't do that.

Thanks man!

I'm not really sure how to go about fixing that (and here my ignorance shows abundantly) but I'll see what I can do.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10901
    • View Profile
    • development blog
    • Email
Exception when static linking SFML and using opengl
« Reply #7 on: October 29, 2015, 12:03:24 pm »
If you can't/don't want to change the design, you'll just have to make sure that the texture doesn't get initialized in global scope.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ranseur

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Exception when static linking SFML and using opengl
« Reply #8 on: October 29, 2015, 12:51:15 pm »
EDIT 1: I have solved this on my own. The problem was the one described here: http://en.sfml-dev.org/forums/index.php?topic=7276.0

I just solved it by destroying my sf::Texture manually before closing the program. Thanks again!

EDIT 2: Apparently it's not really solved... Well, since it doesn't throw the error when in realease mode, I'll rest my case for now.

Thanks to Aster the static sf::Texture is resolved. Now it works fine until I close my window. Closing it will give this error:





There are other static things that should not be static?

This is how the sf::Texture was fixed
#ifndef IMGUI_SFML_RENDERING_BACKEND
#define IMGUI_SFML_RENDERING_BACKEND
#include <vector>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderTarget.hpp>
#include <iostream>
#include <memory>
namespace ImGui
{
        namespace ImImpl
        {
                static sf::RenderTarget* ImImpl_rtarget;
                static std::shared_ptr<sf::Texture> ImImpl_fontTex;

                static void ImImpl_RenderDrawLists(ImDrawData* draw_data)
                {
                        if (draw_data->CmdListsCount == 0)
                                return;

                        ImImpl_rtarget->pushGLStates();

                        GLint last_texture;
                        glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
                        glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                        glDisable(GL_CULL_FACE);
                        glDisable(GL_DEPTH_TEST);
                        glEnable(GL_SCISSOR_TEST);
                        glEnableClientState(GL_VERTEX_ARRAY);
                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                        glEnableClientState(GL_COLOR_ARRAY);
                        glEnable(GL_TEXTURE_2D);

                        glMatrixMode(GL_PROJECTION);
                        glPushMatrix();
                        glLoadIdentity();
                        glOrtho(0.0f, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 0.0f, -1.0f, +1.0f);
                        glMatrixMode(GL_MODELVIEW);
                        glPushMatrix();
                        glLoadIdentity();

                        sf::RenderStates states;
                        states.blendMode = sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::OneMinusSrcAlpha);

#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
                        for (int n = 0; n < draw_data->CmdListsCount; n++)
                        {
                                const ImDrawList* cmd_list = draw_data->CmdLists[n];
                                const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front();
                                const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
                                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)));

                                for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
                                {
                                        const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
                                        if (pcmd->UserCallback)
                                        {
                                                pcmd->UserCallback(cmd_list, pcmd);
                                        }
                                        else
                                        {
                                                sf::Vector2u win_size = ImImpl_rtarget->getSize();
                                                sf::Texture::bind(ImImpl::ImImpl_fontTex.get());
                                                glScissor((int)pcmd->ClipRect.x, (int)(win_size.y - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
                                                glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer);
                                        }
                                        idx_buffer += pcmd->ElemCount;
                                }
                        }
#undef OFFSETOF

                        // Restore modified state
                        glDisableClientState(GL_COLOR_ARRAY);
                        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                        glDisableClientState(GL_VERTEX_ARRAY);
                        glBindTexture(GL_TEXTURE_2D, last_texture);
                        glMatrixMode(GL_MODELVIEW);
                        glPopMatrix();
                        glMatrixMode(GL_PROJECTION);
                        glPopMatrix();
                        glPopAttrib();

                        ImImpl_rtarget->popGLStates();
                }
        }
        namespace SFML
        {
                static void SetRenderTarget(sf::RenderTarget& target) { ImImpl::ImImpl_rtarget = &target; }
                static void InitImGuiRendering()
                {
                        ImGuiIO& io = ImGui::GetIO();
                        io.DisplaySize = ImVec2(ImImpl::ImImpl_rtarget->getSize().x, ImImpl::ImImpl_rtarget->getSize().y);
                        io.RenderDrawListsFn = ImImpl::ImImpl_RenderDrawLists;
                        unsigned char* pixels;
                        int width, height;
                        io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
                        ImImpl::ImImpl_fontTex = std::make_shared<sf::Texture>();
                        ImImpl::ImImpl_fontTex->create(width, height);
                        ImImpl::ImImpl_fontTex->update(pixels);
                        io.Fonts->TexID = (void*)&ImImpl::ImImpl_fontTex;
                        io.Fonts->ClearInputData();
                        io.Fonts->ClearTexData();
                }
                static void UpdateImGuiRendering()
                {
                        ImGuiIO& io = ImGui::GetIO();
                        io.DisplaySize = ImVec2(ImImpl::ImImpl_rtarget->getSize().x, ImImpl::ImImpl_rtarget->getSize().y);
                }
        }
}
#endif
 

The sf::Window is here:
#ifndef IMGUI_SFML_EVENTS_BACKEND
#define IMGUI_SFML_EVENTS_BACKEND
#include <vector>
#include <SFML/Window/Keyboard.hpp>
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Window.hpp>

namespace ImGui
{
    namespace ImImpl
    {
        static sf::Clock ImImpl_timeElapsed;
        static bool ImImpl_mousePressed[5] = { false, false, false, false, false };
        static sf::Window* ImImpl_window;
    }
    namespace SFML
    {
        static void SetWindow(sf::Window& window){ImImpl::ImImpl_window=&window;}
        static void ProcessEvent(sf::Event &event)
        {
            switch(event.type)
            {
                case sf::Event::MouseButtonPressed:
                {
                    ImImpl::ImImpl_mousePressed[event.mouseButton.button]=true;
                    break;
                }
                case sf::Event::MouseButtonReleased:
                {
                    ImImpl::ImImpl_mousePressed[event.mouseButton.button]=false;
                    break;
                }
                case sf::Event::MouseWheelMoved:
                {
                    ImGuiIO& io = ImGui::GetIO();
                    io.MouseWheel += (float)event.mouseWheel.delta;
                    break;
                }
                case sf::Event::KeyPressed:
                {
                    ImGuiIO& io = ImGui::GetIO();
                    io.KeysDown[event.key.code]=true;
                    io.KeyCtrl=event.key.control;
                    io.KeyShift=event.key.shift;
                    break;
                }
                case sf::Event::KeyReleased:
                {
                    ImGuiIO& io = ImGui::GetIO();
                    io.KeysDown[event.key.code]=false;
                    io.KeyCtrl=event.key.control;
                    io.KeyShift=event.key.shift;
                    break;
                }
                case sf::Event::TextEntered:
                {
                    if(event.text.unicode > 0 && event.text.unicode < 0x10000)
                        ImGui::GetIO().AddInputCharacter(event.text.unicode);
                    break;
                }
                default: break;
            }
        }

        static void InitImGuiEvents()
        {
            ImGuiIO& io = ImGui::GetIO();
            io.KeyMap[ImGuiKey_Tab] = sf::Keyboard::Tab;
            io.KeyMap[ImGuiKey_LeftArrow] = sf::Keyboard::Left;
            io.KeyMap[ImGuiKey_RightArrow] = sf::Keyboard::Right;
            io.KeyMap[ImGuiKey_UpArrow] = sf::Keyboard::Up;
            io.KeyMap[ImGuiKey_DownArrow] = sf::Keyboard::Down;
            io.KeyMap[ImGuiKey_Home] = sf::Keyboard::Home;
            io.KeyMap[ImGuiKey_End] = sf::Keyboard::End;
            io.KeyMap[ImGuiKey_Delete] = sf::Keyboard::Delete;
            io.KeyMap[ImGuiKey_Backspace] = sf::Keyboard::BackSpace;
            io.KeyMap[ImGuiKey_Enter] = sf::Keyboard::Return;
            io.KeyMap[ImGuiKey_Escape] = sf::Keyboard::Escape;
            io.KeyMap[ImGuiKey_A] = sf::Keyboard::A;
            io.KeyMap[ImGuiKey_C] = sf::Keyboard::C;
            io.KeyMap[ImGuiKey_V] = sf::Keyboard::V;
            io.KeyMap[ImGuiKey_X] = sf::Keyboard::X;
            io.KeyMap[ImGuiKey_Y] = sf::Keyboard::Y;
            io.KeyMap[ImGuiKey_Z] = sf::Keyboard::Z;
            ImImpl::ImImpl_timeElapsed.restart();
        }

        static void UpdateImGui()
        {
            ImGuiIO& io = ImGui::GetIO();
            static double time = 0.0f;
            const double current_time = ImImpl::ImImpl_timeElapsed.getElapsedTime().asSeconds();
            io.DeltaTime = (float)(current_time - time);
            time = current_time;
            sf::Vector2i mouse = sf::Mouse::getPosition(*ImImpl::ImImpl_window);
            io.MousePos = ImVec2((float)mouse.x, (float)mouse.y);
            io.MouseDown[0] = ImImpl::ImImpl_mousePressed[0] || sf::Mouse::isButtonPressed(sf::Mouse::Left);
            io.MouseDown[1] = ImImpl::ImImpl_mousePressed[1] || sf::Mouse::isButtonPressed(sf::Mouse::Right);
            ImGui::NewFrame();
        }
    }
}
#endif
 

Thanks again.
« Last Edit: October 31, 2015, 06:23:24 pm by ranseur »

 

anything