Pengaturcaraan menggunakan perpustakaan opengl

Anda sedang membaca tutorial OpenGL pertama saya!

Sebelum anda mula mempelajari OpenGL itu sendiri, nampaknya saya adalah lebih baik untuk memberitahu anda cara menyusun kod, menjalankannya, dan yang paling penting, cara mencuba kod sumber yang diberikan dalam pelajaran ini.

Apa yang anda perlu tahu

Pelajaran ini ditujukan kepada pembaca tanpa pengetahuan khusus tentang pengaturcaraan. Sudah tentu, pengetahuan tentang mana-mana bahasa pengaturcaraan (C, Java, Lisp, JavaSript) akan menjadi tambahan yang besar, tetapi ini tidak diperlukan, anda hanya perlu mempelajari dua subjek pada masa yang sama - grafik dan pengaturcaraan 3D.

Semua kod dalam pelajaran ini ditulis dalam C++ dalam gaya yang paling mudah. Tiada templat, kelas atau aritmetik penunjuk. Oleh itu, melihat kod, anda boleh memahami apa yang dilakukannya, walaupun anda hanya biasa dengan JavaSript.

Lupakan semua yang anda tahu tentang OpenGL 1/2

Pelajaran ini menganggap bahawa anda tidak tahu apa-apa tentang grafik 3D. Tetapi jika anda telah membaca tutorial OpenGL dan terjumpa sesuatu seperti glBegin(), maka lupakannya. Di sini kita akan mengkaji OpenGL 3 dan 4, dan apa yang anda baca terpakai pada OpenGL 1 atau 2. Oleh itu, saya syorkan anda melupakan semua yang anda tahu sebelum ini, jika tidak, otak anda akan mula cair daripada ketidakkonsistenan.

Membina projek

Kod daripada pelajaran ini boleh disusun untuk Windows dan Linux. Untuk mula menyusun kod untuk mana-mana platform, anda perlu melakukan perkara berikut:

  1. Kemas kini pemacu untuk kad video anda!! Saya memberi amaran kepada anda :)
  2. Muat turun pengkompil jika anda belum memilikinya.
  3. Pasang CMake
  4. Muat turun sumber pelajaran siap sedia.
  5. Hasilkan projek menggunakan CMake
  6. Pasang projek.
  7. Eksperimen dengan kod untuk lebih memahami perkara yang berlaku di sana.

Di bawah saya telah memberikan penerangan yang lebih terperinci mengenai projek pemasangan untuk setiap platform. Tetapi bergantung pada versi OS, tangkapan skrin mungkin berbeza sedikit daripada apa yang akan muncul pada skrin anda, tetapi secara umum, semuanya sepatutnya lebih kurang sama.

Perhimpunan untuk Windows


Bina untuk Linux

Terdapat sejumlah besar variasi Linux yang berbeza di dunia, jadi saya tidak mahu memberikan contoh memasang projek untuk setiap satu. Jika sesuatu tidak menjadi seperti yang diterangkan di bawah, baca dokumentasi atau cari di Internet.

  1. Pasang pemandu terkini ke kad video anda. Saya sangat mengesyorkan pemacu bukan sumber terbuka. Mereka tidak disertakan dengan GNU, tetapi selalunya berfungsi dengan lebih baik. Jika binaan Linux anda tidak menyediakan pemasang automatik, cuba baca panduan Ubuntu.
  2. Pasang pengkompil dengan semua perpustakaan yang diperlukan dan alatan. Berikut ialah senarai perkara yang anda perlukan: cmake make g++ libx11-dev libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxext-dev. Gunakan sudo apt-get install ***** atau su /yum install ******
  3. Muat turun sumber contoh dan nyahzipnya ke dalam folder, contohnya ~/Projects/OpenGLTutorials/
  4. Pergi ke ~/Projects/OpenGLTutorials/ dan masukkan arahan berikut:
  • mkdir membina
  • binaan cd
  • cmake..
  1. Jika arahan sebelumnya berjaya dilaksanakan, fail make akan dibuat dalam folder binaan/
  2. masukkan "buat semua" dan selepas ini semua contoh dan kebergantungan mereka akan disusun. Jika tiada kesilapan, maka bersedia fail boleh laku akan diletakkan dalam folder ~/Projects/OpenGLTutorials/

Saya sangat suka menggunakan IDE QtCreator. IDE ini boleh berfungsi dengan CMake di luar kotak dan menyediakan banyak barangan lain, seperti penyahpepijatan, autolengkap, dsb.

Arahan untuk membina projek dalam QtCreator:

1. Dalam QtCreator klik Fail->Alat->Pilihan->Kompil&Laksanakan->CMake

2. Tentukan laluan ke CMake. Ini kemungkinan besar akan menjadi /usr/bin/cmake

3. Fail->Buka Projek dan pilih tutorial/CMakeLists.txt

4. Tentukan folder binaan, folder sebaiknya berada di luar folder tutorial.

5. Tetapkan secara pilihan –DCMAKE_BUILD_TYPE=Nyahpepijat dalam medan pilihan.

6. klik pada tukul di bawah. Selepas ini, contoh boleh dijalankan dari folder tutorial/

7. Untuk menjalankan contoh daripada QtCreator, pilih Projects ->Execution parameters ->Working Directory , dan pilih direktori di mana tekstur dan model shader berada. Untuk tutorial 2 ia akan menjadi ~/opengl -tutorial /tutorial02_red_triangle/

Contoh Larian

Setelah projek disusun, aplikasi boleh dilancarkan terus dari direktori.
Jika anda perlu menjalankan contoh terus daripada IDE, gunakan arahan di atas untuk menetapkan direktori kerja dengan betul.

Bagaimana untuk mengambil pelajaran ini

Setiap pelajaran disertakan kod sumber dan data. Semua fail ini boleh didapati dalam direktori tutorialXX/ yang sepadan.

