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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Powereleven

Pages: [1] 2 3
1
I never managed to achieve this using only sf::Context. Maybe it has something to do with incompatible "pixel format" internally?

Digging deeper, I think the following has something to do with it:

In void WglContext::createSurface(HWND window, unsigned int bitsPerPixel), m_deviceContext is updated to a kind of handle to the Win32 window: m_deviceContext = GetDC(window);. This is probably necessary, as window.display() calls SwapBuffers with m_deviceContext as a parameter.

Then, if you use window.create without my changes, it additionally calls void WglContext::createContext(WglContext* shared) in the constructor of WglContext, which calls m_context = wglCreateContextAttribsARB(m_deviceContext, sharedContext, &attributes[0]);, recreating the internal OpenGL context handle HGLRC m_context of WglContext. My adaptation keeps the same HGLRC on the new window.

2
Hello, SFML Forums.

This post is for people who mix custom OpenGL code with SFML.

It's not new that frameworks (like SFML) don't expose low level functionality to be able to keep the same OpenGL context when creating a new window (https://stackoverflow.com/questions/12881049/recreate-window-without-destroying-the-context).

I'm writing this post to show how I managed to minimally adapt SFML's code to support this feature on Windows.

Before, I used to manually delete all my OpenGL resources, call window.create(), then create then back. This is cumbersome and slow, specially when a lot of gigabytes of data are already sitting in the GPU. OpenGL resources included VAO, VBO, FBO, UBO, Shaders, Textures, etc. Now, after recreating the window, I only have to update stuff that actually depend on the window size, like my FBO's GL_TEXTURE_RECTANGLE's with glTexImage2D. Everything is preserved.

We are going to change some things in sfml-window's project.

Firstly, add the directory src\SFML\Window\Win32 to the project's include path. Then, in src/SFML/Window/Window.cpp, add the header #include <SFML/Window/Win32/WglContext.hpp> just below the other headers in the beginning of the file.

Go to SFML/Window/Win32/WglContext.hpp and make this function public:
// ...
public:
void createSurface(HWND window, unsigned int bitsPerPixel);
private:
// ...
 

Then, simply change the beginning of this function:
////////////////////////////////////////////////////////////
void Window::create(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings)
{
        if (m_context)
        {
                delete m_impl;
                m_impl = priv::WindowImpl::create(mode, title, style, settings);
                auto ptr = (sf::priv::WglContext*)m_context;
                ptr->createSurface(m_impl->getSystemHandle(), mode.bitsPerPixel);
                wglMakeCurrent(ptr->m_deviceContext, ptr->m_context);
                initialize();
                return;
        }
        // ...
 

I also noticed that a point for improvement for SFML is remembering the previous state of mouse grabbed, visibility, etc.

Obviously, this is a workaround, and not very pretty. Note that this adaption skips some tests done later in the function, like validating the window's style.

I expect SFML to support this natively in the future, where each platform-specific implementation does its thing.

Cya.

3
General / Re: Can't compile SFML on Windows 11
« on: November 07, 2021, 08:23:02 am »
I'm on Windows 10 and get the same error

4
Network / Workaround to fix connecting nonblocking tcp sockets on Windows
« on: December 20, 2020, 11:28:48 pm »
Hi,
today I decided to try nonblocking tcp socket so I could have a UI that is able to cancel the connecting operation more realiably than using a small timeout in the blocking socket in the connect function, but I found out that calling connect and checking for Done doesn't work on Windows. I found 2 threads from 2012 that mention this problem. https://en.sfml-dev.org/forums/index.php?topic=7435.0 and https://github.com/SFML/SFML/issues/194
Were they ever fixed? Anyway, I'm no expert on windows winsock, so I empirically tested and found out that sleep() a bit after calling connect was enough to work (by work I mean, trying to send bytes worked, even though connect had returned status NotReady), so I suspect that when you call connect, the internal socket is wrongly rebuilt, so it's as if you were always restarting the operation, and it never gets done, as it takes a few milliseconds to connect. Anyway... I coded a small workaround that seems to work fine. Here's some pseudocode. Instead of the more documentation compliant code:
mySocket.setBlocking(false);
while (mySocket.connect(HOST, PORT) != sf::Socket::Status::Done);
mySocket.setBlocking(true); // I only use nonblocking during the first connection phase
 
I do
mySocket.setBlocking(false);
mySocket.connect(HOST, PORT);
while (!mySocket.isConnected())
{
    if (IWantToCancelConnectAttempt)
    {
        mySocket.disconnect();
        goto wherever...
    }
}
mySocket.setBlocking(true);
...
 
where isConnected is implemented like this, which is basically a small portion of the main connect method that doesn't rebuild the socket, but rather just checks what I need
bool TcpSocket::isConnected()
{
        fd_set selector;
        FD_ZERO(&selector);
        FD_SET(getHandle(), &selector);
        timeval time{};
        return select(static_cast<int>(getHandle() + 1), NULL, &selector, NULL, &time);
}
 
I find this documentation confusing https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-select, but apparently timeval == NULL is used for blocking operations, but using it with 0s returns immediately.
That's it. I hope that's useful for anyone having this problem. By the way, where is the most appropriate place to post these kinds of things?

5
Window / Can't declare global window when linking statically
« on: May 04, 2019, 02:48:25 pm »
I get the error "Access violation writing location" when I declare a global sf::RenderWindow, but it works when linking dynamically. What could be happening?

6
Cool!
I like the gta like UI :)
One suggestion: when using sf::Style::Fullscreen, set sf::VideoMode::getDesktopMode().width and height for the window's dimensions so the user can alt + tab the application and have no issues. At least on Windows, for some reason the resolution changes even outside the application.

7
SFML projects / Tetris Clone :P
« on: July 07, 2018, 06:07:12 pm »
Hi forums :)
I decided to make a Tetris Clone, because it is considered a beginner project and I had never tried to do it. I know there are hundreds of Tetris Clones out there, so I made mine a bit different. Every piece has a square as its bounding box (rectangles would mess up the rotations) and they are read from a Pieces.txt file. So I can set pieces in this format:

