tBane Temat założony przez niniejszego użytkownika |
[SDL2 opengles2] Glicze podczas renderowania tekstur » 2023-08-21 12:19:44 Ogólnie to ok. 70% tekstur renderuje mi poprawnie, ale niektóre przy rysowania pierwszego trójkąta zmieniają kolor przezroczysty na jakiś z tekstury. Nie wiem czym to może być spowodowane. Myślę, że to coś na zasadzie "oproznij bufor textury" czy coś takiego. Wie ktoś jak wyczyścić płótno tekstury w opengles2? odrzucam wszystkie rady sugerując by przy każdemu rysowania tekstury deklarować na nowo zmienne - to b. Spowalnia gre void initSDL() { SDL_Init( SDL_INIT_EVERYTHING ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 ); SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 8 ); SDL_DisplayMode DM; SDL_GetCurrentDisplayMode( 0, & DM ); window = SDL_CreateWindow( "Gra - Tajemnicza Mocno", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, int( DM.w ), int( DM.h ), SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN ); SDL_GL_CreateContext( window ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_BLEND ); if( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 4096 ) == - 1 ) { cout << "Mix_OpenAudio Error: " << Mix_GetError() << "\n"; fprintf( stderr, "Mix_OpenAudio Error: %s\n", Mix_GetError() ); } }
void drawRectImage( int x, int y, int w, int h, GLuint texture ) { v1x = x - w / 2.f; v1y = y + h / 2.f; v2x = x + w / 2.f; v2y = y + h / 2.f; v3x = x + w / 2.f; v3y = y - h / 2.f; v4x = x - w / 2.f; v4y = y - h / 2.f; glUseProgram( textureProgram ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, texture ); textureUniform = glGetUniformLocation( textureProgram, "texture" ); glUniform1i( textureUniform, 0 ); vertexes[ 0 ] = v1x * 2.f / scrw; vertexes[ 1 ] = v1y * 2.f / scrh; vertexes[ 2 ] = v2x * 2.f / scrw; vertexes[ 3 ] = v2y * 2.f / scrh; vertexes[ 4 ] = v3x * 2.f / scrw; vertexes[ 5 ] = v3y * 2.f / scrh; texCoords[ 0 ] = 0; texCoords[ 1 ] = 0; texCoords[ 2 ] = 1; texCoords[ 3 ] = 0; texCoords[ 4 ] = 1; texCoords[ 5 ] = 1; position = glGetAttribLocation( textureProgram, "position" ); glEnableVertexAttribArray( position ); glVertexAttribPointer( position, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); glDrawArrays( GL_TRIANGLES, 0, 4 ); texcoord = glGetAttribLocation( textureProgram, "texcoord" ); glEnableVertexAttribArray( texcoord ); glVertexAttribPointer( texcoord, 2, GL_FLOAT, GL_FALSE, 0, texCoords ); glDrawArrays( GL_TRIANGLES, 0, 4 ); vertexes[ 0 ] = v1x * 2.f / scrw; vertexes[ 1 ] = v1y * 2.f / scrh; vertexes[ 2 ] = v3x * 2.f / scrw; vertexes[ 3 ] = v3y * 2.f / scrh; vertexes[ 4 ] = v4x * 2.f / scrw; vertexes[ 5 ] = v4y * 2.f / scrh; texCoords[ 0 ] = 0; texCoords[ 1 ] = 0; texCoords[ 2 ] = 1; texCoords[ 3 ] = 1; texCoords[ 4 ] = 0; texCoords[ 5 ] = 1; position = glGetAttribLocation( textureProgram, "position" ); glEnableVertexAttribArray( position ); glVertexAttribPointer( position, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); glDrawArrays( GL_TRIANGLES, 0, 4 ); texcoord = glGetAttribLocation( textureProgram, "texcoord" ); glEnableVertexAttribArray( texcoord ); glVertexAttribPointer( texcoord, 2, GL_FLOAT, GL_FALSE, 0, texCoords ); glDrawArrays( GL_TRIANGLES, 0, 4 ); }
|
|
DejaVu |
» 2023-08-21 12:54:57 1. Patrząc na obrazek ja nie wiem np. o co Ci w sumie chodzi, bo 'nie widzę na screenie problemu'. 2. Wklej swój opis do ChatGPT - może od ręki znajdzie Ci problem (może nie ustawiasz jakiegoś istotnego atrybutu dla maszyny stanu OpenGL przed każdorazowym renderowaniem tekstury). 3. Rekomendowałbym Ci użycie jakiejś biblioteki w stylu SFML, gdzie skupiasz się na implementowaniu logiki, a nie implementowaniu kodu 'jak renderować teksturę'. Powód: obecnie robisz grę używając czystego OpenGL-a, tak więc musisz spędzać czas na czytanie dokumentacji OpenGL-a 'jak naprawić renderowanie' zamiast skupiać się 'jak dodać kolejną funkcjonalność do gry'.
PS. Jeżeli chcesz się nauczyć OppenGL-a to zignoruj pkt 3. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-08-21 13:04:46 Chcę się nauczyć openglesa. Co by kiedyś napisać lepszą i bardziej wymagającą grę. Teraz fakt walczę z kodem, ale uważam, że w przyszłości mi się to opłaci. Będę tworzył dobre i rozbudowane minigierki. Problematyczne są buttony. Nie wiem dlaczego górny trójkąt przycisku ma inne tło od tego niżej, i nie wiem jak to naprawić, bo takie np. Rysowane drzewa to już trójkąt o wysokości 400px który ma być przezroczysty. Szukałem odpowiedzi w chatGPT oraz khronos, i znalazłem nic. Dlatego tu napisałem. |
|
pekfos |
» 2023-08-21 17:36:32 Jak na rysowanie 2 trójkątów wywołujesz 4 razy glDrawArrays(). Na dobrą sprawę wystarczyłoby raz. Używając prymitywu triangle strip wystarczyłoby 1 wywołanie z 4 wierzchołkami. odrzucam wszystkie rady sugerując by przy każdemu rysowania tekstury deklarować na nowo zmienne - to b. Spowalnia gre Odrzucam póki nie podasz przykładu. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-08-21 18:27:43 Wiesz, nie jestem mistrzem mesha, a te metody są uniwersalne. Mogę zarówno narysować nim pola mapy, jak i przyciski oraz dowolne prostokąty wedle mojego uznania. Nie zacina, więc jest dobrze. Chodziło mi raczej o deklarację w metodzie rysowania trójkąta bo wtedy jest dobrze, a przynajmniej było dobrze. Ale to spowalnia gre, więc postanowiłem, że zmienna tekstury będzie globalna, bo i tak służy do przesyłu danych do karty graficznej. Jakieś pomysły? |
|
pekfos |
» 2023-08-21 19:01:49 Wiesz, nie jestem mistrzem mesha, a te metody są uniwersalne. Mogę zarówno narysować nim pola mapy, jak i przyciski oraz dowolne prostokąty wedle mojego uznania. Nie zacina, więc jest dobrze. A gdzie ja napisałem że masz nie rysować prostokąta? Napisałem że możesz go narysować jednym prymitywem. Co tu sprawia że metoda jest mniej uniwersalna? Poza tym napisałem że rysujesz tu cztery trójkąty. Może przeanalizuj jakie ustawiasz im parametry? Chodziło mi raczej o deklarację w metodzie rysowania trójkąta bo wtedy jest dobrze, a przynajmniej było dobrze. Ale to spowalnia gre, więc postanowiłem, że zmienna tekstury będzie globalna, bo i tak służy do przesyłu danych do karty graficznej. Czyli ładowałeś teksturę przy każdym rysowaniu i koszt przypisywałeś "tworzeniu zmiennej"? Wciąż nie tłumaczy to unikania jakichkolwiek zmiennych lokalnych. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2023-08-21 20:08:06 Otóż to, tworzyć w openglesie2 (czyli OpenGL mobilny) można tylko trójkąty. Dlatego rysuje je aż dwa :P
Używam zmienne lokalne w mniej obciazajacych funkcjach, tylko dla wygody np. W zapisie mapy, wczytywaniu mapy, obsłudze przycisków itp. W renderze pól mapy używam zmiennej globalnej bo i to szybsze i daje więcej możliwości.
Te trójkąty rażą oczy, liczyłem, że ktoś się zna :-/ |
|
pekfos |
» 2023-08-21 20:16:59 Otóż to, tworzyć w openglesie2 (czyli OpenGL mobilny) można tylko trójkąty. GL_TRIANGLE_STRIP to też trójkąty. Dlatego rysuje je aż dwa :P Cztery.... Pierwszy ma ustawione pozycje wierzchołków, a pozycje tekstury już nie. void drawRectImage( int x, int y, int w, int h, GLuint texture ) { v1x = x - w / 2.f; v1y = y + h / 2.f; v2x = x + w / 2.f; v2y = y + h / 2.f; v3x = x + w / 2.f; v3y = y - h / 2.f; v4x = x - w / 2.f; v4y = y - h / 2.f; glUseProgram( textureProgram ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, texture ); textureUniform = glGetUniformLocation( textureProgram, "texture" ); glUniform1i( textureUniform, 0 ); vertexes[ 0 ] = v1x * 2.f / scrw; vertexes[ 1 ] = v1y * 2.f / scrh; vertexes[ 2 ] = v2x * 2.f / scrw; vertexes[ 3 ] = v2y * 2.f / scrh; vertexes[ 4 ] = v3x * 2.f / scrw; vertexes[ 5 ] = v3y * 2.f / scrh; texCoords[ 0 ] = 0; texCoords[ 1 ] = 0; texCoords[ 2 ] = 1; texCoords[ 3 ] = 0; texCoords[ 4 ] = 1; texCoords[ 5 ] = 1; position = glGetAttribLocation( textureProgram, "position" ); glEnableVertexAttribArray( position ); glVertexAttribPointer( position, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); glDrawArrays( GL_TRIANGLES, 0, 4 ); texcoord = glGetAttribLocation( textureProgram, "texcoord" ); glEnableVertexAttribArray( texcoord ); glVertexAttribPointer( texcoord, 2, GL_FLOAT, GL_FALSE, 0, texCoords ); glDrawArrays( GL_TRIANGLES, 0, 4 ); vertexes[ 0 ] = v1x * 2.f / scrw; vertexes[ 1 ] = v1y * 2.f / scrh; vertexes[ 2 ] = v3x * 2.f / scrw; vertexes[ 3 ] = v3y * 2.f / scrh; vertexes[ 4 ] = v4x * 2.f / scrw; vertexes[ 5 ] = v4y * 2.f / scrh; texCoords[ 0 ] = 0; texCoords[ 1 ] = 0; texCoords[ 2 ] = 1; texCoords[ 3 ] = 1; texCoords[ 4 ] = 0; texCoords[ 5 ] = 1; position = glGetAttribLocation( textureProgram, "position" ); glEnableVertexAttribArray( position ); glVertexAttribPointer( position, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); glDrawArrays( GL_TRIANGLES, 0, 4 ); texcoord = glGetAttribLocation( textureProgram, "texcoord" ); glEnableVertexAttribArray( texcoord ); glVertexAttribPointer( texcoord, 2, GL_FLOAT, GL_FALSE, 0, texCoords ); glDrawArrays( GL_TRIANGLES, 0, 4 ); } W renderze pól mapy używam zmiennej globalnej bo i to szybsze i daje więcej możliwości. Bzdura. struct S { float a, tmp; void f1(); void f2(); };
void S::f1() { tmp = a + 4; a = tmp * tmp; }
void S::f2() { float tmp = a + 4; a = tmp * tmp; }
Obie funkcje generują niemal identyczny kod, gdzie jedyną różnicą jest dodatkowy efekt uboczny f1() w formie aktualizacji S::tmp. W f2() zmienna tmp nawet nie istnieje w RAMie. Niczego nie zyskujesz na nie tworzeniu zmiennych, a zapisy do zmiennych globalnych muszą się wydarzyć, nawet jeśli nigdy nie używasz potem ich wartości. https://godbolt.org/z/c371zv7q5Twoje dziwne akcje są głęboko w rejonie mikro optymalizacji, których z pewnością nie odczuwasz, skoro istotny wydajnościowo kod działa szybciej mimo mikro anty-optymalizacji. Lepiej pisz wszędzie tak, jak piszesz dla wygody. Zostaw mikro optymalizacje kompilatorowi. |
|
« 1 » 2 |