Tetapi saya mengesyorkan agar anda tidak mengubah apa-apa dalam fail ini, ia adalah untuk rujukan sahaja. Lebih baik bermain di taman permainan/taman permainan.cpp dan ubah apa sahaja yang anda mahukan di sana. Jika anda memecahkan sesuatu dan tidak dapat memulihkannya semula, anda boleh memulangkan fail ini hanya dengan menyalinnya daripada mana-mana pelajaran lain.

Semasa anda membaca tutorial ini, anda akan melihat bit kod di mana-mana sahaja. Jangan ragu untuk menyalinnya ke taman permainan.cpp untuk melihat mereka beraksi - percubaan sentiasa bagus. Saya akan katakan sekali lagi, jangan hanya membaca. kod sedia, dan cuba melancarkannya. Anda tidak akan belajar banyak dengan hanya membaca kod sumber. Walaupun dengan tampalan salinan mudah, anda akan mendapat baldi masalah anda sendiri, menyelesaikan yang anda akan mendapat pengalaman yang diperlukan.

Membuka tingkap

Akhirnya! OpenGL!

Walaupun, anda perlu menunggu sedikit lagi. Dalam semua pelajaran, operasi 3D akan dilakukan pada tahap yang sangat rendah, jadi tiada keajaiban untuk anda. Walau bagaimanapun, bekerja dengan tetingkap sistem dan mesej tidak menarik dan membosankan, jadi kami akan membiarkan perpustakaan GLFW melakukan kerja kotor untuk kami. Jika anda benar-benar mahu, anda boleh menggunakan Win32 Api untuk Windows atau API X11 untuk Linux, atau gunakan sesuatu yang lain seperti SFML, FreeGLUT, SDL, ... baca halaman pautan.

Baiklah, mari kita mulakan. Mari kita mulakan dengan fakta bahawa kita perlu menyambung kebergantungan. Oleh kerana kami perlu mengeluarkan mesej ke konsol, kami akan menulis perkara berikut:

// Menyambung pengepala standard

#termasuk

#termasuk

Kemudian kita sambungkan GLEW

// Kita tidak boleh lupa itu GLEW mesti disambungkan sebelum ini gl . h atau glfw . h

#termasuk

Kemudian kita sambungkan GLFW. Perpustakaan ini akan melakukan semua keajaiban pengurusan tingkap.

#termasuk

hidup di fasa ini kami tidak memerlukan perpustakaan ini, tetapi ia mengandungi fungsi matematik dan kami akan memerlukannya tidak lama lagi. Tiada keajaiban dalam GLM, dan jika anda benar-benar mahu, anda boleh menggunakan mana-mana perpustakaan lain untuk bekerja dengan matriks dan vektor. Kami menyertakan "menggunakan ruang nama" untuk menulis "vec3" dan bukan "glm::vec3"

#termasuk

menggunakan ruang nama glm;

Jika anda menyalin kepingan kod ini ke dalam playground.cpp, pengkompil akan mula mengadu bahawa ia tidak fungsi utama(). Jadi mari kita tambah:

int utama())(

Adalah lebih baik untuk memulakan GLFW terlebih dahulu:

// Mulakan GLFW

jika(!glfwInit())

{

fprintf(stderr, "Gagal untuk memulakan GLFW\n");

pulangan -1;

}

Sekarang mari buat tetingkap OpenGL kami:

glfwOpenWindowHint( GLFW_ FSAA_ SAMPEL, 4); // 4 xmelicinkan

glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); //kami diperlukan OpenGL 3.3

glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);

glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // kami tidak diperlukan tua OpenGL

// Mari buka tetingkap dan buat konteks

if(!glfwOpenWindow(1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW))

