Войти
ПрограммированиеФорумГрафика

Выбор объектов средствами OpenGL. (Комментарии к статье)

Страницы: 1 2 3 Следующая »
#0
12:24, 29 июня 2005

Комментарий к Статье Выбор объектов средствами OpenGL


#1
12:24, 29 июня 2005

По поводу буфера цвета. Есть у него один большой недостаток - он работает только в труколоре(24/32 bpp). Для режимов которые работают с палитрой (например 16bpp) этот способ работать не будет. Так же нужно не забывать при отрисовке буфера цвета выключать дизеринг(автоматическое внесение в картинку небольшого цветового шума): glDisable(GL_DITHER)

#2
14:36, 29 июня 2005

robot
Можно еще и glScissor поюзать...

Robin
>Для режимов которые работают с палитрой (например 16bpp)
16bpp - это не палитровый режим.

>выключать дизеринг
Дизеринг работает только в палитровом режиме, в котором надо пить йад, а не объекты выбирать.

>автоматическое внесение в картинку небольшого цветового шума
Опять нет. Перенос шумов квантования цвета в высокочастотный диапазон.

Прошло более 2 лет
#3
22:27, 26 янв. 2008

Вот второй способ честно говоря не понял. Лишний рендер + использование glReadPixels никогда быстрыми не были.
Я вот сейчас использую способ, кажущийся мне наиболее оптимальным. Мне нужно выбрать объекты, попадающие в рамку. Сначала нахожу 3д точки вершин этой рамки через glReadPixels & gluUnProject, а затем проверяю попадание объектов в трапецию.
А так ищу способ более быстрый, так как вышеописанный способ снижает производительность на ~15%.

Прошло более 1 года
#4
16:12, 4 июля 2009

У меня есть несколько вопросов на которые я никак не могу найти ответа.
Какое максимальное количество объектов выбора при использовании буфера выбора и как оно определяется?
Влияет ли на производительность количество объектов в буфере выбора?
P.S. Опыт с OpenGL имею не большой, пока использую только 2D.
Имеется перспективное приложение на OpenGL, использую буфер выбора для выбора около 40 тыс. объектов при этом имеется не большая задержка (в моем случае она в принципе не мешает). Причина задержки возможно и не в выборе объектов. Проблема в том что после добавления еще 40 тыс. объектов начали появляться не систематические ошибки :(

Прошло более 8 месяцев
#5
19:56, 13 мар. 2010

в первую очередь спасибо автору. статья хорошая, понятная. написана полюдски, без академического мат. выпендрёжа, и плотной подачи необъяснённых терменов )

прикольная оптимизация у меня тут придумалась к методу цветного выделения)
цвет в буфере кадра 4 байта.
размер dword 4 байта.
можно сделать так чтобы объекты сцены были в массиве, индексом которого была бы переменная DWORD полученная "сливанием подкурсорных" RGBA

DWORD emptyId = 0;                    // айдишник используемый для определения невыделения( промаха при щелчке)...для снятия выделения например....
DWORD maxId = 65535;               // айдишник больше которого быть неможет!!  (пожалуй единственное ограничение)
DWORD actualId = emptyID;         // айдишник для определения очередного айдишника при регистрации нового объекта. 
DWORD selectedId = emptyId;      // для доп обрисовки выделенного объекта.

        ....

class CGeomObject    {   // объект сцены. например стенка! 
       /*
         ....
         вершины всякие, индексы, текскурды ну и всё такое
         ....
       */

       DWORD id;                                     // цыфра которая будет разделена на 4 байта, и переведена в цвет этого объекта. соответствует его индексу в массиве
       void create(dword _id);                  // создаёт и переписывает _id в id, вызывается при регистрации объекта
       void loadFromFile(std::string fn);   // загружет из файла
       void drawToColorBuffer();              // рсиует себя включенным цветом равным id разложенным на 4 байта
       void drawToScreen();                     // рисует всё со всем по нормальному
};
           ...

void registerObjectFromFile( std::string fn)   {      // загрузка нового объекта с HDD
       if (actualId+1 >= maxId)  erroMsgAndReturn("OOPS!!! больше объектов нельзя!");

       actualId ++;                       //получили новый айди
       CGeomObject temp;
       temp.Create(actualId);      // создаём
       temp.loadFromFile(fn);       // грузим

       ojbectArray[actualId] = temp;   //переписали его в кучу с другми объектами сцены?     
}

void select(int x, int y) {       
       /*
         сохранить значения glScissor

         тут было бы неплохо установить   glScissor в районе кооррдинаты точки подмышкой.  
         ScissorTest  делается для пиксела впервую очередь и если этот тест  непроходит все последующие шаги отрисовки точки OGL невыполняются
         а также выключаем свет текстуры и всё что может сделать проекцию объекта неравномерно закрашенной его цветом.
      */

      byte r,b,g,a;
      convertDWORDTo4b(emptyId, r,g,b,a ) ;    // получаем цветовое проедставление айдишника emptyId

      glClearColor(r,g,b,a);                                  // чистим буфер цветом emptyId
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;   
       
      for (DWORD i = emptyId; i <= actualId; i++)   objectArray[i].drawToColorBuffer();    //выводим разнозцетные объекты на экран в области ограниченной glScissor
            
      glReadPixels(....);    // получаем цвет из под мышки записываем в переменные r, b, g, a

      DWORD   Id;
      convert4bToDWORD(r,g,b,a, Id) ;   // собираем DWORD- цыфру из четырёх компонентов цвета.

      if (Id == emptyId)  deselectAll();    //шелкнули "вбуфер"
      else      selectedId == id;
      
     // возвращаем на место координаты glScissor, текстуры, свет материалы и т.д
}

