Текущий архив: 2008.10.19;
Скачать: CL | DM;
ВнизПроблема с класом движка Найти похожие ветки
← →
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;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.006 c