Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.11;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.031 c
1-1082687621
saysu
2004-04-23 06:33
2004.04.11
Казахские шрифты в самом инструменте как добавить


7-1076261532
rentgen
2004-02-08 20:32
2004.04.11
Desktop


14-1079261639
Kobik
2004-03-14 13:53
2004.04.11
Dll, C++


8-1071045370
типа я
2003-12-10 11:36
2004.04.11
Нет длльки OpenGL.dll


14-1079744422
Dudao
2004-03-20 04:00
2004.04.11
Чистка кода