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

Pages: [1] 2 3 ... 5
1
Thank you for your answers!

I think the first answer of this stackoverflow question (the one from Warren Young) describes the situation pretty well for users less familiar to networking concepts as I am ;) I think I can afford the risks associated to using this option.

However, according to the Windows documentation or this IBM article (and if I understand them correctly), the call to setsockopt() should be made on a valid socket before calling bind(), while sf::TcpListener::listen() creates the socket and immediately calls bind() on it. Can this be an issue?

2
Hi,

I am currently learning networking with the SFML, so please bear with me if I'm doing something stupid, or if this situation is normal.
Long story short: it seems that sf::TcpListener fails to listen again to the same port after it was closed while a client was connected.

You will find below a code sample that reproduces the problem. It is a simplified excerpt of a larger code I'm working on, but all the listening, connecting and disconnecting is handled in the same way SFML wise (which I hope is robust and clean enough, please tell me if it's not!).

On the one hand, the server is programmed to accept any incoming TCP connection using a sf::TcpListener, and stores a list of connected clients (sf::TcpSockets), each registered in a common sf::TcpSelector. Whenever one of the client sends a packet, I'm asking the server to restart (this is just a test case) : I close all connections and listening, then start listening again on the same port.

On the other hand, the client simply connects to the server by using a sf::TcpSocket, and sends a dummy packet to the server on demand. When the packet is sent, knowing that the server is going to restart, it routinely checks for incoming packets from the server in order to notice when it actually goes down. Once that is done, it closes the connection and asks for a new one.

The server:
#include <SFML/Network.hpp>
#include <iostream>
#include <vector>
#include <memory>

int main() {
    sf::TcpListener    listener;
    sf::SocketSelector selector;
   
    std::vector<std::unique_ptr<sf::TcpSocket>> client_list;
   
    while (true) {
        std::cout << "starting server..." << std::endl;
        std::size_t last_id = 0;
       
        // Try to open the port
        while (listener.listen(4444) != sf::Socket::Done) {
            std::cout << "cannot listen to port" << std::endl;
            std::cout << "try again (y/n) ? " << std::flush;
            char r; std::cin >> r;
            if (r == 'n') return 0;
        }
       
        std::cout << "connected!" << std::endl;

        selector.add(listener);
       
        // Start the main loop
        bool run = true;
        while (run) {
            selector.wait(sf::milliseconds(10));
           
            // Look for new clients
            if (selector.isReady(listener)) {
                std::unique_ptr<sf::TcpSocket> s(new sf::TcpSocket());
                if (listener.accept(*s) == sf::Socket::Done) {
                    selector.add(*s);
                    client_list.push_back(std::move(s));
                    std::cout << "new client" << std::endl;
                }
            }

            // Receive packets from each clients
            auto iter = client_list.begin();
            while (iter != client_list.end()) {
                auto& socket = **iter;
                if (selector.isReady(socket)) {
                    sf::Packet p;
                    switch (socket.receive(p)) {
                    case sf::Socket::Done :
                        run = false;
                        std::cout << "request restart" << std::endl;
                        break;
                    case sf::Socket::Disconnected :
                    case sf::Socket::Error :
                        socket.disconnect();
                        iter = client_list.erase(iter);
                        continue;
                    default : break;
                    }
                }
               
                ++iter;
            }
        }
       
        selector.clear();
        client_list.clear();
        listener.close();
       
        std::cout << "server is down" << std::endl;
    }

    return 0;
}

The client:
#include <SFML/Network.hpp>
#include <iostream>
#include <string>

int main() {
    sf::TcpSocket socket;
       
    while (true) {
        std::cout << "press [Enter] to connect: " << std::flush;
        std::string line;
        std::getline(std::cin, line);
       
        // Try to connect
        while (socket.connect(sf::IpAddress("127.0.0.1"), 4444, sf::seconds(2)) != sf::Socket::Done) {
            std::cout << "cannot connect" << std::endl;
            std::cout << "try again (y/n) ? " << std::flush;
            char r; std::cin >> r;
            if (r == 'n') return 0;
        }

        std::cout << "connected!" << std::endl;
        std::cout << "press [Enter] to restart server: " << std::flush;
        std::getline(std::cin, line);

        // Send a dummy packet to tell the server to restart
        std::uint8_t word = 0;
        sf::Packet p; p << word;
        if (socket.send(p) != sf::Socket::Done) {
            std::cout << "could not send packet" << std::endl;
            socket.disconnect();
            continue;
        }
       
        std::cout << "packet sent, waiting to see server going down" << std::endl;
       
        p.clear();
        socket.setBlocking(false);
        while (socket.receive(p) == sf::Socket::NotReady) {
            sf::sleep(sf::milliseconds(50));
        }
        socket.setBlocking(true);
       
        std::cout << "server is down" << std::endl;
       
        socket.disconnect();
    }

    return 0;
}

