Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Вниз

DirectDraw   Найти похожие ветки 

 
Zergling ©   (2003-09-30 06:41) [0]

Доброго всем дня! Начал изучать основы DirectX, купил библию по этому случаю (на С++), но пишу на Delphi
И вот возник у меня такой к Вам вопрос:

DDSURFACEDESC2        ddsd;  // Первичная поверхность DirectDraw

int mempitch        = (int)ddsd.lPitch; // Шаг в памяти
UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface; // Указатель на область памяти

Думаю тут все ясно
for (int index=0; index < 1000; index++)
   UCHAR color = rand()%256;
   int x = rand()%640;
   int y = rand()%480;

Интересует эта строка. Как указатель на область памяти превратился в массив (не доходит до меня эта запись)?
Суть вопороса, как тоже самое записать на дельфи, а то чото застрял я натоком приметивном элемете как точка :(
   video_buffer[x+y*mempitch] = color;

Заранее благодарствую за помошь!


 
Sapersky ©   (2003-09-30 09:27) [1]

Короче. Не вдаваясь в эту сишную бурду:

Var pb : PByte;
   ddsd : TDDSurfaceDesc2;

surf.Lock(nil,ddsd,0,0);
// surf - поверхность 8 бит, так?

For i:=0 to 1000 do begin
 x:=Random(640); y:=Random(480);
 pb:=ddsd.lpSurface; Inc(pb, y * ddsd.lPitch + x);
 pb^:=Random(255);
end;

surf.Unlock(nil);


 
Zergling ©   (2003-10-07 11:06) [2]

Чего то у меня не выходит, поэтуму кидаю все.
Помогите начинающему в этом деле сдвинуться с мертвой точки.
Заранее благодарен за помощь!

Const
 WW = 640;
 WH = 480;

var
 WC: WNDCLASSEX;       // Класс окна
 WC_HWND: HWND = 0;    // Дескриптор окна
 WC_MSG: TMsg;         // Сообщение окна
 WC_HDC: HDC = 0;      // Контекст графического устройства
 WC_Rect: TRect;
 WC_PRect: PRect;
 SrtTimes: Cardinal;
 DXRep: TStringList;

{ DirectX }

 // Интерфейс DirectX 7
 DD7: IID_IDirectDraw7 = Nil;
 // Поверхность DirectDraw 7
 DDSurface: IID_IDirectDrawSurface7 = Nil;
 // Первичная поверхность
 DDSf: DDSURFACEDESC2;

 // Палитра на 256 цветов
 DDPal: IID_IDirectDrawPalette = Nil;
 // Массив цветов
 Palette: Array [0..255] of tagPALETTEENTRY;

// Заполнение палитры цветами
Procedure SetColorPalette;
 var
   I: Integer;
begin
 // Заполнение палитры
 for I := 1 to 254 do
   with Palette[I] do
   begin
     peRed := Random(256);
     peGreen := Random(256);
     peBlue := Random(256);
     // Не оптимизировать палитру
     peFlags := PC_NOCOLLAPSE;
   end;
 with Palette[0] do
 begin
   peRed := 0;
   peGreen := 0;
   peBlue := 0;
   peFlags := PC_NOCOLLAPSE;
 end;
 with Palette[255] do
 begin
   peRed := 255;
   peGreen := 255;
   peBlue := 255;
   peFlags := PC_NOCOLLAPSE;
 end;
end;

function Finalization_Game: Boolean;
begin
 Result := True;
 try
   DXRep.SaveToFile("C:\DX.TXT");
   DXRep.Free;  
   DD7 := Nil;
   DDSurface := Nil;
   DDPal := Nil;
 except
   Result := False;
 end;
end;

function Initialization_Game: Boolean;
begin
 Result := True;
 try
   DXRep := TStringList.Create;
   SetColorPalette;
   // Создание интерфейса DirectX 7
   if DirectDrawCreateEx(Nil, DD7, IID_IDirectDraw7, Nil) <> DD_OK then DXRep.Add("DirectDrawCreateEx");
   // Выбор выдекарты по умолчанию
   if DD7.SetCooperativeLevel(WC_HWND, DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE or DDSCL_ALLOWMODEX or DDSCL_ALLOWREBOOT)  <> DD_OK then DXRep.Add("SetCooperativeLevel");
   // Установка видео режима
   if DD7.SetDisplayMode(WW, WH, 8, 0, 0) <> DD_OK then DXRep.Add("SetDisplayMode");
   // Заполнение описания первичной поверхности
   ZeroMemory(@DDSf, SizeOf(DDSf));
   with DDSf do
   begin
     dwSize := SizeOf(DDSf);
     // Задание поле (высота и ширина по умолчанию)
     dwFlags := DDSD_CAPS;
     // Запрос первичной поверхности
     ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;
   end;
   // Создание первичной поверхности
   if DD7.CreateSurface(DDSf, DDSurface, Nil) <> DD_OK then DXRep.Add("CreateSurface");
   // Содание палитры
   if DD7.CreatePalette(DDPCAPS_8BIT or DDPCAPS_ALLOW256 or DDPCAPS_INITIALIZE, @Palette, DDPal, Nil) <> DD_OK then DXRep.Add("CreatePalette");
   // Присоединение палитры к первичной поверхности
   if DDSurface.SetPalette(DDPal) <> DD_OK then DXRep.Add("SetPalette");
 except
   Result := False;
   Finalization_Game;
 end;
end;

// Рисование точек
procedure DrawPixels;
 var
   I, X, Y: Integer;
   PB : PByte;
begin
 For I := 0 to 1000 do
 begin
   X := Random(WW); Y := Random(WH);
   PB := DDSf.lpSurface;
   Inc(PB, X + Y * DDSf.lPitch);
   PB^ := Random(255);
 end;
end;

// Обработка сообщений Windows
function WndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
 Result := 0;
 case uMsg of

   WM_DESTROY:
   begin
     Finalization_Game;
     // Посылка сообщения в очередь о закрытии приложения
     PostQuitMessage(0);
     EXIT;
   end;
 end;
 // Если сообщение не обработанной, то посылаем его окну для обработки по умолчанию
 Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
end;

// Основная программа
Begin
 // Заполнение свойств класса окна
 with WC do
 begin
   cbSize := SizeOf(WNDCLASSEX); // Размер структуры
   style := CS_HREDRAW or CS_VREDRAW or CS_OWNDC or CS_DBLCLKS; // Стили окна
   lpfnWndProc := @WndProc; // Процедура для обработки сообщений
   cbClsExtra := 0;  // Дополнительные параметры
   cbWndExtra := 0;  // Дополнительные параметры
   hInstance := hInstance; // Дескриптор окна
   hIcon := LoadIcon(0, IDI_APPLICATION); // Иконка окна
   hCursor := LoadCursor(0, IDC_ARROW); // Курсор окна
   hbrBackground := HBRUSH(GetStockObject(BLACK_BRUSH)); // Фоновый цвет кисти окна
   lpszMenuName := Nil; // Меню окна
   lpszClassName := "WC_1";  // Имя класса окна
   hIconSm := LoadIcon(0, IDI_APPLICATION);  // Иконка окна (на панели задач)
 end;
 // Регистрация класса окна
 RegisterClassEx(WC);
 // Создание окна
 WC_HWND := CreateWindowEx
 (0, // Дополнительные стили окна
 "WC_1", // Имя класса по образу которого создается окно
 "Тестовая форточкка", // Заголовок окна
 WS_POPUP or WS_VISIBLE,  // Стиль окна
 0, // Позиция по Х (Left)
 0, // Позиция по Y (Top)
 WW, // Ширина окна (Width)
 WH, // Высота окна (Height)
 0,  // Дескриптор родительского окна (если оно есть)
 0,  // Дескриптор меню окна
 HInstance, // Дескриптор экземляра приложения
 nil); // Указатель на параметры создания окна
 // Если окно не созданно, то выходим
 if WC_HWND = 0 then Halt(1);
 // Цикл для ловли и обработки сообщений
 Initialization_Game;
 DrawPixels;
 While GetMessage(WC_MSG, 0, 0, 0) do
 begin
   SrtTimes := GetTickCount;
   // Преобразование клавиатурного ввода
   TranslateMessage(WC_MSG);
   // Посылка сообщения в процедуру обработки сообщений (WndProc)
   DispatchMessage(WC_MSG);
   // Отлавливаем состояние нажатия клавиши ESCAPE
   if Boolean(GetAsyncKeyState(VK_ESCAPE) shr 16) then SendMessage(WC_HWND, WM_DESTROY, 0, 0);
   while GetTickCount - SrtTimes < 33 do
 end;
 // Уничтожаем окно
 DestroyWindow(WC_HWND);
End.


 
cyborg ©   (2003-10-07 11:14) [3]

Что именно не получается?
Чего-то не вижу где у тебя DrawPixels; в программе вызывается? Где Lock и Unlock поверхности? Перед прямой записью в поверхность её нужно блокировать!


 
Zergling ©   (2003-10-07 11:28) [4]

Перед главным циклом программы
Initialization_Game;
DrawPixels;

Lock и UnLock забыл т.к. заного набивал (чтоб без мусора), шас еще попробую.


 
Zergling ©   (2003-10-07 11:35) [5]

Не получается такая приметивщина как рисование точек :( (стыдно даже). Рисование точек в случайном месте, случайным цветом. У меня черный экран, ни чего не рисуется. Что нетак??? Все стараюсь делать по книге.

// Рисование точек
procedure DrawPixels;
 var
   I, X, Y: Integer;
   PB : PByte;
begin
 DDSurface.Lock(Nil, DDSf, 0, 0);
 For I := 0 to 1000 do
 begin
   X := Random(WW); Y := Random(WH);
   PB := DDSf.lpSurface;
   Inc(PB, X + Y * DDSf.lPitch);
   PB^ := Random(255);
 end;
 DDSurface.UnLock(Nil);
end;


 
cyborg ©   (2003-10-07 11:50) [6]

Пришли мне на мыло свои dpr и pas.
cyborg @ hotbox . ru
А то тут неудобно читать.


 
Sapersky ©   (2003-10-07 12:05) [7]

Первичную поверхность нужно создавать как палитровую. Вроде так:

dwFlags := DDSD_CAPS or DDSD_PIXELFORMAT;
ddpfPixelFormat.Size:=SizeOf(TDDPixelFormat);
ddpfPixelFormat.dwFlags:=DDPF_RGB or DDPF_PALETTEINDEXED8;
ddpfPixelFormat.dwRGBBitCount:=8;
ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;

Хотя не тестировал.
А может, ну его нафиг, этот палитровый режим? В TrueColor попроще будет.


 
Zergling ©   (2003-10-07 12:09) [8]

cyborg ©  (07.10.03 11:50) [6]

Отправил. Ждемс ответа :)


 
Zergling ©   (2003-10-07 12:10) [9]

Sapersky ©  (07.10.03 12:05) [7]

Ща похимичем, проверим.


 
Zergling ©   (2003-10-07 12:18) [10]

Sapersky ©  (07.10.03 12:05) [7]

Программа виснет. Песочные часики однако.

> А может, ну его нафиг, этот палитровый режим? В TrueColor попроще будет.

Делаю все попарядку, дабы знать и понимать основы DirectX. Без этого ни как!

>  В TrueColor попроще будет.
Может и да. Еще не пробовал.


 
cyborg ©   (2003-10-07 12:34) [11]

Всё у тебя работает, только окно очищается быстро, перенеси DrawPixels; в

 While GetMessage(WC_MSG, 0, 0, 0) do
 begin
   SrtTimes := GetTickCount;
   // Преобразование клавиатурного ввода
   TranslateMessage(WC_MSG);
   // Посылка сообщения в процедуру обработки сообщений (WndProc)
   DispatchMessage(WC_MSG);
   // Отлавливаем состояние нажатия клавиши ESCAPE
   if Boolean(GetAsyncKeyState(VK_ESCAPE) shr 16) then SendMessage(WC_HWND, WM_DESTROY, 0, 0);
   DrawPixels;
   while GetTickCount - SrtTimes < 33 do
 end;

Только при выходе из программы ошибка вылазит.


 
cyborg ©   (2003-10-07 12:46) [12]

Чтобы ошибка не вылезала сделай проверку:
procedure DrawPixels;
 var
   I, X, Y: Integer;
   PB : PByte;
begin
 if DDSurface=nil then exit;


 
Zergling ©   (2003-10-07 13:09) [13]

cyborg ©  (07.10.03 12:34) [11]

> // Отлавливаем состояние нажатия клавиши ESCAPE
> if Boolean(GetAsyncKeyState(VK_ESCAPE) shr 16) then SendMessage(WC_HWND, WM_DESTROY, 0, 0);
>  DrawPixels;

И с этим я парился столько дней! Ужжааасссс!!!

И еще вопросик назрел. Изображение обновляется, только тогда когда мышь движется в клиенткой части окна. У автора в примере нет ни чего по обновлению клиенсткой части экрана :(. Просто процедурка типа DrawPixels крутится в главном цикле. Наверно нужно применять в процедуре DrawPixels DDSurface.Flip() или применять InValidateRect, ValidateRect? Чтобы обновление изображения присходило постоянно. Применил DDSurface.Flip() но результат тотже.
DDSurface.Flip(Nil, DDFLIP_WAIT);
Может чегото не то?


 
cyborg ©   (2003-10-07 13:19) [14]

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


Var QuitProgram : Boolean = false;

...

// Обработка сообщений Windows
function WndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
 Result := 0;
 case uMsg of

   WM_DESTROY:
   begin
     Finalization_Game;
     // Посылка сообщения в очередь о закрытии приложения
     PostQuitMessage(0);
     EXIT;
   end;
   WM_CHAR : //Клавиша нажата
     Begin
       case wParam of
       27 : //Нажата клавиша Escape
         Begin
          QuitProgram:=True; //Выйти
         End;
       end;//case wParam
     End;
    else
   // Если сообщение не обработанной, то посылаем его окну для обработки по умолчанию
   Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
 end;
end;

...
 Repeat
   if PeekMessage(Mesg,WindowHandle,0,0,PM_REMOVE) then
   begin
     TranslateMessage(Mesg); DispatchMessage(Mesg);
   end;
   DrawPixels;
 Until QuitProgram;


Вот насочинял, надеюсь без ошибок :)


 
Zergling ©   (2003-10-07 13:39) [15]

cyborg ©  (07.10.03 13:19) [14]

Про сообщения я в курсе :). Просто у автора например:

