Привет, All!
юзаю OpenGL под Delphi
можно ли в приложении c OpenGL выводить изображение в несколько форм?
у меня написан класс базовой формы, если вызвать одного наследника все работат хорошо, если одновременно с первым вызвать второго, работа нарушается, прекращается правильная перерисовка формы, почему и как этого можно избежать?
возможно бага в настройках?
unit uGLForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, OpenGL,
Db, ADODB, ExtCtrls;
type
TPoint3d = record
iIdStar : integer;
x,y,z : GLdouble;
MaterialColor: Array [0..3] of GLfloat;
Name : string;
end;
TGLForm = class(TForm)
Timer: TTimer;
tMain: TADOTable;
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
DC : HDC;
hrc : HGLRC;
AngleX, AngleY : GLfloat;
Perspective : GLFloat;
base : GLuint;
myfont : HFONT;
test : HGDIOBJ;
procedure SetDCPixelFormat;
procedure InitializeRC;
procedure Camera;
protected
procedure CalcSelectLine(mouse_x, mouse_y:integer; var p1, p2 : TPoint3D);
procedure DrawScene; virtual;
procedure Draw; virtual;
procedure DrawText(sMessage : string; x,y,z : GLfloat);
procedure InitText;
public
arPoint : array of TPoint3D;
stParams : TStrings;
procedure InitForm;
end;
implementation
{$R *.DFM}
{ TForm1 }
procedure TGLForm.Camera;
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(Perspective, ClientWidth / ClientHeight, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
gluLookAt(0.0, 30.0, 10.0, 0, 0, -5.0, 0, 1, 0);
end;
procedure TGLForm.DrawScene;
begin
// очистка буфера цвета и буфера глубины
glClearColor (0.0, 0.0, 0.0, 0.0); // цвет фона
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
Camera;
// трехмерность
glLoadIdentity;
glTranslatef( 0, 0, -3.0);
glRotatef(30.0, 1.0, 0.0, 0.0);
glRotatef(AngleX, 0.0, 1.0, 0.0); // поворот на угол
glRotatef(AngleY, 0.1, 0.0, 0.0); // поворот на угол
Draw;
SwapBuffers(DC); // конец работы
end;
procedure TGLForm.InitializeRC;
begin
glEnable(GL_DEPTH_TEST); // разрешаем тест глубины
glEnable(GL_LIGHTING); // разрешаем работу с освещенностью
glEnable(GL_LIGHT0); // включаем источник света 0
glEnable(GL_COLOR_MATERIAL);
end;
procedure TGLForm.SetDCPixelFormat;
var
nPixelFormat: Integer;
pfd: TPixelFormatDescriptor;
begin
FillChar(pfd, SizeOf(pfd), 0);
with pfd do begin
nSize := sizeof(pfd);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER;
iPixelType:= PFD_TYPE_RGBA;
cColorBits:= 24;
cDepthBits:= 32;
iLayerType:= PFD_MAIN_PLANE;
end;
nPixelFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, nPixelFormat, @pfd);
end;
procedure TGLForm.FormPaint(Sender: TObject);
var
ps : TPaintStruct;
begin
BeginPaint(Handle, ps);
DrawScene;
EndPaint(Handle, ps);
end;
procedure TGLForm.DrawText(sMessage: string; x, y, z: GLfloat);
var
A: array[0..255] of Char;
begin
StrPCopy(A, sMessage);
glRasterPos3f(x,y,z);
glPushAttrib(GL_LIST_BIT);
glListBase(base - 32);
glCallLists(length(sMessage), GL_UNSIGNED_BYTE, @A);
glPopAttrib();
end;
procedure TGLForm.InitText;
begin
base := glGenLists(96);
DC := wglGetCurrentDC();
if(base = GL_INVALID_VALUE) and (base = GL_INVALID_OPERATION)then exit;
myfont := CreateFont(-9,
0,0,0,
FW_REGULAR,
0,0,0,
ANSI_CHARSET,
OUT_TT_PRECIS,
CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
FF_DONTCARE or DEFAULT_PITCH,
'Agency FB'); //шрифт
if myfont = 0 then exit;
test := SelectObject(DC, myfont);
wglUseFontBitmaps(DC, 32, 96, base);
SelectObject(DC, test);
DeleteObject(myfont);
end;
procedure TGLForm.CalcSelectLine(mouse_x, mouse_y: integer; var p1,
p2: TPoint3D);
var
viewport : array [0..3] of GLint; // параметры viewport-a.
projection : array [0..15] of GLdouble; // матрица проекции.
modelview : array [0..15] of GLdouble; // видовая матрица.
vx,vy,vz : GLdouble; // координаты курсора мыши в системе координат viewport-a.
wx,wy,wz : GLdouble; // возвращаемые мировые координаты.
begin
// mouse_x, mouse_y - оконные координаты курсора мыши.
// p1, p2 - возвращаемые параметры - концы селектирующего отрезка,
// лежащие соответственно на ближней и дальней плоскостях
// отсечения.
glGetIntegerv(GL_VIEWPORT,@viewport); // узнаём параметры viewport-a.
glGetDoublev(GL_PROJECTION_MATRIX,@projection); // узнаём матрицу проекции.
glGetDoublev(GL_MODELVIEW_MATRIX,@modelview); // узнаём видовую матрицу.
// переводим оконные координаты курсора в систему координат viewport-a.
vx := mouse_x;
vy := height - mouse_y - 1; // где height - текущая высота окна.
// вычисляем ближний конец селектирующего отрезка.
vz := -1;
gluUnProject(vx, vy, vz, @modelview, @projection, @viewport, wx, wy, wz);
p1.x := wx;
p1.y := wy;
p1.z := wz;
// вычисляем дальний конец селектирующего отрезка.
vz := 1;
gluUnProject(vx, vy, vz, @modelview, @projection, @viewport, wx, wy, wz);
p2.x := wx;
p2.y := wy;
p2.z := wz;
end;
procedure TGLForm.FormDestroy(Sender: TObject);
begin
stParams.Free;
end;
procedure TGLForm.TimerTimer(Sender: TObject);
begin
AngleX := AngleX + 0.05;
If (AngleX >= 360.0) then AngleX := 0.0;
If (AngleY >= 360.0) then AngleY := 0.0;
InvalidateRect(Handle, nil, False); // перерисовка региона (Windows API)
end;
procedure TGLForm.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(30.0, Width / Height, 1.0, 10.0);
glViewport(0, 0, Width, Height);
glMatrixMode(GL_MODELVIEW);
end;
procedure TGLForm.Draw;
begin
end;
procedure TGLForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
if WheelDelta < 0 then
Perspective := Perspective - 0.5
else
Perspective := Perspective + 0.5;
end;
procedure TGLForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
VK_LEFT : AngleX := AngleX - 0.5;
VK_RIGHT: AngleX := AngleX + 0.5;
VK_UP : AngleY := AngleY - 0.5;
VK_DOWN : AngleY := AngleY + 0.5;
end;
end;
procedure TGLForm.InitForm;
begin
stParams := TStrings.Create;
Perspective := 40.0;
AngleX := 0.0;
AngleY := 0.0;
DC := GetDC(Handle);
SetDCPixelFormat;
hrc := wglCreateContext(DC);
wglMakeCurrent(DC, hrc);
InitializeRC;
InitText;
end;
end.
вызов в наследниках:
...
procedure TfmMap.FormCreate(Sender: TObject);
begin
inherited;
InitForm;
tMain.Open;
SetLength(arPoint, tMain.RecordCount);
InitMap;
Timer.Enabled := True;
end;
...
Спасибо.