Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.07.2013, 16:46   #1
voronuk
 
Регистрация: 12.05.2011
Сообщений: 7
Вопрос OpenGL наложение линий

Добрый день.

Нужна помощь специалистов по OpenGl.

На 2d-плоскости рисуются линии поверх друг друга.
Необходимо отобразить интенсивность их наложения (пересечений) цветом.

Реализовал это используя glBlendFunc - получил результат на рисунке Pic1.jpg.
Все хорошо, но уж ооочень хотелось-бы чтобы интенсивность отображалась не яркостью одного цвета а градиентом, примерно как на рисунке Pic2.jpg.

Главное требование к решению - скорость работы.

Все что связано с glCopyPixels, glDrawPixels не подходит - сильно замедляет работу.
Из видимых мне решений - использовать шейдер частиц - но я в OpenGl новичок.

Возможно есть простые решения?

Буду благодарен за любую помощь, совет.

В архиве мой исходник на Delphi-7
Изображения
Тип файла: jpg Pic1.jpg (33.0 Кб, 68 просмотров)
Тип файла: jpg Pic2.jpg (35.2 Кб, 67 просмотров)
Вложения
Тип файла: rar Test1.rar (328.2 Кб, 14 просмотров)
voronuk вне форума Ответить с цитированием
Старый 08.07.2013, 21:32   #2
саша40
Участник клуба
 
Регистрация: 12.09.2012
Сообщений: 1,030
По умолчанию

Такое используется для визуализации в WindowsMediaPlayer. Там стоят батареи(это типо наложения).
Что нужно программисту: Компьютер, Среда программирование, Воображение, Прямые руки, Мозги, Знания этой среды программирования.
Программист-это профессия, а программирование-это моё хобби.
саша40 вне форума Ответить с цитированием
Старый 08.07.2013, 22:22   #3
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Простые решения? Хм. Забивать рандомно массив точками, удалять дубликаты точек, после этого искать пересечения прямых (см. вложение). Если есть пересечение, то строить не 2 линии, а 4. Построение делать таким образом:
Код:
if peresechenie then //функция
begin
glColor4b(r,g,b,a);// обычный цвет
glVertex2i(m[i].x,m[i].y);
glVertex2i(peresech_x,peresech_y);// найденные зн-ия в функции пересечения
glColor4b(r,g,b,a);//  цвет,отличный от обычного
glVertex2i(peresech_x,peresech_y);
glVertex2i(m[i+1].x,m[i+1].y);

glColor4b(r,g,b,a);// обычный цвет
glVertex2i(m[i+2].x,m[i+2].y);
glVertex2i(peresech_x,peresech_y);
glColor4b(r,g,b,a);//  цвет,отличный от обычного
glVertex2i(peresech_x,peresech_y);
glVertex2i(m[i+3].x,m[i+3].y);
end
else
glColor4b(r,g,b,a);// обычный цвет
glVertex2i(m[i].x,m[i].y);
glVertex2i(m[i+1].x,m[i+1].y);
glVertex2i(m[i+2].x,m[i+2].y);
glVertex2i(m[i+3].x,m[i+3].y);
Вложения
Тип файла: rar Unit1.rar (1.1 Кб, 8 просмотров)
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 08.07.2013 в 22:40.
Rin вне форума Ответить с цитированием
Старый 08.07.2013, 22:44   #4
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Насколько я понимаю, получить правый рисунок из левого можно применением одномерной текстуры в фрагментном шейдере.
Т.е. значение интенсивности голубого используем в качестве текстурной координаты.
s-andriano вне форума Ответить с цитированием
Старый 09.07.2013, 13:38   #5
voronuk
 
Регистрация: 12.05.2011
Сообщений: 7
По умолчанию

Rin - спасибо за идею и source - надо будет попробовать, но боюсь что считать точки пересечений для 1000 линий будет медленее чем взять результат на рисунке 1 и перевести его по пиксельно в рисунок 2 используя glDrawPixels. А тут как раз крайне критична скорость.

s-andriano - спасибо - думаю что копать таки прийдется в сторону шейдеров.
voronuk вне форума Ответить с цитированием
Старый 10.07.2013, 08:56   #6
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Ну, я не думаю, что на картинках отражается 1000 линий. Их на порядок меньше. Но решать вам, как ни крути.
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 26.07.2013, 22:51   #7
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Короче так, заморочился я, мне стало интересно как решить твою задачу без шейдеров. В каждом массиве по 13 точек. Почему? Потому что для 1000 линий хватит и этого (13*13*6).Ну там линий получается 1014, если быть точным. Вот собственно накидал кое-что:
Код:
type
  point_s=record
  x,y:extended;
  end;

  massive=array [0..12] of point_s;

var
 otvet:PPoint2f;
  mass_points_intersection:array of point_s;
  max_mass_n:integer;

.........

function intersection(start1,end1,start2,end2:point_s;tochka_peresech:Ppoint2f):boolean;
var
 dir1,dir2:point_s;// векторы
 a1,b1,d1:double;// для нахождения уравнения 1-ой прямой
 a2,b2,d2:double;// для нахождения уравнения 2-ой прямой
 seg1_line2_start,seg1_line2_end:double;
 seg2_line1_start,seg2_line1_end:double;
 u:double;
