Pertanyaan Anda tampaknya membingungkan konsep-konsep tertentu, jadi mari kita ambil hal-hal dari atas. Ini adalah definisi fungsi glTexImage2D
:
void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );
Ada dua hal yang Anda sebut "format tekstur". Yang pertama adalah internalformat
parameter. Ini adalah format nyata dari gambar ketika OpenGL menyimpannya. The format
parameter menggambarkan bagian dari format data pixel yang Anda berikan dengan data
parameter.
Dengan kata lain, format
dan type
tentukan seperti apa data Anda . internalformat
adalah cara Anda memberi tahu OpenGL untuk menyimpan data Anda. Mari kita panggil format
dantype
"format transfer piksel", sementara internalformat
akan menjadi "format gambar".
Format gambar suatu tekstur tidak pernah bisa menjadi "bgr8". Tidak ada enumerator format gambar GL_BGR8. ada adalah sebuah enum GL_BGR, tapi itu adalah untuk format transfer pixel, bukan format gambar.
Atau dengan kata lain, data piksel Anda yang Anda berikan OpenGL dapat disimpan dalam urutan BGR. Tetapi implementasi OpenGL memutuskan sendiri bagaimana sebenarnya menyimpan data piksel itu. Mungkin menyimpannya dalam urutan little-endian. Mungkin itu menyimpannya big-endian. Mungkin itu hanya sewenang-wenang mengatur ulang byte. Anda tidak tahu, dan OpenGL tidak menyediakan cara untuk mengetahuinya.
Tidak ada cara untuk mengetahui apakah serangkaian parameter format transfer piksel cocok dengan bagaimana implementasi OpenGL akan menyimpannya dengan format gambar.
Ada cara untuk mengatakannya sekarang. Dan dengan "sekarang", maksud saya di OpenGL 4.3 dan / atau ARB_internalformat_query2. Datang ke kartu grafis di dekat Anda:
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);
format
dan type
sekarang memiliki implementasi yang disukai format
dan type
untuk menggunakan glTex(Sub)Image
panggilan ke GL_RGBA8
gambar. Ada pertanyaan format
dan terpisah type
untukglReadPixels
unduhan.
Ada pertanyaan lain yang bisa Anda buat .
Jika Anda tidak memiliki akses ke ini, Anda dapat menggunakan beberapa aturan umum yang dipatuhi oleh sebagian besar perangkat keras:
- akan menyimpan data piksel untuk data 8-bit-per-saluran dalam urutan BGRA. Jadi jika Anda ingin mencocokkan format dengan data piksel Anda, sehingga untuk lebih cepat mengunggah data tekstur, Anda ingin menggunakan
GL_BGRA
untuk format
, dan GL_UNSIGNED_INT_8888
atau GL_UNSIGNED_BYTE
untuktype
.
- tidak akan benar-benar menyimpan warna 24-bit sebagai 24-bit. Itu akan selalu membuat mereka menjadi 32-bit; alpha hanya akan diabaikan ketika membaca data. Jadi jika Anda ingin mencocokkan format, selalu gunakan
GL_BGRA
format
dengan GL_RGB8
format gambar, bahkan jika Anda harus meletakkan data dummy dalam komponen alfa.
Umumnya sebagian besar perangkat keras tidak mendukung format tekstur 3-komponen sehingga dalam contoh khusus ini Anda dapat membuat asumsi yang cukup aman bahwa itu dikonversi. Tekstur OpenGL 3 komponen sebenarnya 4 komponen dalam perangkat keras tetapi dengan komponen alfa diabaikan / diatur ke 255 / apa pun.
https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads (Halaman "kesalahan umum" itu adalah tambang emas - buat bookmark sekarang!)
Untuk kasus yang lebih umum, kinerja glTexSubImage2D dapat memberi Anda indikasi yang baik apakah pengunggahan harus melalui jalur konversi perangkat lunak atau tidak. Anda akan melakukan ini selama startup program - cukup buat tekstur kosong (via glTexImage2D dengan data NULL), lalu keluarkan sekelompok panggilan glTexSubImage2D, masing-masing diikuti oleh glFinish untuk memastikannya selesai. Abaikan yang pertama karena cache / status / etc sedang disiapkan untuk itu, dan waktunya sisanya. Ulangi ini untuk beberapa format berbeda dan pilih yang tercepat.
Alternatif lain - mengingat Anda telah menandai pertanyaan ini "Windows" - adalah membuat perangkat D3D saat startup (tepat setelah Anda membuat jendela tetapi sebelum Anda init OpenGL) kemudian gunakan D3D untuk memeriksa dukungan format. Sementara OpenGL memungkinkan konversi perangkat lunak ke format internal yang valid, D3D tidak - jika itu tidak didukung oleh perangkat keras Anda tidak dapat melakukannya. Kemudian hancurkan D3D dan bawa OpenGL. (Teknik ini juga dapat digunakan untuk menanyakan hal-hal lain yang tidak memungkinkan OpenGL meminta Anda secara langsung).
Sebenarnya ini adalah aturan praktis yang berguna untuk memeriksa ulang apa yang Anda lakukan di OpenGL dengan dokumentasi D3D. Jika D3D tidak dapat melakukan sesuatu maka itu bisa menjadi indikasi yang baik bahwa sesuatu yang dimaksud tidak didukung dalam perangkat keras. Tidak selalu benar, tetapi tempat awal yang bermanfaat.
sumber