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

Вниз

Проблема с класом движка   Найти похожие ветки 

 
beginerProger   (2007-03-24 07:51) [0]

Проблема с класом движка

Пишу движок. Значит сделал пока процедуры старта окна, инициализации
OpenGL, вывод текста на екран и тайминг. Всё это в отдельном модуле и одном класе

TEngine = class
 ....
end;

Делаю простой пример. Создаю консольное приложение.
ПИшу процедуру  рендеринга и обновлений.

program test;

uses
 windows, openGL, engine;

var
 engine: TENG;

procedure Rendering;
begin
 WriteText(1,1,"www") ;
end;

procedure Update;
begin
 
end;

begin
 Engine := TEng.Create;
 Engine.OnInit   := Init;
 Engine.StartEngine("Semple1",800,600,32,32,0,false);  
 Engine.OnRender := Render;
 Engine.OnUpdate := Update;
 Engine.Loop(50);
end.

Всё идёт нормально ,но если я например создаю отдельный модуль и вызываю например
процедуру  
 WriteText(1,1,"www") ;
то выбивает ошибку
 Error
Runtime Error 216 at 00404c62

почему и как єто исправить?


 
DJ KARIES   (2007-03-24 10:34) [1]

Приведи исходники модулей.
А вообще, судя по коду ошибки 216, это Access violation.
Скорее всего вызов метода несозданного объекта.


 
beginerProger   (2007-03-24 10:53) [2]

Да действительно я тоже так думаю. А как должно быть. как нужно объявлять класс


 
DJ KARIES   (2007-03-24 16:18) [3]

Для начала вот перво несоответствие:

TEngine = class
....
end;

var
engine: TENG;

Без исходного кода трудно что-то сказать.


 
beginerProger   (2007-03-24 21:00) [4]

// ########  Модуль движка   ########
unit eng_core;

interface

uses
 windows, messages, OpenGL, eng_utilits;

const
 // Типы задания координат
 COORD2D          = 0;
 COORD3D          = 1;
 COORD_RESTORE    = 2;

type
 TOnRender = procedure;
 TOnUpdate = procedure;
 TOnInit = procedure;

type
 TInput = record
   Keys: array [0..255] of boolean;
 end;

type
  TGLRenderDevice = class;
{================================== Engine ====================================}
 TEngine = class
 private
   FOnRender: TOnRender;
   FOnUpdate: TOnUpdate;
   FOnInit: TOnInit;
 public
   constructor Create;
   destructor  Destroy;
 public
   procedure StartEngine(name: PChar; width, height: integer; depth, bpp, stencil: integer; FullScreen: boolean = false);
   procedure Loop(UPS:integer);
   procedure Quit;
   procedure SetCoord(Flag: byte);
   procedure Begin2D;
   procedure End2D;
   procedure Begin3D;
   procedure End3D;
   procedure RenderingBegin;
   procedure RenderingEnd;
   //time
   function GetTime: integer;
   procedure ResetTimer;
   //font
   procedure BuildFont(name: pChar);
   procedure glWrite( X, Y : GLUint; text: PChar; color: integer);
   procedure KillFont();

   function FPS: integer;

   property OnRender: TOnRender read FOnRender write FOnRender;
   property OnUpdate: TOnUpdate read FOnUpdate write FOnupdate;
   property OnInit: TOnInit read FOnInit write FOnInit;

 public
   RenderDevice: TGLRenderDevice;
   h_wc:  WndClassEX;
   h_wnd: HWND;
   m_msg: TMSG;
   //gl
   h_dc: HDC;
   h_rc: HGLRC;
   eFullScreen: boolean;
   ups_time_old: integer;
   ups_time: integer;
   fps_time: Integer;
   fps_cur:  Integer;
//    FPS:      Integer;
   _FPS: integer;
   Time, Time_delta: integer;
   baseFont : uint;
 end;
{====================================== GL ====================================}
 TGLRenderDevice = class
 private
   h_rc: HGLRC;
   h_dc: HDC;
   PixelFormat: gluINT;
   GLWND: TEngine;
 public
   procedure Init(var GLWind: TEngine);
   procedure Clear;
   procedure SwapBuffer;
   procedure Finalize;
 end;

var

 eng: TEngine;
 EENG : ^TEngine;
 GL: TGLRenderDevice;
 ewidth,eheight: integer;
 finished: boolean;
 input: TInput;
 CoordNow : byte;
 CoordLast : byte;

implementation

//------------------------------------------------------------------------------
constructor TEngine.Create;
begin
 finished := false;
