3.9. Dasturni optimallashtirish Ilovani tashkil etish.
Bir qarashda OpenGL ga asoslangan ilovaning unumdorligi, birinchi navbatda OpenGL ning o‘z kutubxonasini amalga oshirish unumdorligini belgilanishi bo‘lib ko‘rinishi mumkin. Bu to‘g‘ri, ammo umumiy ilovani tashkil etish juda ham muhim.
Yuqori darajali optimallash.
Odatda OpenGL ostida ishlovchi dasturlardan interaktiv tezlikdagi yuqori sifatni vizuallashtirish talab etiladi. Lekin, qoida sifatida, u yoki boshqasiga birdan erishishning imkoni yo‘q. Shunday ekan, sifat va unumdorlik o‘tasida o‘zaro kelishuvni qidirish lozim. Ko‘pgina turlicha yondashuvlar mavjud bo‘lsada, ammo ularning batafsil tavsifi ushbu qo‘llanma doirasidan tashqarida hisoblanadi. Faqatgina bir nechta misollarni keltiramiz:
Animatsiya vaqtida past sifatli sahna geometriyasini tasvirlash mumkin, to‘xtash vaqtida esa uni eng yuqori sifatda ko‘rsatish mumkin. Interaktiv burish vaqtida (masalan, sichqoncha tugmasini bosishda) primitivlar sonini qichqartirish bilan modelni vizuallashtirish. Statistik tasvirlarni chizishda modelni to‘liq tasvirlash.
Obyektlar kuzatuvchidan uzoqda joylashadi va quyi murakkablikdagi model ko‘rinishida taqdim etilishi mumkin. Bu esa OpenGL konveyerining barcha pog‘onalari vazifalarini sezilarli darajada pasaytiradi. Kuzatuv maydonidan to‘liqligicha tashqarida yotgan obyektlar, ko‘rish piramidasida ularning oddiy hajmlari (sfera yoki kub) chegaralanishining tushishini nazorat qilish yordamida OpenGL konvereyiga uzatishsiz samarali kesilishi mumkin.
Animatsiya vaqtida soxta ishlov berish, suzuvchi zalivka, teksturalarni o‘chirib qo‘yish mumkin. Xuddi shunday bularning barchasini statistik tasvirlarni ko‘rsatishda yoqish mumkin. Ushbu yondashuv OpenGL ning apparatli quvvatlanmagan tizimi uchun ayniqsa samaralidir.
Past darajali optimallash.
OpenGL yordamida tasvirlanadigan obyektlar, ayrim ma’lumotlar tuzilmasida saqlanadi. Bunday tuzilmalardan bir turi boshqasiga nisbatan foydalanish ancha samarali va vizuallashtirish tezligini belgilaydi.
OpenGL konveyeriga tez va samarali uzatish mumkin bo‘lgan, ma’lumotlar tuzilmasidan foydalanilishi maqsadga muvofiq. Masalan, agarda biz uchburchak massivini tasvirlamoqchi bo‘lsak, ushbu massivga ko‘rsatkichlardan foydalanish uni qismlar bo‘yicha OpenGL ga uzatishga qaraganda ancha samaraliroq.
Misol:
Tasavvur qilamiz, biz yer xaritasini chizishni amalga oshiruvchi ilovani yozayapmiz. Ma’lumotlar bazasidagi qismlardan biri – shaharlarning nomi, uzunligi va kengligi bo‘yicha ro‘yxati. Ma’lumotlarning mos tuzilmasi quyidagicha bo‘lishi mumkin:
struct city
{
float latitute, longitude; /* shaharning holati */
char *name; /* nomi */
int large_flag; /* 0 = kichik, 1 = katta */
};
Shaharlar ro‘yxati shunday massiv tuzilmasida saqlanishi mumkin. Faraz qilamiz, biz yozuvlar bilan turli o‘lchamdagi nuqta ko‘rinishida xaritada shahar chizish funksiyasini yozayapmiz:
void draw_cities( int n, struct city citylist[] )
{
int i;
for (i=0; i < n; i++)
{
if (citylist[i].large_flag)
glPointSize( 4.0 );
else
glPointSize( 2.0 );
glBegin( GL_POINTS );
glVertex2f( citylist[i].longitude,
citylist[i].latitude );
glEnd();
/* shahar nomini chizamiz */
DrawText(citylist[i].longitude,
citylist[i].latitude,
citylist[i].name);
}
}
Ushbu amalga oshirish quyidagi sabablarga ko‘ra muvaffaqiyatsiz:
glPointSize davrning har bir interasiyasi uchun chaqiriladi.
glBegin va glEnd o‘rtasida faqat bitta nuqta chiziladi.
uchlar qulay bo‘lmagan formatda belgilanadi.
Quyida ancha ratsional yechim keltirilgan:
void draw_cities( int n, struct city citylist[] )
{
int i;
/* dastlab kichkina nuqtalar chizamiz */
glPointSize( 2.0 );
glBegin( GL_POINTS );
for (i=0; i < n ;i++)
{
if (citylist[i].large_flag==0) {
glVertex2f( citylist[i].longitude,
citylist[i].latitude );
}
}
glEnd();
/* ikkinchi navbatda katta nuqtalar chizamiz */
glPointSize( 4.0 );
glBegin( GL_POINTS );
for (i=0; i < n ;i++)
{
if (citylist[i].large_flag==1)
{
glVertex2f( citylist[i].longitude,
citylist[i].latitude );
}
}
glEnd();
/* so‘ngra shaharlar nomini chizamiz */
for (i=0; i < n ;i++)
{
DrawText(citylist[i].longitude,
citylist[i].latitude,
citylist[i].name);
}
}
Bunday amalga oshirishda biz glPointSize buyrug‘ini ikki marta chaqiramiz va uchlar sonini glBegin va glEnd o‘rtasida oshiramiz.
Biroq optimallashtirish uchun yana yo‘llar qoladi. Agar biz ma’lumotlar tuzilmasini almashtirsak, unda nuqtalarni chizish samaradorligini yanada oshirishimiz mumkin. Masalan:
struct city_list
{
int num_cities; /* ro‘yxatdagi shaharlar soni */
float *position;/* shahar koordinatalari */
char **name; /* shaharlar nomiga ko‘rsatkich */
float size; /* shaharni bildiruvchi nuqta o‘lchami */
};
Endi turli o‘lchamdagi shahar turlicha ro‘yxatda saqlanadi. Nuqtaning holati dinamik massivda alohida saqlanadi. Qayta tashkil etishdan so‘ng biz glBegin/glEnd ichida shartli operator zaruriyatini chiqarib tashlaymiz va optimallashtirish uchun uchlar massividan foydalanish imkoniga ega bo‘lamiz. Natijada biz qurgan funksiya quyidagi ko‘rinishga keladi:
void draw_cities( struct city_list *list )
{
int i;
/* nuqtani chizamiz */
glPointSize( list->size );
glVertexPointer( 2, GL_FLOAT, 0,
list->num_cities,
list->position );
glDrawArrays( GL_POINTS, 0, list->num_cities );
/* shahar nomini chizamiz */
for (i=0; i < list->num_cities ;i++)
{
DrawText(citylist[i].longitude,
citylist[i].latitude
citylist[i].name);
}
}
OpenGL da chaqirishlarni optimallashtirish.
OpenGL unumdorligini oshirishning ko‘pgina imkoniyatlari mavjud. Bundan tashqari optimallashtirishga bo‘lgan turlicha yondashuvlar apparatli va dasturiy vizuallashtirishda turlicha effektlar bilan olib boriladi. Masalan, ranglar interpolyasiyasi apparat ta’minotisiz juda qimmatli operatsiya bo‘lishi mumkin, apparatli vizuallashtirishda ushlanish deyarli bo‘lmaydi.
Quyidagi uslublarning har biridan keyin, simvollardan biri ko‘rsatilgan va aniq tizim uchun ushbu uslubning ahamiyatini anglatuvchi kvadrat qavslar kuzatiladi:
[A] – OpenGL ning apparatli ta’minot tizimi uchun afzal
[D] – dasturiy amalga oshirish uchun afzal
[barchasi] – ehtimol barcha amalga oshirishlar uchun afzal
OpenGL da ma’lumotlarni uzatish
Biz quyida OpenGL da primitivlar haqidagi ma’lumotlarni uzatishda vaqtni minimallashtirish usullarini ko‘rib chiqamiz.
Do'stlaringiz bilan baham: |