{

fprintf(stderr, "Gagal membuka tetingkap GLFW\n");

Dalam bab ini kita akan melihat rendering Grafik 3D menggunakan perpustakaan OpenGL, kami akan mengkaji perpustakaan GLU dan GLUT (bukannya yang terakhir, Linux menggunakan perpustakaan FreeGLUT), kami akan menganalisis proses memuatkan tekstur menggunakan perpustakaan SOIL dan DevIL.

Seperti yang telah dinyatakan dalam Bab. 9, Pengaturcara grafik biasanya tidak berfungsi secara langsung dengan GPU. Ini disebabkan oleh fakta bahawa terdapat banyak GPU yang berbeza, dan kerana kerja peringkat rendah dengan GPU adalah agak rumit dan biasanya dilakukan oleh pembangun pemacu. Sebaliknya, mereka menggunakan pelbagai API yang menyediakan lebih banyak antara muka tahap tinggi untuk bekerja dengan GPU. Antara muka ini mengabstrak GPU tertentu (semuanya dikendalikan melalui pemacu, biasanya dibekalkan oleh pengilang GPU), membolehkan anda menulis kod mudah alih yang akan berfungsi merentas GPU yang berbeza. Selain itu, API sedemikian menyembunyikan beberapa butiran peringkat rendah bekerja dengan GPU daripada pengaturcara.

API utama untuk pengaturcaraan grafik 3D dalam masa ini ialah OpenGL dan Dircct3D. Yang terakhir adalah khusus platform sahaja Microsoft Windows. Buku ini merangkumi asas bekerja dengan OpenGL. Ini ialah API merentas platform yang menyokong semua sistem pengendalian utama (Windows, Linux, Mac OS X) dan membolehkan anda bekerja dengan jumlah yang besar pelbagai GPU.

Terdapat versi API - OpenGL ES, direka untuk berfungsi peranti mudah alih. Dengan bantuannya anda boleh mencipta grafik tiga dimensi untuk platform iOS dan Android. Selain itu, terdapat WebGL, perpustakaan yang membolehkan anda menggunakan OpenGL ES secara langsung dalam tetingkap penyemak imbas menggunakan javascript. Terdapat juga pengikatan untuk OpenGL yang berfungsi dengan semua bahasa pengaturcaraan utama, menjadikannya mudah untuk menggunakan OpenGL daripada hampir mana-mana bahasa pengaturcaraan.

Tugas utama OpenGL ialah memberikan grafik dua dan tiga dimensi. Di mana API ini umumnya tidak berurusan dengan mencipta tetingkap untuk pemaparan, membaca input daripada pengguna dan kerja lain yang serupa yang sangat bergantung pada sistem pengendalian tertentu, jadi kami akan menggunakan perpustakaan GLUT merentas platform untuk tujuan ini. perpustakaan ini menyediakan mudah dan cara yang mudah untuk mencipta tetingkap, menjadikannya menggunakan OpenGL dan menerima mesej daripada tetikus dan papan kekunci.

Dari sudut pandangan seni bina OpenGL dibina pada model pelayan-pelanggan. Dalam kes ini, program itu sendiri, yang menggunakan OpenGL, bertindak sebagai pelanggan, dan GPU serta pemacunya bertindak sebagai pelayan. Biasanya program berjalan pada komputer yang sama di mana GPU dipasang, tetapi ini tidak perlu.

Dalam praktiknya, semua arahan OpenGL yang dilaksanakan ditimbal dan kemudian digilir untuk penghantaran ke GPU. Oleh itu, pelaksanaan arahan CPU hanya menunjukkan itu perintah ini masuk ke dalam penimbal atau telah ditambahkan pada baris gilir; kemungkinan besar GPU belum mula melaksanakannya. Pada masa yang sama, OpenGL boleh dianggap sebagai mesin negeri- dia mempunyai keadaan sendiri. Satu-satunya cara tukar keadaan ini - gunakan arahan OpenGL. Keadaan OpenGL tidak berubah antara arahan.

Konsep penting dalam OpenGL ialah penimbal (Rajah 10.1). Untuk membuat, penimbal yang diperlukan mesti dibuat. Penampan Warna sentiasa digunakan dan untuk setiap piksel menyimpan warnanya sebagai nombor 24-bit dalam Format RGB(8 bit untuk setiap warna asas - merah, hijau dan biru) atau sebagai 32-bit in format RGBA(komponen keempat ditambah kepada tiga komponen standard - alfa, yang menetapkan kelegapan).

Apabila menggunakan kaedah r-buffer untuk mengalih keluar permukaan yang tidak kelihatan, anda perlu menyimpan nilai kedalaman yang sepadan untuk setiap piksel (biasanya nilai kedalaman disimpan sebagai integer 16-, 24- dan 32-bit). Sehubungan itu, semua nilai kedalaman yang diambil bersama terbentuk penimbal kedalaman. Anda juga boleh menggunakan penimbal stensil, penimbal pengumpulan.

Apabila mencipta tetingkap untuk dijadikan, anda perlu mencipta konteks OpenGL dan penimbal yang sesuai. Konteks itu sendiri biasanya terikat pada utas semasa, jadi jika aplikasi menggunakan berbilang utas, konteks yang dicipta hanya boleh benar-benar digunakan daripada utas tempat ia dicipta.

Pemprosesan data dalam OpenGL adalah berdasarkan saluran paip pemaparan (lihat Rajah 9.1). Saluran paip mentakrifkan peringkat utama pemprosesan data masuk. Bagaimana tepatnya data akan diproses bergantung pada parameter keadaan OpenGL, tetapi peringkat ini sendiri dan susunan ia berlaku ditetapkan dengan ketat.

nasi. 10.1.

Untuk GPU moden, dua bahagian saluran paip ini diwakili oleh program yang dijalankan pada GPU, dipanggil shaders. Seterusnya, kami akan mempertimbangkan OpenGL versi 2, di mana program ini tidak perlu dinyatakan secara eksplisit: terdapat shader yang berfungsi secara lalai (iaitu, dalam kes apabila pengaturcara tidak menyatakan secara eksplisit shader yang sepadan). Bermula dari versi 3, OpenGL memerlukan shader untuk ditentukan dan sebahagiannya memecahkan keserasian dengannya versi sebelumnya, itulah sebabnya kami akan melihat versi OpenGL 2.

Geometri ditakrifkan sebagai satu set bucu yang membentuk pelbagai primitif (titik, segmen, segi tiga). Pada setiap bucu, sebagai tambahan kepada koordinatnya, anda juga boleh menetapkan beberapa atribut tambahan, seperti warna, normal, koordinat tekstur. Data pada setiap bucu ialah input peneduh bucu: untuk setiap bucu, peneduh bucu melaksanakan dan menjana beberapa nilai output. Nilai keluaran yang diperlukan ialah koordinat puncak seragam selepas semua transformasi dilakukan.

OpenGL menggunakan matriks 4x4 untuk transformasi puncak - matriks reka bentuk paparan model (Rajah 10.2). Jika pelorek puncak tidak dinyatakan secara eksplisit, pelorek puncak lalai digunakan, yang mendarab koordinat puncak (sebagai vektor dalam koordinat homogen) terlebih dahulu dengan matriks modelview dan kemudian dengan matriks reka bentuk.

Selepas ini, primitif dipasang dan dipotong: semua bahagian setiap primitif yang melangkaui kawasan yang kelihatan (melihat frustum) dipangkas secara automatik supaya primitif yang terkandung sepenuhnya dalam skop dihantar ke peringkat saluran paip seterusnya. Seterusnya, bahagian tetap saluran paip melakukan pembahagian perspektif - vektor dalam koordinat homogen dibahagikan kepada komponen keempatnya.


nasi. 10.2.

Jika koordinat pada mulanya ditentukan dalam sistem koordinatnya sendiri, maka pendaraban dengan matriks paparan model memindahkannya ke sistem koordinat kamera. Pendaraban lanjut dengan matriks unjuran membawa koordinat kepada ruang klip. Selepas melakukan pembahagian perspektif yang kita dapat koordinat peranti yang dinormalkan (koordinat peranti dinormalkan).

Langkah terakhir ialah menukar koordinat ternormal kepada koordinat tetingkap yang dinyatakan dalam piksel.

Sebelum pembahagian perspektif, primitif dipasang dan kemudiannya dipotong: semua yang tidak termasuk dalam skop keterlihatan dipotong. Seterusnya, setiap primitif dirasterkan, i.e. diterjemahkan ke dalam satu set serpihan. Siri nilai yang ditentukan dalam bucu diinterpolasi, dan setiap serpihan diberi nilai yang sepadan dengannya. Selepas ini, shader serpihan dilaksanakan untuk setiap serpihan, tugasnya adalah untuk mengira warna untuk setiap serpihan. Dalam kes ini, nilai interpolasi digunakan, adalah mungkin untuk mengakses tekstur - imej pra-disediakan yang ditindih pada primitif output. Ambil perhatian bahawa setiap serpihan mempunyai koordinat sendiri pada skrin dan nilai kedalaman yang diinterpolasi. Selain itu, pelorek serpihan, bukannya mengira warna serpihan, boleh membuang keseluruhan serpihan secara eksplisit.

Pada langkah seterusnya saluran paip, sekumpulan pemeriksaan dilakukan untuk setiap serpihan, setiap satunya boleh membuang serpihan yang diberikan. Semakan pertama ini memeriksa sama ada piksel yang diberikan sepadan dengan bahagian tetingkap yang boleh dilihat. Jika tidak, maka serpihan ini segera dibuang. Ujian berikut menyemak sama ada serpihan itu terkandung dalam segi empat tepat tertentu (dalam koordinat tetingkap). Terdapat juga ujian stensil dan kedalaman. Ujian stensil mendapatkan semula kumpulan bit yang sepadan dengan serpihan yang diberikan daripada penimbal stensil dan menyemak bahawa syarat untuk bit ini dipenuhi. Ujian kedalaman membandingkan kedalaman serpihan dengan nilai yang sepadan daripada penimbal kedalaman. Setiap ujian ini boleh mengakibatkan serpihan yang sepadan dibuang. Di samping itu, terdapat ujian alfa yang membolehkan anda membuang serpihan berdasarkan nilai komponen alfa warnanya.

Selepas ini, langkah mencampurkan warna serpihan dengan warna yang sepadan dengan serpihan ini dalam penimbal warna dilakukan. Operasi ini diperlukan untuk menyokong translucent™.

Pengiraan nilai warna boleh dilakukan dengan ketepatan yang lebih besar daripada yang boleh disimpan dalam penimbal warna. Biasanya dalam kes ini warna hanya dibulatkan. Penggunaan rasterisasi (dithering) menyediakan pilihan lain: warna ditukar supaya purata piksel bersebelahan memberikan nilai yang diingini.

Langkah terakhir adalah untuk melaksanakan bitwise yang diberikan operasi logik antara kandungan penimbal warna dan nilai warna yang terhasil. Ambil perhatian bahawa kebanyakan ujian dan operasi ini boleh dimatikan jika ia tidak diperlukan - ini biasanya meningkatkan prestasi.

Jika anda menulis program menggunakan OpenGL dalam C (atau C++), perkara pertama yang perlu anda lakukan ialah memasukkan fail pengepala berikut:

Untuk memastikan keserasian dan kemudahalihan kod, OpenGL memperkenalkan beberapa jenis datanya sendiri, nama setiap jenis ini bermula dengan awalan GL. Padanan GLint jenis standard integer, jenis GLuint ialah jenis integer tidak bertanda standard, dan GLfloat ialah jenis apungan. OpenGL juga menggunakan beberapa jenis khas, seperti GLsizei, yang menandakan jenis yang digunakan untuk menentukan saiz, dan GLclampf, yang digunakan untuk menentukan nilai titik terapung yang terletak pada baris.

GLenum jenis khas juga diperkenalkan untuk menunjukkan jenis nilai yang sepadan dengan pelbagai pemalar.

Pustaka OpenGL (serta pustaka GLU dan GLUT yang disertakan bersamanya) cenderung menggunakan konvensyen penamaan yang agak mudah untuk pemalar dan fungsi. Nama semua arahan (fungsi) OpenGL bermula dengan awalan gl (untuk fungsi daripada perpustakaan GLU dan GLUT - masing-masing dengan glu dan glut).

Nama semua pemalar bermula dengan GL_ (masing-masing dengan GLU_ dan GLUTJ.

Banyak arahan OpenGL mempunyai berbilang pelbagai pilihan, berbeza dalam bilangan hujah yang diluluskan dan jenisnya. Dalam kes ini, nama arahan juga termasuk akhiran khas yang mengandungi bilangan parameter dan akhiran yang menyatakan jenisnya. Jadi nama arahan dalam OpenGL biasanya kelihatan seperti ini:

glCommand(1 2 3 4)(b s i f d ub us ui)(v)

Nombor pilihan digunakan untuk menentukan bilangan hujah yang diluluskan (dalam kes di mana terdapat versi perintah ini dengan nombor yang berbeza hujah). Seterusnya datang akhiran satu atau dua huruf pilihan yang menyatakan jenis hujah yang diluluskan (dalam kes di mana terdapat versi perintah ini yang menerima nilai input pelbagai jenis). Akhiran v menunjukkan bahawa beberapa parameter (biasanya set parameter terakhir) diluluskan sebagai tatasusunan - sebenarnya, fungsi menerima penunjuk kepada tatasusunan ini dan bukannya parameter ini.

Jadi, perintah glVertex2i mempunyai dua argumen integer, perintah glColor3f mempunyai tiga argumen jenis apungan, dan perintah glColor4ubv mempunyai empat argumen jenis yang tidak ditandatangani bait, diluluskan sebagai tatasusunan (iaitu, apabila fungsi dipanggil, ia hanya menerima satu hujah - alamat tatasusunan).

OpenGL kini merupakan salah satu antara muka pengaturcaraan (API) yang paling popular untuk membangunkan aplikasi dalam bidang grafik dua dimensi dan tiga dimensi. Piawaian OpenGL telah dibangunkan dan diluluskan pada tahun 1992 oleh firma pembangunan perisian terkemuka, dan berdasarkan perpustakaan IRIS GL yang dibangunkan oleh Silicon Graphics.

Pada masa ini, pelaksanaan OpenGL termasuk beberapa perpustakaan (penerangan tentang fungsi asas OpenGL, GLU, GLUT, GLAUX dan lain-lain), yang tujuannya akan diterangkan di bawah.

Ciri ciri OpenGL yang memastikan penyebaran dan pembangunan standard grafik ini ialah:

Kestabilan - penambahan dan perubahan pada piawaian dilaksanakan sedemikian rupa untuk mengekalkan keserasian dengan perisian yang dibangunkan sebelum ini.

Kebolehpercayaan dan mudah alih - aplikasi yang menggunakan OpenGL menjamin hasil visual yang sama tanpa mengira jenis sistem pengendalian yang digunakan dan organisasi paparan maklumat. Selain itu, aplikasi ini boleh dijalankan pada komputer peribadi, stesen kerja dan superkomputer.

Kemudahan penggunaan - Standard OpenGL mempunyai struktur yang difikirkan dengan baik dan antara muka yang intuitif, yang membolehkan anda mencipta aplikasi yang cekap dengan baris kod yang lebih sedikit daripada menggunakan perpustakaan grafik lain pada kos yang lebih rendah. Fungsi yang diperlukan untuk memastikan keserasian dengan pelbagai peralatan dilaksanakan di peringkat perpustakaan dan sangat memudahkan pembangunan aplikasi.

Ciri Asas OpenGL

    Satu set primitif asas: titik, garis, poligon, dsb.

    Lihat dan selaraskan transformasi

    Mengalih keluar garisan dan permukaan yang tidak kelihatan (z-buffer)

    Menggunakan spline untuk membina garisan dan permukaan

    Pemetaan tekstur dan aplikasi pencahayaan

    Menambah kesan khas: kabus, menukar ketelusan, menggabungkan warna, menghapuskan alias (anti-aliasing).

Seperti yang telah disebutkan, terdapat pelaksanaan OpenGL untuk platform yang berbeza, yang mana adalah mudah untuk memisahkan fungsi asas sistem grafik dan fungsi untuk paparan maklumat grafik dan interaksi pengguna. Perpustakaan dicipta untuk memaparkan maklumat menggunakan subsistem tetingkap untuk sistem pengendalian sistem Windows dan Unix (WGL dan GLX, masing-masing), serta perpustakaan GLAUX dan GLUT, yang digunakan untuk mencipta aplikasi konsol yang dipanggil.

Pustaka GLAUX kurang popular berbanding pustaka GLUT yang ditulis agak kemudian, walaupun ia menyediakan keupayaan yang lebih kurang sama. Pustaka GLU termasuk pelaksanaan fungsi yang lebih kompleks, seperti satu set primitif geometri yang popular (kubus, bola, silinder, cakera), fungsi untuk membina spline, pelaksanaan operasi tambahan pada matriks, dsb. Kesemuanya dilaksanakan melalui fungsi OpenGL asas.

Ciri seni bina dan sintaks

Dari sudut pandangan seni bina, sistem grafik OpenGL ialah saluran paip yang terdiri daripada beberapa peringkat pemprosesan data:

    Penghampiran lengkung dan permukaan

    Pemprosesan puncak dan pemasangan primitif

    Rasterisasi dan pemprosesan serpihan

    Operasi pada piksel

    Menyediakan tekstur

    Memindahkan Data ke Penampan Bingkai

Secara umum, OpenGL boleh dibandingkan dengan mesin keadaan, keadaannya ditentukan oleh satu set nilai pembolehubah khas (nama mereka biasanya bermula dengan aksara GL_) dan nilai-nilai normal semasa, warna dan koordinat tekstur. Semua maklumat ini akan digunakan apabila memasuki sistem koordinat puncak untuk membina rajah yang disertakan. Perubahan keadaan berlaku menggunakan arahan, yang dikeluarkan sebagai panggilan fungsi.

MEMULAKAN PERPUSTAKAAN OpenGL DALAM C++

Pertama sekali, anda perlu memasukkan fail pengepala:

#termasuk

#termasuk

#termasuk

· gl.h dan glu.h mengandungi prototaip fungsi OpenGL utama yang ditakrifkan dalam opengl32.dll dan glu32.dll.

· glaux.h mengandungi fungsi tambahan (glaux.dll).

Selepas menyambungkan fail pengepala, anda perlu menetapkan format piksel. Fungsi berikut digunakan untuk tujuan ini:

BOOL bSetupPixelFormat(HDC hdc)

PIXELFORMATDESCRIPTOR pfd, *ppfd;

int pixelformat;

ppfd->nSaiz = saiz(PIXELFORMATDESCRIPTOR);

ppfd->nVersi = 1;

ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

ppfd->dwLayerMask = PFD_MAIN_PLANE;

ppfd->iPixelType = PFD_TYPE_RGBA;

ppfd->cColorBits = 16;

ppfd->cDepthBits = 16;

ppfd->cAccumBits = 0;

ppfd->cStencilBits = 0;

jika ((format piksel = ChoosePixelFormat(hdc, ppfd)) == 0)

MessageBox(NULL, "ChoosePixelFormat gagal", "Ralat", MB_OK);

jika (SetPixelFormat(hdc, pixelformat, ppfd) == SALAH)

MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);

Struktur PIXELFORMATDESCRIPTOR mesti dinyatakan.

cColorBits - kedalaman warna

cDepthBits - saiz penimbal kedalaman (Z-Buffer)

cStencilBits - saiz penimbal stensil (kami belum menggunakannya lagi)

iPixelType - format spesifikasi warna. Boleh mengambil nilai PFD_TYPE_RGBA (warna ditunjukkan oleh empat parameter RGBA - merah, hijau, biru dan alfa) dan PFD_TYPE_COLORINDEX (warna ditunjukkan oleh indeks dalam palet).

Fungsi ChoosePixelFormat() memilih format piksel dan mengembalikan pemegangnya dan SetPixelFormat() menetapkannya dalam konteks peranti (dc).

Selepas format piksel ditetapkan dalam konteks peranti, anda perlu mencipta konteks main balik (Konteks Rendering) untuk ini, fungsi berikut ditakrifkan dalam OpenGL:

HGLRC wglCreateContext(HDC hdc);

BOOL wglMakeCurrent(HDC hdc, HGLRC hglrc);

Dalam pengisytiharan kelas borang, di kawasan peribadi, anda perlu menambah yang berikut:

ghRC - penunjuk kepada konteks rendering (Rendering Context)

ghDC ialah pemegang peranti (bagi kami ia hanya penunjuk ke tetingkap)

Prosedur Cabutan akan bertanggungjawab untuk melukis.

batal __fastcall TForm1::FormCreate(TObject *Penghantar)

ghDC = GetDC(Pemegang);

jika (!bSetupPixelFormat(ghDC))

ghRC = wglCreateContext(ghDC);

wglMakeCurrent(ghDC, ghRC);

glClearColor(0.0, 0.0, 0.0, 0.0);

FormResize(Penghantar);

glEnable(GL_COLOR_MATERIAL);

gEnable(GL_DEPTH_TEST);

gEnable(GL_LIGHTING);

gEnable(GL_LIGHT0);

terapung p=(3,3,3,1),

glLightfv(GL_LIGHT0,GL_POSITION,p);

glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,d);

