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

Author Topic: is it a bug, or a feature ?  (Read 1861 times)

0 Members and 1 Guest are viewing this topic.

snath

  • Newbie
  • *
  • Posts: 5
    • View Profile
is it a bug, or a feature ?
« on: May 21, 2012, 06:34:48 pm »
Hi,
I've written this ocaml-sfml piece of code for rosettacode:

http://rosettacode.org/wiki/Joystick_position#OCaml

and I've noticed 2 problems with it.
(dunno if I should create 2 differents thread for this)

I don't know if these are bugs, or if it is the expected behavior. (Using the RC 2.0)

1) If I omit the calls to SFShape.setOutlineColor and SFShape.setOutlineThickness (because I only want to fill), nothing is drawn at all. The two possible workarounds are define an outlineColor with the same color than the fillColor, OR define the outlineThickness to 0.0. Is it a bug, or is it the expected behavior?

2) As the task requests, the cross may be moved to the entire window with the joystick, but if I reshape the window smaller, the cross then only moves to a subset of the window area. Again is it a bug, or is it the expected behavior?
« Last Edit: May 22, 2012, 02:23:51 am by snath »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: is it a bug, or a feature ?
« Reply #1 on: May 21, 2012, 10:27:02 pm »
I'm sorry but I can't help with OCaml code. The best would be to write the same thing in C++ so that we are sure that it's not a bug in the binding.
Laurent Gomila - SFML developer

snath

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: is it a bug, or a feature ?
« Reply #2 on: May 22, 2012, 02:22:41 am »
The (expected or unexpected) behaviours 1) and 2) are exactly the same in pure C:

#include <SFML/Graphics.h>
#include <string.h>
#include <stdio.h>

float cross[] =
  {   1.0,   1.0,   10.0,   1.0,   10.0, -1.0,     1.0, -1.0,
      1.0, -10.0,   -1.0, -10.0,   -1.0, -1.0,   -10.0, -1.0,
    -10.0,   1.0,   -1.0,   1.0,   -1.0, 10.0,     1.0, 10.0, };

char *buttons_string(unsigned char *buttons)
{
    unsigned int i, j;
    static char str[sfJoystickButtonCount * 2 + 1];
    bzero(str, sfJoystickButtonCount * 2 + 1);
    for (i = 0, j = 0; i < sfJoystickButtonCount; i++) {
        if (buttons[i]) {
            str[j] = '0' + i;
            str[j+1] = ' ';
            j += 2;
        }
    }
    return str;
}

sfVector2f position(sfRenderWindow *app, sfVector2f pos)
{
    sfVector2f vec;
    sfVector2u size = sfRenderWindow_getSize(app);

    float hw = ((float) size.x) / 2.0f;
    float hh = ((float) size.y) / 2.0f;

    vec.x = hw + ((pos.x / 100.0f) * hw);
    vec.y = hh + ((pos.y / 100.0f) * hh);

    return vec;
}

void display(
        sfRenderWindow *app,
        sfShape *shape,
        sfVector2f pos,
        sfText* text,
        unsigned char *buttons)
{
    sfText_setString(text, buttons_string(buttons));
    sfShape_setPosition(shape, position(app, pos));
    sfRenderWindow_clear(app, sfBlack);
    sfRenderWindow_drawText(app, text, NULL);
    sfRenderWindow_drawShape(app, shape, NULL);
    sfRenderWindow_display(app);
}

static unsigned int
my_sfShapeGetPointCountCallback(void *data)
{
    unsigned int len = (sizeof(cross) / sizeof(cross[0])) / 2;
    return (len);
}

static sfVector2f
my_sfShapeGetPointCallback(unsigned int i, void *data)
{
    float *array = (float *)data;
    sfVector2f vec;
    unsigned int j = i * 2;
    vec.x = array[j];
    vec.y = array[j+1];
    return vec;
}

void get_joystick(sfEvent *event, sfVector2f *pos, unsigned char *buttons)
{
    switch (event->type) {
        case sfEvtJoystickButtonPressed:
            if (event->joystickButton.joystickId == 0) {
                buttons[event->joystickButton.button] = 1;
            }
            break;
        case sfEvtJoystickButtonReleased:
            if (event->joystickButton.joystickId == 0) {
                buttons[event->joystickButton.button] = 0;
            }
            break;
        case sfEvtJoystickMoved:
            if (event->joystickMove.joystickId == 0) {
                if (event->joystickMove.axis == sfJoystickX) {
                    pos->x = event->joystickMove.position;
                }
                if (event->joystickMove.axis == sfJoystickY) {
                    pos->y = event->joystickMove.position;
                }
            }
            break;
    }
}

int main()
{
    char title[] = "Joystick Position";
    sfRenderWindow *app;
    sfVideoMode mode;
    sfContextSettings settings;
    sfUint32 style = sfResize | sfClose;

    mode.width = 800;
    mode.height = 600;
    mode.bitsPerPixel = 32;

    settings.depthBits = 24;
    settings.stencilBits = 8;
    settings.antialiasingLevel = 0;
    settings.majorVersion = 0;
    settings.minorVersion = 0;

    app = sfRenderWindow_create(mode, title, style, &settings);
    if (!app) return 1;

    sfText* text = sfText_create();
    if (!text) return 1;

    sfShape *shape = sfShape_create(
        &my_sfShapeGetPointCountCallback,
        &my_sfShapeGetPointCallback,
        (void *)cross);
    if (!shape) return 1;

    sfShape_setFillColor(shape, sfWhite);
#if 1  /* XXX Without this, the shape is not drawn at all: */
    sfShape_setOutlineColor(shape, sfWhite);
    sfShape_setOutlineThickness(shape, 1.0);
#endif

    unsigned char buttons[sfJoystickButtonCount];
    bzero(buttons, sfJoystickButtonCount);

    sfEvent event;
    sfVector2f pos;
    pos.x = 0.0f;
    pos.y = 0.0f;

    while (sfRenderWindow_isOpen(app))
    {
        while (sfRenderWindow_pollEvent(app, &event))
        {
            if (event.type == sfEvtClosed)
                sfRenderWindow_close(app);

            if (event.type == sfEvtKeyPressed && event.key.code == sfKeyEscape)
                sfRenderWindow_close(app);

            get_joystick(&event, &pos, buttons);
        }

        display(app, shape, pos, text, buttons);
    }

    sfText_destroy(text);
    sfShape_destroy(shape);
    sfRenderWindow_destroy(app);
    return 0;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: is it a bug, or a feature ?
« Reply #3 on: May 22, 2012, 08:02:53 am »
Thanks :)

1) Is your "cross" a convex shape? I guess it's not, so it breaks the requirements of sfShape.

2) The default view still displays the initial size of the window (800x600) after you resize it, so if your calculations are based on the current window size then they are wrong after a resize. They must be based on the size of the current view.
Laurent Gomila - SFML developer

snath

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: is it a bug, or a feature ?
« Reply #4 on: May 22, 2012, 08:32:21 pm »
Hi,

1) positionning in the window area using sfView resolve the first problem, thanks for the solution!

2) using convex shapes instead of concave ones still produces the same error when the outline is omitted.
If you compile with this macro, the shape is drawn right:
#define WITH_OUTLINE 1

If you compile with this macro (omitting outline), then the convex shapes are not drawn:
#define WITH_OUTLINE 0

#include <SFML/Graphics.h>
#include <string.h>
#include <stdio.h>

sfVector2f cross1[] = {{10.0,  1.0}, { 10.0, -1.0}, {-10.0, -1.0}, {-10.0, 1.0}};
sfVector2f cross2[] = {{1.0, -10.0}, {-1.0, -10.0}, {-1.0,  10.0}, { 1.0, 10.0}};

typedef struct
{
    unsigned int len;
    sfVector2f *points;
} path;

#define path_struct(data) \
  { (sizeof(data) / sizeof(data[0])), data }


char *buttons_string(unsigned char *buttons)
{
    unsigned int i, j;
    static char str[sfJoystickButtonCount * 2 + 1];
    for (i = 0, j = 0; i < sfJoystickButtonCount; i++) {
        if (buttons[i]) {
            str[j] = '0' + i;
            str[j+1] = ' ';
            j += 2;
        }
    }
    str[j] = 0;
    return str;
}

sfVector2f position(sfRenderWindow *app, sfVector2f pos)
{
    sfVector2f vec;
    const sfView *view = sfRenderWindow_getView(app);
    sfVector2f size = sfView_getSize(view);

    float hw = size.x / 2.0f;
    float hh = size.y / 2.0f;

    vec.x = hw + ((pos.x / 100.0f) * hw);
    vec.y = hh + ((pos.y / 100.0f) * hh);

    return vec;
}

