DirectX 7 VS BitBlt

Работа с 2D и 3D графикой, видео, звуком.

Модератор: Mikle

Gemini
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 390
Зарегистрирован: 24.07.2002 (Ср) 14:15
Откуда: Ozersk

DirectX 7 VS BitBlt

Сообщение Gemini » 20.06.2003 (Пт) 18:06

Проблемма такая: я написал игру в обычном окне при помощи BitBlt она уменя прорисовывала все обьекты очень бысто (даже пришлось ставить паузу). А когда я переделал эту же игру на DirectX7 она стала очень сильно тормозить (для прорисовки я использовал стандартные ф-ции directX7 BltFast и Blt)
Почему Это происходит и как возможно увеличить скорость прорисовки в DirectX7 ???

З.Ы.
А может здесь в другом проблема??? (или в ручках :) ).

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 24.06.2003 (Вт) 2:33

Привет!
В литературе пишут, что DX в оконном режиме работает медленно, в полноэкранном быстрее. Я применял второй - вроде по скорости нормально (игра 2D). Вместо Blt попробуй Flip.

Gemini
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 390
Зарегистрирован: 24.07.2002 (Ср) 14:15
Откуда: Ozersk

Сообщение Gemini » 30.06.2003 (Пн) 23:09

Для рисования я использую BltFast и Blt. А функция Flip для пререворачивания заднего буфера на передний.

З.Ы.
Игра в полноэкранном режиме.

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 02.07.2003 (Ср) 3:35

Ниже часть кода из моей программы (в общем стандартный). Взгляни.

' **********************************************
' ***************** В модуль

Option Explicit

' Патчи для поиска файлов
Public BmpPath As String

Public Type Color
Red As Integer
Green As Integer
Blue As Integer
End Type

' Цвет фона
Public BColor As Color
' Цвет переднего плана
Public FColor As Color

'=============================================
'Объявления объектов DirectDraw
Public dx As New DirectX7
Public dd As DirectDraw7 'Объект DirectDraw
Public ddsPrimary As DirectDrawSurface7 'Главная поверхность
Public ddsBack As DirectDrawSurface7 'Задний буфер
Public ddsd As DDSURFACEDESC2 'Структура с описанием поверхности
Private ddsdStore As DDSURFACEDESC2 'Вспомогательная структура описания
Public rc As RECT 'Структура RECT для блиттинга
Public Caps As DDSCAPS2 'Структура с аппаратными возможностями
Public CurrentFont As New StdFont

'Инициализация DirectDraw в полноэкранном режиме
'============================================
Public Sub CreateDDFullscreen(srcHwnd As Long, ByVal dispX As Long, ByVal dispY As Long, ByVal dispColor As Long)
'Создаем объекты и устанавливаем режим
Set dd = dx.DirectDrawCreate("")
Call dd.SetCooperativeLevel(srcHwnd, DDSCL_EXCLUSIVE Or DDSCL_FULLSCREEN Or DDSCL_ALLOWREBOOT)
Call dd.SetDisplayMode(dispX, dispY, dispColor, 0, DDSDM_DEFAULT)

'Создаем flipping chain
ddsd.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
ddsd.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX
ddsd.lBackBufferCount = 1
Set ddsPrimary = dd.CreateSurface(ddsd)

'Получить BackBuffer
Caps.lCaps = DDSCAPS_BACKBUFFER
Set ddsBack = ddsPrimary.GetAttachedSurface(Caps)
End Sub

'Уничтожить DirectDraw
'====================
Public Sub DestroyDD()

'Убиваем поверхности, а ПОТОМ объект DirectDraw
Set ddsBack = Nothing
Set ddsPrimary = Nothing

'Восстанавливаем режим
Call dd.RestoreDisplayMode
Call dd.SetCooperativeLevel(0, DDSCL_NORMAL)
Set dd = Nothing

End Sub

'Очистка заданного буфера
'========================
Public Sub ClearBuffer(BackgroundColor As Color)
ddsBack.GetSurfaceDesc ddsdStore 'Получить описание очищаемой поверхности
'Заполняем структуру RECT, так, чтобы она охватывала всю поверхность
With rc
.Top = 0
.Left = 0
.Right = ddsdStore.lWidth 'Вот зачем нам надо было описание поверхности
.Bottom = ddsdStore.lHeight 'Высота и ширина подгоняются под нее
End With
' Заполняем цветом область, указанную в RECT
ddsBack.BltColorFill rc, RGB(BackgroundColor.Red, BackgroundColor.Green, BackgroundColor.Blue)
End Sub