case WM_PAINT:
 {
 // simply validate the window
       hdc = BeginPaint(hwnd,&ps);  
       
       // end painting
       EndPaint(hwnd,&ps);

       // return success
 return(0);
    } break;
А проседура рисования в основном цикле вертится.
И ресует же гадина без перерыва.
По книге он обещает, раз поверность первичная, то точки рисуются на прямую в область выделенной видео памяти.

Чуствую попарюсь я с этой книгой :)
Вопрос задал потому, что изображение как обнавлять средсвами DirectDraw или можно использовать средства GDI.


 
cyborg ©   (2003-10-07 13:54) [16]

Обновлять средствами DirectDraw так: DDSurface.Flip();
Что и как ты будешь использовать это твоя проблема. Если делаешь программу под DirectDraw, про GDI лучше забудь из за тормознутости по сравнению с ... :).

Я знаю какая книга у тебя :) - Программирование игр для виндоуз второе издание (Андре Ламот).

WM_PAINT стоит обрабатывать только тогда, когда у тебя не постоянно отрисовывается экран, в случае же, когда он рисуется в цикле программы постоянно, с фиксированными кадрами или без, то обрабатывать WM_PAINT не нужно.


 
Zergling ©   (2003-10-07 14:03) [17]

А как по оптимальному пути правильно будет?

