Witam, AP1994. Na podstawie opisu i kodu można wskazać kilka kluczowych aspektów, które mogą powodować awarię programu. Oto szczegółowe analiza i propozycje rozwiązań:
---
### 1. **Brak ponownego wiązania tekstury w metodzie `Load`**
Chociaż konstruktor klasy `Texture` wiąże teksturę (`glBindTexture`), w metodzie `Load` po prostu wywołuje się `glTexImage2D` bez ponownego wiązania tej samej tekstury. W OpenGL aktywna tekstura jest określana przez ostatnie wywołanie `glBindTexture`. Jeśli przed `glTexImage2D` nie jest aktywny żaden obiekt tekstury (lub inny obiekt), może to prowadzić do błędnego działania lub awarii.
**Rozwiązanie**: Dodaj ponowne wiązanie tekstury przed `glTexImage2D`:
void Texture::Load(ALLEGRO_BITMAP* bitmap)
{
if (!bitmap)
{
std::cerr << "Nie udało się załadować bitmapy!\n";
al_rest(5);
return;
}
ALLEGRO_LOCKED_REGION* region = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY);
if (!region)
{
std::cerr << "Nie udało się zablokować bitmapy!\n";
al_rest(5);
return;
}
glBindTexture(GL_TEXTURE_2D, myTexture); // <<== KLUCZOWE
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
al_get_bitmap_width(bitmap),
al_get_bitmap_height(bitmap),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
region->data
);
al_unlock_bitmap(bitmap);
}
---
### 2. **Mieszanie formatów pikseli (ABGR vs. RGBA)**
W kodzie używasz `ALLEGRO_PIXEL_FORMAT_ABGR_8888` do blokowania bitmapy, ale OpenGL oczekuje `GL_RGBA` (czyli kolejność kanałów RGBA). To może prowadzić do nieprawidłowego odczytu danych pikseli przez OpenGL, co w skrajnych przypadkach może spowodować awarię.
**Rozwiązanie**: Użyj `ALLEGRO_PIXEL_FORMAT_RGBA_8888` zgodnie z formatem oczekiwanym przez OpenGL:
ALLEGRO_LOCKED_REGION* region = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READONLY);
---
### 3. **Brak sprawdzenia błędów OpenGL**
Jeśli `glTexImage2D` kończy się niepowodzeniem, nie generuje komunikatu o błędzie, ale może spowodować awarię (np. segfault). Należy dodać sprawdzenie błędów OpenGL po jego wywołaniu:
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
std::cerr << "Błąd OpenGL: " << error << std::endl;
exit(EXIT_FAILURE);
}
---
### 4. **Brak aktywnego kontekstu OpenGL**
Upewnij się, że kontekst OpenGL został poprawnie utworzony przez Allegro. Na przykład:
al_init();
al_install_system(0, 0);
al_init_image_addon();
al_set_new_display_opengl(true);
ALLEGRO_DISPLAY* display = al_create_display(800, 600);
---
### 5. **Dostępność bitmapy i danych**
Sprawdź, czy `bitmap` nie jest `nullptr` przed wywołaniem `al_lock_bitmap`. Dodatkowo, upewnij się, że `region->data` nie jest `nullptr`:
if (!region || !region->data)
{
std::cerr << "Brak danych bitmapy!" << std::endl;
return;
}
---
### Podsumowanie
1. Dodaj ponowne `glBindTexture` przed `glTexImage2D`.
2. Użyj `ALLEGRO_PIXEL_FORMAT_RGBA_8888` zgodnie z formatem OpenGL.
3. Sprawdzaj błędy OpenGL po wywołaniach.
4. Upewnij się, że kontekst OpenGL jest aktywny.
5. Weryfikuj poprawność danych bitmapy i regionu.
Jeśli problem się utrzymuje, sugeruję dodanie debugowania:
std::cerr << "Rozmiar bitmapy: " << al_get_bitmap_width(bitmap) << "x" << al_get_bitmap_height(bitmap) << std::endl;
std::cerr << "Dane bitmapy: " << (void*)region->data << std::endl;
Pozdrawiam,
termistor