|
|
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
( ввязался в спор на избитую ногами тему «OpenGL и Direct3D», но там неудобно обсуждать, поэтому отвечаю здесь) 2 marked-spb: marked-spbПётр СедовДа обычная справка, ничего выдающегося, по-моему. Не скажите, в ней задокументировано практически все, что есть в наличии, с примерами. Я справку Direct3D 8/9 прочитал, SDK-шные примеры посмотрел, но у меня остались вопросы, например: 1. Как выбирать длину динамического vertex buffer-а? Приходится выбирать от балды. (см. ниже константу VertBufLen в функции PaintHexGrid_D3D9_DVB) 2. У метода IDirect3DDevice9::DrawPrimitive есть параметр PrimitiveCount. Корректно туда передавать ноль? Если выбрать debug runtime, то «пустой» DrawPrimitive возвращает D3DERR_INVALIDCALL. Если выбрать retail runtime, то «пустой» DrawPrimitive возвращает D3D_OK. 3. Где внятные описание/пример, как использовать IDirect3DQuery9? Ещё у Microsoft есть дурацкая привычка убирать из MSDN и DirectX SDK описания/примеры старых версий Direct3D. Если надо понять код, использующий Direct3D 7, то где читать описание этого API? С Direct3D 9/10/11 будет то же самое? marked-spbПётр СедовА я наоборот советую новичкам начать с OpenGL. По нескольким причинам: 1. Базовая часть OpenGL (fixed function pipeline, которая без shader-ов) никогда не переделывалась. Именно поэтому я советую начинать с DirectX. Как раз чтобы сразу приучаться использовать шейдеры. Начинать лучше с чего-то простого (fixed function), а там глядишь дело и до продвинутых вещей дойдёт (shader-ы). Да и зачем новичку shader-ы? Пусть лучше делает shareware-ную игру (см. Alawar , Nevosoft ) с 2D-графикой. Для этого fixed function хватит за глаза и за уши. А уж когда наберётся опыта, тогда можно и на shader-ы посмотреть. Кармак не с Doom начинал, а с Commander Keen. marked-spbПётр СедовСейчас новичкам доступно много хороших актуальных книг по OpenGL на русском языке. К сожалению, хорошие и актуальные книги по OGL я нашел тоже лишь на оф. сайте, и они были на английском... Вообще-то, все книги по OpenGL актуальные (в отличие от книг по Direct3D 7, например). Какие из них считать хорошими -- вопрос туманный. marked-spbПётр Седова бывает не похож (9 и 10). Книго-писателям тяжело угнаться за Microsoft, поэтому книг по Direct3D 10/11 на русском языке очень мало (я знаю всего одну). На самом деле, DX10 в достаточной степени похож на DX9. У меня не возникло с ним проблем в свое время. IDirect3DDevice9 ID3D10Device Ничего себе похож . marked-spbА хороших книг действительно крайне мало. А если Вы имеете в виду книгу Попова по DX10, то это, вообще говоря, вольный перевод вступления к справке из DX SDK. Да, её имею в виду. («книги» В. А. Жаркова, естественно, не в счёт, это развод на деньги) marked-spbПётр Седов2. OpenGL позволяет рисовать примитивы (точки, отрезки прямых, треугольники) без создания vertex buffer-а ... Direct3D 8/9/10/11 принуждает программиста рисовать примитивы через vertex buffer. У меня с этим проблем не возникало никогда. Например, хочется, чтобы во viewport-е была шестиугольная сетка (ведь во многих играх карта состоит из шестиугольников). Размеры шестиугольника: Код: plaintext 1. 2. 3. 4. Код, рисующий шестиугольную сетку с помощью OpenGL-функций glBegin/glVertex*/glEnd (immediate mode): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. Код, рисующий шестиугольную сетку с помощью Direct3D 9: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. Новичку проще написать PaintHexGrid_OGL_IM, хотя бы потому, что там нет указателей, а у новичков традиционно проблемы с указателями. А профессионалу всё равно, в случае Direct3D он соорудит свой собственный immediate mode поверх динамического vertex buffer-а и получит такой же простой понятный код, как в PaintHexGrid_OGL_IM. marked-spbВ любом случае, даже если начать с прямой отрисовки, потом придется пользоваться буфером. Это примерно то же самое, что утверждать «Даже если программа написана на C/C++, потом придётся переписать её на ассемблер.». Отдельные небольшие участки кода, критичные по скорости, может и придётся, но всю программу -- никак нет. Скорость работы функции PaintHexGrid_OGL_IM меня вполне устраивала, переходить на динамический vertex buffer не требовалось. В этом-то и заключается удобство OpenGL: immediate mode позволяет легко и быстро писать простой понятный код с минимумом ошибок. Затем, в критичных по скорости местах (которых мало), можно перейти на vertex buffer-ы. marked-spbПётр СедовА профессиональным игроделам всё равно, они на зарплате сидят. Думаю, каждый новичок должен хотя бы попытаться получить достаточные знания для того, чтобы стать профессиональным игроделом. И OpenGL, да еще и без шейдеров, тут не сильно поможет... В том то и дело, что OpenGL позволяет «плавно» перейти от простых техник к продвинутым, с shader-ами. А Вы предлагаете новичку сразу бросаться в пекло Direct3D 10/11? marked-spbПётр Седов3. Используя Direct3D 8/9, программист вынужден обрабатывать «потерю устройства» (device lost). Всё это лишняя головная боль на ровном месте Обработка пишется в несколько строчек, кстати. Побольше. Берём первый попавшийся SDK-шный пример, скажем ShadowMap, и смотрим обработку потери устройства: shadowmap.cpp из DirectX SDK (June 2010) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. В реальных играх будет ещё больше (всякие там динамические vertex buffer-ы для particle-овых систем). Хотя, для реальных игр такое количество кода несущественно. marked-spbНичего сложного. В книге Фрэнка Луна это есть. На форуме gamedev.ru видел просьбу помочь с Direct3D. В ходе обсуждения выяснилось, что забыли освободить какой-то D3DPOOL_DEFAULT-ресурс перед вызовом Reset. Так что новички реально сталкиваются с проблемами при обработке потери устройства. marked-spbА DX10 и выше не требуют обработки потери устройства. Хорошо, что Microsoft устранила этот дефект Direct3D. Но если хочется, чтобы игра работала в Windows 2000/XP, то придётся использовать Direct3D 8/9, и обрабатывать потерю устройства. marked-spbПётр Седов(Мы ведь не приравниваем понятия «ОО-стиль» и «COM-интерфейсы», правда?) "Стиль" не приравниваем. Но DX - объектно-ориентированная библиотека, пусть и в "стиле COM". Там во главу угла ставятся объекты, а не функции. Это примерно то же самое, что утверждать «В GTK+ глобальные функции, поэтому GTK+ не-объектно-ориентированная, а в Qt классы/методы, поэтому Qt объектно-ориентированная.». На самом деле, обе GUI-библиотеки объектно-ориентированные. Исторически, было 2 вида 3D API: 1. Высоко-уровневый объектно-ориентированный 3D API. Типичное использование: 1.1. Создаём иерархию объектов (scene graph). 1.2. Вызываем Сцена.Нарисовать(), получаем результат (3D-картинка). Примеры таких API: QuickDraw 3D, Direct3D 7 Retained Mode. Они вымерли за ненадобностью. 2. Низко-уровневый функционально-ориентированный 3D API. Типичное использование: 2.1. Определяем функции обработки исходных данных (настраиваем fixed function pipeline, или явно прописываем вычисления в shader-ах). 2.2. Засовываем исходные данные (вершины/индексы, текстуры) в API, получаем результат (3D-картинка). Примеры таких API: OpenGL, Direct3D 7 Immediate Mode (не путать с OpenGL-ским immediate mode), Direct3D 8/9/10/11. Конечно, в этих API есть объекты (shader-ы, vertex/index buffer-ы, текстуры), но этого не достаточно, чтобы считать эти API объектно-ориентированными. То есть OpenGL и используемые на практике варианты Direct3D одинаково не-объектно-ориентированные, они функционально-ориентированные, и это хорошо. А глобальные функции или COM-интерфейсы -- это несущественные особенности синтаксиса. marked-spbИ это как раз хорошо и удобно. И нужно к этому привыкать как можно раньше. Код, включающий альфа-смешивание в OpenGL: Код: plaintext 1. 2. Код: plaintext 1. 2. 3. (Это ещё что, в Direct3D 6/7 вообще был ужас нашего Городка: Код: plaintext 1. 2. 3. 2 aamonster: aamonsterЯ, (новичок в использовании OpenGL/DirectX), начинал с OpenGL - просто потому, что рядом был товарищ с каким-никаким опытом OpenGL, и можно было спросить. Потом из-за проблем с совместимостью пересел на DirectX 9 - Какие проблемы с совместимостью? Можно по-подробнее? aamonsterи стало мне счастье: 1. Вместо необходимости _в правильном порядке_ вызывать всякие функции деинициализации - вызов Release. В OpenGL достаточно вызвать всего одну функцию завершения -- wglDeleteContext. Перед этим можно сделать wglMakeCurrent(NULL, NULL), чтобы деактивировать OpenGL-контекст, но это не обязательно, wglDeleteContext деактивирует OpenGL-контекст: описание функции wglDeleteContext в MSDNif a rendering context is the calling thread's current context, the wglDeleteContext function changes the rendering context to being not current before deleting it. OpenGL-контекст владеет своими ресурсами и освобождает их в конце своей жизни: // http://opengl.org/wiki/Common_Mistakes OpenGL contexts clean up after themselves, поэтому функции освобождения OpenGL-ресурсов вызывать необязательно. Но если хочется, это можно делать в любом порядке: Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. aamonsterУдобно инкапсулировать DirectX-ресурсы в своих объектах. Так и в OpenGL удобно. Инкапсулируем OpenGL-текстуру в C++-класс: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. aamonster2. Отладочные средства (утечки ресурсов, к примеру, ловятся с ходу). В OpenGL нет утечек ресурсов (см. выше) в том же смысле как «в Java нет утечек памяти». Также, в некоторых случаях OpenGL позволяет избежать создания ресурса. Например, функция PaintHexGrid_OGL_IM не создаёт vertex buffer, а функция PaintHexGrid_D3D9_DVB -- создаёт. aamonsterВ общем, спроектирован он позже и лучше, Что Direct3D 9 появился позже OpenGL -- да. Что Direct3D 9 лучше OpenGL -- спорно, та же обработка потери устройства -- очевидный дефект Direct3D 9 (почему-то не исправленный после Direct3D 8). aamonsterи OpenGL после него напоминает времена, когда я писал на бейсике на Львiве - с операторами PSET и LINE. Вообще-то, если хочется, чтобы некая функциональность была доступна более/менее во всех языках, то общепринятый подход -- выставить наружу C-шный API. Использование таких C-шных API (в том числе OpenGL) не напоминает (мне) древние морально устаревшие языки вроде Basic-а (который не Visual). А вот Microsoft для обеспечения кросс-языковости Direct3D пошла своим путём -- COM-интерфейсы, что привело к неудобному синтаксису (см. выше). aamonsterТак что по мне - лучше начинать с DirectX, способствует выработке правильного стиля (инкапсуляция, своевременное устранение ошибок [утечки памяти]). Про инкапсуляцию и утечки -- см. выше. aamonsterНо большой разницы нет. Для профессионала. А для новичка, OpenGL дружелюбнее, по-моему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2011, 06:08 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Пётр Седов2 aamonster: aamonsterЯ, (новичок в использовании OpenGL/DirectX), начинал с OpenGL - просто потому, что рядом был товарищ с каким-никаким опытом OpenGL, и можно было спросить. Потом из-за проблем с совместимостью пересел на DirectX 9 - Какие проблемы с совместимостью? Можно по-подробнее? Детали не помню - прога на каком-то из нужных компов просто не работала. Дефект не в самом OpenGL, а в том, что OpenGL-драйвера под винду пишут по остаточному принципу. Я это не называл как довод в пользу отказа от OpenGL, это просто была причина, которая _меня_ толкнула к DirectX. Пётр Седовaamonsterи стало мне счастье: 1. Вместо необходимости _в правильном порядке_ вызывать всякие функции деинициализации - вызов Release. В OpenGL достаточно вызвать всего одну функцию завершения -- wglDeleteContext. Тю, если всё так глобально - то вообще можно прогу завершить, всё освободится =). Я про более локальные вещи - к примеру, когда освобождаешь одну текстуру, не думая о том, заселекчена она где-то или нет. Пётр Седовпоэтому функции освобождения OpenGL-ресурсов вызывать необязательно. Но если хочется, это можно делать в любом порядке: Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. Две не зависящие друг от друга сущности - понятно. Я про зависящие. Повторяю свой пример: селектим текстуру в контексте, уничтожаем её, селектим в контексте другую. Это корректно? Стандартом описано? Все драйверописатели помнят, что стандартом описано? И если ответы "да" - то надо ли, чтобы это узнать, читать весь стандарт или хватит туториала? Я, как вы понимаете, не жду милостей от природы и деселекчу текстуру перед удалением - что усложняет код. UPD: Таки пока отвечал - прочитал кусок стандарта... оказывается, удаление заселекченной текстуры - более-менее корректная операция, утечек памяти не вызовет... максимум - косяки в отрисовке. Удаление через AddRef/Release лишено и этого недостатка. Пётр СедовaamonsterУдобно инкапсулировать DirectX-ресурсы в своих объектах. Так и в OpenGL удобно. Инкапсулируем OpenGL-текстуру в C++-класс: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. Разница - ровно на glBindTexture. Изменение состояния глобального объекта. Причём там, где это не требуется. Как следствие, кстати, ваш OpenGL-код я бы для себя отметил, как корявый: подобные изменения состояния должны либо откатываться (в конце Texture::Init делаем glBindTexture не с нулём, а с заранее запомненной из glGet(GL_TEXTURE_BINDING_2D), ну и при мультитрединге защищаем семафором), либо явно комментируем - "вызов Texture::Init изменяет активную текстуру в текущем контексте" (и тогда я бы не запаривался вызовом glBindTexture(GL_TEXTURE_2D, 0)) Первое - лишние тормоза и усложнение кода, второе - неудобство инкапсуляции (объект вылезает из своей песочницы). Пётр Седовaamonster2. Отладочные средства (утечки ресурсов, к примеру, ловятся с ходу). В OpenGL нет утечек ресурсов (см. выше) в том же смысле как «в Java нет утечек памяти». Также, в некоторых случаях OpenGL позволяет избежать создания ресурса. Например, функция PaintHexGrid_OGL_IM не создаёт vertex buffer, а функция PaintHexGrid_D3D9_DVB -- создаёт. Хорошо, если так - но что-то не вижу механизма, который бы обеспечил освобождение, к примеру, текстур до освобождения контекста (выделяем текстуры и теряем их номера). А то так мы договоримся до того, что в C++ свободен от утечек памяти: ведь при завершении программы все выделения в куче будут освобождены. Пётр СедовaamonsterВ общем, спроектирован он позже и лучше, Что Direct3D 9 появился позже OpenGL -- да. Что Direct3D 9 лучше OpenGL -- спорно, та же обработка потери устройства -- очевидный дефект Direct3D 9 (почему-то не исправленный после Direct3D 8). Ну да, потеря контекста - косяк очень серьёзный, почти сводящий на нет все преимущества. Но убрали же в DX10? А новичку при написании "для себя" можно его и не обрабатывать. Пётр Седовaamonsterи OpenGL после него напоминает времена, когда я писал на бейсике на Львiве - с операторами PSET и LINE. Вообще-то, если хочется, чтобы некая функциональность была доступна более/менее во всех языках, то общепринятый подход -- выставить наружу C-шный API. Использование таких C-шных API (в том числе OpenGL) не напоминает (мне) древние морально устаревшие языки вроде Basic-а (который не Visual). А вот Microsoft для обеспечения кросс-языковости Direct3D пошла своим путём -- COM-интерфейсы, что привело к неудобному синтаксису (см. выше). Лучше уж ком-интерфейсы, чем передача всей информации через изменение глобального объекта. Пётр СедовaamonsterНо большой разницы нет. Для профессионала. А для новичка, OpenGL дружелюбнее, по-моему. Обманчивое дружелюбие древних бейсиков, позволяющее превратить программу в клубок спагетти. Уффф... Вы правда считаете, что здесь общаться удобнее? Я задолбался тэги quote расставлять... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2011, 16:18 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
2 aamonster: aamonsterДетали не помню - прога на каком-то из нужных компов просто не работала. Проблема была именно в том, что OpenGL-драйвер был кривой? А то «прога просто не работала» -- как-то расплывчато. Я вот с кривоватым Direct3D-драйвером сталкивался, для видео-карты Matrox Millennium G400. Аппаратно-ускоренный Direct3D (D3DDEVTYPE_HAL) глючно рисовал цветные линии: они всегда были белые, вне зависимости от значения D3DRS_TEXTUREFACTOR. Software-ный Direct3D (D3DDEVTYPE_REF) цветные линии рисовал правильно (в той же программе), аппаратно-ускоренный OpenGL -- тоже. aamonsterДефект не в самом OpenGL, а в том, что OpenGL-драйвера под винду пишут по остаточному принципу. OpenGL-драйверы от NVIDIA традиционно хорошие. OpenGL-драйверы от ATI когда-то были кривоватые, но это, насколько я знаю, в прошлом. aamonsterЯ про более локальные вещи - к примеру, когда освобождаешь одну текстуру, не думая о том, заселекчена она где-то или нет. ... Повторяю свой пример: селектим текстуру в контексте, уничтожаем её, селектим в контексте другую. Это корректно? Стандартом описано? Все драйверописатели помнят, что стандартом описано? И если ответы "да" - то надо ли, чтобы это узнать, читать весь стандарт или хватит туториала? Я, как вы понимаете, не жду милостей от природы и деселекчу текстуру перед удалением - что усложняет код. UPD: Таки пока отвечал - прочитал кусок стандарта... оказывается, удаление заселекченной текстуры - более-менее корректная операция, утечек памяти не вызовет... максимум - косяки в отрисовке. Удаление через AddRef/Release лишено и этого недостатка. Обычно, после создания текстуры, и после рисования текстурированных примитивов, текстуру отвязывают (unbind): Код: plaintext 1. 2. 3. 4. 5. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. aamonsterПётр СедовИнкапсулируем OpenGL-текстуру в C++-класс: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. Разница - ровно на glBindTexture. Изменение состояния глобального объекта. Причём там, где это не требуется. Как следствие, кстати, ваш OpenGL-код я бы для себя отметил, как корявый: подобные изменения состояния должны либо откатываться (в конце Texture::Init делаем glBindTexture не с нулём, а с заранее запомненной из glGet(GL_TEXTURE_BINDING_2D), ну и при мультитрединге защищаем семафором), либо явно комментируем - "вызов Texture::Init изменяет активную текстуру в текущем контексте" (и тогда я бы не запаривался вызовом glBindTexture(GL_TEXTURE_2D, 0)) Первое - лишние тормоза и усложнение кода, второе - неудобство инкапсуляции (объект вылезает из своей песочницы). Всё проще: код класса Texture (OpenGL-вариант) уверен, что привязка отсутствует (см. выше), и лучше эту уверенность действительно выразить явно: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. aamonsterПётр Седовпропущено... В OpenGL нет утечек ресурсов (см. выше) в том же смысле как «в Java нет утечек памяти». Также, в некоторых случаях OpenGL позволяет избежать создания ресурса. Например, функция PaintHexGrid_OGL_IM не создаёт vertex buffer, а функция PaintHexGrid_D3D9_DVB -- создаёт. Хорошо, если так - но что-то не вижу механизма, который бы обеспечил освобождение, к примеру, текстур до освобождения контекста (выделяем текстуры и теряем их номера). Тогда надо договориться, что считать утечкой OpenGL-ресурса. Это, например, когда мы создаём текстуру, но не освобождаем её функцией glDeleteTextures? Возможно, gDEBugger (ставший недавно бесплатным) умеет такое ловить. (не использовал) aamonsterПётр Седовта же обработка потери устройства -- очевидный дефект Direct3D 9 (почему-то не исправленный после Direct3D 8). Ну да, потеря контекста - косяк очень серьёзный, почти сводящий на нет все преимущества. Дефект не особо серьёзный, но упомянуть стоит. aamonsterЛучше уж ком-интерфейсы, чем передача всей информации через изменение глобального объекта. COM-интерфейсы -- это всего лишь особенность синтаксиса. А глобальный (то есть доступный в любой точке графического кода) объект -- он в обоих API: Код: plaintext 1. 2. Код: plaintext 1. 2. aamonsterПётр СедовА для новичка, OpenGL дружелюбнее, по-моему. Обманчивое дружелюбие древних бейсиков, позволяющее превратить программу в клубок спагетти. Аналогия между OpenGL и древними Basic-ами -- странная. Древние Basic-и вымерли, а OpenGL широко используется (хоть и не PC-шными игроделами). aamonsterУффф... Вы правда считаете, что здесь общаться удобнее? Ну я ведь там написал, почему сюда перешёл. Здесь не надо большое сообщение разбивать на несколько мелких, есть tag-и для C++-кода. aamonsterЯ задолбался тэги quote расставлять... Зато в цитатах понятно, кто что написал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2011, 06:02 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Пётр Седов2 aamonster: aamonsterДетали не помню - прога на каком-то из нужных компов просто не работала. Проблема была именно в том, что OpenGL-драйвер был кривой? А то «прога просто не работала» -- как-то расплывчато. В точности так и не выяснил, но 90%, что именно так. Так что это не тянет на претензию к OpenGL. Для меня-то это скорей оказался бонус: переписывание того же кода на DirectX его упростило (хотя я на тот момент ожидал обратного) Пётр СедовОбычно, после создания текстуры, и после рисования текстурированных примитивов, текстуру отвязывают (unbind): Дело хорошее - опять же, если явно описано. Пётр Седовчтобы весь остальной код мог быть уверен, что привязка (binding) отсутствует. Поэтому, освобождение (функцией glDeleteTextures) привязанной (bound) текстуры -- операция очень подозрительная, хоть и законная. Лучше это считать логической ошибкой и ловить assert-ом (см. ниже). Опять же хорошо, но в DirectX удобнее - не надо расставлять никаких ассертов, достаточно включить отладку DirectX - и вуаля, получим эксепшн, где надо. А вообще всё это наводит на мысли о аспектно-ориентированном программировании и контрактах... Пётр СедовТогда надо договориться, что считать утечкой OpenGL-ресурса. Это, например, когда мы создаём текстуру, но не освобождаем её функцией glDeleteTextures? Возможно, gDEBugger (ставший недавно бесплатным) умеет такое ловить. (не использовал) Именно это. Прямой аналог malloc без free или new без delete. Пётр Седовaamonsterпропущено... Ну да, потеря контекста - косяк очень серьёзный, почти сводящий на нет все преимущества. Дефект не особо серьёзный, но упомянуть стоит. Он опять же мешает нормально изолировать объекты друг от друга... Приходится всё, что на потерю контекста надо пересоздавать, сводить в одно место. Пётр СедовaamonsterЛучше уж ком-интерфейсы, чем передача всей информации через изменение глобального объекта. COM-интерфейсы -- это всего лишь особенность синтаксиса. А глобальный (то есть доступный в любой точке графического кода) объект -- он в обоих API: Код: plaintext 1. 2. Код: plaintext 1. 2. В обоих, но в DirectX поток информации чуть ближе к нормальному (идеал - иллюзия иммутабельных объектов). Пётр Седовaamonsterпропущено... Обманчивое дружелюбие древних бейсиков, позволяющее превратить программу в клубок спагетти. Аналогия между OpenGL и древними Basic-ами -- странная. Древние Basic-и вымерли, а OpenGL широко используется (хоть и не PC-шными игроделами). Дык бейсики и постарше будут. Basic - появился в 1963, массовым был в 80-х и начале 90-х. OpenGL - появился в 1992. Так что по аналогии - у него есть ещё лет 20 на вымирание, если стандарт полностью не перепишут =) Пётр СедовaamonsterУффф... Вы правда считаете, что здесь общаться удобнее? Ну я ведь там написал, почему сюда перешёл. Здесь не надо большое сообщение разбивать на несколько мелких, есть tag-и для C++-кода. aamonsterЯ задолбался тэги quote расставлять... Зато в цитатах понятно, кто что написал. Просто почему именно сюда? Вроде форум sql-евский, а не геймдев, синтаксис для подобного разговора (ответ на отдельные куски текста) тоже не самый удобный... Кстати, я затупил - надо было не возиться с тегами, а именно дробить сообщение на кучу мелких, отвечая на отдельные реплики. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2011, 11:33 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
to Пётр Седов: Я уже около года не использовал ни DX, ни OGL, так что не все сейчас помню... Пётр Седов1. Как выбирать длину динамического vertex buffer-а? Приходится выбирать от балды. (см. ниже константу VertBufLen в функции PaintHexGrid_D3D9_DVB) Не вижу проблемы. Нужно вычислять его, если возможно. Или брать заранее такой, который вместит в себя необходимое количество вершин. Если же необходимое количество вершин неизвестно, то это, по-моему, довольно странно. Пётр Седов У метода IDirect3DDevice9::DrawPrimitive есть параметр PrimitiveCount. Корректно туда передавать ноль? Если выбрать debug runtime, то «пустой» DrawPrimitive возвращает D3DERR_INVALIDCALL. Если выбрать retail runtime, то «пустой» DrawPrimitive возвращает D3D_OK. Тут все просто: в дебаге проверяются все ошибки, в релизе - не все. По причине оптимизации, думается. Потому, видимо, надо верить дебагу. Пётр Седов Где внятные описание/пример, как использовать IDirect3DQuery9? Не могу посмотреть, что в справке на эту тему написано, так как не установлена сейчас. Но, учитывая, что в MSDN есть его описание, притом достаточно полное , то сомневаюсь, что оно отсутствует в DX SDK. Пётр СедовЕщё у Microsoft есть дурацкая привычка убирать из MSDN и DirectX SDK описания/примеры старых версий Direct3D. Если надо понять код, использующий Direct3D 7, то где читать описание этого API? С Direct3D 9/10/11 будет то же самое? Насколько я знаю, DX11 как бы включает в себя 9 и 10. Как минимум, все объединены в одной SDK. А вот когда произойдет отказ от WinXP и Vista - тогда, наверное, уже будет какой-нибудь DX12 или 13, в котором уже не будет поддержки старых технологий... Или 11 без костылей в виде DX10 и DX9... Пётр СедовНачинать лучше с чего-то простого (fixed function), а там глядишь дело и до продвинутых вещей дойдёт (shader-ы). Да и зачем новичку shader-ы? Пусть лучше делает shareware-ную игру (см. Alawar, Nevosoft) с 2D-графикой. Для этого fixed function хватит за глаза и за уши. А уж когда наберётся опыта, тогда можно и на shader-ы посмотреть. Кармак не с Doom начинал, а с Commander Keen. Если честно, я без шейдеров написал всего 1 кривую программу, и никакой радости от этого не получил. На DX9, кстати. На OGL я даже этого тогда не смог... После чего благополучно перешел на DX9 с шейдерами. Наверное, стоит сделать лирическое отступление на тему "как это было": мне на тот момент естественно, хотелось написать игру. Но не какой-нибудь арканоид, а обязательно 3d с outdoor-ландшафтами. По причине того, что мне это нравилось, а арканоиды не нравились. Поэтому, после чтения форумов, я уже в сторону "без шейдеров" не думал вообще. Ну и, соответственно, нашел единственную книгу, в которой было все что мне нужно. Шейдеры, ландшафты, вода и так далее. И написал где-то за полгода программку. И с водой, и с ландшафтами, и с деревьями, и с багами, и глюками, и с тормозами. И с обработкой потери устройства. В принципе, из этого можно было сделать небольшую тормозную игрушку, но я не сделал - идеи простой игры у меня не было, а сложную на этом сделать было бы проблематично. И да, я на тот момент владел C++ на уровне "несколько лет в глаза не видел, после того как сдал экзамен по основам программирования". Так что не вижу никаких проблем с освоением DX9, сразу с шейдерами, начинающим программистом. Заодно, кстати, и владение C++ подтянуть придется. А с OGL у начинающего обязательно возникнет желание писать на C. Пётр СедовВообще-то, все книги по OpenGL актуальные (в отличие от книг по Direct3D 7, например). Какие из них считать хорошими -- вопрос туманный. Ну вот у меня в столе лежит книга: Ву, Девис, Нейдер, Шрайнер "OpenGL. Руководство по программированию", 4-е издание. 2006 год. ~600 страниц. Да, там на пальцах с картинками объяснено, как закрасить пикселы при помощи OpenGL, но ничего про шейдеры, про современные (хотя бы на тот момент) технологии программирования графики и тп. Так что, информацию из книги можно использовать, но для меня она неактуальна. Когда я решил изучить еще и OpenGL, то у меня сразу же встал вопрос о том, как его правильно проинициализировать под Windows и под Linux, например, как "включить" в нем мультисемплинг. Который я, кстати, начал использовать в DirectX сразу же, поскольку смотреть на артефакты мне совсем не хотелось. В книге есть 7 страниц про инициализацию с X Window, но даже без примера, и описаны только функции glx, про вызов функция X Window System - только в стиле "вызовите функцию создания окна". Естественно, никакого мультисемплинга, так как это расширение ARB... В результате пришлось долго блуждать по web, и на русском не нашел почти ничего... В общем, в OGL для того, чтобы заработал мультисемплинг, требуется пересоздавать контекст OGL и, кроме того, пересоздать окно, в которое происходит отрисовка. Мало того, вместо того, чтобы вменяемо сообщить о том, что заданы не поддерживаемые аппаратурой входные значения, OGL вместо этого создает контекст с "максимально похожими" значениями. Это меня изрядно удивило и обескуражило... И, само собой, не понравилось. В DX - никакого пересоздания окна, и поведение в случае ошибки предсказуемо. Мало того, у меня окно в linux создавалось до создания контекста OGL (поскольку находилось в разных классах). Во многих примерах до создания окна происходит вызов glXChooseVisual(), и depth передавалось в функцию создания окна, и я потратил очень много времени, пытаясь найти истину, могу ли я сделать так, как хочу... Пётр СедовIDirect3DDevice9 ID3D10Device Ничего себе похож . И то, и другое - "устройство" :-) Да, названия их методов отличаются, но реально не составляет большого труда переписать программу с использованием DX9 (с шейдерами, естественно, в DX10 без них никак) в виде программы DX10. Я, собственно, почти сразу по появлению DX10 так и сделал со своей, уже описанной выше, программой. Главная проблема оказалась в переписывании шейдеров, поскольку их синтаксис слегка поменялся. Пётр СедовДа, её имею в виду. («книги» В. А. Жаркова, естественно, не в счёт, это развод на деньги) Ага, именно она и лежит у меня в столе. Купил сдуру, не посмотрев сначала в help... Хорошо еще, цена хоть вменяемая, а не как у Жаркова.... Кстати, по DX9 тоже есть книга, копирующая справку DX9, только на русском, естественно, автор - Горнаков. Пётр СедовНапример, хочется, чтобы во viewport-е была шестиугольная сетка (ведь во многих играх карта состоит из шестиугольников). Размеры шестиугольника: ... И это ещё без обработки ошибок (if (FAILED(hr)) ...), чтобы понятнее. Методы DrawPrimitiveUP/DrawIndexedPrimitiveUP не использовал, потому что авторитетные дядьки настоятельно советуют их избегать, то есть рисовать всё только через vertex buffer-ы. (а в Direct3D 10/11 аналогичных методов вообще нет) Ну, во-первых, я бы в жизни не додумался рисовать шестиугольную сетку, серьезно. Что так, что этак, количество вершин же не изменится? Тогда смысл? К тому же, на карту можно натянуть текстуру, и нарисовать с ее помощью все что угодно. Тогда, если карта плоская, достаточно всего двух треугольников... В принципе, я понимаю, где такая карта нужна... Но, не вижу проблем, если шестиугольники будут виртуальными, а не реальными. По поводу советов гуру, кстати, налицо небольшое противоречие. С одной стороны, используется вертекс буффер, с другой стороны - отказ от шейдеров. По поводу, что кода больше и он неочевиден - это действительно так. Но для меня вообще шестиугольная сетка неочевидна сама по себе :-) Пётр СедовНовичку проще написать PaintHexGrid_OGL_IM, хотя бы потому, что там нет указателей, а у новичков традиционно проблемы с указателями. А профессионалу всё равно, в случае Direct3D он соорудит свой собственный immediate mode поверх динамического vertex buffer-а и получит такой же простой понятный код, как в PaintHexGrid_OGL_IM. Ну, совсем новичку в C++ - возможно. Но, мне кажется, все же главная проблема новичка - это отсутствие хорошего примера. Когда есть пример, разобраться уже в разы проще. Пётр СедовЭто примерно то же самое, что утверждать «Даже если программа написана на C/C++, потом придётся переписать её на ассемблер.». Отдельные небольшие участки кода, критичные по скорости, может и придётся, но всю программу -- никак нет. Скорость работы функции PaintHexGrid_OGL_IM меня вполне устраивала, переходить на динамический vertex buffer не требовалось. В этом-то и заключается удобство OpenGL: immediate mode позволяет легко и быстро писать простой понятный код с минимумом ошибок. Затем, в критичных по скорости местах (которых мало), можно перейти на vertex buffer-ы. Нет, я имел в виду другое, что если стоит задача научиться работать с графикой серьезно, то придется работать с буферами и шейдерами. Я не имел в виду, что придется переписывать какую-то программу только потому, что "так надо". Если всех все устраивает - зачем? Просто, одно дело, скажем, какой-нибудь Neverball (что там внутри, я не знаю, но точно OGL, так как под линуксом), а другое дело - TES4: Oblivion. Пётр СедовВ том то и дело, что OpenGL позволяет «плавно» перейти от простых техник к продвинутым, с shader-ами. А Вы предлагаете новичку сразу бросаться в пекло Direct3D 10/11? Зачем же? По ним пока не найти хороших примеров. А вот по DX9 - вполне. Таки ссылка на книгу Луна. К сожалению, ссылку на примеры к ней найти не могу, сайт книги существовать перестал. У меня они где-то лежат на диске... Пётр СедовПобольше. Берём первый попавшийся SDK-шный пример, скажем ShadowMap, и смотрим обработку потери устройства: ... Ну, вот, открыл свой старый проект... Класс ландшафта, ресетим только эффект(шейдеры): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Текст (ID3DXFont* m_Font): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. класс рендерера: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Ну и в главном цикле: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Пётр СедовНа форуме gamedev.ru видел просьбу помочь с Direct3D. В ходе обсуждения выяснилось, что забыли освободить какой-то D3DPOOL_DEFAULT-ресурс перед вызовом Reset. Так что новички реально сталкиваются с проблемами при обработке потери устройства. Ну, и у меня было нечто похожее, когда забывал вызвать OnResetDevice(). Обычно из-за копипаста при создании нового класса :-) Просто я не выносил это на форум. Кроме того, если окно не сворачивать, то это почти и не критично. А если свернуть, и после этого на экране бяка, то сразу ясно, куда смотреть. Пётр СедовХорошо, что Microsoft устранила этот дефект Direct3D. Но если хочется, чтобы игра работала в Windows 2000/XP, то придётся использовать Direct3D 8/9, и обрабатывать потерю устройства. На самом деле, я читал, что это как-то связано с окнами Windows, в Vist'е сделали несколько иную систему, и смогли от этого избавиться. А OpenGL, видимо, использует грязные хаки :-). Пётр СедовЭто примерно то же самое, что утверждать «В GTK+ глобальные функции, поэтому GTK+ не-объектно-ориентированная, а в Qt классы/методы, поэтому Qt объектно-ориентированная.». На самом деле, обе GUI-библиотеки объектно-ориентированные. ... Примеры таких API: OpenGL, Direct3D 7 Immediate Mode (не путать с OpenGL-ским immediate mode), Direct3D 8/9/10/11. Конечно, в этих API есть объекты (shader-ы, vertex/index buffer-ы, текстуры), но этого не достаточно, чтобы считать эти API объектно-ориентированными. То есть OpenGL и используемые на практике варианты Direct3D одинаково не-объектно-ориентированные, они функционально-ориентированные, и это хорошо. А глобальные функции или COM-интерфейсы -- это несущественные особенности синтаксиса. Не-не-не-не-не, вот тут полностью не согласен. Код: plaintext 1. 2. 3. 4. Пётр СедовКод, включающий альфа-смешивание в Direct3D 8/9: Включение альфы в DX с шейдерами: шейдер воды, код вырезан, ибо многабукаф: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2011, 01:16 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
to Пётр Седов: Скриншот в конце моего предыдущего поста - это из того самого моего проекта, DX9. Не был уверен, что скрин добавится. Пётр СедовOpenGL-драйверы от NVIDIA традиционно хорошие. OpenGL-драйверы от ATI когда-то были кривоватые, но это, насколько я знаю, в прошлом. Могу добавить, что с ATI даже в Linux теперь намного меньше проблем. Но с поддержкой старых видеокарт на новых/обновленых ОС - беда, что в никсах, что в вин. Вообще, по поводу буферов хочется сказать, что в серьезных играх буферов обычно немного. В том смысле, что существует один или несколько убербуферов в рендерере, в которые загоняются объекты. А видеокарта работает уже со всем буфером. Соответственно, может быть статический буфер для неизменяемых объектов и динамический для изменяемых и тп. А GUI в играх может рисоваться хоть буферами по 4 точки (а раньше, да, и без шейдеров делали), так как скорость там не критична. Обо всем этом можно вычитать на том же геймдеве. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2011, 01:26 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
to Пётр Седов: Сейчас на свежую голову подумалось: Если под динамическим буфером Вы имели в виду то, что он должен увеличиваться при добавлении новых вершин, такого нет. А D3DUSAGE_DYNAMIC - означает, что буфер оптимизирован для локов-анлоков каждый кадр. Так что это динамический буфер, но и массив постоянной длины... Ну и по поводу примера с шестиугольной сеткой: 1) Все вычисления должны быть до рисования. Грубо говоря, есть у класса метод Update() - в нем все считаем, но ничего не рисуем, и метод Draw() - в нем домножаем расчеты на матрицу и рисуем. И уж точно никаких локов-анлоков при отрисовке! И, собственно, чем меньше вызовов DrawPrimitive() - тем лучше. Это как раз преимущество буферов - сократить эти вызовы до минимума. 2) Для упрощения отрисовки лучше использовать индексированный буфер. В результате, в вершинный буфер закидываем точки в каком-то порядке, в буфере индексов - расставляем, в каком порядке их отображать. Собрали буфер таким образом - и вот теперь рисовать. Причем, может быть достаточно динамически изменять только буфер индексов в динамике... А он намного меньше, чем вертексы. По поводу того, что каждый кадр отображается разный диапазон точек - тогда да, придется лочить буфер вертексов и перезаписывать его. Но тогда порядок отрисовки точек не нужно менять, и буфер индексов не нужно лочить. Тогда порядок отображения вершин можно посчитать один раз до старта отрисовки. Кроме того, в некоторых случаях, думаю, можно поиграться с матрицами, не переписывая буфер... 3) А рисуем весь буфер очень просто: Код: plaintext Ну и, еще хочется сказать про меши, текстуры и шейдеры... В DX9 есть собственный формат мешей (файлы *.x), который DX понимает "из коробки". Загрузка вызовом одного метода. Аналогично - текстуры. Шейдеры - тоже, во-первых, в одном файле эффекта, во вторых загружаются одной функцией и компилируются. а в OGL - извольте загрузить файл в память сами, а во уже потом... Для новичка самое то, никаких сторонних библиотек, никаких самописных парсингов файлов, "все включено". В DX10 тоже есть собственный формат меша, но они его вроде бы не только не советуют, но и не разрешают использовать в реальных приложениях, только для демок из SDK. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.02.2011, 12:07 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
2 aamonster: aamonsterДля меня-то это скорей оказался бонус: переписывание того же кода на DirectX его упростило (хотя я на тот момент ожидал обратного) А бывает наоборот: при переходе с OpenGL на Direct3D код усложняется (пример -- PaintHexGrid_OGL_IM и PaintHexGrid_D3D9_DVB). aamonsterПётр Седовчтобы весь остальной код мог быть уверен, что привязка (binding) отсутствует. Поэтому, освобождение (функцией glDeleteTextures) привязанной (bound) текстуры -- операция очень подозрительная, хоть и законная. Лучше это считать логической ошибкой и ловить assert-ом (см. ниже). Опять же хорошо, но в DirectX удобнее - не надо расставлять никаких ассертов, достаточно включить отладку DirectX - и вуаля, получим эксепшн, где надо. Какой exception? В Direct3D 9, Release привязанной текстуры: Код: plaintext 1. 2. aamonsterА вообще всё это наводит на мысли о аспектно-ориентированном программировании и контрактах... Это горе от ума, по-моему :). Программирование ради программирования. aamonsterПётр СедовТогда надо договориться, что считать утечкой OpenGL-ресурса. Это, например, когда мы создаём текстуру, но не освобождаем её функцией glDeleteTextures? Возможно, gDEBugger (ставший недавно бесплатным) умеет такое ловить. (не использовал) Именно это. Прямой аналог malloc без free или new без delete. gDEBugger обнаруживает не-освобождённую текстуру: «Memory Leak: 1 object(s) are leaked in GL Context 1 [Leak Size: 1KB]» (см. приложенный screenshot). Не-освобождённый vertex buffer тоже обнаруживается, проверял. Но обращать на это внимание имеет смысл только если ресурсы создаются/освобождаются в течение всей жизни OpenGL-контекста. В простых случаях (ресурсы создаются только при инициализации OpenGL) заморачиваться на освобождение ресурсов необязательно, функция wglDeleteContext освободит всё что надо. aamonsterПётр Седовпропущено... Дефект не особо серьёзный, но упомянуть стоит. Он опять же мешает нормально изолировать объекты друг от друга... Приходится всё, что на потерю контекста надо пересоздавать, сводить в одно место. Просто все C++-объекты/подсистемы, создающие ресурсы Direct3D 8/9, должны иметь 2 метода: 1. Метод (возможно, пустой), создающий D3DPOOL_DEFAULT-ресурсы. Все такие методы вызываются после инициализации Direct3D и после Reset-а. 2. Метод (возможно, пустой), освобождающий D3DPOOL_DEFAULT-ресурсы. Все такие методы вызываются перед Reset-ом и перед завершением Direct3D. marked-spb привёл пример. aamonsterПросто почему именно сюда? Вроде форум sql-евский, а не геймдев, Ну нет у меня account-а ни на одном игродельном сайте, а здесь есть, вот поэтому именно сюда :). И вопросы в этом форуме («Программирование») обсуждаются самые разные, а не только по SQL. И даже по Direct3D изредка бывает . aamonsterсинтаксис для подобного разговора (ответ на отдельные куски текста) тоже не самый удобный... Да, но «человек -- не скотина, ко всему привыкает» :). Я вот привык уже. 2 marked-spb: marked-spbПётр Седов1. Как выбирать длину динамического vertex buffer-а? Приходится выбирать от балды. (см. ниже константу VertBufLen в функции PaintHexGrid_D3D9_DVB) Не вижу проблемы. Нужно вычислять его, если возможно. Или брать заранее такой, который вместит в себя необходимое количество вершин. Если же необходимое количество вершин неизвестно, то это, по-моему, довольно странно. Динамический vertex buffer часто используется как поток (stream) для закачки вершин в Direct3D, и его длина не имеет прямого отношения к количеству закачиваемых вершин. Это похоже на буферизованную запись в файл: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. (Кстати, код, создающий такой же файл с помощью stdio-функций: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. marked-spbПётр СедовУ метода IDirect3DDevice9::DrawPrimitive есть параметр PrimitiveCount. Корректно туда передавать ноль? Если выбрать debug runtime, то «пустой» DrawPrimitive возвращает D3DERR_INVALIDCALL. Если выбрать retail runtime, то «пустой» DrawPrimitive возвращает D3D_OK. Тут все просто: в дебаге проверяются все ошибки, в релизе - не все. По причине оптимизации, думается. Потому, видимо, надо верить дебагу. Это должно быть в документации описано, а не выясняться в результате экспериментов. Поэтому документация по Direct3D 9 не тянет на хорошую, она обычная. marked-spbПётр СедовГде внятные описание/пример, как использовать IDirect3DQuery9? Не могу посмотреть, что в справке на эту тему написано, так как не установлена сейчас. Но, учитывая, что в MSDN есть его описание, притом достаточно полное , то сомневаюсь, что оно отсутствует в DX SDK. Тогда претензия по IDirect3DQuery9 снимается. Посмотрел DirectX SDK June 2010, там эта статья есть. В старых DirectX SDK, в документации по Direct3D 9 этой статьи не было. marked-spbПётр СедовЕщё у Microsoft есть дурацкая привычка убирать из MSDN и DirectX SDK описания/примеры старых версий Direct3D. Если надо понять код, использующий Direct3D 7, то где читать описание этого API? С Direct3D 9/10/11 будет то же самое? Насколько я знаю, DX11 как бы включает в себя 9 и 10. Как минимум, все объединены в одной SDK. А вот когда произойдет отказ от WinXP и Vista - тогда, наверное, уже будет какой-нибудь DX12 или 13, в котором уже не будет поддержки старых технологий... Или 11 без костылей в виде DX10 и DX9... Речь о том, что программы, использующие Direct3D 7, нормально работают в Windows 7. И в будущих версиях Windows, скорее всего, тоже будут нормально работать. Почему описание/примеры Direct3D 7 убраны из MSDN и DirectX SDK? Это, между прочим, усложняет жизнь разработчикам Wine, делавшим альтернативную реализацию Direct3D 7. marked-spbНаверное, стоит сделать лирическое отступление на тему "как это было": мне на тот момент естественно, хотелось написать игру. Но не какой-нибудь арканоид, а обязательно 3d с outdoor-ландшафтами. По причине того, что мне это нравилось, а арканоиды не нравились. Арканоиды, кстати, бывают с 3D-графикой, например Egyptian Ball (использует Direct3D 7 Immediate Mode (грузит d3dim700.dll)). marked-spbА с OGL у начинающего обязательно возникнет желание писать на C. Сомнительно: в магазинах почти нет книг по чистому C, а по C++ -- полно. marked-spbПётр СедовВообще-то, все книги по OpenGL актуальные (в отличие от книг по Direct3D 7, например). Какие из них считать хорошими -- вопрос туманный. Ну вот у меня в столе лежит книга: Ву, Девис, Нейдер, Шрайнер "OpenGL. Руководство по программированию", 4-е издание. 2006 год. ~600 страниц. Да, там на пальцах с картинками объяснено, как закрасить пикселы при помощи OpenGL, но ничего про шейдеры, про современные (хотя бы на тот момент) технологии программирования графики и тп. Так что, информацию из книги можно использовать, но для меня она неактуальна. Эта книга актуальная в том смысле, что OpenGL не является морально устаревшим API. В отличие от Direct3D 7, например. marked-spbКогда я решил изучить еще и OpenGL, то у меня сразу же встал вопрос о том, как его правильно проинициализировать под Windows и под Linux, например, как "включить" в нем мультисемплинг. Который я, кстати, начал использовать в DirectX сразу же, поскольку смотреть на артефакты мне совсем не хотелось. В книге есть 7 страниц про инициализацию с X Window, но даже без примера, и описаны только функции glx, про вызов функция X Window System - только в стиле "вызовите функцию создания окна". Естественно, никакого мультисемплинга, так как это расширение ARB... В результате пришлось долго блуждать по web, и на русском не нашел почти ничего... В общем, в OGL для того, чтобы заработал мультисемплинг, требуется пересоздавать контекст OGL и, кроме того, пересоздать окно, в которое происходит отрисовка. Мало того, вместо того, чтобы вменяемо сообщить о том, что заданы не поддерживаемые аппаратурой входные значения, OGL вместо этого создает контекст с "максимально похожими" значениями. Это меня изрядно удивило и обескуражило... И, само собой, не понравилось. В DX - никакого пересоздания окна, и поведение в случае ошибки предсказуемо. Мало того, у меня окно в linux создавалось до создания контекста OGL (поскольку находилось в разных классах). Во многих примерах до создания окна происходит вызов glXChooseVisual(), и depth передавалось в функцию создания окна, и я потратил очень много времени, пытаясь найти истину, могу ли я сделать так, как хочу... Необязательно так мучаться, гораздо проще использовать библиотеку SDL (лицензия -- L GPL). Там и кросс-платформенная инициализация OpenGL, и anti-aliasing включается двумя строчками: Код: plaintext 1. 2. marked-spbНу, во-первых, я бы в жизни не додумался рисовать шестиугольную сетку, серьезно. Это просто пример, когда количество закачиваемых вершин неизвестно до самого момента рисования. То же самое может быть с продвинутыми системами частиц (particles), где количество примитивов на частицу меняется со временем. (Примитив -- это треугольник или quad. Кстати, да, в OpenGL есть quad-ы, и это часто удобно, например при рисовании полосок.) marked-spbЧто так, что этак, количество вершин же не изменится? Тогда смысл? Смысл в том, что закачивать неизвестное заранее количество вершин через immediate mode гораздо удобнее, чем через динамический vertex buffer. В OpenGL, immediate mode есть из-коробки. Это не самый быстро-работающий способ, но он позволяет легко прототипировать. А в Direct3D 8/9/10/11, immediate mode придётся делать самому, поверх динамического vertex buffer-а. marked-spbПо поводу советов гуру, кстати, налицо небольшое противоречие. С одной стороны, используется вертекс буффер, с другой стороны - отказ от шейдеров. Иногда надо, чтобы программа работала на старых видео-картах, не поддерживающих pixel shader-ы. marked-spbесли стоит задача научиться работать с графикой серьезно, то придется работать с буферами и шейдерами. Для коробочных игр -- наверняка, а вот для shareware-ных игр, для научной/инженерной 3D-графики, вполне подойдут OpenGL-ские fixed function pipeline, immediate mode (для динамических данных) и display list-ы (для статических данных). И работать будет даже на старых видео-картах. marked-spbПётр СедовХорошо, что Microsoft устранила этот дефект Direct3D. Но если хочется, чтобы игра работала в Windows 2000/XP, то придётся использовать Direct3D 8/9, и обрабатывать потерю устройства. На самом деле, я читал, что это как-то связано с окнами Windows, в Vist'е сделали несколько иную систему, и смогли от этого избавиться. А OpenGL, видимо, использует грязные хаки :-). Реализация OpenGL, скорее всего, временно выселяет ресурсы из видео-памяти в системную память, избавляя пользователя OpenGL от утомительного пересоздания ресурсов. marked-spbПётр СедовКод, включающий альфа-смешивание в Direct3D 8/9: Включение альфы в DX с шейдерами: ... Код: plaintext 1. 2. 3. 4. 5. 6. Это удобнее, чем возня с render state-ами. Это работает на старых видео-картах, не поддерживающих pixel shader-ы? marked-spbЕсли под динамическим буфером Вы имели в виду то, что он должен увеличиваться при добавлении новых вершин, такого нет. Нет, я этого не имел в виду. marked-spbА D3DUSAGE_DYNAMIC - означает, что буфер оптимизирован для локов-анлоков каждый кадр. Так что это динамический буфер, но и массив постоянной длины... Да, слово «dynamic» относится к содержимому vertex buffer-а, но не к его длине. marked-spbНу и по поводу примера с шестиугольной сеткой: 1) Все вычисления должны быть до рисования. Грубо говоря, есть у класса метод Update() - в нем все считаем, но ничего не рисуем, и метод Draw() - в нем домножаем расчеты на матрицу и рисуем. И уж точно никаких локов-анлоков при отрисовке! И, собственно, чем меньше вызовов DrawPrimitive() - тем лучше. Это как раз преимущество буферов - сократить эти вызовы до минимума. 2) Для упрощения отрисовки лучше использовать индексированный буфер. В результате, в вершинный буфер закидываем точки в каком-то порядке, в буфере индексов - расставляем, в каком порядке их отображать. Собрали буфер таким образом - и вот теперь рисовать. Причем, может быть достаточно динамически изменять только буфер индексов в динамике... А он намного меньше, чем вертексы. По поводу того, что каждый кадр отображается разный диапазон точек - тогда да, придется лочить буфер вертексов и перезаписывать его. Но тогда порядок отрисовки точек не нужно менять, и буфер индексов не нужно лочить. Тогда порядок отображения вершин можно посчитать один раз до старта отрисовки. Кроме того, в некоторых случаях, думаю, можно поиграться с матрицами, не переписывая буфер... 3) А рисуем весь буфер очень просто: Код: plaintext Это всё, может быть, хорошо для рисования больших ландшафтов, но для рисования шестиугольной сетки -- это ненужное усложнение на ровном месте. Простая понятная функция PaintHexGrid_OGL_IM вполне справляется с задачей. marked-spbНу и, еще хочется сказать про меши, текстуры и шейдеры... В DX9 есть собственный формат мешей (файлы *.x), который DX понимает "из коробки". Загрузка вызовом одного метода. Аналогично - текстуры. Шейдеры - тоже, во-первых, в одном файле эффекта, во вторых загружаются одной функцией и компилируются. а в OGL - извольте загрузить файл в память сами, а во уже потом... Для новичка самое то, никаких сторонних библиотек, никаких самописных парсингов файлов, "все включено". Этим занимается библиотека D3DX, поставляемая вместе с DirectX SDK. Эту библиотеку можно распространять вместе со своей программой? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2011, 06:13 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Пётр Седов2 aamonster: aamonsterДля меня-то это скорей оказался бонус: переписывание того же кода на DirectX его упростило (хотя я на тот момент ожидал обратного) А бывает наоборот: при переходе с OpenGL на Direct3D код усложняется (пример -- PaintHexGrid_OGL_IM и PaintHexGrid_D3D9_DVB). aamonsterпропущено... Опять же хорошо, но в DirectX удобнее - не надо расставлять никаких ассертов, достаточно включить отладку DirectX - и вуаля, получим эксепшн, где надо. Какой exception? В Direct3D 9, Release привязанной текстуры: Код: plaintext 1. 2. Разумеется. Потому что это - не ошибка. Вы, вероятно, не имеете опыта работы с COM или ещё какими-то технологиями, использующими reference counting, иначе вы бы этому не удивлялись. Ошибку можно всадить (или не всадить) позже - выполнив лишний Release. Поясняю. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Да, можно было бы последние два оператора и в обратном порядке выполнять - тоже корректно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2011, 22:56 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Пётр Седов2 aamonster: gDEBugger обнаруживает не-освобождённую текстуру: «Memory Leak: 1 object(s) are leaked in GL Context 1 [Leak Size: 1KB]» (см. приложенный screenshot). Не-освобождённый vertex buffer тоже обнаруживается, проверял. Но обращать на это внимание имеет смысл только если ресурсы создаются/освобождаются в течение всей жизни OpenGL-контекста. В простых случаях (ресурсы создаются только при инициализации OpenGL) заморачиваться на освобождение ресурсов необязательно, функция wglDeleteContext освободит всё что надо. Ну, честь ему и хвала. А заморачиваться на освобождение ресурсов лично мне надо (новые тайлы генерятся по ходу дела), так что... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2011, 22:59 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Да, кстати, сообразил насчёт выбора между DX и GL: если "на ты" с reference counting - то DirectX будет проще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.02.2011, 23:04 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
2 aamonster: aamonsterПётр СедовКакой exception? В Direct3D 9, Release привязанной текстуры: Код: plaintext 1. 2. Разумеется. Потому что это - не ошибка. Речь шла о том, что освобождение привязанной текстуры -- логически противоречивая операция: с одной стороны, раз освобождаем текстуру, значит она не нужна; с другой стороны, раз текстура привязана, значит она нужна (для рисования текстурированных примитивов). Вот чтобы ловить эту операцию в OpenGL, я и предложил использовать assert: Пётр Седов Код: plaintext 1. В ответ Вы написали: aamonsterв DirectX удобнее - не надо расставлять никаких ассертов, достаточно включить отладку DirectX - и вуаля, получим эксепшн, где надо. Я и поинтересовался: какой такой exception? aamonsterВы, вероятно, не имеете опыта работы с COM или ещё какими-то технологиями, использующими reference counting, Я использовал подсчёт ссылок в COM (IUnknown::AddRef, IUnknown::Release), в GLib (g_object_ref, g_object_unref). aamonsterиначе вы бы этому не удивлялись. Я не удивляюсь, что реализация Direct3D 9 не считает Release привязанной текстуры ошибкой. Я удивляюсь, где Вы при этом exception видели? В этом-то и заключается подвох Direct3D: Tex->Release() может не освободить текстуру, а всего лишь уменьшить счётчик ссылок. (Чтобы такого не происходило, даже сделали костыли функции D3DX10UnsetAllDeviceObjects/D3DX11UnsetAllDeviceObjects.) В OpenGL чётче: glDeleteTextures(1, &TexId) гарантированно освобождает текстуру. aamonsterДа, кстати, сообразил насчёт выбора между DX и GL: если "на ты" с reference counting - то DirectX будет проще. Я вполне «на ты» с подсчётом ссылок. Вы думаете, мне функцию PaintHexGrid_D3D9_DVB было проще писать, чем PaintHexGrid_OGL_IM? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.02.2011, 01:52 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Пётр Седов2 aamonster: Разумеется. Потому что это - не ошибка. Речь шла о том, что освобождение привязанной текстуры -- логически противоречивая операция: с одной стороны, раз освобождаем текстуру, значит она не нужна; с другой стороны, раз текстура привязана, значит она нужна (для рисования текстурированных примитивов). [/quot] А говорите - "на ты" с подсчётом ссылок ;-) Кстати, если хотите ловить assert'ом, что кто-то ещё держит отпущенную нами текстуру - можете писать Код: plaintext Пётр Седов2 aamonster: Вот чтобы ловить эту операцию в OpenGL, я и предложил использовать assert: Пётр Седов Код: plaintext 1. В ответ Вы написали: aamonsterв DirectX удобнее - не надо расставлять никаких ассертов, достаточно включить отладку DirectX - и вуаля, получим эксепшн, где надо. Я и поинтересовался: какой такой exception? Вообще-то в этот момент речь шла про утечки ресурсов. И, соответственно, ecxeption получим на выходе из программы. С указанием номера, позволяющего запустить программу ещё раз и увидеть, где мы выделили этот ресурс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.02.2011, 13:30 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
2 Пётр Седов: Пётр СедовДинамический vertex buffer часто используется как поток (stream) для закачки вершин в Direct3D, и его длина не имеет прямого отношения к количеству закачиваемых вершин. Это похоже на буферизованную запись в файл: ... Длина буфера (константа BufLen) не имеет прямого отношения к размеру создаваемого файла. (Кстати, код, создающий такой же файл с помощью stdio-функций: ... Этот код, может, работает не так быстро, как WinAPI-шный вариант, но он проще и понятнее. То есть stdio-функции -- это как бы аналог OpenGL-ского immediate mode.) Ну, хорошо, на примере ввода-вывода в файл: в 1-ом случае Вы записываете данные в буфер определенного размера и используете WriteFile(), во втором случае Вы пишете по одному символу. Налицо разные алгоритмы. Чтобы 1-й и второй случай соответствовали друг друга нужно либо использовать WriteFile точно так же, как работает fputc,то есть, создавать буфер из одного символа и записывать его в файл, либо вместо fputc использовать, например, fwrite. В случае с графикой абсолютно так же - в DX Вы можете создавать буфер из 2-х точек для каждой линии, или в OGL можно использовать VertexArray или Vertex Buffer Object... Хорошим вариантом для DX-функции было бы следующее: с учетом, что Пётр СедовЭто всё, может быть, хорошо для рисования больших ландшафтов, но для рисования шестиугольной сетки -- это ненужное усложнение на ровном месте. можно предположить, что сетка относительно небольшого размера, следовательно, можно после входа в функцию вычислить размер буфера, создать его, записать в него точки, а в конце один раз его отрисовать. Пётр СедовЭто должно быть в документации описано, а не выясняться в результате экспериментов. Поэтому документация по Direct3D 9 не тянет на хорошую, она обычная. Я думаю, там это есть. Ну, вот, например : MSDNThe debug DLLs have additional code that validates internal data structures and outputs debug error messages, using the OutputDebugString function, while your program is executing. Пётр СедовРечь о том, что программы, использующие Direct3D 7, нормально работают в Windows 7. И в будущих версиях Windows, скорее всего, тоже будут нормально работать. Почему описание/примеры Direct3D 7 убраны из MSDN и DirectX SDK? Это, между прочим, усложняет жизнь разработчикам Wine, делавшим альтернативную реализацию Direct3D 7. Ну, во-первых, убрано оно как раз для того, чтобы не использовали устаревшую технологию. Во-вторых, не знаю, как на Win7, а у меня на WinXPSP2 программы на DX7 вылетали и в режиме совместимости со старыми версиями Windows. Ну и про то что "убраны" и "усложняет". У тех, у кого есть DX7SDK и справка к нему, все, собственно, в наличии. У тех, у кого нет DX7 SDK - зачем им справка по DX7? Разработчики Wine - это вообще отдельная тема. Сомневаюсь, что в Microsoft были в восторге от этой затеи... Пётр СедовАрканоиды, кстати, бывают с 3D-графикой,.. Естественно, бывают. Я о том, что большинство новичков мечтает создать не арканоид, а "убийцу" "готики", "обливиона", "фаллаута" и тп. И есть возможность изучить то, что для этого нужно, зачем им арканоид? Пётр СедовСомнительно: в магазинах почти нет книг по чистому C, а по C++ -- полно. Тут дело, скорее, не в книгах, а в собственных знаниях. Я в свое время многие программы с классами "разбирал" на функции, чтобы понять, что там происходит. И отличие DX от OGL, на мой взгляд, сугубо положительное, в том, что он заставляет человека использовать ООП-стиль. Пётр СедовЭта книга актуальная в том смысле, что OpenGL не является морально устаревшим API. В отличие от Direct3D 7, например. Я понял, что Вы имеете в виду, я просто пытаюсь показать, что пользы от такой "актуальности" мало. Пётр СедовНеобязательно так мучаться, гораздо проще использовать библиотеку SDL (лицензия -- L GPL). Там и кросс-платформенная инициализация OpenGL, и anti-aliasing включается двумя строчками: Код: plaintext 1. 2. Во-первых, SDL по умолчанию отсутствует в дистрибутивах Linux, а X11 - присутствует почти всегда. Следовательно, нужно заботиться о его наличии тем или иным способом, а о наличии X11 - нет. Во-вторых, создать окно, что на WInAPI, что на X Window System, и инициализировать графическую подсистему (OGL или DX) - не так много кода. Ну и, наконец, я хотел собрать все сам, так как я хотел изучить не SDL, а OGL. Пётр СедовКстати, да, в OpenGL есть quad-ы, и это часто удобно, например при рисовании полосок. Quad - 2 треугольника :-) Если с индексированием, то вершин - все равно 4, если без, то тогда да, их 6... Пётр СедовА в Direct3D 8/9/10/11, immediate mode придётся делать самому, поверх динамического vertex buffer-а. Ну, как я уже сказал, достаточно просто написать функции, которые будут создавать буферы из нужного количества вершин для рисования того или иного примитива. Ну и, само собой, это будет медленно. Пётр Седов Иногда надо, чтобы программа работала на старых видео-картах, не поддерживающих pixel shader-ы. В таком случае грех жаловаться на то, что современные инструменты неудобны :-) Пётр СедовЭтим занимается библиотека D3DX, поставляемая вместе с DirectX SDK. Эту библиотеку можно распространять вместе со своей программой? Грубо говоря, этим занимается DirectX. Нужно читать Retail-лицензию конкретной версии DX. Пётр СедовДля коробочных игр -- наверняка, а вот для shareware-ных игр, для научной/инженерной 3D-графики, вполне подойдут OpenGL-ские fixed function pipeline, immediate mode (для динамических данных) и display list-ы (для статических данных). И работать будет даже на старых видео-картах. Пётр СедовЭто удобнее, чем возня с render state-ами. Это работает на старых видео-картах, не поддерживающих pixel shader-ы? Естественно, не будет. Но мы же изначально говорили о новичках. А зачем новичку старые видеокарты? Я сомневаюсь, что новичок, который хочет программировать игры, будет делать упор на инженерную графику с поддержкой старых видеокарт... Да, он вполне может захотеть написать простенькую игрушку. Но ему для этого совершенно не нужно думать о поддержке видеокарты 10-летней давности... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.02.2011, 19:09 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
marked-spbВо-первых, SDL по умолчанию отсутствует в дистрибутивах LinuxСреди пользователей участвующих в debian popcon libsdl1.2 установлен у 55.95% , не думаю что среди других дистрибутивов ситуация будет кардинально отличаться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.02.2011, 22:54 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
2 aamonster: aamonsterА говорите - "на ты" с подсчётом ссылок ;-) В подсчёте ссылок есть что-то сложное? aamonsterКстати, если хотите ловить assert'ом, что кто-то ещё держит отпущенную нами текстуру - можете писать Код: plaintext Это хороший приём. Но вообще, делать графический API с COM-интерфейсами и подсчётом ссылок -- не самая удачная идея, по-моему. Ведь Microsoft могла сделать так же, как в GDI: C-шный API (без многословных COM-интерфейсов), освобождение привязанного GDI-объекта считается ошибкой: Код: plaintext 1. 2. 3. 2 marked-spb: marked-spbПётр СедовДинамический vertex buffer часто используется как поток (stream) для закачки вершин в Direct3D, и его длина не имеет прямого отношения к количеству закачиваемых вершин. Это похоже на буферизованную запись в файл: ... Длина буфера (константа BufLen) не имеет прямого отношения к размеру создаваемого файла. (Кстати, код, создающий такой же файл с помощью stdio-функций: ... Этот код, может, работает не так быстро, как WinAPI-шный вариант, но он проще и понятнее. То есть stdio-функции -- это как бы аналог OpenGL-ского immediate mode.) Ну, хорошо, на примере ввода-вывода в файл: в 1-ом случае Вы записываете данные в буфер определенного размера и используете WriteFile(), во втором случае Вы пишете по одному символу. Налицо разные алгоритмы. Код, генерирующий последовательность байтов для записи в файл, в обоих вариантах одинаковый (он скрыт в многоточиях). Разница в том, что в WinAPI-варианте буферизацией занимается мой код, а в stdio-варианте буферизацией занимаются stdio-функции. Поэтому stdio-вариант проще и понятней, хотя может работает не так быстро, как WinAPI-вариант. marked-spbЧтобы 1-й и второй случай соответствовали друг друга Оба варианта и так «соответствуют» друг другу -- они создают одинаковые файлы. marked-spbнужно либо использовать WriteFile точно так же, как работает fputc,то есть, создавать буфер из одного символа и записывать его в файл, Функция fputc не создаёт буфер длиной 1 байт, она пишет байт во внутренний буфер. Изредка (далеко не при каждом вызове fputc), содержимое этого буфера скармливается функции WriteFile. marked-spbлибо вместо fputc использовать, например, fwrite. Это не всегда удобно. А использовать stdio-функции имеет смысл именно ради удобства. marked-spbВ случае с графикой абсолютно так же - в DX Вы можете создавать буфер из 2-х точек для каждой линии, Создавать vertex buffer длиной 2? Рисовать каждый отрезок отдельным вызовом DrawPrimitive? Это плохой способ. Такой же плохой, как писать каждый байт отдельным вызовом WriteFile. Меня по-прежнему интересует, исходя из каких соображений выбирать длину динамического vertex buffer-а, используемого как поток (stream) для закачки неизвестного заранее количества вершин в Direct3D 9. Если этого нет в официальной документации по Direct3D 9 (которая, по-Вашему, «хорошая»), то может быть это есть в книге Луна? marked-spbХорошим вариантом для DX-функции было бы следующее: с учетом, что Пётр СедовЭто всё, может быть, хорошо для рисования больших ландшафтов, но для рисования шестиугольной сетки -- это ненужное усложнение на ровном месте.можно предположить, что сетка относительно небольшого размера, Шестиугольная сетка -- бесконечного размера. Какую её часть рисовать, определяется параметрами MinX, MaxX, MinY, MaxY. Про которые известно только то, что MinX < MaxX и MinY < MaxY. marked-spbследовательно, можно после входа в функцию вычислить размер буфера, создать его, записать в него точки, а в конце один раз его отрисовать. Создавать одноразовый vertex buffer при каждом вызове функции рисования шестиугольной сетки? Это плохой способ. Лучше уж использовать метод DrawPrimitive UP (который полу-deprecated). marked-spbПётр СедовЭто должно быть в документации описано, а не выясняться в результате экспериментов. Поэтому документация по Direct3D 9 не тянет на хорошую, она обычная. Я думаю, там это есть. Ну, вот, например : MSDNThe debug DLLs have additional code that validates internal data structures and outputs debug error messages, using the OutputDebugString function, while your program is executing. Меня интересовало (до проведения экспериментов), корректно ли передавать ноль в параметр PrimitiveCount метода IDirect3DDevice9::DrawPrimitive . Цитата из MSDN этот вопрос не проясняет. marked-spbПётр СедовРечь о том, что программы, использующие Direct3D 7, нормально работают в Windows 7. И в будущих версиях Windows, скорее всего, тоже будут нормально работать. Почему описание/примеры Direct3D 7 убраны из MSDN и DirectX SDK? Это, между прочим, усложняет жизнь разработчикам Wine, делавшим альтернативную реализацию Direct3D 7. Ну, во-первых, убрано оно как раз для того, чтобы не использовали устаревшую технологию. Можно было не убирать, а перенести документацию/примеры в какой-нибудь Legacy DirectX SDK (чтобы не утяжелять современный DirectX SDK) и приписать: «в новых проектах не используйте эти технологии, они морально устарели». marked-spbВо-вторых, не знаю, как на Win7, а у меня на WinXPSP2 программы на DX7 вылетали и в режиме совместимости со старыми версиями Windows. У меня программы, использующие Direct3D 6/7, нормально работают в 64-битной Windows 7. (тот же Egyptian Ball, например) Вероятно, зависит от видео-карты и её драйвера. marked-spbУ тех, у кого нет DX7 SDK - зачем им справка по DX7? 1. Чтобы разобраться в старом коде, который использует Direct3D 7. 2. Чтобы сделать альтернативную реализацию Direct3D 7. (уже сделано разработчиками Wine, поэтому теоретический пункт) marked-spbИ отличие DX от OGL, на мой взгляд, сугубо положительное, в том, что он заставляет человека использовать ООП-стиль. Точнее, Direct3D заставляет использовать синтаксис «Object->Method(...)». Который не всегда удобен (вспоминаем включение альфа-смешивания через render state-ы). marked-spbВо-первых, SDL по умолчанию отсутствует в дистрибутивах Linux, а X11 - присутствует почти всегда. Следовательно, нужно заботиться о его наличии тем или иным способом, а о наличии X11 - нет. Вполне можно поставлять библиотеку SDL вместе со своей программой, лицензия ( L GPL) позволяет. Например, виндовая версия DOSBox так делает. Кстати, если программа использует библиотеку D3DX, то тоже надо заботиться, чтобы эта библиотека была на компьютере пользователя. Причём именно той версии, которую использует программа. Единственный корректный способ для этого -- DirectSetup. Но это усложняет инсталяцию программы, поэтому многие игроделы (в том числе западные) не заморачиваются на DirectSetup, а просто кладут нужный d3dx9_*.dll рядом с .exe-файлом, что не совсем корректно и может вызвать проблемы. marked-spbВо-вторых, создать окно, что на WInAPI, что на X Window System, и инициализировать графическую подсистему (OGL или DX) - не так много кода. А если использовать SDL (или GLUT), то создание окна и OpenGL-контекста делается считанными строчками кода. Это позволяет сосредоточиться на OpenGL и не отвлекаться на низко-уровневый WinAPI. marked-spbНу и, наконец, я хотел собрать все сам, так как я хотел изучить не SDL, а OGL. А если Вам понадобится создать текстуру из .png-файла, Вы будете писать распаковщик самостоятельно? Вряд ли же, скорее всего воспользуетесь библиотекой D3DX (или libpng напрямую). marked-spbПётр СедовКстати, да, в OpenGL есть quad-ы, и это часто удобно, например при рисовании полосок. Quad - 2 треугольника :-) Если с индексированием, то вершин - все равно 4, если без, то тогда да, их 6... Да, но вопрос в удобстве. И в OpenGL, и в Direct3D 9 есть примитив line (отрезок). Но при этом функция PaintHexGrid_OGL_IM проста и понятна, а функция PaintHexGrid_D3D9_DVB -- нет. marked-spbПётр СедовА в Direct3D 8/9/10/11, immediate mode придётся делать самому, поверх динамического vertex buffer-а. Ну, как я уже сказал, достаточно просто написать функции, которые будут создавать буферы из нужного количества вершин для рисования того или иного примитива. Ну и, само собой, это будет медленно. Да, я уже ответил выше, что создавать vertex buffer длиной 2 или 3, а также рисовать каждый примитив отдельным вызовом DrawPrimitive -- это плохой способ. marked-spbНо мы же изначально говорили о новичках. А зачем новичку старые видеокарты? Чтобы его shareware-ная игра (коробочную вряд ли осилит) работала на офисных компьютерах с Windows XP и интегрированной Intel-овской видео-картой, не поддерживающей pixel shader-ы. marked-spbЯ сомневаюсь, что новичок, который хочет программировать игры, будет делать упор на инженерную графику с поддержкой старых видеокарт... Я упомянул научную/инженерную 3D-графику в ответ на Ваше утверждение: marked-spbесли стоит задача научиться работать с графикой серьезно, то придется работать с буферами и шейдерами. Тут вроде как не про игры, а вообще. marked-spbДа, он вполне может захотеть написать простенькую игрушку. Но ему для этого совершенно не нужно думать о поддержке видеокарты 10-летней давности... Об этом думают компании Alawar и Nevosoft , продающие shareware-ные игры, ведь скучающие офисные работники (сидящие за офисными компьютерами, см. выше) -- важная часть их целевой аудитории. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2011, 06:31 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Пётр Седов2 aamonster: aamonsterА говорите - "на ты" с подсчётом ссылок ;-) В подсчёте ссылок есть что-то сложное? Нет, ничего. Но должна же уложиться в голове соответствующая идеология, чтобы при взгляде на тот код сразу было понятно, что он корректен. Пётр СедовЭто хороший приём. Но вообще, делать графический API с COM-интерфейсами и подсчётом ссылок -- не самая удачная идея, по-моему. Ведь Microsoft могла сделать так же, как в GDI: C-шный API (без многословных COM-интерфейсов), освобождение привязанного GDI-объекта считается ошибкой: Люто, бешено ненавижу. Дико усложняет обёртывание соответствующих ресурсов в объекты - зависимости между объектами сразу становятся двусторонними. Кстати, когда упоминал старые бейсики - как раз хотел в качестве второго примера привести windows gdi. И таки M$ ушёл от gdi - идеологии (вначале появился gdi+ с подсчётом ссылок, потом windows.forms и wpf со сборкой мусора). Пётр СедовА если использовать SDL (или GLUT), то создание окна и OpenGL-контекста делается считанными строчками кода. Это позволяет сосредоточиться на OpenGL и не отвлекаться на низко-уровневый WinAPI. В моём случае, кстати, не прокатило. OpenGL - отнюдь не основа, вокруг которой строится вся программа. Напротив - его надо было интегрировать в уже имеющееся приложение с готовой WndProc. Пётр Седовmarked-spbЯ сомневаюсь, что новичок, который хочет программировать игры, будет делать упор на инженерную графику с поддержкой старых видеокарт... Я упомянул научную/инженерную 3D-графику в ответ на Ваше утверждение: marked-spbесли стоит задача научиться работать с графикой серьезно, то придется работать с буферами и шейдерами. Тут вроде как не про игры, а вообще. У меня как раз не игра была. Вначале сделал без шейдеров, потом переделал на их использование (просто часть задачи на них хорошо легла - отрисовка с использованием палитры). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.02.2011, 16:19 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
2 aamonster: aamonsterПётр СедовВедь Microsoft могла сделать так же, как в GDI: C-шный API (без многословных COM-интерфейсов), освобождение привязанного GDI-объекта считается ошибкой: Люто, бешено ненавижу. Дико усложняет обёртывание соответствующих ресурсов в объекты - зависимости между объектами сразу становятся двусторонними. Это вполне удалось Microsoft-у (класс CBrush в библиотеке MFC) и Borland-у (класс TBrush в библиотеке VCL). Я смотрел их код, чего-то дикого не заметил. aamonsterИ таки M$ ушёл от gdi - идеологии (вначале появился gdi+ с подсчётом ссылок, потом windows.forms и wpf со сборкой мусора). В библиотеке Cairo (аналог GDI+) тоже есть подсчёт ссылок ( пример , см. cairo_pattern_destroy), но я от этого какого-то особого удобства не ощутил. Хотя, возможно, это упрощает создание привязки (binding) для Python-а. aamonsterПётр СедовА если использовать SDL (или GLUT), то создание окна и OpenGL-контекста делается считанными строчками кода. Это позволяет сосредоточиться на OpenGL и не отвлекаться на низко-уровневый WinAPI. В моём случае, кстати, не прокатило. OpenGL - отнюдь не основа, вокруг которой строится вся программа. Напротив - его надо было интегрировать в уже имеющееся приложение с готовой WndProc. Даже в этом случае библиотеки SDL/GLUT могут помочь: можно смотреть их код как пример использования GLX/WGL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.02.2011, 14:35 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
Пётр Седов Код, генерирующий последовательность байтов для записи в файл, в обоих вариантах одинаковый (он скрыт в многоточиях). Разница в том, что в WinAPI-варианте буферизацией занимается мой код, а в stdio-варианте буферизацией занимаются stdio-функции. Поэтому stdio-вариант проще и понятней, хотя может работает не так быстро, как WinAPI-вариант. Оба варианта и так «соответствуют» друг другу -- они создают одинаковые файлы. Функция fputc не создаёт буфер длиной 1 байт, она пишет байт во внутренний буфер. Изредка (далеко не при каждом вызове fputc), содержимое этого буфера скармливается функции WriteFile. Это не всегда удобно. А использовать stdio-функции имеет смысл именно ради удобства. Да, действительно, забыл про внутреннюю буферизацию... Пётр СедовСоздавать vertex buffer длиной 2? Рисовать каждый отрезок отдельным вызовом DrawPrimitive? Это плохой способ. Такой же плохой, как писать каждый байт отдельным вызовом WriteFile. Естественно. И без шейдеров отрисовывать графику тоже плохой способ. И старые видеокарты использовать плохо. Если в OGL есть буферизация, то тогда действительно Ваш вариант функции для DX в общем-то правильный. Пётр СедовМеня по-прежнему интересует, исходя из каких соображений выбирать длину динамического vertex buffer-а, используемого как поток (stream) для закачки неизвестного заранее количества вершин в Direct3D 9. Если этого нет в официальной документации по Direct3D 9 (которая, по-Вашему, «хорошая»), то может быть это есть в книге Луна? Думаю, что нет и быть не должно. Выбираете сами, естественно. Это же Вы его создаете, а не DX, Вам виднее. А как внутри OpenGL происходит выбор размера этого самого буфера? Документация хорошая. Пётр СедовШестиугольная сетка -- бесконечного размера. Какую её часть рисовать, определяется параметрами MinX, MaxX, MinY, MaxY. Про которые известно только то, что MinX < MaxX и MinY < MaxY. Создавать одноразовый vertex buffer при каждом вызове функции рисования шестиугольной сетки? Это плохой способ. Лучше уж использовать метод DrawPrimitive UP (который полу-deprecated). Само собой плохой. На самом деле, я уже говорил - создаете один буфер для динамики. Максимально необходимого размера. И все. Пётр СедовМеня интересовало (до проведения экспериментов), корректно ли передавать ноль в параметр PrimitiveCount метода IDirect3DDevice9::DrawPrimitive . Цитата из MSDN этот вопрос не проясняет. Да, действительно, не проясняет. Это недочет. Но я по прежнему буду утверждать, что справка по DirectX хорошая и уж точно одна из лучших, что я видел. Пётр СедовМожно было не убирать, а перенести документацию/примеры в какой-нибудь Legacy DirectX SDK (чтобы не утяжелять современный DirectX SDK) и приписать: «в новых проектах не используйте эти технологии, они морально устарели». 1. Чтобы разобраться в старом коде, который использует Direct3D 7. 2. Чтобы сделать альтернативную реализацию Direct3D 7. (уже сделано разработчиками Wine, поэтому теоретический пункт) А зачем это нужно Microsoft? И не так уж велико количество людей, которым необходима справка по DX7. Зная DX9, можно разобраться в программе, работающей с любой другой версией DirectX. И не думаю, что это нужно новичку. Пётр СедовТочнее, Direct3D заставляет использовать синтаксис «Object->Method(...)». Который не всегда удобен (вспоминаем включение альфа-смешивания через render state-ы). Я не про это. Я про то, что объекты DX удобно инкапсулировать в классы. А вот с OGL - еще не все ясно. Случай с мультисемплингом я привел. У меня все кончилось хорошо. Но найти настоящую информацию в потоке сетевого мусора оказалось не так-то просто... Опять же, OGL провоцирует человека писать в стиле C. Пётр СедовВполне можно поставлять библиотеку SDL вместе со своей программой, лицензия ( L GPL) позволяет. Например, виндовая версия DOSBox так делает. А зачем мне SDL? Мне нужны были только окно и инициализация. Мне не нужно все остальное. В любом случае, если для корректного использования OpenGL требуется SDL, как тогда можно говорить о том, что это хорошая библиотека? Пётр СедовКстати, если программа использует библиотеку D3DX, то тоже надо заботиться, чтобы эта библиотека была на компьютере пользователя. Причём именно той версии, которую использует программа. Единственный корректный способ для этого -- DirectSetup. Но это усложняет инсталяцию программы, поэтому многие игроделы (в том числе западные) не заморачиваются на DirectSetup, а просто кладут нужный d3dx9_*.dll рядом с .exe-файлом, что не совсем корректно и может вызвать проблемы. Да, все именно так. Но почему-то большинство игроделов, особенно западных, продолжают использовать DirectX. Пётр СедовА если использовать SDL (или GLUT), то создание окна и OpenGL-контекста делается считанными строчками кода. Это позволяет сосредоточиться на OpenGL и не отвлекаться на низко-уровневый WinAPI. Гуру настоятельно не советуют использовать GLUT. Кроме того, я хотел написать библиотеку, которая сможет создавать окна и без инициализации OGL или DX. И у использующего ее человека, то есть, меня, должен быть удобный интерфейс для доступа к классу окна. Пётр СедовА если Вам понадобится создать текстуру из .png-файла, Вы будете писать распаковщик самостоятельно? Вряд ли же, скорее всего воспользуетесь библиотекой D3DX (или libpng напрямую). Нет, зачем? Я прекрасно представляю себе, как данные хранятся в файлах :-) Мне неинтересно изучать конкретную реализацию. Естественно, я подключу необходимую библиотеку. Но, если мне она не подойдет по каким-то причинам, придется писать самому. Например, STL, Boost и luaBind мне не подошли, а вот zlib и сам Lua я использую. Пётр СедовДа, но вопрос в удобстве. И в OpenGL, и в Direct3D 9 есть примитив line (отрезок). Но при этом функция PaintHexGrid_OGL_IM проста и понятна, а функция PaintHexGrid_D3D9_DVB -- нет. Потому что разные технологии. DX9 ориентирован на использование буферов. OGL же со своим Immediate Mode - в общем-то устаревшая технология. Почему его и не следует рекомендовать новичкам. О такой возможности они должны узнать позже, как о дополнительном костыле. Ну и, как Вы сами сказали, в DX есть метод DrawPrimitiveUp... Пётр СедовЯ упомянул научную/инженерную 3D-графику в ответ на Ваше утверждение: marked-spbесли стоит задача научиться работать с графикой серьезно, то придется работать с буферами и шейдерами. Ну, если так, значит задачи инженерной графики не предъявляют серьезные требования к программисту графики. И если он задумает сменить деятельность на создание серьезных игр, ему предстоит еще многому научиться. Пётр СедовЧтобы его shareware-ная игра (коробочную вряд ли осилит) работала на офисных компьютерах с Windows XP и интегрированной Intel-овской видео-картой, не поддерживающей pixel shader-ы. Пётр СедовОб этом думают компании Alawar и Nevosoft , продающие shareware-ные игры, ведь скучающие офисные работники (сидящие за офисными компьютерами, см. выше) -- важная часть их целевой аудитории. Хорошо, новичок пишет игру для продажи. Тогда он выбирает не то, что он хочет изучить, а инструмент для решения конкретной задачи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2011, 23:25 |
|
||
|
OpenGL и Direct3D
|
|||
|---|---|---|---|
|
#18+
2 marked-spb: marked-spbИ без шейдеров отрисовывать графику тоже плохой способ. И старые видеокарты использовать плохо. Что значит «плохо»? Для некоторых программ требуется, чтобы они работали на старых видео-картах, не поддерживающих pixel shader-ы. marked-spbЕсли в OGL есть буферизация, Да, насколько я понимаю, OpenGL-ские immediate-mode-функции (glColor*, glNormal*, glTexCoord*, glVertex* и прочие) складывают полученные данные во внутренний буфер, и когда он наполняется, накопленные данные скармливаются видео-карте. marked-spbПётр СедовМеня по-прежнему интересует, исходя из каких соображений выбирать длину динамического vertex buffer-а, используемого как поток (stream) для закачки неизвестного заранее количества вершин в Direct3D 9. Если этого нет в официальной документации по Direct3D 9 (которая, по-Вашему, «хорошая»), то может быть это есть в книге Луна? Думаю, что нет и быть не должно. Выбираете сами, естественно. Это же Вы его создаете, а не DX, Вам виднее. Не виднее, поэтому и спрашиваю: если Вам надо, к примеру, рисовать бесконечную шестиугольную сетку, то как Вы будете выбирать длину динамического vertex buffer-а? Я выбрал 100 (константа VertBufLen в функции PaintHexGrid_D3D9_DVB), но это от балды. В старом DirectX SDK было два места, где динамический vertex buffer используется как поток (stream) для закачки неизвестного заранее количества вершин в Direct3D 9: 1. Класс CD3DFont. Длина vertex buffer-а -- 300 (на всякий случай уточню, что эта длина не имеет прямого отношения к количеству рисуемых букв). 2. Пример PointSprites. Длина vertex buffer-а -- 2'048 (на всякий случай уточню, что эта длина не имеет прямого отношения к количеству рисуемых частиц, о чём даже сказано в комментарии в C++-коде: «The size of this buffer does not relate to the number of particles that exist. Rather, the buffer is used as a communication channel with the device.»). «Хорошая» документация умалчивает, исходя из каких соображений выбраны эти длины. А в DirectX SDK June 2010, CD3DFont и PointSprites вообще отсутствуют, как и многие примеры по Direct3D 9 из старого DirectX SDK, например BumpWaves. marked-spbА как внутри OpenGL происходит выбор размера этого самого буфера? Насколько я понимаю, размер буфера для immediate-mode-функций выбирается OpenGL-драйвером оптимально для конкретной видео-карты (а не от балды, как в случае с Direct3D, когда размер буфера выбирается программистом). marked-spbПётр СедовМожно было не убирать, а перенести документацию/примеры в какой-нибудь Legacy DirectX SDK (чтобы не утяжелять современный DirectX SDK) и приписать: «в новых проектах не используйте эти технологии, они морально устарели». 1. Чтобы разобраться в старом коде, который использует Direct3D 7. 2. Чтобы сделать альтернативную реализацию Direct3D 7. (уже сделано разработчиками Wine, поэтому теоретический пункт) А зачем это нужно Microsoft? Что «это»? Разбираться в старом коде, который использует Direct3D 7? marked-spbИ не так уж велико количество людей, которым необходима справка по DX7. Да, но я имею в виду вот что. Microsoft убрала из MSDN и DirectX SDK документацию/примеры по Direct3D 1/5/6/7/8, хотя программы, использующие эти API, по-прежнему работают в современных версиях Windows. Документация/примеры по Direct3D 9/10/11 тоже когда-нибудь будут убраны? Похоже, стоит на всякий случай сохранить инсталятор DirectX SDK June 2010. С другими старыми API ситуация нормальная. Например, в MSDN до сих пор есть документация по GDI, хотя давно уже существует GDI+, и вот недавно появился Direct2D (потому что какая-то Microsoft-овская команда разработчиков обнаружила фатальный недостаток в GDI+ ). marked-spbЗная DX9, можно разобраться в программе, работающей с любой другой версией DirectX. На Direct3D 9 похож только его предшественник -- Direct3D 8. Остальные версии существенно отличаются от Direct3D 9. marked-spbЯ про то, что объекты DX удобно инкапсулировать в классы. А вот с OGL - еще не все ясно. Обсудили с aamonster-ом, вроде всё решаемо. marked-spbСлучай с мультисемплингом я привел. Насколько я понимаю, в WGL для этого надо создать временное окно с OpenGL-контекстом, чтобы получить pixel format с anti-aliasing-ом (по крайней мере, SDL так делает). Разве это мешает инкапсулировать основное окно в C++-класс? marked-spbА зачем мне SDL? Мне нужны были только окно и инициализация. Мне не нужно все остальное. В исходниках SDL можно посмотреть, как включается anti-aliasing на разных платформах, и сделать так же. marked-spbВ любом случае, если для корректного использования OpenGL требуется SDL, как тогда можно говорить о том, что это хорошая библиотека? Для корректного использования OpenGL не требуется библиотека SDL. Так же как для корректного использования Direct3D не требуется библиотека D3DX. marked-spbНо почему-то большинство игроделов, особенно западных, продолжают использовать DirectX. Тут есть и политические причины, Microsoft регулярно пытается притеснять OpenGL, например: // http://www.osnews.com/story/11489 Windows Vista May Degrade OpenGL ... Aug 2005 ... Microsoft's current plan for OpenGL on Windows Vista is to layer OpenGL over Direct3D in order to use OpenGL with a composited desktop to obtain the Aeroglass experience. This means that OpenGL performance will be significantly reduced - perhaps as much as 50%. It would be technically straightforward to provide an OpenGL ICD within the full Aeroglass experience without compromising the stability or the security of the operating system. Layering OpenGL over Direct3D is a policy more than a technical decision. Этого, к счастью, не произошло, но такие заявления создают тревожную неопределённость вокруг будущего OpenGL на Windows, что делает OpenGL непривлекательным для разработчиков PC-шных игр и инструментов. marked-spbГуру настоятельно не советуют использовать GLUT. Так эта библиотека не предназначена для «серьёзных» программ. Она для примеров из официальной книги по OpenGL, для быстрого прототипирования, для демонстрации разных техник рисования. marked-spbSTL, Boost ... мне не подошли, Мне тоже, но это тема для отдельного разговора :). marked-spbDX9 ориентирован на использование буферов. OGL же со своим Immediate Mode - в общем-то устаревшая технология. Почему его и не следует рекомендовать новичкам. О такой возможности они должны узнать позже, как о дополнительном костыле. OpenGL-ские immediate-mode-функции -- это не устаревший костыль, это для удобства (так же как stdio-функции). И начинать надо именно с них, а уже потом переходить к менее удобным, но более быстро-работающим способам (например, vertex/index buffer-ы). marked-spbНу и, как Вы сами сказали, в DX есть метод DrawPrimitiveUp... В Direct3D 8/9 -- да, есть. Кстати, «хорошая» документация не содержит внятных разъяснений, когда лучше использовать методы DrawPrimitive / DrawIndexedPrimitive , а когда http://msdn.microsoft.com/en-us/library/bb174372(v=vs.85).aspx]DrawPrimitive UP / http://msdn.microsoft.com/en-us/library/bb174370(v=vs.85).aspx]DrawIndexedPrimitive UP . В описании каждого UP-метода написано: MSDNThis method is intended for use in applications that are unable to store their vertex data in vertex buffers. Это очень странная фраза, ведь ничто не мешает программе создавать vertex/index buffer-ы. Авторитетные дядьки настоятельно советуют избегать UP-методы, но в примерах по Direct3D 9 из DirectX SDK June 2010, метод DrawPrimitive UP используется часто, обычно чтобы нарисовать единственный quad. marked-spbПётр СедовЧтобы его shareware-ная игра (коробочную вряд ли осилит) работала на офисных компьютерах с Windows XP и интегрированной Intel-овской видео-картой, не поддерживающей pixel shader-ы. Пётр СедовОб этом думают компании Alawar и Nevosoft , продающие shareware-ные игры, ведь скучающие офисные работники (сидящие за офисными компьютерами, см. выше) -- важная часть их целевой аудитории. Хорошо, новичок пишет игру для продажи. Тогда он выбирает не то, что он хочет изучить, а инструмент для решения конкретной задачи. Не понял, как это относится к выбору 3D API. На всякий случай замечу, что на обоих упомянутых сайтах продаётся игра АвиаНалёт, использующая OpenGL. АвиаНалёт на Alawar АвиаНалёт на Nevosoft ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.02.2011, 06:56 |
|
||
|
|

start [/forum/topic.php?fid=16&fpage=90&tid=1343141]: |
0ms |
get settings: |
6ms |
get forum list: |
20ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
58ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
79ms |
get tp. blocked users: |
2ms |
| others: | 263ms |
| total: | 450ms |

| 0 / 0 |