begin
// находим векторы
  dir1.x:=end1.x-start1.x;
  dir1.y:=end1.y-start1.y;
  dir2.x:=end2.x-start2.x;
  dir2.y:=end2.y-start2.y;
//считаем уравнения прямых проходящих через отрезки
  a1:=-dir1.y;
  b1:=+dir1.x;
  d1:=-(a1*start1.x+b1*start1.y);

  a2:=-dir2.y;
  b2:=+dir2.x;
  d2:=-(a2*start2.x+b1*start2.y);

  //подставляем концы отрезков, для выяснения в каких полуплоскотях они
  seg1_line2_start := a2*start1.x + b2*start1.y + d2;
  seg1_line2_end   := a2*end1.x + b2*end1.y + d2;

  seg2_line1_start := a1*start2.x + b1*start2.y + d1;
  seg2_line1_end   := a1*end2.x + b1*end2.y + d1;

  //если концы одного отрезка имеют один знак, значит он в одной полуплоскости и пересечения нет.
  if  (seg1_line2_start * seg1_line2_end >= 0) or
      (seg2_line1_start * seg2_line1_end >= 0) then
      result:=false
  else
  begin
    u := seg1_line2_start / (seg1_line2_start - seg1_line2_end);
    tochka_peresech.x :=  start1.x + u*dir1.x;
    tochka_peresech.y :=  start1.y + u*dir1.y;
    result:=true;
  end;
end;


procedure TForm1.paint2(var mass1,mass2:massive);
var a,b,c,d:integer;
begin
 max_mass_n:=0;
  for a := low(mass1) to high(mass1)-1 do
  for b := 1 to high(mass2) do
  for c := a+1 to high(mass1) do
  for d := low(mass2) to b-1 do
    if intersection(mass1[a],mass2[b],mass1[c],mass2[d],otvet) then
        begin
        inc(max_mass_n);
        setLength(mass_points_intersection,max_mass_n);
        mass_points_intersection[max_mass_n-1]:=otvet^;
        end;

        glColor4f(0.35,0,1,0.3);
        for a := 0 to 12 do
        for b := 0 to 12 do
          glVertex3f(mass1[a].x,mass1[a].y,0);glVertex3f(mass2[b].x,mass2[b].y);

 glColor4f(1,1,1,0.31);
 for a := 0 to max_mass_n - 1 do
        begin
          glBegin(GL_POINTS);
          glVertex3f(mass_points_intersection[a].x,mass_points_intersection[a].y);
          glEnd;
        end;

end;

// сортировка по х
procedure quick_sort_x(First,last:integer;var m:massive);
var x,w:extended;
    i,j:integer;
begin
i:=First;
j:=Last;
x:=m[(i+j) div 2].x;
repeat
  while m[i].x<x do i:=i+1;
  while x<m[j].x do j:=j-1;
  if i<=j then
  begin
      w:=m[i].x;
      m[i].x:=m[j].x;
      m[j].x:=w;
      w:=m[i].y;
      m[i].y:=m[j].y;
      m[j].y:=w;
      i:=i+1;
      j:=j-1;
  end;
until i>j;
if first<j then quick_sort_x(first,j,m);
if i<last then quick_sort_x(i,last,m);
end;
.....
procedure TForm1.FormPaint(Sender: TObject);
var
  ps : TPaintStruct;// структура рисования
  m1:massive;
  m2:massive;
  m3:massive;
  m4:massive;
  i:byte;
begin
..........
 for I := 0 to 12 do
  begin
    m1[i].x:=-1-random(100)/300;
    m1[i].y:=1+random(100)/300;

    m2[i].x:=1+random(100)/300;
    m2[i].y:=1+random(100)/300;

    m3[i].x:=-1-random(100)/300;
    m3[i].y:=-1-random(100)/300;

    m4[i].x:=1+random(100)/300;
    m4[i].y:=-1-random(100)/300;
  end;

quick_sort_x(0,12,m1);
quick_sort_x(0,12,m2);
paint2(m1,m2); 
........
// и т.д.
{ сам дальше допрешь. Там нужно будет ещё сделать 2 процедуры: для 3 массивов точек и для 4 массивов точек. Они у меня есть, но я их не дам. Хочу, чтобы ты сам просек фишку.}
Если помог, проси поставить минус. Будь оригинален!

Последний раз редактировалось Rin; 26.07.2013 в 22:54.
Rin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
штриховка линий Opengl Dr.Teck Visual C++ 0 06.11.2012 22:18
OpenGL - наложение текстур. Nater Общие вопросы Delphi 0 21.02.2011 20:14
наложение текстур в OpenGL FJFray Мультимедиа в Delphi 1 23.10.2010 12:40
Наложение нескольких текстур в OpenGL Krechet Мультимедиа в Delphi 4 06.05.2010 15:30
OpenGL некорректное наложение текстуры Selestis Мультимедиа в Delphi 1 03.02.2009 19:59