0 1 0
0 1 0
0 1 0

1 1 1
0 1 0
0 1 0

1 1
1 1

In which the piece must be a square.
I know it's not optimized because I didn't worry about it, since Tetris is by itself a very light game.

Source:
https://github.com/Powereleven/Tetris-Clone

Feedback would be nice :)

8
Thanks, but I still get the error on the console:
An internal OpenGL call failed in RenderTextureImplFBO.cpp(192).
Expression:
   GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.
 
Is it just me?

9
Where exactly do I need to call setActive(); ? I tried many permutations but still no success

10
I did what you said, but I get spammed with errors on the console:
failed to activate opengl context the requested resource is in use
 
PS.: I added
sf::Context context;
 
In the function used by the thread but the error persists

11
What's the terrible mistake I'm making here?

Minimal code:
#include <SFML/Graphics.hpp>
#include <thread>

void run(sf::RenderWindow &window, sf::CircleShape &shape)
{
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                window.clear();
                window.draw(shape);
                window.display();
        }
}

int main()
{
        sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
        sf::CircleShape shape(100.f);
        shape.setFillColor(sf::Color::Green);

        std::thread t1(run, window, shape);
        t1.join();

        return 0;
}
 

Error log:
'sf::RenderWindow::RenderWindow(const sf::RenderWindow &)': attempting to reference a deleted function
 

12
Graphics / Re: I need help handling custom OpenGL with SFML
« on: May 27, 2018, 04:56:47 am »
I found out, I just had to do this...
                glBindVertexArray(0);
                window.pushGLStates();
                window.draw(fps);
                window.popGLStates();
 
It took me so long because I thought pushGLStates did glBindVertexArray(0) automatically.

13
Graphics / Re: I need help handling custom OpenGL with SFML
« on: May 25, 2018, 01:46:03 am »
I added glBindVertexArray(0); after glDrawArrays from Parallelepiped::draw and it stopped the crash. However this way fps is drawn once and then never again. Also, if I switch the order fps and the cube are rendered, it crashes again. What's going on? :o Please help.
Also, just unbinding the VAO, for some reason the depth buffer stopped working.  :o
How do I fix this to properly switch from sfml to custom opengl?

14
Quick fix:
class Game
{
private:
        static sf::RenderWindow window;
        static sf::CircleShape circle;
public:
        static void render()
        {
                while (window.isOpen())
                {
                        window.clear();
                        circle.move(0.1f, 0.0f);
                        window.draw(circle);
                        window.display();
                }
        }
};

sf::RenderWindow Game::window(sf::VideoMode(800, 600), "Test");
sf::CircleShape Game::circle(50.0f);

int main()
{
        Game game;
        Game::render();
}
 
There are many ways to structure your code. This is just a quick fix in case you are wondering how to "make it work" modifying the code you provided the minimum as possible. I would definitely NOT recommend it.

15
Graphics / I need help handling custom OpenGL with SFML
« on: May 24, 2018, 11:51:55 pm »
I have read https://www.sfml-dev.org/tutorials/2.5/window-opengl.php many times but I still can't get things right.
I made a program that prints a simple rotating cube, and everything was working until I decided to mix with SFML Graphics stuff. I just can't understand how to use window.pushGLStates(), window.popGLStates(); and window.setActive(bool) properly.
I read https://github.com/SFML/SFML/blob/master/examples/opengl/OpenGL.cpp#L46 but even using SFML commands that I listed above as used there I still get the error:
An internal OpenGL call failed in RenderTarget.cpp(301).
Expression:
   glVertexPointer(2, GL_FLOAT, sizeof(Vertex), data + 0)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

An internal OpenGL call failed in RenderTarget.cpp(302).
Expression:
   glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 8)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

An internal OpenGL call failed in RenderTarget.cpp(304).
Expression:
   glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.


 
