2013-03-10 3 views
1

Я пишу простой raycaster в C#, используя OpenTK. Я хочу, чтобы мое представление обновлялось 60 раз в секунду, поэтому у меня есть таймер, вызывающий мою функцию Render(), которая показывает текстуру на экране.фоновая резьба рендеринга текстуры

Я хочу использовать рекурсивную функцию для рендеринга моей сцены, разделив ее на более мелкие прямоугольники и визуализируя каждый до тех пор, пока размер прямоугольника не станет равным 1px. Моя рекурсия записывает цвета пикселей в байтовый массив, которые мне нужно преобразовать в текстуру. Рекурсия довольно медленная, поэтому я хочу запускать ее в потоке backgroud всякий раз, когда меняется моя сцена.

Каков правильный способ синхронизации потоков, так что один записывает в массив текстур (занимает около секунды), но другой поток читает его каждые 1/60 секунды и печатает на экране?

byte[, ,] texture; 

рекурсии:

public void RenderAdaptively(int top, int left, int width, int height) 
    { 
     Color color = getColor(top, left); 
     for (int i = top; i < top + width + 1; i++) 
     { 
      for (int j = left; j < left + height; j++) 
      { 
       texture[i, j, 0] = color.R; 
       texture[i, j, 1] = color.G; 
       texture[i, j, 2] = color.B; 
      } 
     } 

     int halfw = width/2; 
     int halfh = height/2; 
     int newwidth = width - halfw; 
     int newheight = height - halfh; 

     if (width > 1 && height > 1) 
     { 
      RenderAdaptively(top, left, halfw, halfh, false); 
      RenderAdaptively(top + halfw, left + halfh, newwidth, newheight, false); 
      RenderAdaptively(top, left + halfh, halfw, newheight, false); 
      RenderAdaptively(top + halfw, left, newwidth, halfh, false); 
     } 
    } 

в другом потоке:

raycasting_texture = TexUtil.CreateRGBTexture(width, height, texture); 
+0

Показать свою работу здесь .. –

ответ

1

У вас есть несколько вариантов, чтобы попробовать, но я хотел бы сделать это следующим образом:

  • есть два буфера для хранения текста повторно в виде массива байтов, скажем 0 и 1,

  • сделать вычисление текстуры в одном буфере,

  • , когда это сделано, сигнал его, установив volatile int updated_buffer на обновленный индекс буфера.

  • есть другие темы, которые читают updated_buffer и сохраняют копию ее последнего значения. . Когда эта копия и ИНТ не синхронизировано, обновить копию и загрузить текстуру в память,

Обратите внимание, что это решение зависит от нескольких вещей:

  1. существует только две нитей дело с буферами байтового массива,

  2. updated_buffer только для чтения с помощью (текстуры) потребителем нити и написано продюсером нитью,

  3. и, самое главное, загрузка текстуры разумно быстрее чем вычисление.

Если # 2 или # 3 сломаны, вам придется использовать более строгий подход синхронизации на буферов текстур, как мьютексы, чтобы убедиться, что текстурные буферы не перезаписываются, когда все еще загружается.

Наконец, ваше рекурсивное вычисление может получить небольшой импульс, перейдя к итерации ниже определенного порога (например, блок 8 * 8 пикселей), вместо того, чтобы полностью опуститься до 1px. Фактически, все это итеративно должно быть быстрее (если сделано в одном потоке на одном ядре), хотя это сильно зависит от алгоритма вычисления пикселей.

Смежные вопросы