glViewport(0, 0, Lebar, Tinggi);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-5.5, -5.5, 2.12);

gluLookAt(0,0,5, 0,0,0, 0,1,0);

glMatrixMode(GL_MODELVIEW);

glClearColor() menetapkan warna yang akan mengisi skrin apabila mengosongkan. Prosedur ini mempunyai 4 parameter, yang sepadan dengan RGBA. Sebaliknya, anda boleh menulis glClearIndex(0.0) . Prosedur ini menetapkan indeks warna dalam palet.

glViewport() menetapkan kawasan output - kawasan di mana OpenGL akan mengeluarkan imej.

glMatrixMode() menetapkan mod matriks transformasi pandangan.

glLoadIdentity() menggantikan matriks transformasi paparan semasa dengan satu.

glOrtho() menetapkan mod unjuran ortogon (segi empat tepat). Ini bermakna imej akan dilukis seperti dalam isometri. 6 parameter jenis GLdouble (atau hanya dua kali ganda): kiri, kanan, bawah, atas, dekat, jauh menentukan koordinat satah keratan kiri, kanan, bawah, atas, dekat dan jauh, i.e. semua yang di luar had ini tidak akan ditarik. Malah, prosedur ini hanya menetapkan skala paksi koordinat. Untuk menetapkan unjuran perspektif, prosedur glFrustum() dan gluPerspective() digunakan.