Я использую InValidateRect и WM_PAINT
С точки зрниния DirectX как правельней реализовать?


 
cyborg ©   (2003-10-07 14:29) [18]

Как правильней сказать не могу, так как сам многого не знаю, как у тебя получится, начит так правильней :). А рисование можно по разному реализовывать, в основном цикле программы, по таймеру, в другом потоке и пр. смотря как ты умеешь и что для твоей программы подходит/нужно.

DirectX пофиг где будет вызываться Flip, лижь бы он вызывался правильно.


 
Zergling ©   (2003-10-08 05:51) [19]

Всем спасибо!!! С мертвой точки сдвинулся. Теперь дальше будем изучать DirectX. :-)


 
_designer_   (2003-10-08 11:25) [20]

Народ, вы тут про DX заговорили.... Был у меня один вопросик по этому поводу...
Кто-нть из вас юзал DrawAlpha? Он у меня глючит по-страшному!!!


 
Советчик   (2003-10-08 18:34) [21]

Как указатель на область памяти превратился в массив (не доходит до меня эта запись)?
В си массив и указатель имеют много общего.

char arr[10]; //объявление массива

arr[0] = "x";
cout << *arr; //напечатает x, т.к. имя массива это указатель на  первый элемент массива.


 
_designer_   (2003-10-09 10:19) [22]

Вот нашел мессагу:

Делаю DirectDrawSurface.FillRectAlpha(..., Value, AlphaValue)
Value = $0f0f0f, в зависимости от AlphaValue результат получается либо никакой (AlphaValue = 0) либо ЗЕЛЕНЫЙ (AlphaValue > 0) В чем прикол? Почему AlphaBlend Серым по белому ЗЕЛЕНЫЙ?



Страницы: 1 вся ветка

Форум: "Игры";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.038 c
1-1079711005
Cosinus
2004-03-19 18:43
2004.04.11
Меню для иконки в трее


7-1075198334
Shurik_212
2004-01-27 13:12
2004.04.11
Кто положил файл?


1-1079939246
SergeyV
2004-03-22 10:07
2004.04.11
Вызыв консольного окна из своей программы


3-1081854872
Andriano
2004-04-13 15:14
2004.04.11
1С-подобный генератор отчетов


6-1076158181
KalmykovSergei
2004-02-07 15:49
2004.04.11
Управление ICQ





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский