Autor Wątek: GL_POINTS wyświetlane jako kwadraty  (Przeczytany 4313 razy)

Offline Avaj

  • Użytkownik

# Sierpień 04, 2016, 19:26:26
Nie mam zielonego pojęcia o tym w jaki sposób pisze się sterowniki do kart graficznych, ale chyba aż tak bym nie przesadzał - emulacja starych API OpenGL za pomocą wywołań z nowszych wersji wydaje się być czymś stosunkowo trywialnym, przynajmniej w porównaniu do złożoności tego sterownika "właściwego". Jeżeli goście z nVidii mają czas i chęci na optymalizacje poprzez wciskanie "ifów" pod kątem konkretnych gier, to nie widzę czemu taka warstwa tłumacząca miałaby być jakimkolwiek problemem. Szczególnie że jest to zadanie w zasięgu osoby nawet bardzo pobieżnie zaznajomionej z OpenGL (takiej jak ja). Jasne, pewnie trzeba pamiętać o bardzo wielu kruczkach w specyfikacji ale ogólnie to jest robota "na raz" i nie wiem czemu wsparcie by miało być gorsze z każdą aktualizacją.
To nie jest robota "na raz", bo za każdym razem ktoś wyciągnie jakąś aplikację np. z kategorii workstation (CADy), która MUSI działać, a np. w nieprawidłowy sposób używa API (bo "na nvidii działa").

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Mr. Hania

  • Użytkownik

# Sierpień 05, 2016, 01:49:35
Dlatego szczerze polecam nawet nie udzielać odpowiedzi na pytania dotyczace deprecated API. To jedyny sposób żeby zmusić ludzi do nauczenia się właściwego korzystania z biblioteki. Jeżeli ktoś już musi samemu pisać w OpenGL zamiast używać jakiegoś frameworka, to oczekuje od niego aby poświęcił czas i używał go właściwie albo wcale. To nie jest personalny przytyk - po prostu szanujmy swoj czas na wzajem, promujmy poprawne wzorce.

Ech, a moim zdaniem lepsze od nieudzielania odpowiedzi byłoby pokazanie przykładu na zasadzie "zobacz jakie to jest proste do zrobienia przy użyciu nowego API". Bez zachęty początkującym ciężko się przebić przez to rysowanie pierwszego trójkąta - no bo przecież jakim cudem ten nowy OpenGL jest niby taki fajny skoro zamiast napisać 4 linijki trzeba się nagimnastykować i poznać działanie kilkunastu (jak nie więcej) dziwnych wywołań oraz ogarniać dodatkowy język? My wiemy że ten klif na który trzeba się wspiąć jest tylko jeden a jak już się jest na górze to wszędzie płaska równina, ale z dołu tego nie widać.

I dlatego reszta wywodu niestety nie jest prawdziwa. To nie jest robota "na raz", to są osobo-miesiące implementacji wstępnej a potem utrzymanie. HW sie zmienia z kazda generacja kart, np. to co kiedys bylo Fixed Function teraz moze byc emulowane w shaderach, etc. W rezultacie wspieranie glBegin/glEnd i innych zaszlosci z czasów gdy renderowano jednokolorowe trójkąty jest ciągłą udręką a nie czyms cos sie zrobi raz i zapomni.

Ja to widzę tak (a jak wspominałem, zielonego pojęcia o tym nie mam więc dużo nie widzę): klepiemy sterownik tylko i wyłącznie do nowego API OpenGL oraz mamy warstwę tłumaczącą stare wywołania na nowego w razie czego (powiedzmy na OpenGL 3.2). Lata mijają, sprzęt się zmienia, trzeba dostosować sterownik ale warstwa tłumacząca się nawet o linijkę nie zmienia bo ani specyfikacja OpenGL 3.2 się nie zmieniła ani ta od starych OpenGLi, oczywiście po warunkiem że jest napisana w 100% zgodnie ze specyfikacją (w takim świcie niestety nie żyjemy, ale czy jest to aż tak bardzo nieosiągalne...?). Lata mijają, wychodzi Vulkan, od tego momentu piszemy sterownik tylko i wyłącznie do Vulkana, robimy warstwę tłumaczącą wywołania nowego OpenGL na Vulkan. Obsługę prastarego w tym momencie OpenGL mamy za darmo (poprzez złożenie dwóch tłumaczy).

W każdym razie Microsoft ma to swoje ANGLE i jakoś działa. Choć faktem jest że OpenGL ES 2.0 ma chyba najkrótszą specyfikacją ze wszystkich OpenGLi więc jego emulacja jest stosunkowo prosta.

To nie jest robota "na raz", bo za każdym razem ktoś wyciągnie jakąś aplikację np. z kategorii workstation (CADy), która MUSI działać, a np. w nieprawidłowy sposób używa API (bo "na nvidii działa").

To prawda. Ale tylko dowodzi że syf w sterowniku zawsze był i zawsze będzie, tego się nie da wyplewić i już. Więc jakbyście z tym nie walczyli to i tak nie wygracie bez względu na to czy uda wam się na tym forum kogokolwiek przekonać (czego mimo wszystko szczerze życzę!).

Offline MrKaktus

  • Użytkownik

  • +2
# Sierpień 05, 2016, 10:15:43
Ja to widzę tak (a jak wspominałem, zielonego pojęcia o tym nie mam więc dużo nie widzę): klepiemy sterownik tylko i wyłącznie do nowego API OpenGL oraz mamy warstwę tłumaczącą stare wywołania na nowego w razie czego (powiedzmy na OpenGL 3.2). Lata mijają, sprzęt się zmienia, trzeba dostosować sterownik ale warstwa tłumacząca się nawet o linijkę nie zmienia bo ani specyfikacja OpenGL 3.2 się nie zmieniła ani ta od starych OpenGLi, oczywiście po warunkiem że jest napisana w 100% zgodnie ze specyfikacją (w takim świcie niestety nie żyjemy, ale czy jest to aż tak bardzo nieosiągalne...?). Lata mijają, wychodzi Vulkan, od tego momentu piszemy sterownik tylko i wyłącznie do Vulkana, robimy warstwę tłumaczącą wywołania nowego OpenGL na Vulkan. Obsługę prastarego w tym momencie OpenGL mamy za darmo (poprzez złożenie dwóch tłumaczy).
Gdybys tak zrobil to bys mial slideshow a nie Real Time graphics. Takie rozwiazanie jest kompletnie niewydajne, tworzysz iles warstw tlumaczacych abstrakcje API ktore nie maja nic wspolnego z GPU. Jednoczesnie enkapsulujesz te calle starego API translatorem wiec nie da sie zrobic z nimi niczego bezposrednio pod dany HW. OpenGL na Vulkanie mozna "napisac raz" ale bedzie to droga przez meke z milionem hakow, a na koncu i tak okaze sie ze milion gier zle uzywa OpenGL "bo na NV dziala" i trzeba bedzie dodac kolejne miliony "fixow" pod nie.

Sterownik od poczatku do konca jest pisany pod maksymalnie wydajne dopasowanie zasobow do GPU. Kod moze byc dziedziczony ale z poprzednich generacji HW dla kolejnych. Po wywolaniu funkcji API wszystko jest od razu tlumaczone na stany GPU, OpenGL to tylko abstrakcja ktore w dzisiejszych czasach strasznie odbiega od tego jak HW na prawde dziala. Regularnie sprawdza sie rozmiar binarki sterownika w runtime, czasy wywolania roznych API calli ktore sa entry pointami etc. Performance jest wszystkim i na takie abstrakcyjne translatory nie ma po prostu szans.

Offline Mr. Hania

  • Użytkownik