void display(
        sfRenderWindow *app,
        sfShape *shape1,
        sfShape *shape2,
        sfVector2f pos,
        sfText* text,
        unsigned char *buttons)
{
    sfText_setString(text, buttons_string(buttons));
    sfShape_setPosition(shape1, position(app, pos));
    sfShape_setPosition(shape2, position(app, pos));
    sfRenderWindow_clear(app, sfBlack);
    sfRenderWindow_drawText(app, text, NULL);
    sfRenderWindow_drawShape(app, shape1, NULL);
    sfRenderWindow_drawShape(app, shape2, NULL);
    sfRenderWindow_display(app);
}

static unsigned int
my_sfShapeGetPointCountCallback(void *data)
{
    return (((path *)data)->len);
}

static sfVector2f
my_sfShapeGetPointCallback(unsigned int i, void *data)
{
    return (((path *)data)->points)[i];
}

void get_joystick(sfEvent *event, sfVector2f *pos, unsigned char *buttons)
{
    switch (event->type) {
        case sfEvtJoystickButtonPressed:
            if (event->joystickButton.joystickId == 0) {
                buttons[event->joystickButton.button] = 1;
            }
            break;
        case sfEvtJoystickButtonReleased:
            if (event->joystickButton.joystickId == 0) {
                buttons[event->joystickButton.button] = 0;
            }
            break;
        case sfEvtJoystickMoved:
            if (event->joystickMove.joystickId == 0) {
                if (event->joystickMove.axis == sfJoystickX) {
                    pos->x = event->joystickMove.position;
                }
                if (event->joystickMove.axis == sfJoystickY) {
                    pos->y = event->joystickMove.position;
                }
            }
            break;
    }
}

