Hangi OpenGL doku formatlarının yerel olarak desteklendiğini nasıl tespit edebilirim?


10

Örneğin, video kartımın "bgr8" i desteklemediğini nasıl tespit edersiniz ve bunu yazılım modunda "rgba8" gibi başka bir biçime dönüştürür.

GÜNCELLEME: Karışıklık için özür dilerim. Bu soru daha durum hakkında belirlediğim zaman internalFormat içinde glTexImage2D "bgra8" gibi bir şey ama VideoDriver içten "rgba8" gibi başka bir biçime verileri dönüştürmek.

Yanıtlar:


11

Sorunuz belirli kavramları karıştırıyor gibi görünüyor, bu yüzden şeyleri üstten alalım. Bu fonksiyonun tanımıdır glTexImage2D:

void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );

"Doku formatları" diyebileceğiniz iki şey vardır. Birincisi internalformatparametredir. Bu, görüntünün OpenGL tarafından saklandığı şekliyle gerçek biçimidir . formatParametre piksel verilerinin biçimi parçasını anlatmaktadır sizinle sağlıyoruz dataparametresi.

Diğer bir deyişle, için formatve typetanımlamak için veri görünüyor gibi. internalformatOpenGL'ye verilerinizi depolamasını nasıl söylediğinizdir . Bizi arayalım formatve type"piksel aktarım formatı", internalformat"imaj formatı" olacak.

Bir dokunun görüntü formatı asla "bgr8" olamaz. GL_BGR8 görüntü formatı numaralandırıcısı yok. Orada olan bir GL_BGR enum, ama bu piksel transferi biçiminde değil, görüntü formatı içindir.

Veya başka bir deyişle, OpenGL'ye verdiğiniz piksel verileriniz BGR düzeninde saklanabilir. Ancak OpenGL uygulaması, bu piksel verilerinin gerçekte nasıl saklanacağına kendi başına karar verir. Belki de küçük endian düzeninde saklar. Belki onu büyük endian depolar. Belki de sadece baytları keyfi olarak yeniden düzenler. Bilmiyorsunuz ve OpenGL bunu öğrenmenin bir yolunu sunmuyor.

Belirli bir piksel aktarım formatı parametreleri kümesinin, görüntü formatı göz önüne alındığında OpenGL uygulamasının bunları nasıl saklayacağını eşleştirip eşleştirmediğini anlamanın bir yolu yoktur.

Şimdi anlatmanın bir yolu var . Ve "şimdi" ile, OpenGL 4.3 ve / veya ARB_internalformat_query2'de kastediyorum. Yakınınızdaki bir grafik kartına geliyor:

GLenum format, type;
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &format);
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1, &type);

formatve typeşimdi uygulamanın tercihlerini formatve görsel çağrılarını typekullanmak glTex(Sub)Imageiçin GL_RGBA8. İndirmeler için ayrı formatve typesorgular vardır glReadPixels.

Yapabileceğiniz başka sorgular da var .

Bunlara erişiminiz yoksa, çoğu donanımın uyacağı genel kurallar kullanabilirsiniz:

  • kanal başına 8 bit veri için piksel verilerini BGRA düzeninde depolar. Daha çabuk böylece gibi bir uygulamayla piksel verileri ile biçimiyle eşleşecek doku veriler yüklemek istiyorsanız, kullanmak istediğiniz GL_BGRAiçin format, ve GL_UNSIGNED_INT_8888ya GL_UNSIGNED_BYTEiçin type.
  • 24 bit renkleri 24 bit olarak depolamaz. Onları her zaman 32 bite kadar dolduracaktır; alfa sadece verileri okuduğunda yok sayılır. Yani, biçimleri eşleşecek hep kullanmak istiyorsanız GL_BGRA formatile GL_RGB8alfa bileşeninde kukla verileri koymak zorunda bile görüntü formatları.

4
Ayrıca dahiliFormat GL_RGBA ile GL_BGRA kullanım biçimini daha iyi buldum http.download.nvidia.com/developer/Papers/2005/…
KindDragon

InternalFormat parametresini "görüntü biçimi" olarak yeniden markalamaktan kaçınırım, çünkü aynı derecede kafa karıştırıcıdır. Belki de "internalFormat" ı "doku piksel formatı" olarak düşünmek mantıklıdır. "Format" ve "type" parametre bileşimi "kaynak piksel formatı" dır (bu genellikle bir resimdir, dolayısıyla benim yorumumdur). Ve sonra elbette tamsayı tipi formatlar için BGRA olan GPU formatı vardır.
StarShine

6

Genellikle çoğu donanım 3 bileşenli doku formatlarını desteklemez, bu nedenle bu özel örnekte dönüştürüldüğünü makul olarak güvenli bir şekilde kabul edebilirsiniz. 3 bileşenli OpenGL dokusu aslında donanımda 4 bileşenlidir, ancak alfa bileşeni yok sayılır / 255 / değerine ayarlanır.

https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads (Bu "yaygın hatalar" sayfası bir altın madeni - şimdi yer işareti koyun!)

Daha genel bir durum için glTexSubImage2D performansı, yüklemenin bir yazılım dönüştürme yolundan geçip geçmeyeceği konusunda iyi bir gösterge verebilir. Program başlangıcı sırasında buna devam edersiniz - sadece boş bir doku oluşturun (NULL verilerle glTexImage2D aracılığıyla), ardından her biri tamamlandığından emin olmak için bir glFinish gelen bir grup glTexSubImage2D çağrısı yapın. Birincisini yok sayın çünkü önbellekler / durumlar / vb. Bunu birkaç farklı format için tekrarlayın ve en hızlısı seçin.

Başka bir alternatif - bu soruyu "Windows" olarak etiketlediğiniz gibi görmek - başlangıçta bir D3D cihazı oluşturmaktır (pencerenizi oluşturduktan hemen sonra ancak OpenGL'yi başlatmadan önce), sonra format desteğini kontrol etmek için D3D'yi kullanmaktır. OpenGL, geçerli bir iç biçime yazılım dönüştürmeye izin verirken, D3D desteklemez - donanım tarafından desteklenmiyorsa bunu yapamazsınız. Sonra D3D'yi yok edin ve OpenGL'yi getirin. (Bu teknik, OpenGL'nin doğrudan sorgulamanıza izin vermediği diğer şeyleri sorgulamak için de kullanılabilir).

Aslında OpenGL'de ne yaptığınızı D3D belgeleriyle çapraz kontrol etmek için kullanışlı bir kural. D3D bir şey yapamazsa, söz konusu şeyin donanımda desteklenmediğinin iyi bir göstergesi olabilir. Her zaman doğru değil, ama yararlı bir başlangıç ​​yeri.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.