Compiling:
Code: [Select]
g++ -std=c++0x server.cpp -lsfml-network -lsfml-system -o server
g++ -std=c++0x client.cpp -lsfml-network -lsfml-system -o client

Here is how to demonstrate the issue:
  • In a first window, launch the server. If everything goes fine, it should print:
    Quote
    starting server...
    connected!
  • In a second window, launch the client, and press Enter to try to connect. If everything goes fine, it should print in the client window:
    Quote
    press [Enter] to connect
    connected!
    press [Enter] to restart server
    and in the server window:
    Quote
    new client
  • Still in the client window, press Enter once more to send the packet, then watch the two windows carefully. If everything goes fine, it should print fairly quickly in the client window:
    Quote
    packet sent, waiting to see server going down
    server is down
    press [Enter] to connect
    and in the server window:
    Quote
    request restart
    server is down
    starting server...
  • After a few seconds, the server will inform you that it failed to setup:
    Quote
    Failed to bind listener socket to port 4444
    cannot listen to port
    try again (y/n) ?
    If you try again repeatedly, it should be able to start after some time (took me more than 40 seconds).
This issue doesn't show up if I try to listen to a different port after the restart.
On the other hand, it also happens in this more brutal situation :
  • launch the server,
  • launch the client and connect,
  • kill the sever (Ctrl-C for example),
  • while the client is still alive, launch the server again.
Now that is something I can understand, because killing the server in such a brutal way prevents the SFML (or myself) from properly closing the connections. But I don't get why it still happens if I do things cleanly.

Am I doing it wrong? Or is this an inherent limitation of networking?

Thank you for your help.

3
SFML projects / Re: lxgui - a Lua and XML Graphical User Interface
« on: January 07, 2013, 01:47:35 am »
Took me the whole day, but the library now compiles fine and warning free with MSVC 2010 (/W4, useless warnings disabled), and the test program renders exactly as with GCC.

I had to remove some of the C++11 code I was using when it didn't really matter (range based for loops and initializer lists), and use conditional compilation for the other cases (define NO_CPP11_EXPLICIT_CONV, NO_CPP11_DELETE_FUNCTION, NO_CPP11_FUNCTION_TEMPLATE_DEFAULT, NO_CPP11_CONSTEXPR and NO_CPP11_UNICODE_LITTERAL). Thanks to the different implementation of Microsoft's compiler, I also fixed some undefined behaviors that I couldn't notice because they were harmless in GCC (like calling str[0] on an empty std::string, or some uninitialized variables).

I have updated the CMake scripts to be able to compile with MSVC, even though I couldn't run them because they fail at finding the dependencies (I'm still learning CMake...). In any case, I also added project files for Visual C++ (.sln and .vcxproj) and updated the Code::Blocks projects to supply MSVC targets. I'm not very familiar with MSVC, so maybe the configuration can be improved. Please tell me if you find anything wrong.

I guess this is a good time to switch to version 1.2.0 (as always, see sourceforge.net for the files).

Apart from this, I have made the usage of the library in C++ easier by providing more shortcut functions, and potentially improved the performances. It is now also possible to specify colors using the HTML syntax (i.e. "#RRGGBBAA") in XML and Lua code. Finally, one can also select the filtering to apply to the textures that are displayed by the GUI (no filter, of linear filter). Again, see the changelog for the whole details.

4
SFML projects / Re: lxgui - a Lua and XML Graphical User Interface
« on: January 06, 2013, 02:25:49 pm »
I have never tried to compile it with MSVC to be honest. The errors you're getting are due to the poor C++11 support of the Microsoft compiler (explicit conversion operators in this particular case). I will add a clean workaround for it to compile nonetheless.

I'll see if there are other features that are not supported by MCVS (I can only test the 2010 version since I'm using Windows XP) and keep you updated whenever (/if) I manage to compile everything.

5
SFML projects / Re: lxgui - a Lua and XML Graphical User Interface
« on: January 05, 2013, 02:58:44 pm »
I've added a binary (Win32 only) version of the test application provided with the library (what was used to generate the screenshot of the first post). You can download it [here], hopefully no DLL is missing.

6
SFML projects / Re: lxgui - a Lua and XML Graphical User Interface
« on: January 02, 2013, 03:45:08 pm »
If you had read my previous post you would have seen that this is no longer an issue, and that I am now using the SFML event! ;) (still, I edited my post to make it clearer)

7
SFML projects / Re: lxgui - a Lua and XML Graphical User Interface
« on: January 02, 2013, 12:47:12 am »
A quick post to announce the 1.1.0 version of lxgui.

This new version is mostly composed of bug fixes and a few enhancements (on code quality and/or performance), but sadly its API is slightly different than the one of the 1.0.0 version. In other words: one will have to do small adjustments to ones code in order to use this new version. In particular, the gui::locale class (which used to take care of localizing the keyboard keys for different layouts, such as AZERTY or QWERTY) is gone, its work now being delegated to the SFML. This little change induces a modification of the way one initializes the GUI, so here is the updated sample code for 1.1.0 :
// Create an SFML window
sf::Window mWindow(...);

// Create an input handler (mouse, keyboard, ...)
utils::refptr<input::handler_impl> pSFMLHandler(new input::sfml_handler(mWindow));

// Initialize the gui
gui::manager mManager(
    // Provide an input handler
    pSFMLHandler,
    // The language that will be used by the interface (purely informative: it's always up to each addon to localize itself according to this value)
    "enGB",
    // Dimensions of the render window
    mWindow.getSize().x, mWindow.getSize().y,
    // The OpenGL implementation of the gui
    utils::refptr<gui::manager_impl>(new gui::gl::manager())
);

// Load files :
//  - first set the directory in which the interface is located
mManager.add_addon_directory("interface");
//  - create the lua::state
mManager.create_lua([&mManager](){
    // This code might be called again later on, for example when one
    // reloads the GUI (the lua state is destroyed and created again).
    //  - register the needed widgets
    mManager.register_region_type<gui::texture>("Texture");
    mManager.register_region_type<gui::font_string>("FontString");
    mManager.register_frame_type<gui::button>("Button");
    mManager.register_frame_type<gui::slider>("Slider");
    mManager.register_frame_type<gui::edit_box>("EditBox");
    mManager.register_frame_type<gui::scroll_frame>("ScrollFrame");
    mManager.register_frame_type<gui::status_bar>("StatusBar");
    //  - register additional lua glues functions if needed
    // ...
});

//  - and eventually load all files
mManager.read_files();

// Start the main loop
while (bRunning)
{
    // Retrieve the window events
    sf::Event mEvent;
    while (mWindow.pollEvent(mEvent))
    {
        // ...

        // Send these to the input manager
        pSFMLHandler->on_sfml_event(mEvent);
    }

    // ...

    // Update the GUI
    mManager.update(fDeltaTime);

    // ...

    // Render the GUI
    mManager.render_ui();

    // ...
}

Apart from this change, everything works exactly the same way.
Among the few novelties, the following are probably the most interesting:
  • typing text in an edit_box is now fully functional when using the SFML as input source
  • added CMake scripts for the compilation (makes it much easier to install on linux)
  • updated the SFML input handler to fit the latest snapshot of the 2.0 RC
  • added an input handler for GLFW (a windowing library for OpenGL)
  • it is now possible to use std::functions (or functors or lambdas) to define "scripts".
A simplistic example that blindly mimics the Lua scripts of my first post:
float update_time = 0.5f, timer = 1.0f;
int frames = 0;

pFrame->define_script("OnUpdate",
    [&](gui::frame* self, gui::event* event) {
        float delta = event->get(0)->get<float>();
        timer += delta;
        ++frames;

        if (timer > update_time) {
            gui::layered_region* reg = self->get_region("FPSCounterText");
            gui::font_string* text = dynamic_cast<gui::font_string*>(reg);

            text->set_text("FPS : "+utils::to_string(floor(frames/timer)));
           
            timer = 0.0f;
            frames = 0;
        }
    }
);
It's a little bit less "user-friendly" than Lua code, and also less flexible since one has to re-compile the program to modify the script, but it will always be faster and more robust (for example, it is not possible to call a method that doesn't exist on an object). The other advantage of using std::functions is that one can really use anything as a script (as long as it has the proper signature). For example, if one wants the "OnUpdate" event to call my_on_update_function(), then all one has to do is to call:
pFrame->define_script("OnUpdate", &my_on_update_function);

For more detailed information, please refer to the changelog.

8
SFML projects / lxgui - a Lua and XML Graphical User Interface
« on: May 06, 2012, 04:29:20 pm »
Hi,

After more than 5 years of spare time coding, I am finally ready to present my biggest project ever : lxgui.


Screenshot of the gui in action (sample provided in the package).

I am aware that there are plenty of different GUI libraries out there, but they all have something that makes them unique. This is also the case of lxgui. It's main advantages are :
  • platform independence : it is coded in standard C++ (using C++11 features). Platform dependent concepts, such as rendering or input, are handled by front-end plugins (for rendering : only pure OpenGL for now, for input : SFML and OIS).
  • fully extensible : except for the base GUI components (gui::frame), every widget is designed to be used as a plugin : gui::texture, gui::font_string, gui::button, gui::edit_box, ...
  • fully documented : every class in the library is documented. Doxygen documentation is included (and available online here).
  • GUI data from XML and Lua files : it can use a combination of XML files (for GUI structure) and Lua scripts (for event handling, etc) to construct a fully functional GUI. One can also create everything in C++ code if needed.
  • a familiar API... : the XML and Lua API are directly inspired from World of Warcraft's successful GUI system. It is not a plain copy, but most of the important features are there (virtual widgets, inheritance, ...).
  • caching : the whole GUI can be cached into screen size render targets, so that interfaces with lots of widgets render extremely fast (provided it is not animated, and mostly event driven : the sample screenshot renders at 1080 FPS with caching enabled, for example).
I have tried to make use of as few external libraries as possible, so compiling it is rather easy (projects files are included for Code::Blocks, Visual Studio 2010 and CMake). The GUI library in itself only depends on Lua 5.1 (not 5.2 !) through the "luapp" C++ wrapper that I wrote (included in the source package). XML parsing is done by a library of my own (also included in the package).
The only rendering front end available uses OpenGL. It depends on Freetype for font loading and rendering, and libpng for texture loading (hence, only PNG textures are supported).
For the input front end, you can use SFML2 or OIS. Though, since SFML doesn't provide an API for keyboard layout independent input, the edit_box widget will not function properly (among other things) (edit: fixed in 1.1.0!).

Here is a brief list of the available widgets (but nothing prevents you from creating more without touching the lxgui library !) :
  • uiobject (abstract) : the very base of every GUI widget. Can be placed on screen.
  • layered_region (abstract) : can be rendered on the screen.
  • frame : can contain layered_regions (sorted by layer) and other frames.
  • texture : can render a texture file, a gradient, or a plain color.
  • font_string : can render text.
  • button : a clickable frame with several states : normal, pushed, highlight
  • check_button : a button with a check box
  • slider : a frame that has a texture that can be moved vertically or horizontally
  • status_bar : a frame that uses a texture that grows depending on some value (typical use : health bars, ...)
  • edit_box : an editable text box (multiline edit_boxes are not yet fully supported)
  • scroll_frame : a frame that has scrollable content
Setting up the GUI in C++ is rather straight forward (code updated for 1.2.0) :
// Create an SFML window for example
sf::Window mWindow;

// Create an input handler (mouse, keyboard, ...)
utils::refptr<input::handler_impl> pSFMLHandler(new input::sfml_handler(mWindow));

// Initialize the gui
gui::manager mManager(
    // Provide an input handler
    pSFMLHandler,
    // The language that will be used by the interface
    // (purely informative: it's always up to each addon to localize
    // itself according to this value)
    "enGB",
    // Dimensions of the render window
    mWindow.getSize().x, mWindow.getSize().y,
    // The OpenGL implementation of the gui
    utils::refptr<gui::manager_impl>(new gui::gl::manager())
);