# Sierpień 06, 2016, 00:27:07
Gdybys tak zrobil to bys mial slideshow a nie Real Time graphics. Takie rozwiazanie jest kompletnie niewydajne, tworzysz iles warstw tlumaczacych abstrakcje API ktore nie maja nic wspolnego z GPU. Jednoczesnie enkapsulujesz te calle starego API translatorem wiec nie da sie zrobic z nimi niczego bezposrednio pod dany HW. OpenGL na Vulkanie mozna "napisac raz" ale bedzie to droga przez meke z milionem hakow, a na koncu i tak okaze sie ze milion gier zle uzywa OpenGL "bo na NV dziala" i trzeba bedzie dodac kolejne miliony "fixow" pod nie.

Okej, okej, powiedzmy że udało Ci się mnie przekonać że jednak nie powinienem w najbliższym czasie aplikować do nVidii na stanowisko programisty sterowników.

Choć zastanowiłbym się czy na pewno zależy nam na żyłowaniu wydajności dla starych API. W końcu robimy to tylko po to żeby nadal mieć wsparcie dla starego kodu (jest jakieś eleganckie polskie tłumaczenie dla legacy code?), więc dzisiejsze karty graficzne, które w końcu są o kilka rzędów szybsze, powinny im sprostać nawet pomimo kilku warstw pośredniczących. Dodatkowo, znacząca różnica w wydajności byłaby też subtelną zachętą dla osób takich jak OP z tego wątku aby nie korzystać ze starego API.

A żeby nie ciągnąć tematu w nieskończoność to sobie sam odpowiem: nie, nie możemy sobie na to pozwolić bo wtedy przychodzi AMD ze swoimi mniej eleganckimi ale szybszymi sterownikami i śmieją się że u nich Quake 3 chodzi w 900 FPS a u nas tylko w 300.

Offline Xion

  • Redaktor
    • xion.log

# Sierpień 06, 2016, 01:07:02
Cytuj
Choć zastanowiłbym się czy na pewno zależy nam na żyłowaniu wydajności dla starych API.
Tak. Chcesz żeby twoi użytkownicy kupili twoje nowe GPU i zorientowali się, że ich aktualne gry działają gorzej? Reddit by się załamał pod ciężarem narzekań, a księgowość pod ciężarem żądań refundów.

Offline slowbro

  • Użytkownik

# Sierpień 07, 2016, 00:12:16
Dziękuję wszystkim za wskazówki, a zwłaszcza karol57. Udało się zrobić teksturę w postaci koła:) Skończę projekt, na którym pracuje w starym API i przesiadam się na nowe:)
« Ostatnia zmiana: Sierpień 07, 2016, 00:33:04 wysłana przez slowbro »

Offline ArekBal

  • Użytkownik

# Sierpień 07, 2016, 16:41:24
Na dzień dzisiejszy, pod tym samym pretekstem moglibyśmy tez powiedzieć wszystkim produkującym na PC że mają się przerzucić na Vulcan... oczywiście wyolbrzymiam. Ale za kilka miechów, to zdanie będzie bardziej niż prawdziwe.

A argument, w stylu "pokażmy mu, jakie to proste" jest nieprawdziwy.  :D Te API i każde kolejne są coraz bardziej skomplikowane i ogarnięcie ich, wymaga jeszcze więcej pracy.

Jedyne co takiego początkującego, niewymagającego programistę może uratować, to istniejące wrappery na ten ogrom możliwości - o ile w danej kwestii istnieją.

Offline slowbro

  • Użytkownik

# Sierpień 14, 2016, 13:13:48
Robię testy działania funkcji glBlendfunc. Mam teksturę koloru czarno-białego (nie ma w niej kolorów pośrednich czyli szarych). Ta tekstura to tło sceny. Na tym tle chce wyświetlić poruszające się trójkąty z nałożoną teksturą koloru czarno-białego (w taj teksturze jest także brak kolorów pośrednich). Tekstura jest tworzona za pomocą tablocy typu GLubyte Image[IMAGE_WIDTH][IMAGE_HEIGHT][4]. W teksturze tej składowe kolorów ustawione są dla koloru białego (w formacie RGBA) 255, 255, 255, 255, dla czarnego (w formacie RGBA) 0, 0, 0, 255. Czyli wartość kanału alfa ustawiona jest na 255 dla pixeli koloru białego oraz czarnego. W części inicjalizującej kodu z tablicy tworzona jest tekstura:

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, IMAGE_WIDTH, IMAGE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE,
Image);

