Direct3D 8 (переход от Delphi)

Модератор: Модераторы

Сообщение @lex » 24.06.2006 15:19:02

Пишет: BEGIN excepted but INTERFACE found :(

А при использовании FORWARD:
Если не писать implementation, то опять куча "function nesting >31"
А если написать: BEGIN excepted but IMPLEMENTATION found :( :(
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение Sergei I. Gorelkin » 24.06.2006 15:45:27

interface и implementation нужно писать только один раз...
Короче говоря, вот пример:

Код: Выделить всё
unit Test1;

interface
// эта процедура будет доступна извне модуля
procedure f1(A: Integer);

implementation

// а  эта - не будет.
procedure f2(A, B, C: Integer); forward;

procedure f1(A: Integer);
begin
  // здесь уже можно вызывать f2
  f2(A, 0, 1);
end;

procedure f2(A,B,C: Integer);
begin
  // собственно текст процедуры
end;

end.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1395
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение @lex » 24.06.2006 19:08:45

Спасибо!
Я так понял, что суть в том чтобы после каждого такого "предварительного" определения функции нужно прописывать "forward;"
Последний раз редактировалось @lex 03.07.2006 16:13:36, всего редактировалось 1 раз.
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение @lex » 26.06.2006 20:13:02

Наткнулся на такой вот прикол:
Код: Выделить всё
DTVertex = packed record
    X,Y,Z,RHW: Single;
    U, V : Single;
  end;

...

procedure TForm1.draw_tex;
var
vtx:^DTVertex;
...
vtx.X:= ... //Тут возникает ошибка ?!?!

(Троеточия это пропуск кода :) )
Действия правда происходят в Лазарусе, но тут ему "^" чтоли не нравится, как быть?
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение @lex » 07.07.2006 11:34:14

Не подскажите что сделать с вышезаданным вопросом ? :) ?

И ещё, вы мне посоветовали скачать новые библиотеки DirectX, я нашёл DirectX_92 чисто для FP, там даже, насколько я понял, есть библиотека для Direct3D8, но в старых был файл DirectXGraphics.pas, который собственно и надо было подключать. А тут его нет! Я указал вместо него DSirect3d8.pas, всё вроде нормально, только возникла данная ошибка... :(
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение Mirage » 07.07.2006 15:04:11

@lex писал(а):Наткнулся на такой вот прикол:
Код: Выделить всё
procedure TForm1.draw_tex;
var
vtx:^DTVertex;
...
vtx.X:= ... //Тут возникает ошибка ?!?!


Надо vtx^.X := ...

А также документацию почитать.
Если в Лазаре нет - ставь Дельфу и читай хелп.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Сообщение pda » 08.07.2006 02:58:42

В делфе может и ненайти. Там, чуть ли на с первой версии такая "фича" появилась, когда компилятор решил стать "шибко умным" и сам разименовывать указатели... ;-)
Аватара пользователя
pda
постоялец
 
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение @lex » 08.07.2006 16:47:31

Не, ну в Делфях это всё работало (писал по книге Краснова). В любом случае many thanks! :)
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение @lex » 11.07.2006 15:19:43

Люди, можно маленький тупой вопросик:
Как из трёх byte слепить один TColor :?:
В байтах записаны R,G,B :) ...
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение Sergei I. Gorelkin » 11.07.2006 19:23:10

Либо сдвигами:

Код: Выделить всё
rgbValue := (Byte(R) shl 16)  or (Byte(G) shl 8) or Byte(B);


либо с помощью вариантной записи (или как там ее правильно называть):

Код: Выделить всё
var
  rec: LongRec;
begin
  rec.Bytes[0] := B;
  rec.Bytes[1] := G;
  rec.Bytes[2] := R;
  rec.Bytes[3] := 0;
  rgbValue := TColor(rec);
end;


порядок R,G и B, возможно, придется поменять - смотря где потом будет использоваться полученный цвет.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1395
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение @lex » 13.07.2006 15:19:16

Спасибо!
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение @lex » 17.07.2006 11:22:23

Вернулся к вопросу о handle окна приложения. Конечно изначально я не ожидал ничего хорошего от того что поставлю там ноль (где интересно он собирался рисовать ? :) ). Наткнулся на одно IDE, под названием Dev-Pas, судя по всему уже мёртвое (версия 2002 г. , компилятор 1.0.6), но тем не менее она не отказалось работать с версией 2.0.2, причём весьма успешно. При создании "Windows Application" генерирует код, если я правильно понял, создания и инициализации окна:
Код: Выделить всё
program WindowsApp;
{$MODE DELPHI}
uses Windows;

const AppName = 'WindowsApp';
function WindowProc(Window: HWnd; AMessage, WParam,
          LParam: Longint): Longint; stdcall; export;

begin
  WindowProc := 0;

  case AMessage of
    wm_Destroy : begin
                   PostQuitMessage(0);
                   Exit;
                 end;
  end;

  WindowProc := DefWindowProc(Window, AMessage, WParam, LParam);
end;

{ Register the Window Class }
function WinRegister: Boolean;
var WindowClass: WndClass;
begin
  WindowClass.Style := cs_hRedraw or cs_vRedraw;
  WindowClass.lpfnWndProc := WndProc(@WindowProc);
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := system.MainInstance;
  WindowClass.hIcon := LoadIcon(0, idi_Application);
  WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := AppName;
  Result := RegisterClass(WindowClass) <> 0;
end;

{ Create the Window Class }
function WinCreate: HWnd;
var hWindow: HWnd;
begin
  hWindow := CreateWindow(AppName, 'Windows App',
         ws_OverlappedWindow, cw_UseDefault, cw_UseDefault,
         cw_UseDefault, cw_UseDefault, 0, 0, system.MainInstance, nil);

  if hWindow <> 0 then begin
     ShowWindow(hWindow, CmdShow);
     UpdateWindow(hWindow);
  end;

  Result := hWindow;
end;

var AMessage: Msg;
    hWindow: HWnd;

begin
  if not WinRegister then begin
     MessageBox(0, 'Register failed', nil, mb_Ok);
     Exit;
  end;

  hWindow := WinCreate;
  if longint(hWindow) = 0 then begin
     MessageBox(0, 'WinCreate failed', nil, mb_Ok);
     Exit;
  end;

  while GetMessage(@AMessage, 0, 0, 0) do begin
    TranslateMessage(AMessage);
    DispatchMessage(AMessage);
  end;
  Halt(AMessage.wParam);
end.

Чесно говоря, я нечто подобное вижу впервые (Дельфи всё это делал сам и ничего не показывал), но вместо handle прописал hWindow, и программа вобщем-то запустилась (с нулём выдавала Access Violation). Последный цикл (while), насколько я понял, всю "сознательныю жизнь" программы обрабатывает сообщения, я немного преобразовал его:
Код: Выделить всё
while true do begin
   Timer; //это как-бы TTimer.OnTimer :)
   if not GetMessage(@AMessage, 0, 0, 0) then break;
   if halted then break;
   sleep(GSpeed); // "Ограничение FPS" GSpeed = 1;
   TranslateMessage(AMessage);
   DispatchMessage(AMessage);
   end;
closefile(logfile);
Halt(AMessage.wParam)
end.

В результате программа запускается, переходит в полноэкранный режим и ничего не делает, но сразу же закрывается по Alt+F4.
Осмелюсь предположить, что "виснет" она на функции GetMessage, может есть какая-нибудь функция, проверяющая наличие сообщений а не ожидающая их получения ? :)
Хотя возможно я тут вовсе не прав :roll:
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение Sergei I. Gorelkin » 17.07.2006 13:01:07

Функция, проверяющая наличие сообщений без ожидания - это PeekMessage().
Однако же в стандартном цикле обработки сообщений ее использовать не следует - это даст только ненужную загрузку процессора. Чтобы рисовать по таймеру, нужно:
1. После создания окна вызвать для него SetTimer. После этого Windows начнет посылать сообщения WM_TIMER с заданной периодичностью.
2. В обработчик сообщений (это который WindowProc) добавить обработку WM_TIMER и уже там рисовать.
3. (в идеале) Чтобы попусту не грузить процессор, таймер нужно останавливать, если пользователь переключился в другое приложение, и запускать снова при активации своего.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1395
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение @lex » 17.07.2006 13:38:06

Спасибо, буду пробовать! Однако в случае перключения в другое приложение возникает проблема с восстановлением DirectX, поэтому я сделал проще - просто закрываю программу :) . Побочный эффект: защита от ArtMoney :D
А стандартный таймер для перерисовки не очень подходит, потому как например в Windows 9x, ME он работает очень медленно.
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Сообщение @lex » 17.07.2006 21:57:55

Всё сработало, благодарю всех за отзывы!
@lex
постоялец
 
Сообщения: 180
Зарегистрирован: 19.06.2006 13:16:29
Откуда: Невинномысск

Пред.

Вернуться в Графика

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

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

Рейтинг@Mail.ru