// Load files :
//  - first set the directory in which the interface is located
mManager.add_addon_directory("interface");
//  - create the lua::state
mManager.create_lua([&mManager](){
    // This code might be called again later on, for example when one
    // reloads the GUI (the lua state is destroyed and created again).
    //  - register the needed widgets
    mManager.register_region_type<gui::texture>();
    mManager.register_region_type<gui::font_string>();
    mManager.register_frame_type<gui::button>();
    mManager.register_frame_type<gui::slider>();
    mManager.register_frame_type<gui::edit_box>();
    mManager.register_frame_type<gui::scroll_frame>();
    mManager.register_frame_type<gui::status_bar>();
    //  - register additional lua "glue" functions if needed
    // ...
});

//  - and eventually load all files
mManager.read_files();

// Start the main loop
while (bRunning)
{
    // Retrieve the window events
    sf::Event mEvent;
    while (mWindow.pollEvent(mEvent))
    {
        // ...

        // Send these to the input manager
        pSFMLHandler->on_sfml_event(mEvent);
    }

    // Update the GUI
    mManager.update(fDeltaTime);

    // Render the GUI
    mManager.render_ui();
}

With these few lines of code, you can then create as many "interface addons" in XML and Lua as you wish. Let's consider a very simple example : we want to create an FPS counter at the bottom right corner of the screen.
First create a new addon, by going to the "interface" folder, and creating a new folder "FPSCounter". In this folder, we create a "table of content" file which lists all the .xml and .lua files this addons uses, and some other informations (addon author, GUI version, saved variables, ...). It has to be called "FPSCounter.toc" :
Code: [Select]
## Interface: 0001
## Title: A neat FPS counter
## Version: 1.0
## Author: Kalith
## SavedVariables:

addon.xml

As you can see, we will only require a single .xml file : "addon.xml". Let's create it in the same folder. Every XML file must contain a <Ui> tag :
<Ui>
</Ui>

Then, within this tag, we need to create a frame (which is more or less a GUI container) :
    <Frame name="FPSCounter">
        <Size>
            <RelDimension x="1.0" y="1.0"/>
        </Size>
        <Anchors>
            <Anchor point="CENTER"/>
        </Anchors>
    </Frame>
This creates a Frame named "FPSCounter" that fills the whole screen : the <Size> tag gives it relative size of "1.0" (relative to the parent frame, but since there is none, it is relative to the screen size), and the <Anchor> tag positions the frame in the middle of the screen.
Now, within the Frame, we create a FontString object, that can render text :
    <Frame name="FPSCounter">
        <Size>
            <RelDimension x="1.0" y="1.0"/>
        </Size>
        <Anchors>
            <Anchor point="CENTER"/>
        </Anchors>
        <Layers><Layer>
            <FontString name="$parentText" font="interface/fonts/main.ttf" text="" fontHeight="12" justifyH="RIGHT" justifyV="BOTTOM" outline="NORMAL">
                <Anchors>
                    <Anchor point="BOTTOMRIGHT">
                        <Offset>
                            <AbsDimension x="-5" y="-5"/>
                        </Offset>
                    </Anchor>
                </Anchors>
                <Color r="0" g="1" b="0"/>
            </FontString>
        </Layer></Layers>
    </Frame>
We've named our FontString "$parentText" : "$parent" gets replaced by it's parent name, so in the end it is called "FPSCounterText". Intuitively, the "font" attribute specifies which font file to use for rendering (can be a .ttf or .otf file), "fontHeight" the size of the font, "justifyH" and "justifyV" gives the horizontal and vertical justification, and "outline" creates a black border around the letters, so that it is readable regardless of the background content. We anchor it at the bottom right corner of its parent frame, with a small offset, and give it a green color.

Now that the GUI structure is in place, we still need to display the number of frame per second. To do so, we will define two "scripts" for the "FPSCounter" Frame :
        <Scripts>
            <OnLoad>
                -- This is Lua code !
                self.update_time = 0.5;
                self.timer = 1.0;
                self.frames = 0;
            </OnLoad>
            <OnUpdate>
                -- This is Lua code !
                self.timer = self.timer + arg1;
                self.frames = self.frames + 1;

                if (self.timer > self.update_time) then
                    local fps = self.frames/self.timer;
                    self.Text:set_text("FPS : "..fps);
               
                    self.timer = 0.0;
                    self.frames = 0;
                end
            </OnUpdate>
        </Scripts>