void render() {
      // чистим экран

      for (DWORD i = emptyId; i <= actualId; i++)   objectArray[i].drawToScreen();    //выводим нормальную картинку объекта. 

      if (selectedId != emptyId )   {
               glColor3f(1,0,0);     // подсвечиваем красным что он выделен
               objectArray[ selectedId ].drawToScreen();    // рисуем его!!!
      }     
}

вот.... минимум математики, и прямая адресация к объектам!  массив насколько я знаю самый быстрый... перевод чисел из дворд в  байта - делается побитовыми операциями. что тоже оч быстро делается.

а чтобы выделять множество объектов "насквозь" через всю сцену можно так

void select(int x, int y) {       
       /*
         сохранить значения glScissor

         тут было бы неплохо установить   glScissor в районе кооррдинаты точки подмышкой.  
         ScissorTest  делается для пиксела впервую очередь и если этот тест  непроходит все последующие шаги отрисовки точки OGL невыполняются
         а также выключаем свет текстуры и всё что может сделать проекцию объекта неравномерно закрашенной его цветом.
      */

      byte r,b,g,a;
      convertDWORDTo4b(emptyId, r,g,b,a ) ;    // получаем цветовое проедставление айдишника emptyId

      glClearColor(r,g,b,a);     // чистим буфер цветом emptyId
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;   
      
      // чтобы цвета ВСЕХ объектов могли быть прорисованы под точкой курсора. депф_тест может нам напортачить, и спрятать коечто. поэтому выключаем его.
      glDisable(GL_DEPTH_TEST) ;           

      for (DWORD i = emptyId; i <= actualId; i++)   {
                objectArray[i].drawToColorBuffer();    //выводим ОДИН ОЧЕРЕДНОЙ объекты на экран в области ограниченной glScissor
            
                glReadPixels(....);    // получаем цвет из под мышки записываем в переменные r, b, g, a

                DWORD   Id;
                convert4bToDWORD(r,g,b,a, Id) ;

                //  selectedStack - стэк хранящий значения DWORD - Айди "щёлкнутых" объектов
                //  второе условие чтобы небыло одинаковых значений подряд.
                //  т.к объекты могут быть в стороне или глубже, а под курсором один и тотже.
                if (   (Id != emptyId) &&  (Id != selectedStack.getPrevId() )  )        selectedStack.addId( selectedId );   // добавляем его в стек выделенных объектов                
      }

     // возвращаем  glScissor, текстуры, свет материалы и т.д
}

void render() {
      // чистим экран

      for (DWORD i = emptyId; i <= actualId; i++)   objectArray[i].drawToScreen();    //выводим нормальную картинку объекта. 

      glColor3f(1,0,0);     // подсвечиваем красным выделеные объекты

      while ( !selectedStack.isEmpty() )                  //пока стек непуст   
               objectArray[ selectedStack.get()  ].drawToScreen();    // рисуем очередного выделенного         
}

вот.... на куски прошу нервать. в коде косяков много, ибо тут всё абстрактно, непроверено, неоткомпилено. (влом чесноговоря) и писалось прям тут походу.
просто как иллюстрация к идее. что думаете? имеет такая оптимизация право на жизнь?

#6
20:30, 13 мар. 2010

во блин!
Мою бредятину подняли :)
Мне тогда 17 лет было, а на дворе 2003 год.
Но я старался, честно :)

#7
20:32, 13 мар. 2010

http://www.gamedev.ru/flame/forum/?id=13515

а тут я свой ник пытался продать. Точнее id, ибо фсотне :)

#8
22:11, 13 мар. 2010

//comment
ммм... как-бы так и делается...

#9
22:30, 13 мар. 2010

Larik
за мой сколько даш? )))
17 лет в 2003-м ) тебе как бонус могу ещё уин продать) там год рождения твой в конце)
ну или почти твой.

MarkoPolo
вот что не придумаеш уже ктонить да спёр...
Ну хоть придумалось живое и то радует.

#10
0:16, 28 мая 2010

Всем привет.
Очень заботит один вопрос.
При использовании буфера цвета для выбора обьекта обязательным условием должно быть чтобы объекты были разных цветов?
Или есть какая нить хитроумная фича как это можно обойти. Перебывал на многих сайтах но понял что ни у кого такого вопроса даже не возникало.

#11
0:48, 28 мая 2010

largo20007

> Или есть какая нить хитроумная фича как это можно обойти.
Есть какая-нибудь объективная причина, ради которой это стоит "обходить"?

#12
3:21, 28 мая 2010

Разумеется есть. Смысл делать например графический редактор если потом чтобы смоделировать в нем например машинку потребуется чтобы каждая деталька ее была разного цвета :-)

#13
5:04, 28 мая 2010

largo20007
> Или есть какая нить хитроумная фича как это можно обойти.

Просто не используй буфер выбора, пиши свой функционал...

#14
5:18, 28 мая 2010

Дак дело то как раз не в буфере выбора, а в буфере цвета. По любому есть какое нибудь улучшение данного алгоритма чтобы пользователь мог моделировать множество фигур одинакового колора и потом выбирать их. Я думал кто нить подкинет дельную мысль. Иначе как раз придется переключиться на второй вариант-буфер выбора

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.