рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

Несколько слов о недоработках.

Несколько слов о недоработках. - раздел Образование, Состоит из следующих компонентов Первое: Пример Mainexample В Окне В Видеорежимах Highcolor И...

Первое: пример MainExample в окне в видеорежимах HighColor или TrueColor на всех компьютерах с видеокартами GeForce2 MX 400, где я его тестировал, почему-то работает некорректно. Наблюдается странное поведение всей операционной системы в виде общего замедления работы. Это можно было бы со злорадством отнести к ошибкам движка, НО:

  1. На видеокарте S3 Trid3D/2X движок работает нормально в любом режиме!
  2. На видеокарте GeForce всё работает нормально в режиме 256 цветов!

Вот так. Самое удивительно - примеры из MS SDK работают у меня корректно на обеих видеокартах. Вообще, когда такая ошибка обнаружилась, я был в большом недоумении и полностью растерян. Для "чистоты эксперимента" я даже написал отдельную программу (не на движке), которая также работала в оконном режиме. К сожалению, и она работала некорректно, а ведь программный код был минимален и ошибке попросту негде было спрятаться. Поразмыслив, я пришёл к выводу, что имеет место некорректное взаимодействие программ, написанных на Delphi и драйверов Detonator. Звучит дико, но других объяснений я не нахожу.

Второе: я переделал функцию сохранения изображения в файле, теперь она работает корректно для видеокарты S3. К сожалению, на GeForce в 16-битовом режиме она получается искажённой, причину я так не нашёл. Для режима 32 бита всё работает правильно.

Мысли вслух:

  1. Если планируется писать какую-то игру или мультимедийное приложение, лучше написать сначала движок для неё.
  2. Разработка более-менее крупной программы после маленьких развязывает руки, позволяет "развернуться" программисту, реализовать некоторы свои амбиции.
  3. Вместе с тем работа по ловле ошибок довольно хлопотна и иногда раздражает.
  4. Уделите некоторое внимание организации вывода сообщений об ошибках - это окупится сторицей в процессе разработки.
  5. Иногда встречаются никак, совершенно, ну абсолютно необъянимые "bugs"! Это может здорово испортить жизнь.
  6. Иногда (только иногда) такие баги пропадают сами собой, если их "заморозить" недельки на две заглушкой, а потом снять %)
  7. Собственная(!) реализация всяких эффектов вроде прозрачности и поворота радует глаз, однако слишком уж они медленны и неказисты, их качество часто желает оставлять лучшего. Вдобавок, DirectDraw API постепенно становится устаревшей технологией, её развите корпорацией Microsoft уже давно остановлено. Возможно, захотев иметь в своей программе красочные спецэффекты, следует обратить своё внимание на двумерное рисование посредством таких API, как Direct3D и OpenGL.
DirectX для начинающих

 

Sprite

 

Вернуться к разделу Hello, World! DirectX для начинающих Автор Виктор Кода, дата публикации 8 апреля 2002г.

Этот пример демонстрирует вывод изображения средствами DirectDraw. Он построен без использования VCL, но я надеюсь это не помешает вам. Вот файлы проекта:

  • sprite.dpr - отвечает за создание окна и выборку системных сообщений.
  • basedd8.pas - содержит функции для работы с DirectDraw.

После регистрации класса окна и его отображения производится инициализация DirectDraw. За это отвечает функция InitDirectDraw(). Рассмотрим её работу подробнее.

 

Первым делом необходимо создать объект DirectDraw. На сегодняшний момент его нужно создавать функцией DirectDrawCreateEx(), а не DirectDrawCreate(), как это было в прошлых версиях. Первый параметр представляет собой указатель на уникальный идентификатор драйвера видеоадаптера, но т. к. в большинстве случаев компьютеры оснащаются одним видеоадаптером, то можно передать nil. Второй параметр является указателем на интерфейс IDirectDraw7.

