OpenGL - błąd przy rysowaniu?

0

Chce stworzyć prosty ProgressBar typu MARQUEE w OpenGL, jednak mam problem przy kodzie rysującym jego 'wartość'.

Otóż przy pierwszym 'przejściu' wygląda On tak:
???
Natomiast przy kolejnych tak:
???

Oto kod odnośnie 'wartości' ProgressBar'a:

//In right
   for(int i = 0; i <= sizeof(position)/sizeof(int); i++)
  {
   position[i] += value;
   if(start == 1)position[i] = x + i;
   if(position[i] >= (x + width))position[i] = x + 1; //Jestem prawie pewien, że tu jest blad
   glBegin(GL_LINES);// Rysujemy linie
     glVertex3f(position[i], y, -1); // początek linii
     glVertex3f(position[i], y + (height - 1), -1); // punkt końcowy lini 
   glEnd();
  }
start = 0;

position[i] to tablica przechowująca wartość dla każdej kreski
(bo z nich składa się pasek (patrz obraz 'Przed.png') i jest rozmiaru 25 elementów ale to nie ma znaczenia).

Kreski są rysowane jedna przy drugiej i gdy jedna z nich przekroczy wartość to jest przenoszona na początek ProgressBar'a.

if(position[i] >= (x + width))position[i] = x + 1; //Jestem prawie pewien, że tu jest blad

I to jest ten moment w którym kreski się od siebie oddalają.
Błąd występuje gdy value jest większe niż 1 (w przykładach użyłem wartości 5).
Nie wiem jak temu zapobiec.

PS: W tym temacie http://4programmers.net/Forum/C_i_C++/215831-wysrodkowanie_tekstu_opengl chodziło mi o środkowanie tekstu w przycisku.
Co myślicie o tym przycisku (jak się prezentuje graficznie)?

0

Nie rysuj linii tylko prostokąt o potrzebnej szerokości...

0

Tak robiłem na początku ale gdy prostokąt doszedł do granicy nagle znikał i pojawiał się na początku.
To mi nie pasowało.

Co myślisz o wyglądzie graficznym przycisku?

0

Może rozwiązaniem będzie że gdy pasek dojdzie do końca to na chwilę zniknie i pojawi się z powrotem na początku?

0

Sa 2 opcje:

  1. robisz tak, ze w pelni znika i pojawia sie na poczatku.
  2. robisz tak, ze czesc, ktora juz zniknela pojawia sie na poczatku (ta jest pewnie trudniejsza).
0

Zrobiłem punkt 2 i widać efekt.

0

Robisz typ, ktory jak osiagnie okreslona wartosc to sie zeruje i jedzie od nowa. Potem w algorytmie rysujacym sprawdzasz czy pozycja x lewej krawedzi jest mniejsza niz pozycja x prawej krawedzi, jesli tak rysujesz normalny prostokat od lewej do prawej, jesli nie rysujesz od lewej do konca powierznichni i od poczatku do wartosci prawego xa, to najprostsze co mi przyszlo do glowy w czasie polsatowych reklam.

Dobra udalo mi sie cos pokombinowac.

  1. Klasa tego integera.
class MyInt
{
public:
    MyInt(unsigned var, unsigned maxvalue = 100):
        var(var),
        maxvalue(maxvalue)
    {
        ;
    }

    operator unsigned()
    {
        return var;
    }

    MyInt operator+(const MyInt& m) const
    {
        unsigned tmp = var + m.var;
        while(tmp > maxvalue) tmp -= maxvalue;
        return MyInt(tmp);
    }

    MyInt& operator++()
    {
        if((++var) >= maxvalue)
            var = 0;
        return *this;
    }

    bool operator<(const MyInt& m) const
    {
        return var < m.var;
    }

    bool operator>(const MyInt& m) const
    {
        return var > m.var;
    }

private:
    unsigned var;
    const unsigned maxvalue;
};

na pewno do dopisania jest minimalny zakres i bym dodal troche funkcjonalnosci/operatorow.

  1. Klasa progressbara.
class ProgressBar
{
public:
    ProgressBar(unsigned len, unsigned width,
                unsigned height, unsigned colorfg,
                unsigned colorbg):
        len(len),
        width(width),
        height(height),
        posx(0, len),
        posy(0),
        colorfg(colorfg),
        colorbg(colorbg)
    {
        ;
    }

    void run()
    {
        while(true)
        {
            drawRect(0, 0, len, height, colorbg);

            MyInt tmpx = posx + (MyInt)width;
            if(posx > tmpx)
            {
                drawRect(posx, posy, len-(unsigned)posx, height, colorfg);
                drawRect(0, posy, tmpx, height, colorfg);
            }
            else
            {
                drawRect(posx, posy, width, height, colorfg);
            }
            SDL_Flip(SDL_GetVideoSurface());
            ++posx;
            SDL_Delay(50);
        }
    }

private:
    void drawRect(MyInt x, MyInt y, unsigned w, unsigned h, unsigned color)
    {
        SDL_Rect r;
        r.w = w;
        r.h = h;
        r.x = x;
        r.y = y;

        SDL_Surface* screen = SDL_GetVideoSurface();

        SDL_FillRect(screen, &r, color);
    }

private:
    const unsigned len;
    const unsigned width;
    const unsigned height;
    MyInt posx;
    MyInt posy;
    unsigned colorfg;
    unsigned colorbg;
};

Klasa napisana typowo na pokaz, jedna metoda uruchamiajaca, jedna rysujaca nic wiecej. Musisz przepisac rendering na opengla. No i dodac tam co masz za sluszne i chyba tyle.

Wklejam caly kod na pastebina, zebys mogl sobie sciagnac i skompilwoac bez udziwnien: http://pastebin.com/mRYpvemw

0

Robisz typ, który jak osiągnie określona wartość to się zeruje i jedzie od nowa. Potem w algorytmie rysującym sprawdzasz czy pozycja x lewej krawędzi jest mniejsza niż pozycja x prawej krawędzi, jeśli tak rysujesz normalny prostokąt od lewej do prawej, jeśli nie rysujesz od lewej do końca powierzchni i od początku do wartości prawego x a, to najprostsze co mi przyszło do głowy w czasie polsatowych reklam.

x to współrzędna krawędzi rysowanego prostokąta czy ProgressBar'a?

Robisz typ, który jak osiągnie określona wartość to się zeruje i jedzie od nowa.

Tak zrobiłem (tablica position[]).

Czym się różni:

(...)od lewej do prawej, jeśli nie rysujesz od lewej do końca powierzchni

od lewej do prawej i od lewej do końca powierzchni?

0

Czym się różni:

(...)od lewej do prawej, jeśli nie rysujesz od lewej do końca powierzchni

od lewej do prawej i od lewej do końca powierzchni?

W skrocie - dlugoscia. Przeanalizuj kod wyzej to bedziesz mial wszystko jak na dloni.

1 użytkowników online, w tym zalogowanych: 0, gości: 1