ДР/2011/Л5/easy (3т)
- Forums:
Вашата група = вашият факултетен номер MOD 3
Група 0:
Реализирайте Bilinear filtering. За целта, първо модифицирайте създаването на текстурата на пода - вместо скалиране 256, ползвайте 1024. Модифицирайте BitmapTexture::getTexColor() метода, като вместо да вземате само един тексел от текстурата (както правехме досега - ползвахме само целите части на tx, ty координатите в метода getTexColor()), вземете още 3 - съседният тексел отдясно, съседният отдолу и съседният диагонално вдясно и отдолу. Намерете дробните части на координатите tx, ty (и ги кръстете, да речем, p и q). 4-те цвята смесете по следната схема:
<резултат> = <горен_ляв> * (1 - p) * (1 - q) + <горен_десен> * p * (1 - q) + <долен_ляв> * (1 - p) * q + <долен_десен> * p * q;
Резултатът трябва да изглежда нещо подобно на това: пример. Вземете под внимание факта, че текстурата е повтаряща се. Може да нямате десен съсед, а да се налага да ползвате най-левия в същия ред на текстурата.
Група 1:
Понастоящем, BitmapTexture::getTexColor() нормира uv координатите от info структурата, като ги вкарва в единичния квадрат, след което ги умножава по размерите на картинката, за да вземе подходящия тексел. Този подход очаква картинката да е квадратна - ако не е, изображението ще изглежда разтеглено. Направете си следния експеримент: заменете (в generateScene()) за текстура на пода, вместо floor.bmp, да се ползва тази текстура.
Ще видите разтеглено изображение върху пода. Задачата ви е да елиминирате този проблем, като модифицирате BitmapTexture::getTexColor(). Вместо в квадратче, координатите info.u, info.v трябва да се нормализират в правоъгълник със страни, пропорционални на размерите на картинката (т.е. все едно цялата равнина е запълнена с правоъгълници, и ние трябва да вземем точката (u, v) и да намерим относителните й координати спрямо правоъгълника, в който тя попада). Колко е голям точно правоъгълника е съществено - вземете по-късата страна на този правоъгълник да е 1 (например, за зададената 275x120 картинка, правоъгълникът трябва да е с размери 2.291666.. × 1). Изчислете подходящо мащабиране, което, от получения правоъгълник, да ви прехвърля в правоъгълника на истинската картинка, и подавайте така трансформираните координати на bitmap->getPixel(). В следствие на всичко това, картинката на пода не трябва да изглежда разтеглена - текселите трябва да изглеждат "квадратни" - ето пример.
Тази трансформация ще обърка UV координатите за сферата. За да няма проблеми, добавете нов параметър към BitmapTexture - "squareTexels", който по подразбиране е false. Само ако е true прилагайте новата логика, в противен случай да се ползва старият код.
Група 2:
Задачата изисква показването на анимация; за да ви върви по-бързо рендерирането, ползвайте по-ниска разделителна способност (задайте RESX, RESY на 320, 240 в constants.h) и компилирайте в Release.
Създайте анимация: вкарайте извикванията на renderScene() и displayVFB() във for-цикъл. Този цикъл трябва да итерира параметъра rotation от 0 до 360 градуса през някаква стъпка, например 10 градуса. Въпросният параметър представлява ротация на UV координатите на пода. Добавете метод setRotation() на BitmapTexture, който приема double параметър от 0 до 360. Този параметър ще задава ротация около точката (-30, 100) с дадения ъгъл, в равнината на UV координатите. Самата ротация реализирайте, като във BitmapTexture::getTexColor() ротирате входните (info.u, info.v) координати с текущата ротация (вижте wikipedia относно ротационни матици). В generateScene() си копирайте първият BitmapTexture обект (текстурата за "пода") на някое удобно място. За всеки кадър извиквайте setRotation() метода на bitmap текстурата. Параметъра трябва да се движи от 0 (в първия кадър) до 360 (в последния кадър).
Добре е, вместо да смятате sin()/cos() на всяко извикване на getColor(), да си ги преизчислите в setRotation(). Освен това, на така преизчислените данни задайте подходящи стойности по подразбиране (във BitmapTexture конструктора), така, че ако не се вика setRotation() метода, ротацията да е нулева - т.е. текстурата върху сферата да не се променя при анимацията.
Крайният резултат трябва да е все едно "подът" се върти, с ос на въртене някъде изпод кълбото с планетата земя. Посоката на въртене не е от голямо значение.
Comments
зад.2
Някой може ли да даде идея, как да сменим координатите на точката, около която се върти равнината във втора задача?