end;
//------------------------------------------------------------------------------
destructor TEngine.Destroy;
begin
 Quit;

 DestroyWindow(h_wnd);
 UnRegisterClass("Dream",hInstance);
 RenderDevice.Finalize;

 wglMakeCurrent(0, 0);
 wglDeleteContext(h_RC);
 ReleaseDC(h_Wnd, h_DC);

 if eFullscreen then ChangeDisplaySettings(TDevMode(nil^), CDS_FULLSCREEN);

end;
//------------------------------------------------------------------------------
// Изменение размеров окна
procedure ResizeWin( Width, Height : integer );
begin
 eWidth := Width;
 eHeight := Height;

 glViewport(0, 0, eWidth, eHeight);    // Установить порт отображения
 glMatrixMode(GL_PROJECTION);          // Установить матрицу проекции
 glLoadIdentity();                     // Востановить
 //  gluPerspective(45.0, eWidth/eHeight, 0.1, 100.0);
 glFrustum( -( eWidth/eHeight ), ( eWidth/eHeight ), -1, 1, 1.0, 100.0 );

 glTranslatef( 0.0, 0.0, -2.0 );
 glMatrixMode(GL_MODELVIEW);           // Установить матрицу отображения
 glLoadIdentity();
 CoordNow := COORD3D;
end;
//------------------------------------------------------------------------------
function WindowProc(_wnd: HWND; _msg:integer; wparam: wparam; lparam: lparam):lresult;stdcall;
begin
 case _msg of
 WM_CREATE:begin  end;
 WM_DESTROY: begin PostQuitMessage(0); Result:= 0; eng.Free;  exit; end;
 WM_KEYDOWN: begin Input.keys[wparam] := true; end;
 WM_KEYUP:   begin Input.keys[wparam] := false; end;
 WM_PAINT:   begin
               glClear(GL_DEPTH_BUFFER_BIT OR GL_COLOR_BUFFER_BIT);
               glClearColor(0,0,0,0);
               ValidateRect(_wnd,nil); result := 0; exit;
             end;
 WM_SIZE:    begin ResizeWin(loword(lparam),hiword(lparam)); end;
 end;
 Result := DefWindowProc(_wnd,_msg,wparam,lparam);
end;


 
beginerProger   (2007-03-24 21:01) [5]

//------------------------------------------------------------------------------
procedure TEngine.StartEngine(name: PChar; width, height: integer; depth, bpp, stencil: integer; FullScreen: boolean = false);
var
 dwStyle: DWORD;   // Стиль окна
 dwExStyle: DWORD; // Стиль окна
 dmScreenSettings : DEVMODE;
 pfd: TPixelFormatDescriptor;
 nPixelFormat: Integer;
begin
 ewidth := width;
 eheight:= height;
 ZeroMemory(@h_wc,SizeOf(h_wc));
 h_wc.style        := CS_HREDRAW OR CS_VREDRAW OR CS_OWNDC;
 h_wc.cbSize       := sizeof(h_wc);
 h_wc.lpfnWndProc  := @WindowProc;
 h_wc.hInstance    := hInstance;
 h_wc.hbrBackground:= COLOR_BTNFACE+1;
 h_wc.hCursor      := LoadCursor(0,IDC_ARROW);
 h_wc.lpszClassName:= "Dream";

 if (RegisterClassEX(h_wc) = 0) then begin MessageBox(0,"Невозможно зарегестрировать класс окна","Error",MB_OK); exit; end;

  // Изменение режима екрана
 if Fullscreen then
 begin
   eFullScreen := fullscreen;
   ZeroMemory(@dmScreenSettings, SizeOf(dmScreenSettings));
   with dmScreenSettings do begin              // Установления параметров екрана
     dmSize       := SizeOf(dmScreenSettings);
     dmPelsWidth  := Width;                    // Ширина окна
     dmPelsHeight := Height;                   // Высота окна
     dmBitsPerPel := Depth;                    // Глубина цвета
     dmFields     := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL;
   end;

   // Установить полноекраный режим
 if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN) = DISP_CHANGE_FAILED) then
   begin
     MessageBox(0, "Невозможно перейти в полноекранный режим", "Error", MB_OK or MB_ICONERROR);
     Fullscreen := False; eFullScreen := fullscreen;
   end;
 end;

 if (FullScreen) then
 begin
   dwStyle   := WS_POPUP OR WS_CLIPCHILDREN OR WS_CLIPSIBLINGS;
   dwExStyle := WS_EX_APPWINDOW;
   ShowCursor(False);
   eFullScreen := fullscreen;
 end
 else
 begin
   dwStyle   :=  WS_SYSMENU OR WS_MINIMIZEBOX OR WS_CLIPCHILDREN OR WS_CLIPSIBLINGS; // <-- Updated 29.12.2006
   dwExStyle := WS_EX_APPWINDOW OR WS_EX_WINDOWEDGE;
   ShowCursor(true);
   eFullScreen := fullscreen;
 end;

 h_wnd := CreateWindowEX(dwExStyle,"Dream",name,dwStyle,0,0,Width,Height,0,0,hInstance,nil );
 h_dc := GetDC(h_wnd);

 with pfd do
 begin
   nSize := SizeOf(TPixelFormatDescriptor); // размер структуры
   nVersion := 1;                            // номер версии
   dwFlags := PFD_DOUBLEBUFFER or PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL; // множество битовых флагов, определяющих устройство и интерфейс
   iPixelType := PFD_TYPE_RGBA; // режим для изображения цветов
   cColorBits := bpp;            // число битовых плоскостей в каждом буфере цвета
   cRedBits := 0;               // число битовых плоскостей красного в каждом буфере RGBA
   cRedShift := 0;              // смещение от начала числа битовых плоскостей красного в каждом буфере RGBA
   cGreenBits := 0;             // число битовых плоскостей зелёного в каждом буфере RGBA
   cGreenShift := 0;            // смещение от начала числа битовых плоскостей зелёного в каждом буфере RGBA
   cBlueBits := 0;              // число битовых плоскостей синего в каждом буфере RGBA
   cBlueShift := 0;             // смещение от начала числа битовых плоскостей синего в каждом буфере RGBA
   cAlphaBits := 0;             // число битовых плоскостей альфа в каждом буфере RGBA
   cAlphaShift := 0;            // смещение от начала числа битовых плоскостей альфа в каждом буфере RGBA
   cAccumBits := 0;             // общее число битовых плоскостей в буфере аккумулятора
   cAccumRedBits := 0;          // число битовых плоскостей красного в буфере аккумулятора
   cAccumGreenBits := 0;        // число битовых плоскостей зелёного в буфере аккумулятора
   cAccumBlueBits := 0;         // число битовых плоскостей синего в буфере аккумулятора
   cAccumAlphaBits := 0;        // число битовых плоскостей альфа в буфере аккумулятора
   cDepthBits := depth;            // размер буфера глубины (ось z)
   cStencilBits := stencil;           // размер буфера трафарета
   cAuxBuffers := 0;            // число вспомогательных буферов
   iLayerType := PFD_MAIN_PLANE;// тип плоскости
   bReserved := 0;              // число плоскостей переднего и заднего плана
   dwLayerMask := 0;            // игнорируется
   dwVisibleMask := 0;          // индекс или цвет прозрачности нижней плоскости
   dwDamageMask := 0;           // игнорируется
 end;

 nPixelFormat := ChoosePixelFormat( H_DC, @pfd ); // запрос системе - поддерживается ли выбранный формат пикселей
 SetPixelFormat( H_DC, nPixelFormat, @pfd );      // устанавливаем формат пикселей в контексте устройства

 RenderDevice := TGLRenderDevice.Create;
 RenderDevice.Init(self);

 ShowWindow(h_wnd,SW_SHOW); SetForegroundWindow(h_Wnd);

 if (Assigned(FOnInit)) then FOnInit;

end;
//------------------------------------------------------------------------------
procedure TGLRenderDevice.Clear;
begin
 glClear(GL_DEPTH_BUFFER_BIT OR GL_COLOR_BUFFER_BIT);
 glClearColor(0,0,0,0);
end;
//------------------------------------------------------------------------------
procedure TGLRenderDevice.Finalize;
begin
 wglDeleteContext(h_rc);
 ReleaseDC(GLWnd.h_wnd,GLWnd.h_dc);
end;
//------------------------------------------------------------------------------


 
beginerProger   (2007-03-24 21:02) [6]

procedure TGLRenderDevice.SwapBuffer;
begin
 SwapBuffers(h_dc);
end;
//------------------------------------------------------------------------------
procedure TGLRenderDevice.Init(var GLWind: TEngine);
begin
 GLWnd := GLWind;
 h_dc := GLWnd.h_dc;
 h_rc := wglCreateContext(h_dc);
 ReleaseDC( GLwnd.h_Wnd, h_DC );
 wglMakeCurrent( h_DC, h_rc);
end;
//------------------------------------------------------------------------------
// Задание кординатной системы
procedure TEngine.SetCoord( Flag : byte );
begin
 if CoordNow = Flag then exit;
 Case Flag of
   COORD2D : begin
     glPushMatrix();
     glMatrixMode(GL_PROJECTION);  // Установить проекционую матрицу
     glLoadIdentity();             // Очистить стек
     glOrtho(0, eWidth, 0, eHeight, 0, 100);
     glMatrixMode(GL_MODELVIEW);   // Установить матрицу отображения
     glLoadIdentity;
     glTranslatef( 0, 0, -1 );
   end;
   COORD3D : begin
     ResizeWin(eWidth, eHeight );
   end;
   COORD_RESTORE : begin
     SetCoord(CoordLast);
   end;
 end;
 if Flag <> COORD_RESTORE then
 begin
   CoordLast := CoordNow;
   CoordNow := Flag;
 end;
end;
//------------------------------------------------------------------------------
procedure TEngine.Begin2D;
begin
 SetCoord(COORD2D);
 glDisable(GL_DEPTH_TEST);
 glPushMatrix();
 glTranslatef( 0, 0, -1.0 );
end;
//------------------------------------------------------------------------------
procedure TEngine.End2D;
begin
 glPopMatrix();
 glEnable(GL_DEPTH_TEST);
 SetCoord(COORD_RESTORE);
end;
//------------------------------------------------------------------------------
procedure TEngine.Begin3D;
begin
 SetCoord(COORD3D);
 glEnable(GL_DEPTH_TEST);
 glPushMatrix();
 glTranslatef( 0, 0, -1.0 );
end;
//------------------------------------------------------------------------------
procedure TEngine.End3D;
begin
 glPopMatrix();
 glDisable(GL_DEPTH_TEST);
 SetCoord(COORD_RESTORE);
end;
//------------------------------------------------------------------------------
procedure TEngine.RenderingBegin;
begin
 glClearColor(0.0, 0.0, 0.0, 0.0); // Установить цвет окна
 glLoadIdentity();                 // Очистить стек
 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT);
end;
//------------------------------------------------------------------------------
procedure TEngine.RenderingEnd;
begin
RenderDevice.SwapBuffer;
GlFlush;
end;
//------------------------------------------------------------------------------
procedure TEngine.Quit;
begin
 finished := true;
end;
//------------------------------------------------------------------------------
function TEngine.GetTime: integer;
var
 T: LARGE_INTEGER;
 F: LARGE_INTEGER;
begin
 QueryPerformanceFrequency(Int64(F));
 QueryPerformanceCounter(Int64(T));
 Result:= Trunc(1000 * T.QuadPart / F.QuadPart);
end;

procedure TEngine.ResetTimer;
begin
 ups_time_old := GetTime;
end;

function TEngine.FPS: integer;
begin
 Result := _FPS;
end;
//------------------------------------------------------------------------------
procedure TEngine.Loop(UPS: Integer);
begin
//  finished := false;
 ups_time_old := GetTime - 1000 div UPS;
 ups_time := GetTime;
 fps_time := GetTime;

 while not finished do
 begin
   while PeekMessage(m_msg,0,0,0,PM_REMOVE) do
   begin
     if m_msg.message = WM_QUIT then finished := true else begin
       TranslateMessage(m_msg);
       DispatchMessage(m_msg);
     end;
   end;
   while GetTime - ups_time_old >= (1000 div ups) do
   begin
   if (Assigned(FOnUpdate)) then FOnUpdate;
   inc(ups_time_old, 1000 div ups);
   end;
   if (Assigned(FOnRender)) then FOnRender;
   RenderDevice.SwapBuffer;
   if fps_time <= GetTime then
   begin
     fps_time := GetTime + 1000;
     _FPS := fps_cur;
     fps_cur := 0;
   end;
   inc(fps_cur);

 end;
 Destroy;
end;
//------------------------------------------------------------------------------
// Создаём базовый текст
procedure TEngine.BuildFont(name: PChar);
var font : HFONT;
begin
 baseFont := glGenLists(255);
 font := CreateFont(-18, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE or DEFAULT_PITCH, name);
 SelectObject( h_DC, font );
 wglUseFontBitmaps( h_DC, 0, 256, baseFont );