'Создание поверхности из картинки в файле
'======================================
Public Function LoadPic(ByVal FileName As String, Optional CKey As Long = 0) As DirectDrawSurface7

'Объявления
Dim dds As DirectDrawSurface7 'Временная вспомогательная поверхность
Dim ddsd As DDSURFACEDESC2 'Описание временной поверхности
Dim StorePic As Long 'Временное хранилище картинки
Dim Bmp As Win32.BITMAP 'Тип BITMAP, описывающий растровое изображение
Dim hDCPicture As Long, hDCSurface As Long 'DC картинки и поверхности
Dim ddCK As DDCOLORKEY 'Для установки ключевого цвета

Const LR_LOADFROMFILE = &H10
Const LR_CREATEDIBSECTION = &H2000


'Загружаем картинку и получаем объект картинки
StorePic = LoadImage(0&, FileName, 0, 0, 0, LR_LOADFROMFILE Or LR_CREATEDIBSECTION) 'Загружаем картинку из файла
'Получаем описание картинки в структуру BITMAP
Win32.GetObject StorePic, Len(Bmp), Bmp

'Теперь, создаем поверхность
ddsd.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT 'Необходимые флаги
ddsd.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN 'Поверхность оффскринная
ddsd.lHeight = Bmp.bmHeight 'Высота поверхности как у картинки
ddsd.lWidth = Bmp.bmWidth 'Ширина поверхности как у картинки
'Вызываем метод, создающий поверхность
Set dds = dd.CreateSurface(ddsd) 'dd - глобальный объект DirectDraw7

'Получаем DC картинки
hDCPicture = Win32.CreateCompatibleDC(ByVal 0&)
Win32.SelectObject hDCPicture, StorePic
'Переводим картинку на поверхность
Call dds.restore
hDCSurface = dds.GetDC 'Подготовка к прямому доступу к поверхности
Call Win32.StretchBlt(hDCSurface, 0, 0, Bmp.bmWidth, Bmp.bmHeight, hDCPicture, 0, 0, Bmp.bmWidth, Bmp.bmHeight, SRCCOPY) 'Это копирует картинку в буфер
Call dds.ReleaseDC(hDCSurface) 'Конец прямого доступа к поверхности
Call Win32.DeleteDC(hDCPicture) 'Уничтожить объект картинки - больше не нужен

'Устанавливаем ключевой цвет
ddCK.low = RGB(BColor.Red, BColor.Green, BColor.Blue) 'Работает правильно только в 24-битном цвете (Но для случая 0 пойдет)
ddCK.high = ddCK.low
Call dds.SetColorKey(DDCKEY_SRCBLT, ddCK)

'Возвращаем объект
Set LoadPic = dds
'Set dds = Nothing
End Function

' Рисование картинок
' =======================================
Public Sub DrawPic(DdsPic As DirectDrawSurface7, ByVal OffsX As Long, ByVal OffsY As Long, Count As Integer, Width As Integer, Height As Integer, Optional Vvec As Boolean = False, Optional BmpX As Integer = 0, Optional BmpY As Integer = 0)
If Vvec = True Then
rc.Top = BmpY + Count * Height
rc.Left = BmpX
rc.Bottom = rc.Top + Height
rc.Right = BmpX + Width
Else
rc.Top = BmpY
rc.Left = BmpX + Count * Width
rc.Bottom = BmpY + Height
rc.Right = rc.Left + Width
End If
Call ddsBack.BltFast(OffsX, OffsY, DdsPic, rc, DDBLTFAST_DONOTWAIT Or DDBLTFAST_SRCCOLORKEY)
End Sub

'Рисование текста
'===========================================
Public Sub DrawText(OffsX As Long, OffsY As Long, TextBackColor As Color, TextForeColor As Color, Text As String, FontSize As Integer, Optional Transparent As Boolean = False, Optional FontBold As Boolean = False, Optional FontName As String = "Arial")
Dim TColor As Long
If Text = "" Then Exit Sub
ddsBack.SetFontBackColor RGB(TextBackColor.Red, TextBackColor.Green, TextBackColor.Blue)
ddsBack.SetFontTransparency Transparent

CurrentFont.Bold = FontBold
CurrentFont.Size = FontSize
CurrentFont.Name = FontName