gluLookAt() menetapkan parameter kamera: tiga yang pertama ialah koordinatnya, yang kedua ialah vektor arah, yang ketiga ialah arah paksi Y.

Dalam OpenGL, semuanya dihidupkan dan dimatikan (didayakan dan dilumpuhkan) oleh prosedur glEnable() dan glDisable().

glLightfv() menetapkan sifat "mentol lampu": kedudukan dan arah cahaya.

Sebaik sahaja anda selesai bekerja dengan OpenGL, anda perlu membebaskan sumber yang diduduki dengan membebaskan konteks dengan memanggil wglMakeCurrent dengan parameter nol untuk pengecam konteks OpenGL dan memusnahkan konteks tersebut dengan wglDeleteContext. Di samping itu, anda perlu mengeluarkan pemegang ghDC. Memandangkan kerja dengan OpenGL biasanya tamat apabila aplikasi keluar, kod yang sepadan perlu diletakkan dalam FormClose:

void __fastcall TForm1::FormClose(TObject *Penghantar, TCloseAction &Action)

wglMakeCurrent(ghDC,0);

wglDeleteContext(ghRC);

ReleaseDC(Handle, ghDC);

KESIMPULAN

Semasa latihan saya dari 5 Julai hingga 31 Julai 2011 di JSC Transas, Bahagian Penerbangan dalam jabatan pengaturcaraan, saya mula mengenali kerja jabatan pengaturcaraan. Saya berkenalan dengan reka bentuk dan fungsi simulator penerbangan kompleks yang dibangunkan di JSC Transas. Saya belajar tentang sistem untuk menggambarkan landskap dan pelbagai objek yang dipanggil Aurora. Saya memperoleh kemahiran dan kebolehan praktikal awal yang diperlukan untuk membangunkan aplikasi dan perisian menggunakan bahasa pengaturcaraan peringkat tinggi moden dan perpustakaan grafik.