end;
//------------------------------------------------------------------------------
// Рисуем текст
procedure TEngine.glWrite(X, Y: GLUint; text : PChar; color: integer);
begin
//  glColor3ub(0,20,250);
 SetColor(color);
 Y := eHeight-Y;
 glRasterPos2i(X, Y);
 glPushAttrib(GL_LIST_BIT);
 glListBase(baseFont);
 glCallLists(length(text), GL_UNSIGNED_BYTE, text);
 glPopAttrib();
end;
//------------------------------------------------------------------------------
// Удаляем базовый текст
procedure TEngine.KillFont();
begin
 glDeleteLists( baseFont, 255 );
end;
end.


 
beginerProger   (2007-03-24 21:03) [7]

// #####  Модуль примера для теста  #####  

unit TestU;

interface

uses
 windows, eng_core, eng_utilits;

procedure pr;

implementation

procedure pr;
begin
 EEng.glWrite(10,10,"www",1);
end;

end.


 
beginerProger   (2007-03-24 21:04) [8]

// #### Главная программа ##### //
program Semple1;

uses
 windows,
 messages,
 OpenGL,
 eng_core in "Engine\eng_core.pas",
 eng_utilits in "Engine\eng_utilits.pas",
 TestU in "TestU.pas";

var
 ENGsemple: TEngine;
 
procedure Init;
begin

end;

procedure Menu;
begin

ENGsemple.RederingBegin;
ENGsemple.begin2D;

pr;
ENGsemple.glWrite(50,500 - x1,"Engine",white);

ENGsemple.end2d;
ENGsemple.RenderingEnd;
end;

procedure Render;
begin
 Menu;
end;

procedure Update;
begin
if Input.Keys[27] = true then ENGsemple.Quit;
end;

begin
 ENGsemple := TEngine.Create;
 ENGsemple.OnInit   := Init;
 ENGsemple.StartEngine("Semple1",800,600,32,32,0,false);  // bpp,depth,stecil
 ENGsemple.BuildFont("Courier");
 ENGsemple.OnRender := Render;
 ENGsemple.OnUpdate := Update;
 ENGsemple.Loop(50);
 ENGsemple.KillFont;
end.


 
XProger ©   (2007-03-24 21:18) [9]

> Делаю простой пример. Создаю консольное приложение.
Где?


 
beginerProger   (2007-03-25 00:18) [10]

вот модули движка
eng_core in "Engine\eng_core.pas",
eng_utilits in "Engine\eng_utilits.pas",
Это просто модуль
TestU in "TestU.pas";

Вся проблема в том, что Программа работает консольная
без модуля  TestU in "TestU.pas";
а когда вызываю процедуру pr; из этого модуля получется ошибка...
Почему?


 
Rial ©   (2007-03-25 05:00) [11]

> [10] beginerProger   (25.03.07 00:18)
> а когда вызываю процедуру pr; из этого модуля получется
> ошибка...
> Почему?

А потому, что EENG нигде не инициализируется.
Что в нем лежит - да ничего.

А вообще надо пересмотреть тебе основную задачу твоего модуля.
Тут и окна создаются, и OpenGL инициализируется...
Надо как то уже определить задачу класса.
Один для окна, другой для графики.

Код не очень читается. Чаще новые что ли на новые
строки переходи.
Воотще критики тут много... но писать лень.


 
beginerProger   (2007-03-25 15:41) [12]

Всё заработало. Проблема действительно была такая. Класс просто не создавался.
Спасибо за советы и за критику.
Да Дейстивтельно мне надо разбить движок по отдельным модулям и сделаю код более структуированным.
:)


 
beginerProger   (2007-03-26 02:21) [13]

Ещё один глюк при переходе в полноекраній режим 1024х768 всё дёргается
а при 800х600 обрезается нижняя и правая сторона на пикслей 150.
Почему. Я в отчаянии ;(
Что может соедует писать с нуля.


 
homm ©   (2007-03-26 07:04) [14]

<offtop>
> Что может соедует писать с нуля.

Учись ставить запятые.
</offtop>



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

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

Наверх





Память: 0.53 MB
Время: 0.006 c
2-1221206822
N77
2008-09-12 12:07
2008.10.19
Next, Prior (SQL)


15-1219907118
tesseract
2008-08-28 11:05
2008.10.19
Чего-то все про Абрамова забыли


15-1219872645
+koha
2008-08-28 01:30
2008.10.19
Кто занимается параллельными машинами подскажите


15-1219820202
Denis__
2008-08-27 10:56
2008.10.19
МГУ ВМК Языки программирования


2-1220876858
programmer90
2008-09-08 16:27
2008.10.19
как убрать у комбобокса убрать эту штуку справа





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский