Форум: "Игры";
Текущий архив: 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.04 c