Параметр iid может принимать только одно значение - IID_IDIRECTDRAW7. Любое другое значение приведёт к ошибке DDERR_INVALPARAMS. Последний параметр в описываемой функции на данный момент не используется и предназначен для будущих версий. Результат, возвращаемый функцией (равно как и любой другой в DirectX), имеет тип HRESULT, т.е. может иметь множество кодов завершения. В DirectDraw успешная работа функции определяется константой DD_OK, а ошибочная - множеством других, зависящих от типа ошибки. Кроме упоминавшейся константы DDERR_INVALPARAMS функция может вернуть DDERR_UNSUPPORTED, сообщив тем самым, что объект DirectDraw не инициализирован. Чтобы избежать мороки с проверкой возвращённого результата, рекомендуется применять макросы (в Delphi практически функции) FAILED() и SUCCEEDED(), определённые в windows.pas. Дело в том, что 31-й бит возвращаемого значения содержит флаг критичности, который указывает, произошла ли ошибка или нет. Если бит равен 0, то ошибки не было, а если он равен 1, то ошибка имела место. Это как раз и проверяют вышеуказанные макросы. Конечно, никто не запрещает написать так:

If DirectDrawCreateEx( nil, lpDD7, IID_IDIRECTDRAW7, nil ) <> DD_OK then...

Но профессионалы используют исключительно макросы FAILED() и SUCCEEDED().

После создания объекта необходимо установить режим кооперации - т. е. определить, оконный или полноэкранный режим будет использовать DirectDraw. Надо сразу "брать быка за рога" и программировать полноэкранные приложения. Режим кооперации учтанавливается методом IDirectDraw7.SetCooperativeLevel(). Первым параметром передаётся идентификатор окна типа HWND. Второй представляет собой комбинацию флагов. Установим такие:

  • DDSCL_ALLOWREBOOT - указывает, что будет доступно окно снятия программы по нажатию клавиш Ctrl-Alt-Del. Полезно при отладке приложения (вдруг зависнет). Этот флаг впоследствии можно и убрать.
  • DDSCL_EXCLUSIVE - используется только в полноэкранных приложениях.
  • DDSCL_FULLSCREEN - устанавливает полноэкранный режим. При его ипользовании обязателен флаг DDSCL_EXCLUSIVE.

Следующим действием является установка видеорежима. Это делает метод
IDirectDraw7.SetDisplayMode(). Первые три параметра указывают ширину и высоту экрана, а также глубину палитры (8, 16, 24, 32). Последние два параметра используются редко. Подробности о них можно узнать из SDK.

Итак, мы создали объект DirectDraw и изменили разрешение экрана. В этот момент работы программы наше окно моментально заслоняет все объекты на Рабочем столе, включая панель задач. Если вы ещё не обратили внимание, для создания окна я использовал структуру WNDCLASSEX, а не WNDCALSS. Дело в том, что окно, построенное на базе последней, не сразу закрывает весь экран - 1-1,5 секунды продолжает красоваться Панель задач. Возможно, всё дело во флаге WS_EX_TOPMOST, который можно использовать только совместно с WNDCLASSEX.

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

Поскольку поверхности могут быть разных типов (не только первичными, но и внеэкранными), а метод для их создания только один - lDirectDraw7.CreateSurface(), необходимо каким-то образом указать, что мы хотим создать именно первичную поверхность. Как это сделать?

Обратите внимание, что первый параметр метода - это указатель на структуру TDDSURFACEDESC2 (кстати, в SDK 8 для С++ этим параметром нужно передавать адрес структуры TDDSURFACEDESC, а не TDDSURFACEDESC2. Это ошибка перевода заголовочных файлов C++ на Pascal: тем не менее, всё работает корректно). Именно через эту структуру DirectDraw узнает, какой тип поверхности нужно создать.

Перед использованием структуры распространённой практикой является заполнение её нулями - на случай всякого "мусора" в RAM, который может привести к ошибке во время выполнения. Я использую функцию ZeroMemory(), но можно и FillChar(). Следующим действием является заполнение поля dwSize этой структуры размером самой структуры. Это действие обязательно!

Поле dwFlags определяет, какие другие поля структуры мы будем использовать. По-видимому, это сделано для обеспечения наивысшего быстродействия - теперь DirectDraw не будет просматривать все поля структуры (а их очень много), а "заглянет" только в те, которые мы указали. Мы будем использовать поля ddsCaps и dwBackBufferCount. Укажем это флагами DDSD_CAPS и DDSD_BACKBUFFERCOUNT. Поле ddsCaps.dwCaps как раз и определяет тип создаваемой поверхности - флаги DDSCAPS_PRIMARYSURFACE, DDSCAPS_FLIP и DDSCAPS_COMPLEX сообщат DirectDraw, что мы хотим создать первичную комплексную поверхность с возможностью переключения буферов. Поле dwBackBufferCount указывает количество задних буферов, которые мы подключим к первичной поверхности - установим 1 (хотя можно подключить и больше).

Вызываем метод lDirectDraw7.CreateSurface(), указав вторым параметром нужный интерфейс. Третий параметр заразервирован и не используется.

Теперь к первичной поверхности нужно "приаттачить" задний буфер. Этот буфер исключительно важен для самого механизма вывода изображений и необходим для избавления от мерцания спрайтов. Для создания заднего буфера используется структура TDDSCAPS. Очищаем её и задаём флаг DDSCAPS_BACKBUFFER. Методом IDirectDrawSurface.GetAttachedSurface() подсоединим задний буфер. Всё, инициализация DirectDraw закончена.

Теперь нужно создать внеэкранные поверхности и загрузить в них изображение. Внеэкранные поверхности представляют собой линейные области данных в видео- или системной памяти, которые предназначены для хранения графических данных. За всё это отвечает процедура LoadFiles(). Первым делом получаем идентификатор загруженного функцией LoadImage() растра. Я не буду её описывать, т. к. к DirectDraw она не имеет прямого отношения - за этим прошу в Help Win32 API. Скажу лишь, почему я применил именно эту функцию. Дело в том, что часто возникает необходимость загружать не только файлы формата bmp, но и файлы других форматов, например gif или JPEG. Обычно для их загрузки применяются различные библиотеки DLL (например, nViewLib.dll), результаты работы функций в этих библиотеках - величина типа HBITMAP. Её можно использовать в единообразном методе загрузки файлов различных форматов. Рекомендую использовать именно такой метод, если только вы не гуру в алгоритмах сжатия разных форматов файлов и не собираетесь самостоятельно писать функции по преобразованию сжатых файлов в растр - ведь DirectDraw подобных решений не предоставляет. К сожалению, недостаток такого способа в том, что он немного медленнен :-(. Впрочем, увеличенное время считывания должно сколь-нибудь существенно проявиться лишь при загрузке очень большого количества файлов (30-40 МБ и более).

Теперь рассмотрим процедуру CopyImage(). Первым параметром мы передаём адрес интерфейса IDirectDrawSurface - именно на на эту поверхность и будет загружен растр. Вторым - идентификатор загруженного растра. Вообще, работа функции CopyImage() базируется на GDI. После создания контекста и выбора в него растра мы получаем размеры этого растра функцией GetObject(). Теперь нужно создать поверхность DirectDraw c полученными шириной и высотой растра. За это отвечает ещё одна функцияCreateSurface(). Механизм в ней похож на тот, что использовался для создания первичной поверхности, поэтому подробно я его описывать не буду. Обратите только внимание на флаг DDSCAPS_OFFSCREENPLAIN - он указывает, что мы хотим создать именно внеэкранную поверхность. К сожалению, нельзя динамически менять размер поверхности DirectDraw - для этого нужно заново создать её и загрузить данные. После успешного создания поверхности можно загрузить на неё растр - для этого существует удобный метод IDirectDrawSurface.GetDC(). Захватив контекст устройства, осуществляем копирование растра с одного контекста на другой, захваченный (а фактически на поверхность DirectDraw). Для этого используется функция GDI BitBlt(). Достоинством метода можно считать тот факт, что теперь на поверхности DirectDraw можно рисовать любыми функциями GDI, а не только BitBlt(), не прибегая к прямому доступу к памяти, в которой расположена поверхность - например, нарисовать линию или овал. А если возникнет потребность вывести текст? Так что отказываться от GDI пока ещё рано. Да, захваченный контекст нужно освободить методом IDirectDrawSurface.ReleaseDC().

Ну вот, ещё один шаг позади. Самое время вернуться в модуль .dpr и посмотреть, что происходит дальше. Приложение начинает осуществлять выборку системных сообщений, а при отсутствии таковых вызывает функцию OnDraw(). В VCL этот алгоритм называется Application.OnIdle.

Рассмотрим OnDraw() подробнее. Это - сердце алгоритма вывода изображений на экран.
Вывод изображения в полноэкранном режиме осуществляется методом IDirectDrawSurface.BltFast(). Этот метод должен вызываться для поверхности, созданной как задний буфер - именно на нём мы и будем рисовать. Этот метод максимально быстр, но ограничен функционально, например, он не в состоянии сжать по осям выводимое изображение. Первые два параметра - координаты левого верхнего угла вывода спрайта. Третий - поверхность, содержимое которой будем выводить. Четвёртый - адрес структуры типа TRect, которая будет определять облать вывода поверхности - её инициализацию я сделал перед вызовом метода IDirectDrawSurface.BltFast(). Поэксперементируйте с функцией SetRect() и посмотрите, как параметры в ней влияют на изменение в выводе графики. Пятым параметром метода передадим константу DDBLTFAST_WAIT - она нужна для корректного вывода на экран.

Описанные действия нужно повторить для каждого выводимого спрайта. Последним делом нужно переместить содержимое заднего буфера на первичную поверхность, содержимое которой, как я уже сказал, представляет собой текущее изображение на мониторе. Сделаем это методом IDirectDrawSurface.Flip(), указав первым параметром nil - ведь у нас только один задний буфер. Константа DDFLIP_WAIT нужна для коректного вывода на экран. Этот метод следует вызывать только для первичной поверхности. Перемещение заднего буфера на экран - один из самых быстрых методов DirectDraw.
Теперь изображение появится на экране. Можете подвигать спрайт при помощи клавиатуры - так интересней.

После нажатия на клавишу Escape происходит выход из цикла. Затем программа вызывает нижестоящую функцию ReleaseDirectDraw(), которая восстанавливает начальное разрешение и удаляет созданные поверхности и объект DirectDraw. Заметьте, что вызов _Release() для соответствующего интерфейса будет корректным только в том случае, если произошёл вызов _AddRef(). Вообще, говорят что вызовы эти необязательны, но я всё же использую их для полной корректности работы программ.

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

DirectX для начинающих

 

Sound

 

Вернуться к разделу Hello, World! DirectX для начинающих Автор Виктор Кода, дата публикации 8 апреля 2002г.

Одним из достоинств компоненты DirectSound является то, что она имеет прямой (ну, почти прямой) доступ к аппаратному обеспечению звуковой карты. Среди интересных возможностей следует выделить размещение данных в памяти звуковой платы, использование аппаратного микширования звука, возможность создавать объёмный звук, используя специальные алгоритмы (это нужно для 3D-игр) - всё это мультимедиа-средства Windows обеспечить не в состоянии. Если как следует поработать с DirectSound API, можно создать очень качественный движок для вывода звука - такой, как во многих современных играх. Разумеется, желательно и соответствующее оборудование для вывода звука.

Этот пример использует только общие возможности компонента DirectSound (DirectXAudio), в частности, не используется механизм подкачки звуковых данных, не используются трёхмерные эффекты для придания "объёмности" звуку и т. д. Зато к несомненным достоинствам следует отнести универсальность алгоритма считывания звуковых данных из wav-файлов - читается любой формат. Пускай не обижаются Денис Гончаров и Тимур Салихов, по книге которых я и изучал DirectSound, но поставлять учебные примеры в стадии "обмоченные детские пелёнки" просто стыдно. Дело в том, что учебный пример по воспроизведению звуковых файлов, который поставлялся вместе в книгой, открывал только те wav-файлы, которые поставлялись на том же CD-ROM. С другими, в частности, из каталога WindowsMedia, пример работать наотрез отказывался - программа просто "вылетала". Поэтому пришлось прибегнуть к SDK и воспользоваться его примерами - благо, они работают корректно со всеми wav-файлами в формате PCM (я не встретил ни одного, который бы вызвал ошибку). Всё-таки парни из Microsoft знают, что делают.

К сожалению, за универсальность приходится платить, поэтому данный пример по объёму мало смахивает на учебный. К тому же, он недописан до конца :-( - надеюсь, кто-нибудь поможет мне одолеть возникшие проблемы.

Вот файлы проекта:

  • main.pas - главное окно программы.
  • wavread.pas - реализация класса TWaveSoundRead для чтения данных из wav-файлов.
  • lowfunc.pas - функции для работы с wav-файлами на низком уровне. Используются классом TWaveSoundRead.

Итак, кликаем два раза по форме - попадаем в процедуру FormCreate(). Певой вызывается функция InitDirectSound() - обычный подход. В ней создаётся главный объект DirectSound и устанавливается уровень кооперации. Для установки эксклюзивного уровня кооперации в DirectX 7 использовался флаг DSSCL_EXCLUSIVE. В документации SDK 8 сказано, что этот флаг уже устарел и не предоставит приложению эксклюзивного режима. Для этого теперь используется флаг DSSCL_PRIORITY. Вообще, эксклюзивный режим подразумевает приглушение всех других звуков, если наше приложение активно и само воспроизводит какой-либо звук. Я пробовал устанавливать оба флага, и в обоих случаях помимо собственного вывода был слышен и вывод других программ, запускаемых параллельно, даже если окно приложения было активно. Что это, мои ошибки или ошибки в DirectSound - я не знаю. Если у вас всё работает корректно, напишите мне.

Теперь программа ничего не делает, а ждёт, когда пользователь нажмёт кнопку "Открыть...". По щелчку на ней открывается диалоговое окно выбора звукового файла. После успешного выбора вызывается функция CreateStaticBuffer(), единственный параметр которой - имя открываемого wav-файла. Эта функция создаёт специальный звуковой буфер.

Звуковой буфер - это область памяти, создаваемая в RAM или памяти звуковой карты, в которой будут размещены сэмплы - звуковы данные, считанные из wav-файла. Используя этот буфер, DirectSound сможет воспроизвести звук.

Для создания звукового буфера служит метод IDirectSound8.CreateSoundBuffer(). Первый параметр - адрес структуры типа TDSBUFFERDESC. Её поля необходимо предварительно заполнить. Второй - указатель на интерфейс IDirectSoundBuffer, третий - вездесущий параметр агрегирования - передаём nil. Теперь разберёмся со структурой TDSBUFFERSDESC.

Она указывает DirectSound, какой тип буфера мы хотим создать. Как обычно, системную память, где расположены поля структуры, необходимо заполнить нулевами значениями функцией ZeroMemory() (или FillChar()). Поле dwSize должно содержать размер самой структуры в байтах. Поле dwFlags определяет тип создаваемого звукового буфера. Вот некоторые флаги:

  • DSBCAPS_STATIC - обычный звуковой буфер. Будучи создан один раз, может проигрываться многократно. DirectSound пытается разместить такой буфер в памяти звуковой карты.
  • DSBCAPS_LOCHARDWARE - указывает, что микширование данного буфера будет выполняться аппаратно.
  • DSBCAPS_LOCSOFTWARE - указывает, что будет применяться программное микширование.
  • DSBCAPS_CTRL3D - буфер позволит управлять объёмным звучанием.
  • DSBCAPS_CTRLPAN - указывает на необходимость изменять баланс звука а колонках
  • DSBCAPS_CTRLVOLUME - буфер позволит менять громкость выводимого звука.
  • DSBCAPS_GLOBALFOCUS - воспроизведение звука не прекратится даже в том случае, если приложение потеряет активносить.

Это только половина возможных флагов. Подробнее о них можно узнать из справки SDK.
Теперь необходимо назначить требуемый размер для буфера в байтах, чтобы в нём поместились все данные из wav-файла - заполнить поле dwBufferBytes.

Вся работа по открытию wav-файлов, загрузке из них данных и завершению работы с ними возлагается на класс TWaveSoundRead - можно пользоваться им как "чёрным ящиком" - ничего увлекательного в реализации методов класса нет - сплошные операции с указателями и вызов функций из модуля lowfunc.pas. Вообще DirectSound создавался лишь для прямого доступа к звуковой карте, и в его задачу не входит чтение звуковых данных из файлов, будь то даже несжатые wav-файлы - мультимедиа-стандар Windows. Вся работа по загрузке данных в буфер ложится на программиста. К сожалению, это сильно усложняет даже простейшие проекты, т. к. функции для работы с wav-файлами довольно громоздки, а о работе с другими форматами и говорить не приходится. О классе я ещё упомяну, а сейчас лишь скажу, что при вызове метода TWaveSoundRead.Open() при успешном открытии звукового файла поле m_ckIn.cksize класса содержит размер прочитанных данных в байтах - это значение и указываем в поле dwBufferBytes структуры TDSBUFFERDESC. Также необходимо указать формат данных в звуковом файле - ведь запись может быть стерео- или монофонической, с разной частотой дискретизации и т. д. Узнать это DirectSound сможет из поля lpwfxFormat типа TWAVEFORMATEX структуры TDSBUFFERDESC. Его необходимо приравнять к полю m_pwfx класса TWaveSoundRead - оно как раз и содержит эти данные. Здесь я допустил небольшую ошибку в программотехнике - ООП требует, чтобы доступ к данным класса осуществлялся только через методы этого класса - но я просто скопировал реализацию класса из файлов SDK Microsoft.

На случай, если DirectSound не сможет создать буфер заданого размера - например, большая часть памяти звуковой карты или RAM занята - необходимо запомнить реальный размер созданного буфера - он (размер) будет помещён в поле dwBufferBytes той же струтуры, что передавалась в метод IDirectSound8.CreateSoundBuffer().

Итак, буфер создан, теперь необходимо его заполнить звуковыми данными. В этом снова поможет класс TWaveSoundRead. Заполнение буфера данными происходит в функции FillBuffer().

Сперва необходимо прочитать данные из звукового файла. Процедурой GetMem() выделяем облать памяти нужного размера и получаем на неё указатель - переменная pbWavData. Затем записываем данные в память при помощи метода TWaveSoundRead.Read(). Теперь необходимо скопировать данные в буфер DirectSound.

Порядок действий достаточно прост: необходимо заблокировать память буфера, скопировать в него звуковые данные и затем не забыть разблокировать буфер. Блокировка буфера происходит методом IDirectSoundBuffer.Lock(). Первый параметр, dwWriteCursor, показывает, с какой позиции необходимо заблокировать буфер. Позиция представляет собой простое смещение от начала буфера. Если передать 0, то блокировка будет происходить с самого начала буфера. Второй, dwWriteBytes, сообщает размер блокируемой области, он не должен превышать реальный размер буфера. Здесь я передал значение переменной bbytes - в ней хранится реальный размер созданного звукового буфера. Далее необходимо передать адреса двух пар "указатель-размер", в которые метод помещает адреса блокированных областей и их размер. Последний параметр - 0.

Данные в буфер копируются процедурой CopyMemory() - указываем, куда копировать, откуда копировать и сколько копировать :-).

Теперь разблокируем буфер методом IDirectSoundBuffer.Unlock() и удалим область, откуда копировали процедурой FreeMem().

Мы создали звуковой буфер и загрузили в него данные. Вся чёрная работа позади, теперь можно программировать "с удовольствием". Проигрывание данных в буфере осуществляется методом IDirectSoundBuffer.Play(). Первый параметр зарезервирован - нужно указать 0. Второй указывает на приоритет звукового буфера - что это за зверь, я и сам толком не знаю. Значение может меняться от 0 до $FFFFFFFF. Если при создании звукового буфера не указывался флаг DSBCAPS_LOCDEFER, то необходимо передать 0. Последний параметр - комбинация флагов, указывающих способ проигрывания буфера. Для простого проигрывания просто передаём 0, а при цикличном - флаг DSBPLAY_LOOPING. О других можно узнать из SDK.

В окне есть два регулятора TScrollBar. Левый предназначается для изменения громкости звука, второй - для изменения баланса в колонках. Изменение громкости производится методом IDirectSoundBuffer.SetVolume(), единственным параметром которого является значение в интервале от 0 до -10000 - определено константами DSBVOLUME_MAX и DSBVOLUME_MIN. Да-да, изменение громкости звука производится только в сторону приглушения, даже в восьмой версии этот недостаток не устранён :( Изменение баланса в колонках производится методом IDirectSoundBuffer.SetPan(), единственным параметром которого является значение в интервале от 10000 до -10000 - определено константами DSBPAN_LEFT и DSBPAN_RIGHT. Расставьте колонки (если они есть) пошире, запустите пример и попробуйте подвигать скроллбар - слушайте сами. Конечно, это не 3D-эффекты, но зато очень просто.

Теперь самое время заглянуть в файл wavread.pas - если у кого есть желание копаться с указателями, можете поработать с ним. Я не буду описывать его методы, т. к. всё это довольно сложно и требует несколько страниц текста. Этот класс предельно прост, но не он работает с wav-файлами - идёт вызов функций из lowfunc.pas. Эти два файла являются МОИМ переложением с DirectX SDK 7 для C++ - в SDK 8 всё существенно переделано, и как мне кажется, усложнено. Теперь о не слишком приятном. Полагаю, не очень хорошо показывать людям, как работает DirectSound, не разобравшись со всем до конца самому. Проблема в том, что одна из функций из lowfunc.pas не работает, а другая недописана до конца. Я не смог перевести некоторые сложные операции над указателями в контекст языка Object Pascal, поэтому пришлось создать динамическую библиотеку на C++ для работоспособности примера. Если кто-то сможет помочь мне перевести всё на Pascal - буду премного благодарен. Я оставил исходный код из SDK в отдельном каталоге.

– Конец работы –

Эта тема принадлежит разделу:

Состоит из следующих компонентов

Введение... Фанаты игр часто встречаются с аббревиатурой quot DirectX quot На упаковках... Компоненты DirectX обеспечивают не только прямой доступ к устройствам компьютера они избавляют программиста от...

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Несколько слов о недоработках.

Что будем делать с полученным материалом:

Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:

Все темы данного раздела:

DirectShow
используется в мультимедиа-технологиях - можно выполнить высококачественое воспроизведение или захват видео и звука. Распространённость использования компоненты не слишком велика Все компо

Виктор Кода
Смотрите по теме : DirectX для начинающих.Часть вторая DirectX для начинающих. Часть третья. Считывание и запись Цикл лекция JINX'а Direc

Небольшое отступление
Прошёл месяц с тех пор как я написал первую часть ( http://www.delphikingdom.com/helloworld/directx.htm ) статьи по использованию DirectX в среде Delphi. У меня накопилось ещё несколько примеров, к

Почему я не рекомендую использовать DelphiX
Хочется поделиться с новичками своим мнением по поводу компонетов DelphiX и почему я не рекомендую их использовать. С одной стороны, DelphiX - это удобно – нет необходимости выполнять утом

DDLOCK_NOSYSLOCK
данный флаг указывает на то, что приложение пытается получить прямой доступ к поверхности без остановки стандартных механизмов Win32. По умолчанию при блокировке все действия ОС приостанавливаются

DDLOCK_READONLY и DDLOCK_WRITEONLY
указываются, если из памяти будет производиться только чтение или наоборот, будет идти только запись. Обычно в использовании этих флагах нет необходимости, но их можно применять для контроля содерж

E_string.pas
- две функции - ltos() и ltoc() для преобразования типа longint к строке string или pchar соответственно. Базируются на процедуре str() из модуля system.pas. Это здорово сокращает объём исполняемог

Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • Популярное
  • Облако тегов
  • Здесь
  • Временно
  • Пусто
Теги