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 - Wizzard

Pages: 1 2 [3] 4 5 ... 15
31
Window / Handling User Input
« on: April 21, 2011, 03:28:07 am »
The input class, internally, is functionally equivalent to your class except that the input class does not register callback functions. Instead, the input class can be queried for the state of an input by calling the appropriate function. Here's the code to show you just how equivalent they are.
Code: [Select]
bool Input::IsKeyDown(Key::Code key) const
{
    return myKeys[key];
}


void Input::OnEvent(const Event& event)
{
    switch (event.Type)
    {
        // Key events
        case Event::KeyPressed :  myKeys[event.Key.Code] = true;  break;
        case Event::KeyReleased : myKeys[event.Key.Code] = false; break;

        // Mouse event
        case Event::MouseButtonPressed :  myMouseButtons[event.MouseButton.Button] = true;  break;
        case Event::MouseButtonReleased : myMouseButtons[event.MouseButton.Button] = false; break;

        // Mouse move event
        case Event::MouseMoved :
            myMouseX = event.MouseMove.X;
            myMouseY = event.MouseMove.Y;
            break;

        // Joystick button events
        case Event::JoyButtonPressed :  myJoystickButtons[event.JoyButton.JoystickId][event.JoyButton.Button] = true;  break;
        case Event::JoyButtonReleased : myJoystickButtons[event.JoyButton.JoystickId][event.JoyButton.Button] = false; break;

        // Joystick move event
        case Event::JoyMoved :
            myJoystickAxis[event.JoyMove.JoystickId][event.JoyMove.Axis] = event.JoyMove.Position;
            break;

        // Lost focus event : we must reset all persistent states
        case Event::LostFocus :
            ResetStates();
            break;

        default :
            break;
    }
}


Futhermore, SFML runs the OnEvent callback of the Input class always. This means that you always have the SFML input manager running even when you're not using it. It's unnecessary to have two implementations of the same thing running at the same time. Even if you want to create your own input manager for portability to other input managing libraries, you should simply rebind the functions of your input manager to use SFML's input manager. You won't be able to use callback functions like this, but instead, just give the objects in your application an update method that is run every frame and checks for it's own input. Those callback functions add some extremely minor overhead too that is unnecessary. Your method doesn't have any code encapsulation benefits over my method either. Both implementations make classes fully aware of what input they're going to receive. The same amount of internal information is exposed.

32
Window / Handling SetActive efficiently in multithreaded environments
« on: April 20, 2011, 10:09:29 am »
How do you make a thread wait for another thread?

In SFML, the only way I can think of is like this
Code: [Select]
while (!threadReady)
    sf::Sleep(0.1);


Anyways, I will just curb the majority of my curiosity until your threading library is complete.

33
Window / Handling User Input
« on: April 20, 2011, 09:27:06 am »
You are over complicating this to an extreme. For one, don't use events to see if a key is down, just use the window's input.

Using the window's input tutorial (skip to "Getting real-time inputs")
Input (SFML 1.6)
Input (SFML 2.0)

If you want objects to be aware of input, just make the window's input globally accessable via a global variable, a function that returns a reference or pointer to the input, or via passing a reference or pointer to functions.

Quote from: "Megatron"
Additionally, I'm likely going to need to know later on when the key became active, so I might change my array from a bool array to an array of bools/float where float indicates the gametime when that input became active

Create a timer that activates when the pressed event of the key you're measuring is triggered. Then, check on every frame to see if the timer has elapsed the amount of seconds you want it to and, if it has, do what you want to be done. Finally, make sure to ignore the timer if a released event is called for the key you're measuring.

Edit:
You should also ignore the timer if a LostFocus event occurs.

34
Network / Good idea for a network thread?
« on: April 20, 2011, 09:12:27 am »
I'm interested in how using a while loop to use the receive function is different than an if statement.

35
General / Good Collision detection technique?
« on: April 20, 2011, 09:07:09 am »
sf::Rect::Intersect handles detecting intersecting rectangles for you.

Rect (SFML 1.6)
Rect (SFML 2.0)



SFML 2.0 implementation
Code: [Select]
template <typename T>
bool Rect<T>::Intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
{
    // Compute the intersection boundaries
    T left   = std::max(Left,         rectangle.Left);
    T top    = std::max(Top,          rectangle.Top);
    T right  = std::min(Left + Width, rectangle.Left + rectangle.Width);
    T bottom = std::min(Top + Height, rectangle.Top + rectangle.Height);

    // If the intersection is valid (positive non zero area), then there is an intersection
    if ((left < right) && (top < bottom))
    {
        intersection = Rect<T>(left, top, right - left, bottom - top);
        return true;
    }
    else
    {
        intersection = Rect<T>(0, 0, 0, 0);
        return false;
    }
}

36
System / Re: Pause for input and displaying values
« on: April 19, 2011, 03:15:27 am »
Quote from: "Stupebrett"
How do I display a value? For example; int value = 5. How do I display "value" to the window?

You should read the displaying text tutorial here: http://www.sfml-dev.org/tutorials/1.6/graphics-fonts.php
The console is still a viable source for output too if you don't disable it.

Quote from: "Stupebrett"
My first question is: How do I make the program stop/pause completely until the user for example presses a key? (Like the _getch() function from the conio.h header).

You can change your main loop to the following:
Code: [Select]
// At any point, you can call "wait = true;" in order to make the application wait for a key press
bool wait = false;

while (window.IsOpened())
{
    sf::Event event;
    while (window.GetEvent(event)) // This function has been renamed to PollEvent in SFML 2.0
    {
        if (event.Type == sf::Event::Closed)
            window.Close();
        else if (event.Type == sf::Event::KeyPressed)
            // Stop waiting if a key was pressed
            wait = false;

        // Don't process any other events if we're waiting
        if (!wait)
        {
            // Process your own events here
        }
    }

    // Don't process any drawing or logic if we're waiting
    if (!wait)
    {
        // Process your drawing and logic here

        // Example: Draw a randomized rectangle every frame
        window.Draw(sf::Shape::Rectangle(sf::Randomizer::Random(0, 540), sf::Randomizer::Random(0, 380), 100, 100, sf::Color::White));
        static sf::Clock timer;
        if (timer.GetElapsedTime() >= 4)
        {
            // If four seconds have elapsed since the first frame, call "wait = true;"
            wait = true;
        }
    }

    window.Display();
}

37
Window / Handling SetActive efficiently in multithreaded environments
« on: April 18, 2011, 03:25:29 pm »
To clarify, this is similar to treating threads sort of like blocking sockets, right? I'd process a thread until it needs data from other threads and then make a blocking call to request data from another thread. It seems too similar to mutexes to me. Do you have a compilable implementation I can toy with in order to see the difference? Does this really get a better performance than using mutexes?

38
Graphics / [solved] Dragging with mouse
« on: April 18, 2011, 07:00:31 am »
There is two reasons on why I ask you to write a compilable, minimal example. The first being that you may, while writing new code, discover something you did wrong previously. If that's not the case, then secondly, it's easy for me to go in and run the new code and edit if it's not bloated with all the unimportant bits to your problem. It's very hard for me to look at portions of an entire project and think about how to theoretically fix a small problem. I need to know exactly what is happening and I feel as if going through your whole project to learn exactly what is happening instead of a small example is a waste of my time. I hope you can understand. If you reproduce your drag and drop problem in a minimal example, I can make every effort to help you out.

Edit:
Also, in your example, I don't even see any code that moves a sf::Shape. It's mainly internal state changes and functions that call your custom functions that I don't know what do except for inferring from their names. There isn't enough here for me to even recreate your method of dragging sf::Shapes around.

39
Window / Handling SetActive efficiently in multithreaded environments
« on: April 18, 2011, 06:16:53 am »
That sounds pretty interesting Groogy, but I've decided to keep it simple, at least for now, and just get rid of threads on the C++ side for my game engine.

Quote from: "Groogy"
Also the whole thing with scripts having direct access to rendering context is not an appropriate way to go.

They don't have direct access to a rendering context. In fact, threads that are ran from the scripting language will not be able to draw anything to the screen in my current concept of how things will work. I just want textures to be able to be loaded from threads. So, to achieve that, I'll make a call to SetActive(true) to see if a thread has an OpenGL context and create a valid OpenGL context for threads that don't have one when attempting to load textures.

Quote from: "Groogy"
Erhm, when I get to school I think I can have a solution for you that we went trough if you still want it to be multi threaded and also be compatible with older platforms. It's quite advanced and will require you to rewrite your whole structure but it is exactly what you are looking for. It will also handle the problem with SetActive.

What you do is divide everything up to different jobs with different dependencies. So running your "scripts" will be one job for instance.

... What you want to do is the [script] thread to generate output that is sent to whatever thread is handling the rendering...

For closure, since this forum thread is named "Handling SetActive efficiently in multithreaded environments" and I'm still interested (but don't plan on implementing it), I would like to understand what you're saying. This implies that I would want threads to be able to draw to the screen. Is there a way to, without hindering single core processors, forward OpenGL commands to the main thread?

The following code is how I'd do it with hindering single core processors through lock/unlock (SFML-2.0). It's quite a lot, but I wanted to sacrifice shortness for realism. It basically just sets up a class that can queue OpenGL commands and then runs them all in the main thread.

glwindow.cpp
Code: [Select]
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "glwindow.hpp"
#include <SFML/OpenGL.hpp>


////////////////////////////////////////////////////////////
// Color defines a color for the SetColor function
////////////////////////////////////////////////////////////
struct ByteColor
{
    GLubyte r;
    GLubyte g;
    GLubyte b;
};


////////////////////////////////////////////////////////////
// IntRect defines a rectangle for the DrawRectangle function
////////////////////////////////////////////////////////////
struct IntRect
{
    GLint x1;
    GLint y1;
    GLint x2;
    GLint y2;
};


GLWindow::GLWindow() :
    myShouldClose(false)
{
    Initialize();
}


GLWindow::GLWindow(sf::VideoMode mode, const std::string& title, unsigned long style, const sf::ContextSettings& settings) :
    sf::Window(mode, title, style, settings),
    myShouldClose(false)
{
    Initialize();
}


void GLWindow::Clear()
{
    // Add a call to ClearColorBuffer to the renderer calls buffer with no argument
    myRendererCalls.push_back(RendererCall(ClearColorBuffer, 0));
}


void GLWindow::Close()
{
    // We don't directly close the window here because that will make the OpenGL context invalid for any subsequent OpenGL calls
    myShouldClose = true;
}


void GLWindow::Display()
{
    // Lock other threads' writing access to the renderer calls buffer
    myRendererCallsMutex.Lock();

    // Flush buffered renderer calls
    for (RendererCalls::iterator it = myRendererCalls.begin(); it != myRendererCalls.end(); it = myRendererCalls.erase(it))
        switch (it->first)
        {
            case ClearColorBuffer:
            {
                // Clear the OpenGL color buffer
                glClear(GL_COLOR_BUFFER_BIT);

                break;
            }
            case Color:
            {
                // Get ByteColor argument
                ByteColor* color = static_cast<ByteColor*>(it->second);

                // Set the current color with the given arguments
                glColor3ub(color->r, color->g, color->b);

                // Deallocate the ByteColor argument
                delete color;

                break;
            }
            case Rect:
            {
                // Get IntRect argument
                IntRect* rect = static_cast<IntRect*>(it->second);

                // Draw a rectangle with the given arguments
                glRecti(rect->x1, rect->y1, rect->x2, rect->y2);

                // Deallocate the IntRect argument
                delete rect;

                break;
            }
        }

    // Unlock other threads' writing access to the renderer calls buffer when we're done
    myRendererCallsMutex.Unlock();

    // Call the underlying Display function
    sf::Window::Display();

    // If the window should close, call the underlying Close function
    if (myShouldClose)
        sf::Window::Close();
}


void GLWindow::DrawRectangle(int x1, int y1, int x2, int y2)
{
    // Allocate an IntRect with the given coordinates
    IntRect* rect = new IntRect;
    rect->x1 = x1;
    rect->y1 = y1;
    rect->x2 = x2;
    rect->y2 = y2;

    // Add a call to Rect to the renderer calls buffer with an IntRect argument
    myRendererCalls.push_back(RendererCall(Rect, rect));
}


void GLWindow::Initialize()
{
    // Initialize any OpenGL render states
    glOrtho(0, GetWidth(), GetHeight(), 0, -1, 1);
}


void GLWindow::Lock()
{
    // Lock other threads' writing access to the renderer calls buffer
    myRendererCallsMutex.Lock();
}


void GLWindow::SetColor(unsigned char r, unsigned char g, unsigned char b)
{
    // Allocate a ByteColor with the given RGB
    ByteColor* color = new ByteColor;
    color->r = r;
    color->g = g;
    color->b = b;

    // Add a call to Color to the renderer calls buffer with a ByteColor argument
    myRendererCalls.push_back(RendererCall(Color, color));
}


void GLWindow::Unlock()
{
    // Unlocks other threads' writing access to the renderer calls buffer
    myRendererCallsMutex.Unlock();
}


glwindow.hpp
Code: [Select]
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window.hpp>


////////////////////////////////////////////////////////////
// GLWindow member functions are used instead of directly
// using OpenGL functions to give commands to the hardware
////////////////////////////////////////////////////////////
class GLWindow : public sf::Window
{
public :

    ////////////////////////////////////////////////////////////
    // Default constructor
    ////////////////////////////////////////////////////////////
    GLWindow();

    ////////////////////////////////////////////////////////////
    // Constructs a new GL window
    ////////////////////////////////////////////////////////////
    GLWindow(sf::VideoMode mode, const std::string& title, unsigned long style = sf::Style::Default, const sf::ContextSettings& settings = sf::ContextSettings());

    ////////////////////////////////////////////////////////////
    // Clears all pixels to black
    ////////////////////////////////////////////////////////////
    void Clear();

    ////////////////////////////////////////////////////////////
    // Tells the window that it should close
    ////////////////////////////////////////////////////////////
    void Close();

    ////////////////////////////////////////////////////////////
    // Do the renderer calls that have been buffered so far
    ////////////////////////////////////////////////////////////
    void Display();

    ////////////////////////////////////////////////////////////
    // Draws a rectangle
    ////////////////////////////////////////////////////////////
    void DrawRectangle(int x1, int y1, int x2, int y2);

    ////////////////////////////////////////////////////////////
    // Perform renderer initializations
    ////////////////////////////////////////////////////////////
    void Initialize();

    ////////////////////////////////////////////////////////////
    // Locks the renderer buffer
    ////////////////////////////////////////////////////////////
    void Lock();

    ////////////////////////////////////////////////////////////
    // Sets the color of the renderer
    ////////////////////////////////////////////////////////////
    void SetColor(unsigned char r, unsigned char g, unsigned char b);

    ////////////////////////////////////////////////////////////
    // Unlocks the renderer buffer
    ////////////////////////////////////////////////////////////
    void Unlock();

private :

    ////////////////////////////////////////////////////////////
    // Enumeration of the different rendering functions the
    // GLWindow is capable of
    ////////////////////////////////////////////////////////////
    enum RendererFunction
    {
        ClearColorBuffer,
        Color,
        Rect
    };

    typedef std::pair<RendererFunction, void*> RendererCall;
    typedef std::vector<RendererCall>          RendererCalls;

    RendererCalls myRendererCalls;      // Container of buffered renderer calls to be processed by the GLWindow
    sf::Mutex     myRendererCallsMutex; // Mutex for synchronizing threads' writing to the renderer calls buffer
    bool          myShouldClose;        // If window should close, this variable is true, else false
};


main.cpp
Code: [Select]
#include "glwindow.hpp"


bool threadShouldRun = true;


void Thread(GLWindow* window)
{
    while (threadShouldRun)
    {
        // Draw an expanding red rectangle in the top left in this thread
        static int Width  = 0;
        static int Height = 0;
        ++Width;
        ++Height;
        window->Lock();
        window->SetColor(255, 0, 0);
        window->DrawRectangle(0, 0, Width, Height);
        window->Unlock();

        sf::Sleep(0.01);
    }
}


int main()
{
    GLWindow window(sf::VideoMode(640, 480), "Test", sf::Style::Close);
    window.SetFramerateLimit(100);

    sf::Thread thread(&Thread, &window);
    thread.Launch();

    while(window.IsOpened())
    {
        sf::Event event;
        while (window.PollEvent(event))
            if (event.Type == sf::Event::Closed)
                window.Close();

        // Draw an expanding blue rectangle in the bottom right in this thread
        static int Width  = 640;
        static int Height = 480;
        --Width;
        --Height;
        window.Lock();
        window.SetColor(0, 0, 255);
        window.DrawRectangle(640, 480, Width, Height);
        window.Unlock();

        window.Display();
    }

    threadShouldRun = false;

    return 0;
}


It's pretty long. In hindsight, it might have been better to upload the files to a separate location and provide a download link. :lol:

40
General / SFML 2 change I don't know how to fix
« on: April 18, 2011, 01:41:18 am »
The GetEvent function has been renamed to PollEvent. This is a newer feature and the documentation on the website hasn't been updated in awhile. Read the include files or generate your own documentation with Doxygen for up-to-date information.

41
Graphics / [solved] Dragging with mouse
« on: April 17, 2011, 12:06:44 pm »
I don't think you've posted enough code for people to help you. You should post a commented and compilable, albeit minimal, example of what you're trying to do.

42
Window / Handling SetActive efficiently in multithreaded environments
« on: April 17, 2011, 10:37:29 am »
I'll just remove all threads from the C++ side of my game engine. It may be naive for me to say, but I do feel like I understand threads. It's just that I think I'm losing more performance than I am gaining by using threads. I want my game engine to run fast on multiple core CPUs and single core CPUs as well. Single core CPUs shouldn't have to suffer to make multiple core CPUs faster. Managing SetActive as well as all the synchronization I was already doing just puts it at a point where I'd rather cut my losses and settle on not using threads.

Quote from: "Groogy"
Having maxed out to 100% on a CPU isn't necessary a bad thing. I can max out the CPU without having any advanced graphics or doing any heavy operations at all. Why the CPU usage goes down is because somewhere somehow your application Sleeps.

My CPU usage measuring was done when the application was idling. It was calling no more than it needed to display a few hundred textured rectangles on the screen. If I want my game engine to be compatible with as old of computers as I can possibly can handle, I feel that I need that basic loop to not put my PC that's way above the specs I'm aiming for at a constant 100% CPU usage.

Quote from: "Laurent"
Not exactly. Switching the current OpenGL context is indeed a very expensive operation, and the only reason why I can usually avoid this in SFML is because I don't activate a context if it's already active (I never call SetActive(false) for windows, so basically the context never changes).

What is the point of calling SetActive(true) in that case at all then? I wasn't aware the SFML graphics library did anything to the OpenGL context. I thought it was all left up to the user. I assume that this has something to do with ensuring there is a valid OpenGL context, and if there isn't, you create one?

I'm interested in this because if I make a scripting side implementation of threads, I want textures to be able to be loaded from those. I remember reading somewhere that all SFML OpenGL contexts share resources such as textures. If this is true, all I need to do is give the thread an OpenGL context and then it will be able to load textures, right?



Thanks for the responses Groogy, Laurent!

43
Window / Handling SetActive efficiently in multithreaded environments
« on: April 16, 2011, 12:58:18 pm »
I have a game engine I'm writing with SFML that sets up an interface for the Lua scripting language to provide game logic. I've set up functions for the scripting language that directly map to OpenGL calls. The problem is that sometimes the scripting language executes inside of threads invisibly to the scripting language. So, sometimes calls to OpenGL would be made without an OpenGL context. To remedy this, I internally lock/unlock a mutex and call SetActive(true)/SetActive(false) on the window each time I run any scripting language callback from any thread. However, SetActive is too expensive a function to call as frequently as I am (~200 times per second while idling). It's maxing out my 2.13GHz dual core CPU usage to 100%. When commented out on Windows XP, my CPU usage goes down to 1-12%.


A few ideas have ran past my head on how to fix this performance issue:

1.) Reduce the amount of times I call SetActive
Instead of doing SetActive(true)/SetActive(false) each time I run a callback from the scripting language, have the current thread check if it is the window active thread and, if it is not, make a request for the current window active thread to release the window so we can set it active for the current thread. All threads will call a polling function that checks if they need to release the window. This should reduce the amount of calls to SetActive drastically, especially while idling, but it still won't be at an acceptable level in complex scripts that run many different-threaded scripting callbacks every second. It can also create a lot of wait time for threads to finally read the request of other threads.

2.) Drop threading completely (or at least the invisible non-scripted threading)
This really simplifies things. I actually don't know why threads are such a hot topic. The only thing I know of that can't be done smoothly without threads is loading resources while displaying something else. There is also a hack in my application that puts input into a different thread so that the window still performs display updates while being dragged on Windows, but I can live without that.

3.) Stop calling SetActive(true)/SetActive(false) at all
Instead, create a new OpenGL context for every thread with the color buffer starting/clearing color set to be completely transparent and, when the thread finishes running a scripting callback, display the result on top of the window's (the real) OpenGL context and clear the color buffer of the thread's OpenGL context.


I'm just looking for some feedback on my problem. I've been thinking about it all day and am still not sure if I am approaching it the right way. I'll probably go attempt to implement option 3 when I get some motivation to see how it will work. I'd be completely fine with doing option 2 though. This whole thing is sort of low priority since this is just an optimization thing.


P.S. It's 4AM so I'm not sure if this post makes complete sense. :lol:

44
Graphics / View problems
« on: April 12, 2011, 07:15:34 am »
If you're still having problems, you need to post compilable, but minimal, code that demonstrates what you're trying to do and fails to do with comments that explain what your goal is.
All the code that you have posted doesn't demonstrate a problem. I can't help you if you don't post compilable code where you tried to achieve a result and it failed.

I'm just not that good. ;)

45
General / Re: Getting an object from another file
« on: April 12, 2011, 04:00:17 am »
I can think of three ways to do this, but there is probably more (google these):
 * Extern keyword
 * Singleton
 * Accessors to a pointer or reference


Here's how to use extern if I remember right...
Input.cpp
Code: [Select]
#include "Input.hpp"
#include "Window.hpp"

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

namespace
{
       extern sf::RenderWindow window;

       const sf::Input &input = window.GetInput(); //window not declared in this scope
}

Input::Input()
{
      while (input.IsKeyDown(sf::Key::Left)){
              Input::LeftKeyDown = true;}
      Input::LeftKeyDown = false;

Pages: 1 2 [3] 4 5 ... 15