ddsBack.SetFont CurrentFont

TColor = ddsBack.GetForeColor 'Чтобы не влиять потом на установленный цвет
ddsBack.SetForeColor RGB(TextForeColor.Red, TextForeColor.Green, TextForeColor.Blue)
ddsBack.DrawText OffsX, OffsY, Text, False
ddsBack.SetForeColor TColor
End Sub

' *****************************************************
' ******** В форму

Option Explicit
'Implements DirectXEvent

Dim Clouds As DirectDrawSurface7 ' Поверхность для рисунка облаков

Dim Running As Boolean 'Программа все еще работает?

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case vbKeyEscape
Running = False ' Выход
End Select
End Sub

Private Sub Form_Activate()

BmpPath = App.path & "\Bitmaps\"

Running = True

' ---------------------------------------------------------------------------------------------------------------------------------
' Установить окно проги поверх всех остальных
Dim Flags As Long
SetWindowPos Me.HWnd, -1, 0, 0, Me.Width / Screen.TwipsPerPixelX, Me.Height / Screen.TwipsPerPixelY, Flags

' ----------------------------------------------------------------------------------------------------------------------------------
' Цвет фона
BColor.Red = 255
BColor.Green = 255
BColor.Blue = 255

' Цвет переднего плана
FColor.Red = 0
FColor.Green = 0
FColor.Blue = 0

' ----------------------------------------------------------------------------------------------------------------------------------
' Инициализация DirectSound
' DirectSoundCreate Me.HWnd
' Инициализация DirectMusic
'DirectMusicCreate
'LoadMID MusicPath & "Matrix.mid"
'MusicPlay
' Инициализация DirectDraw
CreateDDFullscreen Me.HWnd, 800, 600, 16
'----------------------------------------------------------------
' Загружаем картинки

Set Clouds = LoadPic(BmpPath & "Clouds.bmp") 'Создаем буфер с нашей графикой

' --------------------------------------------------------

' Создать DirectInput
' и установить мышь
' MouseInitialise Me, Me.HWnd

' Инициализируем наш курсор
' MouseX = 400
' MouseY = 300
' MouseSens = 2
' UpdateCursor

' Теперь создаем главный цикл прорисовки экрана
While Running = True
DoEvents 'Будем жалостливы к системе
ClearBuffer BColor 'Чистим полотно
' Рисуем облака
DrawPic Clouds, 0, 0, 0, 800, 600, False, 0
'DrawText 0, 0, BColor, FColor, "Description "
'Теперь, завершающие действия витка
ddsPrimary.Flip ddsBack, DDFLIP_WAIT ' Переводим задний буфер на передний
Wend
ClearBuffer BColor 'Чистим полотно перед выходом
'MusicStop
'DestroyDS

DestroyDD

'DestroyMouse
'Unload Me
'MainMenu.Show
End
End Sub

Gemini
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 390
Зарегистрирован: 24.07.2002 (Ср) 14:15
Откуда: Ozersk

Сообщение Gemini » 04.07.2003 (Пт) 15:09

Yurich:

Я посмотрю твой пример и напишу такая же у него производительность или нет.


И ещё есть у тебя алгоритм для создания прозрачноси картинки???

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

алгоритм для создания прозрачноси картинки

Сообщение Yurich » 04.07.2003 (Пт) 22:41

Для 3DRM - точно, есть! Для DDraw можно порешать вместе.

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 05.07.2003 (Сб) 1:53

Пояснение параметров функции DrawPic:

DdsPic - исходная картинка (размер и количество элементов мо бы лю);
OffsX и OffsY - в какое место экрана рисовать элемент (или всё);
Count - 'порядковый номер элемента' в исходной картинке (от нуля);
Width и Height - размер элемента в пикселах;
Vvec - характер расположения элементов в исходной картинке (True - по вертикали, False - по горизонтали);
BmpX и BmpY - смещение 'нулевого элемента' ( в пикселах) от левого верхнего угла кртинки.

Пример исходной картинки
---------------------------
| эл 00 | эл 01 | эл 02 |
---------------------------
| эл 10 |
| эл 11 |
| эл 12 |
| эл 13 |
---------------------------

Для полупрозачности используйте что-нить типа:

Public Sub DrawPicBlending(DdsPic As DirectDrawSurface7, ByVal OffsX As Long, ByVal OffsY As Long, Count As Integer, Width As Integer, Height As Integer, Optional Vvec As Boolean = False, Optional BmpX As Integer = 0, Optional BmpY As Integer = 0)