int main()
{
    char title[] = "Joystick Position";
    sfRenderWindow *app;
    sfVideoMode mode;
    sfContextSettings settings;
    sfUint32 style = sfResize | sfClose;

    mode.width = 800;
    mode.height = 600;
    mode.bitsPerPixel = 32;

    settings.depthBits = 24;
    settings.stencilBits = 8;
    settings.antialiasingLevel = 0;
    settings.majorVersion = 0;
    settings.minorVersion = 0;

    app = sfRenderWindow_create(mode, title, style, &settings);
    if (!app) return 1;

    sfText* text = sfText_create();
    if (!text) return 1;

    path path1 = path_struct(cross1);
    path path2 = path_struct(cross2);

    sfShape *shape1 = sfShape_create(
        &my_sfShapeGetPointCountCallback,
        &my_sfShapeGetPointCallback,
        (void *)&path1);
    if (!shape1) return 1;

    sfShape *shape2 = sfShape_create(
        &my_sfShapeGetPointCountCallback,
        &my_sfShapeGetPointCallback,
        (void *)&path2);
    if (!shape2) return 1;

#define WITH_OUTLINE 0  /* XXX Without this, the shape is not drawn at all: */

    sfShape_setFillColor(shape1, sfWhite);
#if WITH_OUTLINE
    sfShape_setOutlineColor(shape1, sfWhite);
    sfShape_setOutlineThickness(shape1, 1.0);
#endif

    sfShape_setFillColor(shape2, sfWhite);
#if WITH_OUTLINE
    sfShape_setOutlineColor(shape2, sfWhite);
    sfShape_setOutlineThickness(shape2, 1.0);
#endif

    unsigned char buttons[sfJoystickButtonCount];
    bzero(buttons, sfJoystickButtonCount);

    sfEvent event;
    sfVector2f pos = { 0.0f, 0.0f };

    while (sfRenderWindow_isOpen(app))
    {
        while (sfRenderWindow_pollEvent(app, &event))
        {
            if (event.type == sfEvtClosed)
                sfRenderWindow_close(app);

            if (event.type == sfEvtKeyPressed && event.key.code == sfKeyEscape)
                sfRenderWindow_close(app);

            get_joystick(&event, &pos, buttons);
        }

        display(app, shape1, shape2, pos, text, buttons);
    }

    sfText_destroy(text);
    sfShape_destroy(shape1);
    sfShape_destroy(shape2);
    sfRenderWindow_destroy(app);
    return 0;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: is it a bug, or a feature ?
« Reply #5 on: May 22, 2012, 11:33:51 pm »
If the problem is now only about drawing shapes, can the code be reduced to its minimum please?
Laurent Gomila - SFML developer

snath

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: is it a bug, or a feature ?
« Reply #6 on: May 23, 2012, 12:01:23 am »
sure!

#include <SFML/Graphics.h>

sfVector2f rectangle[] =
    {{80.0, 80.0}, {80.0, -80.0}, {-80.0, -80.0}, {-80.0, 80.0}};

typedef struct
{
    unsigned int len;
    sfVector2f *points;
} path;

#define path_struct(data) \
  { (sizeof(data) / sizeof(data[0])), data }


sfVector2f position(sfRenderWindow *app)
{
    sfVector2f vec;
    const sfView *view = sfRenderWindow_getView(app);
    sfVector2f size = sfView_getSize(view);
    vec.x = size.x / 2.0f;
    vec.y = size.y / 2.0f;
    return vec;
}

void display(sfRenderWindow *app, sfShape *shape)
{
    sfShape_setPosition(shape, position(app));
    sfRenderWindow_clear(app, sfBlack);
    sfRenderWindow_drawShape(app, shape, NULL);
    sfRenderWindow_display(app);
}

static unsigned int
my_sfShapeGetPointCountCallback(void *data)
{
    return (((path *)data)->len);
}

static sfVector2f
my_sfShapeGetPointCallback(unsigned int i, void *data)
{
    return (((path *)data)->points)[i];
}

int main()
{
    char title[] = "Joystick Position";
    sfRenderWindow *app;
    sfVideoMode mode;
    sfContextSettings settings;

    mode.width = 800;
    mode.height = 600;
    mode.bitsPerPixel = 32;

    settings.depthBits = 24;
    settings.stencilBits = 8;
    settings.antialiasingLevel = 0;
    settings.majorVersion = 0;
    settings.minorVersion = 0;

    app = sfRenderWindow_create(mode, title, sfResize | sfClose, &settings);
    if (!app) return 1;

    path rect = path_struct(rectangle);

    sfShape *shape = sfShape_create(
        &my_sfShapeGetPointCountCallback,
        &my_sfShapeGetPointCallback,
        (void *)&rect);
    if (!shape) return 1;

#define WITH_OUTLINE 0  /* XXX Without this, the shape is not drawn at all: */

    sfShape_setFillColor(shape, sfWhite);
#if WITH_OUTLINE
    sfShape_setOutlineColor(shape, sfWhite);
    sfShape_setOutlineThickness(shape, 1.0);
#endif

    while (sfRenderWindow_isOpen(app))
    {
        sfEvent event;
        while (sfRenderWindow_pollEvent(app, &event))
        {
            if (event.type == sfEvtClosed)
                sfRenderWindow_close(app);
        }
        display(app, shape);
    }

    sfShape_destroy(shape);
    sfRenderWindow_destroy(app);
    return 0;
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: is it a bug, or a feature ?
« Reply #7 on: May 23, 2012, 03:15:49 pm »
This simple code works for me:
#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "test");

    sf::CircleShape shape;
    shape.setRadius(100);
    shape.setPosition(200, 200);
    shape.setFillColor(sf::Color::White);
#if 0
    shape.setOutlineColor(sf::Color::White);
    shape.setOutlineThickness(1.0f);
#endif

    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();
    }

    return 0;
}

You can try to convert it to C and test it.
Laurent Gomila - SFML developer

snath

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: is it a bug, or a feature ?
« Reply #8 on: May 23, 2012, 08:37:31 pm »
I replaced the user defined shape by a circle shape in my previous example, there is no problem with the circles.

So is it a bug for user defined shapes ?

I also tried to define the shape CW or CCW (like in OpenGL), but the problem with the outline is still there.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: is it a bug, or a feature ?
« Reply #9 on: May 23, 2012, 10:55:38 pm »
Quote
So is it a bug for user defined shapes ?
Maybe. I'll try that :)
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: is it a bug, or a feature ?
« Reply #10 on: May 24, 2012, 11:13:02 am »
The problem is that you never call sfShape_update (it reconstructs the shape after the points have changed). I guess I should call it automaticaly in sfShape_create.
Laurent Gomila - SFML developer