natomiast w części rysującej scenę rysowane są poruszające się TRIANGLE_STRIPY z nałożną teksturą

void drawParticles()
{
// glEnable (GL_BLEND); // wlaczamy przezroczystosc
// glColor4f(1.0f,1.0f,1.0f,0.0f);         
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, tex);
// glDisable (GL_DEPTH_TEST); // wylaczenie testowania glebokosci

for (int k = 0; k < MAX_PARTICLES; k++) // petla przez wszystkie czastki
{
float x = particles[k].xPos; // przechwytujemy polozenie X czastki
float y = particles[k].yPos; // przechwytujemy polozenie Y czastki
float z = particles[k].zPos; // przechwytujemy polozenie Z czastki

glColor3f (1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLE_STRIP); // rysujemy trojkat
glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z); // gorny prawy wierzcholek
glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z); // gorny lewy wierzcholek
glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z); // dolny prawy wierzcholek
glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z); // dolny prawy wierzcholek
glEnd();

particles[k].xPos += particles[k].xDirect/(fSlowdown*10000)*1000;// poruszamy czastke na osi X
particles[k].yPos += particles[k].yDirect/(fSlowdown*10000)*1000;// poruszamy czastke po osi Y
particles[k].fZPos += particles[k]].fZDirect/(fSlowdown*10000)*g_fDeltaTime*1000;// poruszamy czastke po osi Z
}
// glEnable(GL_DEPTH_TEST);   
// glDisable(GL_BLEND); 
}
Jak są zakomentowane polecenia jak to jest widoczne w kodzie powyżej to na ekranie widać poruszające się TRIANGLE_STRIPY z nałożonymi czarno-białymi teksturami na czarno-białym tle. Jak kod odkomentuje to widać tylko czarno-białe tło bez poruszających się TRIANGLE_STRIPów. Jak trzeba ustawić funkcje dotyczące blendingu, aby na czarno-białym tle było widać poruszające się TRIANGLE_STRIPY, ale tylko z widocznym białym kolorem, czarny ma być przezroczysty? Próbowałem rożnych kombinacji, ale bez efektu;(

Offline Avaj

  • Użytkownik

# Sierpień 14, 2016, 13:26:53
Nie możesz dla czarnych pikseli dać alfę na 0?

ew. spróbuj  glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);

Offline MrKaktus

  • Użytkownik

# Sierpień 14, 2016, 13:31:55
Ustaw alfe na czarnych texelach na 0 zamiast 255.
255/1.0f to solid alfa, 0/0.0f to transparent/translucent alfa wiec te texele beda niewidoczne.

Offline slowbro

  • Użytkownik

# Sierpień 14, 2016, 23:25:40
Dziękuję za podpowiedzi. Sprawdzę je. Mam jeszcze kilka pytań odnośnie blendingu:
1. W jakiej kolejności w funkcji renderującej rysuje się poszczególne elementy sceny, jeżeli będzie korzystało się z blendingu? Rysuje się kolejno elementy zaczynając od najdalej położonych do tych najbliżej czy odwrotnie?
2. W tutorialach dotyczących blendingu często występuje polecenie dotyczące kolorów np. glColor4f(1.0f,1.0f,1.0f,0.0f). Jest ono konieczne? W moim przypadku będę blednował tylko tekstury.
3. Jakie powinny być atrybuty funkcji glBlendFunc aby czarny zrobić przezroczystym, a biały nie?

Offline Avaj

  • Użytkownik

# Sierpień 15, 2016, 07:55:11
1. oficjalnie powinieneś rysować nieprzezroczyste obiekty od bliższych do dalszych, wyłączyć zapis do depthbuffera i rysować przezroczyste obiekty od dalszych do bliższych.
2. dla pewniaka warto dać, bo inna funkcja mogła naśmiecić, a ten kolor przy domyślnych ustawieniach będzie wymnożony z kolorem tekstury
3. próbowałeś tego mojego blendfunca?

Offline slowbro

  • Użytkownik

# Sierpień 15, 2016, 11:24:34
1. OK.
2. OK.
3. Zmieniłem alfe na 0 jak pisałeś. glBlendFunc ustawiłem inaczej niż proponowałeś, ale udało mi się uzyskać to co zamierzałem (czarne tło tekstury nałożonej na triangle_stripy jest przezroczyste). Mam jeszcze trochę do poprawy z przenikaniem innych tekstur, ale krok do przodu jest:)

W jaki sposób można zmienić wartości kolorów pixeli w teksturze na przeciwny bez użycia shaderów? Np. jest tekstura z pixelami tylko czarnymi i białymi, a chce czarne zmienić na białe, a białe na czarne?
« Ostatnia zmiana: Sierpień 15, 2016, 12:18:00 wysłana przez slowbro »

Offline slowbro

  • Użytkownik

# Sierpień 20, 2016, 01:35:43
Nikt? Nic? Wakacje się powoli kończą:)

Offline slowbro

  • Użytkownik

# Wrzesień 04, 2016, 03:37:30
Bawię się obecnie wykorzystaniem blendingu z użyciem kilku tekstur. Mam coś pomieszane tylko nie mogę dojść co. Nie mogę uzyskać efektu, na którym mi zależy. Od najdalej oddalonego obiektu do najbliżej położonego obiektu względem ekranu mam według myśli:

1. Nieruchomy kwadrat ze zbindowaną teksturą co stanowi tło całej sceny.
2. Poruszające się kwadraty ze zbindowanymi teksturami z ustawionym blendingiem.
3. Nieruchomy kwadrat ze zbindowaną teksturą szumu z ustawionym blendingiem.
4. Nie przezroczysty Kwadrat bez zbindowanej tekstury zasłaniający część całej sceny (tak ma być celowo). Kwadrat nie ma ustawionego blendingu w tym celu.

Problem polega na tym, że na kwadrat oznaczony jako 4 jest zbindowana tekstura, a być nie powinna. Tesktura oznaczona jako 1 jest widoczna jak by była przed 3, a w kodzie jest ustawiona za nią.

W części rysującej scenę zgodnie z wytycznymi OpenGL w kodzie 

kolejno są rysowane:
- Jako pierwszy kwadrat bez zbindowanej tekstury (zasłaniający część sceny), nie przezroczysty oznaczony powyżej jako 4.
- Jako drugi rysowany jest kwadrat oznaczony jako 1 czyli tło.
- Jako trzecie rysowane są poruszające się kwadraty ze zbindowaną teksturą oznaczone jako 2.
- Jako czwarty rysowany jest kwadrat ze zbindowaną teksturą szumem oznaczony jako 3.

W części inicjującej mam następujący kod (najważniejsza dotycząca blendingu i z tym związane):
glClearColor (0.0, 0.0, 0.0, 0.5);
glClearDepth(1.0);   
glDepthFunc (GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
W części rysującej scenę kolejno co się dzieje:
- czyszczenie ekranu i bufora głębokości
- wyłączenie blendingu
- wyłączenie teksturowania
- Wyłączenie oświetlenia
- rysowanie kwadratu bez ustawionego przenikania, który przysłania cześć sceny
- Włączenie teksturowania
- rysowanie kwadratu ze zbindowaną teksturą - tłem
- wyłączenie teksturowania
- wyłączenie testowania głębokości
- włączenie blendingu
- ustawienie blendingu (GL_ONE, GL_SRC_ALPHA)
- włączenie teksturowania
- rysowanie poruszających się kwadratów ze zbindowaną teksturą z ustawionum przenikaniem
- ustawienie blendingu (GL_ONE, GL_ONE)
- rysowanie kwadratu ze zbindowaną teksturą szumem
- wyłączenie teksturowania
- włączenie testowania głębokości
- wyłączenie blendingu

Gdzie może tkwić błąd?