The "OnLoad" script gets executed only once, when the Frame is created. It is used here to initialize some variables. The "OnUpdate" script is called every frame (use it carefully...). It provides the time elapsed since last update in the "arg1" variable.  We use it to record the number of frames that are rendered, and update the FPS counter every half seconds.
The "self" variable in Lua is the equivalent of "this" in C++ : it is a reference to the "FPSCounter" Frame. Note that, since we've called the FontString "$parentText", we can use the handy shortcut "self.Text" instead of the full name "FPSCounterText" to reference the FontString object in Lua.

Once this is done, we have the full .xml file :
<Ui>
    <Frame name="FPSCounter">
        <Size>
            <RelDimension x="1.0" y="1.0"/>
        </Size>
        <Anchors>
            <Anchor point="CENTER"/>
        </Anchors>
        <Layers><Layer>
            <FontString name="$parentText" font="interface/fonts/main.ttf" text="" fontHeight="12" justifyH="RIGHT" justifyV="BOTTOM" outline="NORMAL">
                <Anchors>
                    <Anchor point="BOTTOMRIGHT">
                        <Offset>
                            <AbsDimension x="-5" y="-5"/>
                        </Offset>
                    </Anchor>
                </Anchors>
                <Color r="0" g="1" b="0"/>
            </FontString>
        </Layer></Layers>
        <Scripts>
            <OnLoad>
                -- This is Lua code !
                self.update_time = 0.5;
                self.timer = 1.0;
                self.frames = 0;
            </OnLoad>
            <OnUpdate>
                -- This is Lua code !
                self.timer = self.timer + arg1;
                self.frames = self.frames + 1;

                if (self.timer > self.update_time) then
                    local fps = self.frames/self.timer;
                    self.Text:set_text("FPS : "..math.floor(fps));
               
                    self.timer = 0.0;
                    self.frames = 0;
                end
            </OnUpdate>
        </Scripts>
    </Frame>
</Ui>

... and a working GUI addon !
One last thing to do before being able to see it in your program is to go to the "interface" folder, and create a file called "addons.txt". It will contain the list of addons that you want to load. In our case just write :
Code: [Select]
FPSCounter:1The "1" means "load". If you put a "0" or remove that line, your addon will not be loaded.

Doing the very same thing in C++ would give the following code :
// Create the Frame
gui::frame* pFrame = mManager.create_frame<gui::frame>("FPSCounter");
pFrame->set_rel_dimensins(1.0f, 1.0f);
pFrame->set_abs_point(gui::ANCHOR_CENTER, "", gui::ANCHOR_CENTER);

// Create the FontString
gui::font_string* pFont = pFrame->create_region<gui::font_string>(gui::LAYER_ARTWORK, "$parentText");
pFont->set_abs_point(gui::ANCHOR_BOTTOMRIGHT, "$parent", gui::ANCHOR_BOTTOMRIGHT, -5, -5);
pFont->set_font("interface/fonts/main.ttf", 12);
pFont->set_justify_v(gui::text::ALIGN_BOTTOM);
pFont->set_justify_h(gui::text::ALIGN_RIGHT);
pFont->set_outlined(true);
pFont->set_text_color(gui::color::GREEN);
pFont->notify_loaded();

// Create the scripts in C++ (one can also provide a string containing some Lua code)
float update_time = 0.5f, timer = 1.0f;
int frames = 0;
pFrame->define_script("OnUpdate",
    [&](gui::frame* self, gui::event* event) {
        float delta = event->get<float>(0);
        timer += delta;
        ++frames;

        if (timer > update_time)
        {
            gui::font_string* text = self->get_region<gui::font_string>("Text");
            text->set_text("FPS : "+utils::to_string(floor(frames/timer)));
           
            timer = 0.0f;
            frames = 0;
        }
    }
);

// Tell the Frame is has been fully loaded.
pFrame->notify_loaded();

