Работа с графикой средствами Direct3D
От: Аноним  
Дата: 12.07.05 04:56
Оценка: 230 (14) +2
Статья:
Работа с графикой средствами Direct3D
Автор(ы): Виталий Брусенцев, Алексей Поляков
Дата: 24.11.2005
В этот раз мы публикуем главу из книги Виталия Брусенцева и Алексея Полякова "Программирование графики: GDI+ и DirectX". Эта глава посвящена введению в Direct3D. Приводятся примеры создания простейших приложений, использующих эту технологию. В главе даны примеры кода на C++ и С#.


Авторы:
retalik
AP999

Аннотация:
В этот раз мы публикуем главу из книги Виталия Брусенцева и Алексея Полякова "Программирование графики: GDI+ и DirectX". Эта глава посвящена введению в Direct3D. Приводятся примеры создания простейших приложений, использующих эту технологию. В главе даны примеры кода на C++ и С#.
Re: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 27.11.05 12:32
Оценка:
И это выдержка из книги, на веб странички какогонибуть Васи Пупкина можно лудше найти.
Особено мне понравилось:
  while(GetMessage(&msg, 0, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

Черезвычайно эфиктивный и удобный метод рендеринга:
    case WM_PAINT:
    {
      PAINTSTRUCT ps;
      BeginPaint(hWnd, &ps);
      g_App.Render();
      EndPaint(hWnd, &ps);
      return 0;
    }

В методе Rende этому самое место:
      // создаем источник света
      D3DLIGHT9 light=
        { D3DLIGHT_DIRECTIONAL, // бесконечно удаленный источник
          {1,1,0,0},            // диффузное освещение: желтый цвет
          {0,0,0,0},            
          {0.1f,0.1f,0.1f,1},   // рассеянный свет: тусклый белый 
          {0,0,0},              
          {7,-2,1}              // вектор направления
        } ;

      pDevice->SetLight( 1, &light ) ;
      pDevice->LightEnable( 1, TRUE ) ;
      
      // создаем материал
      D3DMATERIAL9 material = { 
          {1,1,1,1}  
        , {1,1,1,1}  
        , {1,1,1,1}  
        , {0,0,0,0}  
        , 1          
        } ;
      pDevice->SetMaterial( &material ) ;



Вот изврощение.
Re[2]: Работа с графикой средствами Direct3D
От: Аноним  
Дата: 28.11.05 11:32
Оценка:
U49>    case WM_PAINT:
U49>    {
U49>      PAINTSTRUCT ps;
U49>      BeginPaint(hWnd, &ps);
U49>      g_App.Render();
U49>      EndPaint(hWnd, &ps);
U49>      return 0;
U49>    }


Вообще то имеет смысл — когда таскаешь окно
Re[3]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 28.11.05 18:15
Оценка:
А>Вообще то имеет смысл — когда таскаешь окно

Вобщето во время перетаскивания окна рендеринг нужно отключить, если оконмый режим вобще нужен.
Re[2]: Работа с графикой средствами Direct3D
От: retalik www.airbandits.com/
Дата: 28.11.05 21:17
Оценка:
Здравствуйте, U-4X-96, Вы писали:

U49>И это выдержка из книги, на веб странички какогонибуть Васи Пупкина можно лудше найти.

А если без распальцовок, можно конкретно сказать, что не понравилось? Конструктивную критику выслушаю с удовольствием. А твои цитаты не снабжены даже малейшим намеком, "что не так".

U49>Особено мне понравилось:

U49>
U49>  while(GetMessage(&msg, 0, 0, 0))
U49>  {
U49>    TranslateMessage(&msg);
U49>    DispatchMessage(&msg);
U49>  }
U49>


Что не так с этим кодом?

U49>Черезвычайно эфиктивный и удобный метод рендеринга:


В примере используется оконный режим, как наиболее удобный для отладки. Воленс-ноленс приходится взаимодействовать с очередью сообщений и подчиняться порядкам отрисовки. Еще вопросы есть?

U49>В методе Rende этому самое место:

А где "этому" самое место?

U49>

U49>Вот изврощение.

Спасибо за исчерпывающий комментарий. Все его прочитавшие извлекут немалую пользу.
Успехов,
Виталий.
Re[3]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 28.11.05 22:51
Оценка:
Здравствуйте, retalik, Вы писали:

R>А если без распальцовок, можно конкретно сказать, что не понравилось? Конструктивную критику выслушаю с удовольствием. А твои цитаты не снабжены даже малейшим намеком, "что не так".

Я сказал что, ПРИМЕР, а это самое главное. Тоесть для статьи этобы сошло но для книги.
Хотелбы распольцовки спрасилбы что то вроде, какого было вобще липить GDI+ и Direct3D в одной книги. \^^/
На томже GameDev.ru введение в Direct3D описано намного лудьше.


R>Что не так с этим кодом?

Ну например пишут так
    while( msg.message!=WM_QUIT )
    {
      if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
      {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
      }
      else
        Render();
    }

Не совершенство но для учебника сойдет. В любом случаи GetMessage табу в 3D програмировании.

R>В примере используется оконный режим, как наиболее удобный для отладки. Воленс-ноленс приходится взаимодействовать с очередью сообщений и подчиняться порядкам отрисовки. Еще вопросы есть?

Есть, никто, никогда, нигде не использует WM_PAINT для рендеринга, во что это обходится, обьястять не надо? Даже для оконых приложений. И главное отладка, отладкой но нельзяже менять под это дело светая, светых программы.

U49>>В методе Rende этому самое место:

R>А где "этому" самое место?
В процедуре инициализации сцены.
Re[4]: Работа с графикой средствами Direct3D
От: retalik www.airbandits.com/
Дата: 29.11.05 00:20
Оценка:
Здравствуйте, U-4X-96, Вы писали:

U49>Ну например пишут так

U49>
U49>    while( msg.message!=WM_QUIT )
U49>    {
U49>      if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
U49>      {
U49>        TranslateMessage( &msg );
U49>        DispatchMessage( &msg );
U49>      }
U49>      else
U49>        Render();
U49>    }
U49>


Угу, и грузим процессор на 100%. "Правильный" цикл с учетом всех условий (оконное/полный экран, пауза/активно), состояния поверхности и т.д. занимает два экрана. Но мы-то пишем для новичков! Видишь, у любой медали есть две стороны. Не стоит кидаться обвинениями, хотя бы не подумав о причинах, по которым выбрано осуждаемое тобой решение.

U49>Есть, никто, никогда, нигде не использует WM_PAINT для рендеринга, во что это обходится, обьястять не надо? Даже для оконых приложений.


Нет уж, пожалуйста, объясни. Заодно объясни, почему демо-примеры из DX9 SDK вовсю пользуются этим способом.

Я понял: ты ставишь во главу угла производительность. Для статичной картинки в примере FPS не показатель. Зато обработка WM_PAINT — простейший способ добиться гарантированной перерисовки при перемещении, ресайзе окна и т.д.

R>>А где "этому" самое место?

U49>В процедуре инициализации сцены.

ОК, это принимается.
Успехов,
Виталий.
Re[5]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 29.11.05 08:02
Оценка:
Здравствуйте, retalik, Вы писали:

R>Угу, и грузим процессор на 100%. "Правильный" цикл с учетом всех условий (оконное/полный экран, пауза/активно), состояния поверхности и т.д. занимает два экрана. Но мы-то пишем для новичков! Видишь, у любой медали есть две стороны. Не стоит кидаться обвинениями, хотя бы не подумав о причинах, по которым выбрано осуждаемое тобой решение.

Ну и пускай грузиться, а паузы в важем примере вобще нет, верней он это одна большая пауза.
Может вы хотели в качестве первого примера продемонстрировать реализацию паузы?

R>Нет уж, пожалуйста, объясни. Заодно объясни, почему демо-примеры из DX9 SDK вовсю пользуются этим способом.

Может у нас с вами разные SDK, но мой CD3DApplication использует WM_PAINT только для отрисовки в паузе, ровно как и GetMessage(). Более подходящий для сравнения Tutorial(в котором нет поддержки состояний, и не пользуется классами) использует мою схему рендеринга, гораздо более близкию к реальности.

R>Я понял: ты ставишь во главу угла производительность. Для статичной картинки в примере FPS не показатель. Зато обработка WM_PAINT — простейший способ добиться гарантированной перерисовки при перемещении, ресайзе окна и т.д.

А вы ставите во главу угла относительно коректную работу программы в оконном режиме, хотя большенство учебников и огромное количество реальных программ работают только в полноэкранном режиме.

И сам посебе первый пример чересчур оригинален, былобы лудче использовать класический вращающийся кубик(или другой простой объект), вроде Tutorial Step4-5 из SDK
Re[5]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 29.11.05 08:14
Оценка:
Sorry учебник из SDK работает в оконном режими, но на его "особености" не обращает ни какого внимания.
Re[5]: Работа с графикой средствами Direct3D
От: Аноним  
Дата: 29.11.05 08:29
Оценка:
Здравствуйте, retalik, Вы писали:

R>Здравствуйте, U-4X-96, Вы писали:


U49>>Ну например пишут так

U49>>
U49>>    while( msg.message!=WM_QUIT )
U49>>    {
U49>>      if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
U49>>      {
U49>>        TranslateMessage( &msg );
U49>>        DispatchMessage( &msg );
U49>>      }
U49>>      else
U49>>        Render();
U49>>    }
U49>>


А можна поподробнее — зачем там Render?
Re[4]: Работа с графикой средствами Direct3D
От: Аноним  
Дата: 29.11.05 08:32
Оценка:
Здравствуйте, U-4X-96, Вы писали:

А>>Вообще то имеет смысл — когда таскаешь окно


U49>Вобщето во время перетаскивания окна рендеринг нужно отключить, если оконмый режим вобще нужен.


Согласен — рендерить не нужно, но все равно последний кадр нужно обновлять из бек буффера
Re[6]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 29.11.05 08:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А можна поподробнее — зачем там Render?

Чтобы изображение обновлять.
Re[5]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 29.11.05 08:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Согласен — рендерить не нужно, но все равно последний кадр нужно обновлять из бек буффера

Зачем
Re[6]: Работа с графикой средствами Direct3D
От: Аноним  
Дата: 29.11.05 09:07
Оценка:
Здравствуйте, U-4X-96, Вы писали:

U49>Здравствуйте, Аноним, Вы писали:


А>>Согласен — рендерить не нужно, но все равно последний кадр нужно обновлять из бек буффера

U49>Зачем

В оконном режиме: когда ты к примеру передвигаешь окно, которое выходит за рамки десктопа при передвижении — те части окна которые вышли за границы десктопа нужно перерисовать, поэтому и срабатывает WM_PAINT, в котором и нужно восстановить эти участки — но что бы не заморачиваться с участками окна обычно восстанавливают все окно — ну а изображение последнего кадра хранится в бек буффере — поэтому и ресторим его на окно в WM_PAINT.
Re[7]: Работа с графикой средствами Direct3D
От: Аноним  
Дата: 29.11.05 09:11
Оценка:
Здравствуйте, U-4X-96, Вы писали:

U49>Здравствуйте, Аноним, Вы писали:


А>>А можна поподробнее — зачем там Render?

U49>Чтобы изображение обновлять.


Render();

while( msg.message!=WM_QUIT )
{
   if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
   {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
   };
};


А если так?
Re[7]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 29.11.05 09:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В оконном режиме: когда ты к примеру передвигаешь окно, которое выходит за рамки десктопа при передвижении — те части окна которые вышли за границы десктопа нужно перерисовать, поэтому и срабатывает WM_PAINT, в котором и нужно восстановить эти участки — но что бы не заморачиваться с участками окна обычно восстанавливают все окно — ну а изображение последнего кадра хранится в бек буффере — поэтому и ресторим его на окно в WM_PAINT.


А всегда ли оно там хранится, как насчет D3DERR_DEVICELOST?

Render();

while( msg.message!=WM_QUIT )
{
   if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
   {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
   };
};

А>А если так?

Тогда картинка обновляться не будет.
Re[8]: Работа с графикой средствами Direct3D
От: Аноним  
Дата: 29.11.05 09:45
Оценка:
Здравствуйте, U-4X-96, Вы писали:

U49>Здравствуйте, Аноним, Вы писали:


А>>В оконном режиме: когда ты к примеру передвигаешь окно, которое выходит за рамки десктопа при передвижении — те части окна которые вышли за границы десктопа нужно перерисовать, поэтому и срабатывает WM_PAINT, в котором и нужно восстановить эти участки — но что бы не заморачиваться с участками окна обычно восстанавливают все окно — ну а изображение последнего кадра хранится в бек буффере — поэтому и ресторим его на окно в WM_PAINT.


U49>А всегда ли оно там хранится, как насчет D3DERR_DEVICELOST?


U49>
U49>Render();

U49>while( msg.message!=WM_QUIT )
U49>{
U49>   if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
U49>   {
U49>      TranslateMessage( &msg );
U49>      DispatchMessage( &msg );
U49>   };
U49>};
U49>

А>>А если так?

U49>Тогда картинка обновляться не будет.


D3DERR_DEVICELOST возникает при ALT+TAB и при переходе между режимами — тогда ресторить все придется.

Сорри, у меня так:

while (true) 
{
   HandlerEvents(); // обработка событий;

   Render();
        
   if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
   {
      if( 0 == GetMessage(&msg, NULL, 0, 0 ) )
      {
     Destroy();
     return (int)msg.wParam;
      };

      if (0==TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
      {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      };
   };
   
   FPSBalancer(); //что бы не грузить проц на 100 %
};
Re[9]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 29.11.05 10:28
Оценка:
Здравствуйте, Аноним, Вы писали:



А>D3DERR_DEVICELOST возникает при ALT+TAB и при переходе между режимами — тогда ресторить все придется.


Ресторить и рендерить, а это долго. Так что луше пускай пользователь расплывчитую картинку во время перетаскивания увидет, чем тормоза. Когда возникает D3DERR_DEVICELOST помойму не документировано, тоесть сказано что приложение всегда должно быть готовым к его появлеию. Хотя может я и чтото путаю.

А>Сорри, у меня так:

А>

А>while (true) 
А>{
А>   HandlerEvents(); // обработка событий;

А>   Render();
        
А>   if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
А>   {
А>      if( 0 == GetMessage(&msg, NULL, 0, 0 ) )
А>      {
А>     Destroy();
А>     return (int)msg.wParam;
А>      };

А>      if (0==TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
А>      {
А>      TranslateMessage(&msg);
А>      DispatchMessage(&msg);
А>      };
А>   };
   
А>   FPSBalancer(); //что бы не грузить проц на 100 %
А>};
А>


Ничего для примера, хотя зачем вначале вызывать PeekMessage(,,,,PM_NOREMOVE) а потом GetMessage(). Второй не достаток, не обеспечивает обработку всех сообщений до рендеринга. Тебя ни когда не бесило когда ты закрываеш приложение, а оно не закрывается.

И что вам всем так далась "100% загрузка процесора", ее все равно не будет проверь на Tutorial от SDK.
Re[10]: Работа с графикой средствами Direct3D
От: Аноним  
Дата: 29.11.05 11:36
Оценка:
Здравствуйте, U-4X-96, Вы писали:

U49>И что вам всем так далась "100% загрузка процесора", ее все равно не будет проверь на Tutorial от SDK.


А зачем рендерить 1000 кадров в секунду, если и 50 достаточно — за этим собственно и следит FPS балансер.
Re[11]: Работа с графикой средствами Direct3D
От: U-4X-96  
Дата: 29.11.05 19:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А зачем рендерить 1000 кадров в секунду, если и 50 достаточно — за этим собственно и следит FPS балансер.


Ну не всегда достаточно, в идеале один кадр сцены на кадр монитора, ну это уже лишнии сложности для учебника.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.