Îmi dezvolt jocul de cele mai multe ori sub ArchLinux. Am decis să încerc recent pe Ubuntu 16.04. Situația pe care am întâlnit-o a fost cu adevărat ciudată:
- Niciun
glGetError()
deloc. - Fără erori, avertismente, nimic rău în ieșirea de depanare gl.
- Toate afirmațiile pe care le-am făcut pentru toate situațiile nefaste nu s-au declanșat.
-
glClear
a șters cu succes bufferele I specificat, dar: -
glDraw*
nu a desenat nimic.
Din fericire, am găsit o soluție care urma să fie setat glViewport
. Cu toate acestea, nu prea înțeleg, de ce este necesar pentru desen în Ubuntu, dar nu este necesar în ArchLinux? De asemenea, diferența este între adaptoarele grafice: pe archlinux folosesc NVIDIA 1060, pe Ubuntu folosesc HD Graphics P530 integrat (Skylake GT 2 ).
Dacă este important, folosesc SDL2 cu opengl 4.4.
Comentarii
- Este ' este important pentru dvs. să vă dați seama că sistemul de operare nu este relevant aici; OpenGL este implementat de furnizorul GPU în driverele lor, deci factorii importanți sunt GPU-urile și driverele lor. Unde sistemul de operare ar putea fi interesant este dacă furnizorul dvs. de GPU are baze de cod diferite pentru sisteme de operare diferite, dar în caz contrar ' nu este o informație utilă.
- @MaximusMinimus acesta ar putea fi răspunsul la întrebare.
Răspuns
Aveți deja două răspunsuri bune, dar pot fi greu de înțeles pentru un începător, așa că eu „Vă spun de ce avem într-adevăr nevoie de .
În redarea tipică poate părea să nu aibă sens – pur și simplu creați o fereastră sau redați țintă și desenați pe ea, nu? Aș spune că 95% din aplicații funcționează așa.
Dar să spunem că scrieți o aplicație precum 3DS MAX, unde aveți fereastra împărțită în 4 redări distincte. Vă amintiți poziția curentă de împărțire și gestionați evenimentele mouse-ului, deci atunci când treceți peste bara de împărțire puteți schimba cursorul mouse-ului la redimensionarea unuia etc. Când trageți bara de împărțire vă amintiți noua sa poziție și așa mai departe. Când doriți să redați vizualizările 3D, veți califica glViewport cu poziția și dimensiunea primei dvs. sub-ferestre 3D și rulați comenzi tipice GL pentru a desena aici. OpenGL va scala automat randarea astfel încât să se potrivească în fereastra dată. Faceți același lucru pentru restul vizualizărilor dvs. și la sfârșit veți obține o fereastră cu câteva redări diferite, fiecare cu parametrii săi. Astfel puteți avea cât mai multe redări distincte pe o fereastră / țintă de redare dorite.
De ce nu a funcționat pe o singură mașină?
GPU-urile și driverele lor au o mulțime de detalii de implementare și diferențe, deci, în general, trebuie să vă obișnuiți cu astfel de probleme. Un exemplu simplu: în GLSL shader puteți crea un vector zero 2D de genul: vec2(0.0,0.0)
, puteți încerca, de asemenea, să scrieți o valoare: vec2(0.0)
și cu acest cod, unii drivere îl vor trata ca versiune anterioară, în timp ce alții vor returna erori și nu vor reda nimic. Rețineți că driverele de la doi furnizori vor diferi mai mult de cele două versiuni ale aceluiași driver, deci este o idee bună să vă testați codul pe GPU-urile nVidia, ATI și Intel. În acest caz, bănuiesc că în driverele nVidia, atunci când nu setați singur vieportul, presupun că doriți să utilizați întreaga țintă de redare, în timp ce driverele Intel nu fac asta.
Răspunde
glViewport permite opengl să știe cum să mapeze coordonatele NDC la coordonatele framebuffer.
În mod implicit, este setat la dimensiunea completă a tamponului de ecran. Deci, trebuie să-l apelați numai atunci când fereastra se redimensionează sau de fapt doriți să o modificați.
Comentarii
- Sau când redați la un framebuffer, presupunând că dimensiunea ferestrei este diferită.
Răspuns
glViewport specifică transformarea afină a xx și yy de la coordonatele dispozitivului normalizate la coordonatele ferestrei. Let (xnd , ynd) xndynd fi coordonat dispozitiv normalizat inates. Apoi, coordonatele ferestrei (xw, yw) xwyw sunt calculate după cum urmează:
- „xw = (xnd + 1) (width2) + xxw = xnd + 1width2 + x”
- „yw = (ynd + 1) (height2) + yyw = ynd + 1height2 + y”
Lățimea și înălțimea ecranului sunt fixate în mod silențios la un interval care depinde de implementarea. Pentru a interoga acest interval, apelați glGet cu argumentul „GL_MAX_VIEWPORT_DIMS”
Parametrii x și y specifică colțul din stânga jos al ferestrei în pixeli, în timp ce lățimea și înălțimea specifică lățimea și înălțimea ferestrei