As you can see from the screenshot above, this system can be used to create very complex GUIs (the "File selector" frame is actually a working file explorer !). This is mainly due to a powerful inheritance system : you can create a "template" frame (making it "virtual"), that contains many object, many properties, and then instantiate several other frames that will use this "template" ("inherit" from it). This reduces the necessary code, and can help you make consistent GUIs : for example, you can create a "ButtonTemplate", and use it for all the buttons of your GUI.

I think I will close here this presentation. There are no official tutorials and no API for the Lua functions, but you can rely on some World of Warcraft sites for the moment (such as WoWWiki). I hope that some of you will find this library useful !

Included in the source package (in the "gui/test" directory) is a test program that should compile and work fine if you have installed the whole thing properly. It is supposed to render exactly as the sample screenshot above. It can also serve as a demo program, and you can see for yourself what the XML and Lua code looks like for larger scale GUIs.

Download :
The project has its sourceforge page : here.
You will find direct download of the source in either .zip or .7z format, or an SVN repository.

Note : lxgui and all the provided libraries are released under the GNU LGPL 3 license (you can use the libraries in your project without having to make the source code public, but if you ever modify these, you have to show the changes you made. See "gnu.txt" for more information).

9
SFML projects / iCE³ - clone of Minecraft
« on: October 05, 2011, 07:28:34 pm »
To me, it's more a tech demo than anything else right now. And as I've said in previous posts, I won't be able to work seriously on this for a while because of my studies. But nothing prevents me from coming back to it later, and who knows how far it'll go !
Anyway, thank you. Glad you like it :)

10
SFML projects / iCE³ - clone of Minecraft
« on: October 05, 2011, 07:16:45 pm »
That's strange. As a temporary workaround, you can go to the Save folder, and create a new file called KeyBindings.lua, in which you'll have to copy the following :
Code: [Select]
KeyBindings = {
    ["MoveForward"] = 17,
    ["Jump"] = 57,
    ["StrafeLeft"] = 30,
    ["MoveBackward"] = 31,
    ["StrafeRight"] = 32,
}


This is the standard WSAD layout for QWERTY keyboards. If you're not comfortable with it, you can adjust the numbers above using the KeyCodes.lua file, located at the root directory of the game.

This will prevent the start screen from popping the next time you start the game.

11
SFML projects / iCE³ - clone of Minecraft
« on: October 05, 2011, 07:08:45 pm »
It works well for me on Windows. Are you playing on linux ?

12
SFML projects / iCE³ - clone of Minecraft
« on: September 24, 2011, 03:28:37 pm »
That's up to you to decide ;)
I think the latest one is less cluttered with text : [click].

13
SFML projects / iCE³ - clone of Minecraft
« on: September 23, 2011, 06:51:30 pm »
Nice initiative ! And thank you for picking up a picture of iCE3 :)

14
SFML projects / iCE³ - clone of Minecraft
« on: September 19, 2011, 07:41:29 pm »
Quote from: "Groogy"
I you need help with the octree just let me know.

Thank you ! I'll keep you in touch ;)

Quote from: "Sylmael"
Can you please explain me, which faces do you use when you calculate smooth - per vertex lighting?

Sure ! Here is a little drawing, that will most likely be clearer than my words :


The exact same algorithm is used for LEFT, RIGHT, FRONT, BACK and BOTTOM faces (of course, except the fact that the drawing is rotated), and for any of their 4 vertices.

15
SFML projects / iCE³ - clone of Minecraft
« on: September 17, 2011, 11:42:47 am »
Yes, using octrees is a possible solution I've been thinking of.
I've never implemented such a system but that shouldn't be too hard, I'll think about it more, thanks !

Quote from: "Groogy"
Might even be able to get away with using Quadtree since if I remember correctly, chunks don't grow in one direction right? You don't generate more chunks when going up and down.

Actually no. That's the way Minecraft works, but I decided to allow unlimited depth and height (as Minetest does). It complicates things a little, but I think it is worth it.
You loose some performance, as you have much more chunks to deal with (10 times more approximately), but you can also use that at your advantage to perform more culling (Minecraft renders everything that is below your feets, even if you can't see it). For example, in the current version, every chunk (15x15x15) that is surrounded by non empty chunks is not rendered if all its faces are hidden. That helps a little.

Edit : cross posting !
Yes that's more or less the philosophy of the octree... I'll try to see what I can come up with, thanks ;)

Pages: [1] 2 3 ... 5