How do I fix this code? (Sorry for the big code, but at least now I am sure I provided a "Minimal, Complete, and Verifiable example" :P However it's easy to read because most of it are just coordinates you can ignore)
PS.: The frameworks I used besides SFML shouldn't interfere in anything.
PS2: I am using SFML 2.5.0
#include <glad/glad.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>

#include <iostream>

int SCR_WIDTH = 800;
int SCR_HEIGHT = 600;

sf::Glsl::Mat4 glm_to_Glsl(glm::mat4 matrix) // converts from glm to glsl for convenience to use with SFML
{
        float m_array[16];
        uint8_t index = 0;
        for (uint8_t i = 0; i < 4; i++)
                for (uint8_t j = 0; j < 4; j++)
                        m_array[index++] = matrix[i][j];
        sf::Glsl::Mat4 matrix_Glsl(m_array);
        return matrix_Glsl;
}

class Resource_manager
{
private:
        sf::RenderTarget &window;
        sf::Font arial;
        sf::Text fps;
        unsigned int fps_counter = 0;
public:
        Resource_manager(sf::RenderTarget &p_window) : window(p_window)
        {
                arial.loadFromFile("arial.ttf");
                fps.setFont(arial);
                fps.setCharacterSize(24);
                fps.setFillColor(sf::Color::Red);
                fps.setString("Hello World"); // for simplicity here
        }
        void show_fps()
        {
                window.draw(fps); // program always breaks here
        }
};

struct Global_variables
{
        static float global_time;
};

float Global_variables::global_time = 0.0f;

class Parallelepiped
{
private:
        unsigned int VAO;
        sf::Shader &shader;
        sf::Texture &texture;
public:
        Parallelepiped(sf::Shader &p_shader, sf::Texture &p_texture) : shader(p_shader), texture(p_texture)
        {
                float vertices[] = {
                        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
                        0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
                        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
                        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

                        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
                        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
                        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
                        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
                        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

                        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

                        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                        0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

                        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
                        0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
                        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
                        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
                        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
                        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

                        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
                        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
                        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
                        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
                        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
                };
                unsigned int VBO;
                glGenVertexArrays(1, &VAO);
                glGenBuffers(1, &VBO);
                glBindVertexArray(VAO);
                glBindBuffer(GL_ARRAY_BUFFER, VBO);
                glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
                glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
                glEnableVertexAttribArray(0);
                glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
                glEnableVertexAttribArray(1);

                shader.setUniform("texture1", sf::Shader::CurrentTexture);
        }
        ~Parallelepiped()
        {
                glDeleteVertexArrays(1, &VAO);
        }

        void draw(glm::mat4 &p_projection, glm::mat4 &p_view)
        {
                sf::Shader::bind(&shader);
                sf::Texture::bind(&texture);

                glm::mat4 model;
                model = glm::translate(model, glm::vec3(0.0f, 0.0f, -3.0f));
                model = glm::rotate(model, Global_variables::global_time, glm::vec3(0.5f, 1.0f, 0.0f));
                shader.setUniform("projection", glm_to_Glsl(p_projection));
                shader.setUniform("view", glm_to_Glsl(p_view));
                shader.setUniform("model", glm_to_Glsl(model));

                glBindVertexArray(VAO);
                glDrawArrays(GL_TRIANGLES, 0, 36);
        }
};

int main()
{
        sf::RenderWindow window(sf::VideoMode(SCR_WIDTH, SCR_HEIGHT), "OpenGL", sf::Style::Default, sf::ContextSettings(32));
        window.setActive(true);
        window.setVerticalSyncEnabled(true);
        window.setMouseCursorGrabbed(true);
        window.setMouseCursorVisible(false);
        window.setKeyRepeatEnabled(false);
        sf::Mouse::setPosition(sf::Vector2i(SCR_WIDTH / 2, SCR_HEIGHT / 2), window);

        Resource_manager resources(window); // load resources

        gladLoadGL();
        glEnable(GL_DEPTH_TEST);

        sf::Shader cube_shader;
        cube_shader.loadFromFile("cube.vs", "cube.fs"); // just standard shaders
        sf::Texture cube_texture;
        cube_texture.loadFromFile("background.jpg");

        Parallelepiped cube(cube_shader, cube_texture);

        sf::Clock clock;

        while (window.isOpen())
        {
                float dt = clock.restart().asSeconds();
                Global_variables::global_time += dt;
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                        {
                                window.close();
                        }
                        else if (event.type == sf::Event::Resized)
                        {
                                glViewport(0, 0, event.size.width, event.size.height);
                                SCR_WIDTH = event.size.width;
                                SCR_HEIGHT = event.size.height;
                        }

                        if (event.type == sf::Event::KeyPressed)
                        {
                                if (event.key.code == sf::Keyboard::Escape)
                                {
                                        window.close();
                                }
                        }
                }

                glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                // Draw ...
                glm::mat4 view;
                glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);

                cube.draw(projection, view);
                //resources.show_fps(); // error :((((((( it works if I comment this line
                window.display();
        }

        // release resources...

        return 0;
}
 

Pages: [1] 2 3