Biasanya, kawasan di mana ia perlu untuk menentukan kehadiran objek (kawasan pemilihan objek) ditakrifkan sebagai serpihan unjuran pemandangan. Sebagai contoh, pengguna memilih kawasan segi empat tepat dalam imej tayangan menggunakan manipulator (contohnya, penunjuk tetikus) atau hanya mengklik butang tetikus, dengan itu mentakrifkan kawasan pemilihan.

Oleh kerana dalam kes ini kawasan pemilihan ditentukan pada unjuran adegan tiga dimensi, adalah perlu untuk menentukan kawasan yang sepadan dengan adegan tiga dimensi (adegan pemilihan). Pemandangan yang anda pilih akan bergantung pada beberapa faktor: unjuran yang digunakan, saiz pemandangan dan kawasan output.

Untuk menentukan kawasan pemilihan 3D berdasarkan bahagian segi empat tepat unjuran pemandangan, maklumat tentang matriks unjuran diperlukan. Untuk melakukan ini, anda boleh menggunakan beberapa fungsi daripada perpustakaan GLUT, yang merupakan tambahan kepada perpustakaan OpenGL dan menyediakan beberapa keupayaan tambahan.

Dalam perpustakaan OpenTK, fungsi perpustakaan GLUT berada dalam kelas Glu dalam ruang nama Tao.OpenGL(C#). Dalam Object Pascal, semua fungsi dan prosedur perpustakaan GLUT diawali dengan "glu" untuk membezakannya daripada prosedur dan fungsi OpenGL.

Untuk menjana matriks unjuran berdasarkan serpihan unjuran pemandangan yang dipilih, anda boleh menggunakan arahan PickMatrix pustaka GLUT:

C#: void gluPickMatrix(double x, double y, double width, double height, int viewport); Objek Pascal: prosedur gluPickMatrix(x,y,lebar,tinggi: GLdouble; viewport: PGLint);

Perintah PickMatrix perpustakaan GLUT mengubah suai matriks semasa supaya saiz kawasan pemandangan sepadan dengan kawasan pemilihan yang ditakrifkan dalam koordinat unjuran pemandangan itu. Perintah itu mempunyai parameter berikut:

  • x, y – koordinat mendatar dan menegak bagi kawasan pemilihan dalam koordinat tetingkap di mana tayangan pemandangan 3D dipaparkan.
  • lebar, tinggi – lebar dan tinggi kawasan unjuran segi empat tepat yang dipilih bagi pemandangan 3D dalam koordinat tetingkap.
  • viewport ialah susunan empat elemen integer. Dalam C#, tatasusunan dihantar terus sebagai parameter; dalam Objek Pascal, penuding kepada tatasusunan diluluskan sebagai parameter. Tatasusunan mentakrifkan kawasan keluaran unjuran pemandangan 3D. Nilai tatasusunan mesti sepadan dengan koordinat kawasan output yang ditakrifkan menggunakan arahan ViewPort. Unsur-unsur tatasusunan ini mesti ada nilai berikut: Elemen 1 dan 2 – koordinat x dan y sebelah kiri bucu atas kawasan yang dipilih dalam koordinat skrin, 3 dan 4 elemen – lebar dan ketinggian kawasan ini.

Arahan mesti dilaksanakan sebelum melaksanakan perintah Ortho atau Frushtum, yang menjana matriks unjuran.

Meletakkan perpustakaan OpenGL ke dalam mod pemilihan

Untuk meletakkan perpustakaan ke dalam mod pemilihan, gunakan arahan RenderMode:

C#: int RenderMode(Mod RenderingMode); Objek Pascal: fungsi glRenderMode(mod: GLenum): GLint;

Parameter mod menentukan mod pengendalian pustaka OpenGL dan boleh mengambil salah satu daripada tiga nilai:

Jadual 10.1. Nilai yang mungkin untuk parameter mod arahan RenderMode
Penerangan Maknanya
Pustaka OpenTK, C# Objek Pascal
Mod pemilihan nilai yang diberi digunakan untuk meletakkan perpustakaan ke dalam mod pemilihan. RenderingMode.Pilih GL_SELECT
Mod pengimejan adegan. Mod ini digunakan secara lalai selepas pustaka OpenGL dimulakan. Dalam mod ini imej dijana oleh perpustakaan OpenGL. RenderingMode.Render GL_RENDER
Mod maklum balas. RenderingMode.Maklum Balas GL_MAKLUM BALAS

Selepas bertukar kepada mod pemilihan, OpenGL tidak memaparkan imej sehingga mod ditukar kepada mod pemaparan pemandangan menggunakan perintah RenderMode dengan nilai RenderingMode.Render dalam C# dan GL_RENDER dalam Object Pascal.

Menamakan dan membentuk objek pemandangan

Seperti yang dibincangkan di atas, tiada imej dijana dalam mod pemilihan. Perintah pengimejan dalam mod ini digunakan untuk menentukan objek yang berada dalam kawasan pemilihan.

Memandangkan objek yang digunakan oleh pengguna biasanya terbentuk daripada banyak primitif yang berbeza, timbunan nama digunakan untuk menentukan objek yang dipilih. Nama-nama adalah nilai integer. Sebelum mengeluarkan objek seterusnya bermula, nama (nombor) objek ini diletakkan pada timbunan nama. Jika, apabila membentuk objek, perpustakaan mengesan bahawa primitif objek ini jatuh ke dalam kawasan pemilihan, maka kandungan timbunan nama disalin ke penimbal pemilihan (bersama dengan beberapa maklumat tambahan) dimulakan dengan arahan SelectBuffer. Apabila primitif objek bernama lain memasuki kawasan pemandangan, kandungan timbunan nama juga akan disalin ke penimbal pemilihan. Oleh itu, nama (nombor) objek yang sepenuhnya atau sebahagiannya dalam kawasan pemilihan boleh diperolehi. Ia mesti diambil kira bahawa untuk menentukan dengan betul objek yang dipilih, adalah perlu bahawa transformasi koordinat objek bertepatan dengan yang dilakukan semasa membentuk imej adegan.

Beberapa arahan digunakan untuk bekerja dengan timbunan nama. Mengosongkan timbunan nama dilakukan menggunakan perintah InitNames:

C#: void InitNames(); Objek Pascal: prosedur glInitNames;

Menolak nama ke tindanan dilakukan menggunakan arahan PushName:

C#: void PushName(uint name); Objek Pascal: prosedur glPushName(nama: GLuint);

Nama itu diluluskan sebagai parameter arahan.

Sebelum timbunan nama boleh digunakan, ia mesti dimulakan menggunakan arahan InitNames. Kemudian anda perlu menolak satu elemen ke dalam timbunan menggunakan arahan PushName. Sebelum setiap objek dibentuk, satu elemen timbunan nama akan digantikan dengan nama objek yang dibentuk menggunakan arahan LoadName. Prosedur menggantikan elemen terakhir dalam timbunan nama dengan yang diberikan sebagai parameter. Oleh itu, permulaan dan penggunaan timbunan nama boleh digambarkan secara skematik seperti berikut:

InitNames; PushName(0); ...LoadName(1); //pembentukan objek No. 1 LoadName(2); //pembentukan objek No. 2 LoadName(3); //pembentukan objek No. 3 //dll. Penyenaraian 10.7. Gambar rajah untuk menggunakan timbunan nama untuk memilih objek

Dalam bahagian ini, kita akan belajar cara mencipta imej 3D menggunakan fungsi perpustakaan OpenGL, supaya dalam bab seterusnya kita boleh membangunkan aplikasi Windows yang boleh dianggap sebagai alat untuk melihat hasil pengiraan saintifik. Bahan dalam bahagian ini akan membolehkan anda secara beransur-ansur bangkit dan menguasai teknologi yang sangat menarik untuk mencipta dan mengurus imej tiga dimensi. Mula-mula kita akan melihat keupayaan asas perpustakaan OpenGL, kemudian kita akan belajar bagaimana untuk mengawal Fungsi OpenGL Sebagai contoh aplikasi mudah jenis konsol dan hanya selepas itu kami akan mula membangunkan aplikasi Windows.

Pembaca mungkin tahu bahawa OpenGL adalah yang dioptimumkan, berprestasi tinggi perpustakaan grafik fungsi dan jenis data untuk memaparkan grafik dua dan tiga dimensi. Piawaian OpenGL telah diluluskan pada tahun 1992. Ia berdasarkan perpustakaan IRIS GL yang dibangunkan oleh Silicon Graphics (www.sgi.com). OpenGL disokong pada semua platform. Selain itu, OpenGL disokong dalam perkakasan. Terdapat kad video dengan pemecut dan kad SD khusus yang melaksanakan primitif OpenGL dalam perkakasan.

Bahan dalam bahagian pertama pelajaran ini diilhamkan oleh buku yang sangat bagus (tersedia dalam talian) daripada Addison-Wesley, "Panduan Pengaturcaraan OpenGL, Panduan Rasmi untuk Mempelajari OpenGL". Jika pembaca memiliki Bahasa Inggeris, maka kami mengesyorkan membacanya.

Perpustakaan Terpaut

Pelaksanaan OpenGL oleh Microsoft termasuk set penuh Perintah OpenGL, iaitu fungsi global, termasuk dalam teras perpustakaan OPENGL32.LIB dan mempunyai awalan gl(cth glLineWidth). Ambil perhatian bahawa fungsi perpustakaan teras mempunyai berbilang versi, membolehkan anda menentukan parameter atau tetapan yang dikehendaki dalam apa jua cara yang anda suka. Lihat bantuan untuk fungsi dalam keluarga glColor*. Ternyata anda boleh menetapkan warna semasa dalam 32 cara. Sebagai contoh, fungsi:

Tidak sah glColorSb(GLbyte merah, GLbyte hijau, GLbyte biru);

Mentakrifkan warna menggunakan tiga komponen jenis GLbyte dan fungsi:

Tidak sah glColor4dv (const GLdouble *v);

Menentukannya menggunakan alamat tatasusunan empat komponen.

Dengan mengambil kira pilihan ini, perpustakaan teras mengandungi lebih daripada 300 arahan. Di samping itu, anda boleh menyambungkan perpustakaan utiliti GLU32.LIB yang melengkapkan kernel utama. Terdapat fungsi untuk mengawal tekstur, mengubah koordinat, menjana sfera, silinder dan cakera, penghampiran spline lengkung dan permukaan ( NURBS - B-Spline Rasional Tidak Seragam), serta pengendalian ralat. Satu lagi, tambahan ( bantu) perpustakaan GLAUX.LIB membenarkan dengan cara yang mudah buat tetingkap Windows, paparkan beberapa objek SD, kendalikan acara input dan urus proses latar belakang. Malangnya, perpustakaan ini tidak didokumenkan. Syarikat Microsoft Ia tidak disyorkan untuk menggunakannya untuk membangunkan projek komersil, kerana ia mengandungi kod gelung pemprosesan mesej yang mana mustahil untuk memasukkan pemprosesan mesej sewenang-wenangnya yang lain.

Catatan
Jenis GLbyte adalah bersamaan dengan jenis aksara yang ditandatangani, dan GLdouble adalah bersamaan dengan jenis berganda. Jenis sendiri digunakan untuk memudahkan mudah alih ke platform lain. Kami menyediakan senarai jenis OpenGL di bawah. Komponen warna keempat menentukan ketelusan warna, iaitu bagaimana warna latar belakang digabungkan dengan warna imej. Sesetengah arahan OpenGL mempunyai v pada penghujungnya, yang menunjukkan bahawa hujah haruslah alamat tatasusunan (vektor). Vektor dalam matematik ialah jujukan nombor (koordinat) yang secara unik mentakrifkan unsur ruang vektor. Banyak arahan mempunyai berbilang versi, akhirnya membolehkan anda menentukan vektor dengan cara yang berbeza
.

Kira-kira dua puluh fungsi Windows GDI dicipta khusus untuk berfungsi dengan OpenGL. Kebanyakannya mempunyai awalan wgl(akronim untuk Windows GL). Fungsi ini adalah analog daripada fungsi yang diawali dengan glx, yang menyambungkan OpenGL ke platform Sistem tetingkap X. Akhir sekali, terdapat beberapa fungsi Win32 untuk mengawal format piksel dan buffer berganda. Ia hanya terpakai pada tetingkap OpenGL khusus.