2012-07-07 12 views
6

Mamy aplikację do rysowania iOS. Obecnie rysunek jest implementowany z OpenGL ES 1.1. Używamy niektórych algorytmów do wygładzania linii, takich jak krzywe Beziera. Tak więc, gdy pojawiają się zdarzenia dotykowe, otrzymujemy zestaw punktów poza punktami zdarzeń dotykowych (w oparciu o algorytmy) i narysujemy te punkty. Używamy również tekstury pędzla, aby punkty miały bardziej naturalny wygląd.Gładka, teksturowana linia z modułami cieniującymi OpenGL ES 2.0

Zastanawiam się, czy możliwe jest zaimplementowanie tych algorytmów w modułach cieniujących OpenGL ES 2.0. Coś jak wywołać funkcję OpenGL, aby narysować linie wykonane z punktów dotykowych, a na wyjściu wygładzono krzywą ze szczotkowanego tekstu.

enter image description here

Punkty P0, P1, ... P4 oto dotykowe wydarzenia i punkty na czerwonej krzywej - punktów wyjściowych, z takim kroku dla T tak, że odległość między dwoma punktami na krzywej sąsiednich nie jest większy niż 1 piksel.

A tu jest link z Beziera algorytmu wyjaśnienia: Bézier curve - Wikipedia, the free encyclopedia

Każda pomoc jest mile widziane. Dzięki.

+0

Czy możesz być bardziej konkretny? Nie możemy powiedzieć, czy możliwe jest zaimplementowanie określonego algorytmu w module cieniującym, jeśli nie wiemy, co to jest algorytm! – user1118321

+0

Nie ma znaczenia, z jakiego algorytmu korzystamy. Chodzi o to, że moduł cieniujący powinien generować więcej punktów wyjściowych niż punktów wejściowych. Zmieniłem moje pytanie i dodałem przykład z algorytmem Beziera. –

Odpowiedz

6

Nie można generować nowych wierzchołków wewnątrz modułu cieniującego wierzchołków (można to zrobić w module cieniującym geometrii, którego ES nie posiada). Liczba wierzchołków wyjściowych jest zawsze taka sama jak liczba wierzchołków wejściowych, można zmieniać tylko ich pozycje (i, oczywiście, atrybuty oczywiście).

W związku z tym należy narysować pasek linii złożony z wystarczającej liczby wierzchołków, aby zagwarantować gładką krzywiznę. To, co możesz zrobić, to wstawić zawsze ten sam pasek linii, mający wartości parametrów krzywej T jako pozycje wierzchołków 1D. W module cieniującym następnie użyj tej pozycji wejściowej (wartość parametru), aby obliczyć rzeczywistą pozycję 2D/3D na krzywej, używając algorytmu DeCasteljau (lub czegoś podobnego) i punktów P0 do P4, które wstawisz do modułu cieniującego jako stałe (zmienne jednolite w kategoriach GLSL).

Ale nie jestem pewien, czy to naprawdę kupiłoby ci coś ponad obliczanie tych punktów na procesorze i umieszczanie ich w dynamicznym VBO. To, co zapisujesz, to kopiowanie punktów krzywych z procesora na procesor graficzny i obliczenia na procesorze, ale z drugiej strony twój procesor werteksów jest znacznie bardziej złożony. Należy ocenić, które jest lepsze podejście. Jeśli musisz obliczyć punkty krzywej każdej klatki (ponieważ punkty kontrolne zmieniają każdą ramkę), a krzywa jest dość wysoka, może to nie być taki zły pomysł. Ale poza tym nie sądzę, że to naprawdę się opłaca. Ponadto twój moduł cieniujący nie będzie można łatwo dostosować do zmieniającej się liczby punktów kontrolnych/stopnia krzywej w czasie wykonywania.

Ale po raz kolejny nie można umieścić 5 punktów kontrolnych i wygenerować punktów N krzywej na GPU. Moduł cieniujący wierzchołków zawsze działa na pojedynczym wierzchołku i tworzy pojedynczy wierzchołek, taki sam jak moduł cieniujący zawsze działa na jednym fragmencie (np. Piksel, ale jeszcze nie jest) i powoduje powstanie pojedynczego (lub nie) fragmentu .

+0

Dzięki za bardzo wyczerpującą odpowiedź! Szukałem sposobu, aby uczynić kod jaśniejszym, a także uzyskać pewną wydajność. Ale, jak widzę, tak nie jest. Przy okazji zasugerowałeś bardzo interesujące podejście, przekazując linię 1D, która reprezentuje T. Zastanowię się nad tym. –

+0

Pewnie :) Właśnie nacisnąłem enter, aby napisać z nowej linii i wysłał komentarz :) Jeszcze raz dziękuję! –