Dim DestRect As RECT
Dim DDBLTEFFECT As DDBLTFX
Dim FLAG As CONST_DDBLTFLAGS

If Vvec = True Then
rc.Top = BmpY + Count * Height
rc.Left = BmpX
rc.Bottom = rc.Top + Height
rc.Right = BmpX + Width
Else
rc.Top = BmpY
rc.Left = BmpX + Count * Width
rc.Bottom = BmpY + Height
rc.Right = rc.Left + Width
End If

With DestRect
.Top = OffsX
.Left = OffsY
.Right = .Left + Width
.Bottom = .Top + Height
End With


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


With DDBLTEFFECT
' .ddckDestColorKey_high =
' .ddckDestColorKey_low =
' .ddckSrcColorKey_high =
' .ddckSrcColorKey_low =
' .lAlphaDestConst =
' .lAlphaDestConstBitDepth =
' .lAlphaSrcConstBitDepth =
' .lAlphaEdgeBlend =
' .lFill =
' . . . . . .
End With


' FLAG = DDBLT_ASYNC
' Исполняет этот blit асинхронно через первый в, сначала из (В ПОРЯДКЕ ПОСТУПЛЕНИЯ) аппаратных средств в полученном заказе(порядке). Если никакой участок памяти не доступен во В ПОРЯДКЕ ПОСТУПЛЕНИЯ аппаратных средствах, сбоях запроса.
' DDBLT_WAIT
' Откладывает DDERR_WASSTILLDRAWING возвращаемое значение, если blitter занят, и возвращается, как только blit может быть установлен, или другая ошибка происходит.
' DDBLT_COLORFILL
' Использует lFill члена структуры DDBLTFX как цвет RGB, который заполняет прямоугольник адресата на поверхности адресата.
' DDBLT_DDFX
' Использует lDDFX члена структуры DDBLTFX, чтобы определить эффекты, чтобы использовать для этого blit.
' DDBLT_DDROPS
' Использует lROP члена структуры DDBLTFX, чтобы определить растровые операции (ROPS), которые - не часть Win32 API.
' DDBLT_DEPTHFILL
' Использует lFill члена структуры DDBLTFX как значение глубины, чтобы заполнить прямоугольник адресата на поверхности z-буфера адресата
' DDBLT_DONOTWAIT
' Если blitter занят, не ждет blitter, чтобы стать доступным, но возвращения без blitting.
' DDBLT_KEYDESTOVERRIDE
' Использует ddckDestColorKey_high и ddckDestColorKey_low членов структуры DDBLTFX как цветная клавиша(ключ) для поверхности адресата.
' DDBLT_KEYSRCOVERRIDE
' Использует ddckSrcColorKey_high и ddckSrcColorKey_low членов структуры DDBLTFX как цветная клавиша(ключ) для исходной поверхности.
' DDBLT_ROP
' Использует lROP члена структуры DDBLTFX для ROP для этого blit. Эти ROPS - тот же самый, поскольку определили в Win32 AP
' DDBLT_ROTATIONANGLE
' Использует lRotationAngle члена структуры DDBLTFX как угол вращения(циклического сдвига) (указанный в 1/100s градуса(степени)) для поверхности.
' DDBLT_KEYDEST
' Использует цветную клавишу(ключ), связанную с поверхностью адресата.
' DDBLT_KEYSRC
' Использует цветную клавишу(ключ), связанную с исходной поверхностью.


Call ddsBack.BltFx(DestRect, DdsPic, rc, FLAG, DDBLTEFFECT)

End Sub

Aquarius
Постоялец
Постоялец
 
Сообщения: 692
Зарегистрирован: 04.11.2002 (Пн) 13:13
Откуда: Russia

Сообщение Aquarius » 11.07.2003 (Пт) 6:03

Yurich скинь на AquariusNet@yandex.ru весь проект, я покапаюсь.
(Всем изучать ASSEMBLER)
www.Wasm.ru, www.FlatAssembler.Net

Yurich
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 675
Зарегистрирован: 05.03.2003 (Ср) 3:43
Откуда: DONBASS/Gorlovka

Сообщение Yurich » 12.07.2003 (Сб) 3:34

Сорри, только кодом, и под "Разговор".


Вернуться в Мультимедиа

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 58

    TopList