2012-12-12 14 views
6

Jest to kod używam narysować prostokąt w moim programie:obramowania wokół tekstur OpenGL

glBegin(GL_QUADS); 
    glTexCoord2f(0.0f, maxTexCoordHeight);    glVertex2i(pos.x, pos.y + height); 
    glTexCoord2f(0.0f, 0.0f);       glVertex2i(pos.x, pos.y); 
    glTexCoord2f(maxTexCoordWidth, 0.0f);    glVertex2i(pos.x + width, pos.y); 
    glTexCoord2f(maxTexCoordWidth, maxTexCoordHeight); glVertex2i(pos.x + width, pos.y + height); 
glEnd(); 

czerpie tylko prosty prostokąt o określonej strukturze, np tak: enter image description here

Chciałbym zapytać, czy jest to możliwe w OpenGL, aby osiągnąć efekt granicy takiego:

Jak widać wewnątrz tej dachówki jest tylko zwykły niebieskim tle, które mogą być traktowane oddzielnie - po prostu automatycznie zmieniłem teksturę. Można to łatwo osiągnąć za pomocą kodu, który podałem, ale problem dotyczy granicy.

Jeśli granica miała być jednokolorowa, mógłbym spróbować narysować pusty, niezajęty prostokąt, używając GL_LINES wokół mojej tekstury, ale tak nie jest.

Również jeśli kafelki były zawsze o ustalonym rozmiarze, mogłem przygotować tekst, który by pasował, ale MUSI BYĆ łatwo skalowalny bez zmiany pliku mapy bitowej używam jako tekstury.

Więc jeśli nie jest to możliwe z podstawowymi funkcjami OpenGL, jakie są podejścia do osiągnięcia tego efektu, który byłby najbardziej wydajny i/lub łatwy?

EDYCJA: Musi być 2D.

+0

Jeśli nie potrzebujesz 2d, dlaczego nie chcesz uzyskać efektu ukosowania, wykonując ten trapezoidalny kształt w 3D i wykorzystując oświetlenie do uzyskania cieniowanych efektów, których potrzebujesz? – Quetzalcoatl

+0

@Quetzalcoatl Dziękuję za odpowiedź, ale tak, to musi być 2D. Będę edytować moje pytanie, aby dodać te informacje. –

+1

Można napisać moduł cieniujący fragmentu, aby dodać obramowanie. Jeśli jednak nadal używasz trybu natychmiastowego (przestarzałe funkcje, takie jak "glVertex"), prawdopodobnie zajmie ci to trochę czasu, aby dogonić cudowny świat OpenGL 2.0 i nie tylko. –

Odpowiedz

4

Jest to klasyczny problem z GUI z OpenGL i często jest rozwiązywany za pomocą 9-komorowego wzorca. W tym przypadku dodajemy efekt do oryginalnego obrazu (lub definiujemy go przy pomocy innych parametrów OpenGL) i dzielimy renderowane kwadraty w dziewięciu quadach: trzech rzędach i trzech kolumnach.

Następnie ustawiasz wysokość górnego i dolnego rzędu, ustawiając szerokość lewej i prawej kolumny. Środkowy kwadracik jest skalowany tak, aby twój obiekt pasował do prostokąta, który chcesz dopasować. Następnie mapujesz tylko graniczne części tekstury na kwadraty tworzące zewnętrzne komórki, podczas gdy ty mapujesz środek tekstury na środek kwadratu.


W związku z tym, co zostało powiedziane w komentarzach, można również użyć rzeczywistych efektów 3D, wykonując quad 3D. Nikt nie zmusza cię do używania projekcji perspektywicznej w takim przypadku, możesz pozostać z rzutowaniem ortogonalnym (tryb 2D). OpenGL i tak zawsze wykona obliczenia 3D.

+0

Myślę, że ta odpowiedź składa się z wszystkiego, co muszę wiedzieć. Dziękuję bardzo, Jonas! –

0

Oprócz odpowiedzi Jonasa, która jest doskonała, chcę dodać jeszcze dwie opcje.
Pierwszym z nich jest sprawienie, by tekstura wyglądała jak żądany kwadrat. Żadnego wymyślnego kodu nie jest konieczne, jeśli możesz to zrobić w Photoshopie;).
Drugi to nieco skomplikować swój kod rysunkowy. Jeśli spojrzysz na swój obraz, zobaczysz, że każde "zbocze boczne" twojego kwadratu może zostać narysowane dwoma trójkątami. można dokonać kod narysować 10 trójkąty zamiast jeden kwadrat i użyć innego koloru dla każdej grupy dwa trójkąty:

draw() { 
    GLFloat i = <your_inset_here>; 

    //top border part, top left triangle 
    glColor3f(<color_0>); 
    glVertex2f(pos.x, pos.y); 
    glVertex2f(pos.x + w, pos.y); 
    glVertex2f(pos.x + i, pos.y + i); 
    //top border part, bottom right triangle 
    glVertex2f(pos.x + w, pos.y); 
    glVertex2f(pos.x + w - i, pos.y + i); 
    glVertex2f(pos.x + i, pos.y + i); 

    //repeat this process with the other coordinates for the other three borders 

    // draw the middle square using {(pos.x+i,pos.y+i),(pos.x+w-i,pos.y+i),(pos.x+w-i,pos.y+h-i),(pos.x+i,pos.y+h-i)} as coordinates 
} 

można dodatkowo poprawić to poprzez stworzenie funkcji narysować nieregularnym kształcie quad ze współrzędnymi dają i kolor i wywołanie tej funkcji 5 razy.

Powiązane problemy