Вопрос: Как нарисовать таблицу с фиксированным соотношением сторон в OpenGL с помощью Delphi?
Ответ: Для рисования таблицы с фиксированным соотношением сторон в OpenGL с помощью Delphi, вам нужно учитывать соотношение сторон окна, в котором рисуется таблица. В приведенном коде автор пытается нарисовать таблицу с одинаковыми ячейками, но при изменении размера окна таблица не сохраняет правильное соотношение сторон.
Чтобы решить эту проблему, вам нужно изменить размеры таблицы в зависимости от соотношения сторон окна. Вы можете сделать это, рассчитав ширину и высоту ячеек таблицы на основе соотношения сторон окна. Например, если ширина окна больше, чем высота, вы можете сделать ячейки таблицы уже, чтобы сохранить правильное соотношение сторон. Если высота окна больше, чем ширина, вы можете сделать ячейки таблицы выше.
Вот пример кода, который демонстрирует, как это можно сделать:
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, Winapi.OpenGL, System.SysUtils,
System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.Menus;
type
TfrmMain = class(TForm)
PopupMenu: TPopupMenu;
mnuDrawGrid: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure mnuDrawGridClick(Sender: TObject);
procedure FormResize(Sender: TObject);
private
glDC: HDC;
oldW: Integer;
oldH: Integer;
glContext: HGLRC;
errorCode: GLenum;
openGLReady: Boolean;
procedure DisegnaLinea(const aX1, aY1, aX2, aY2: Double; aSpessore,
aOffSet: Integer);
procedure DisegnaTabellone(const aNumRighe, aNumColonne: SmallInt);
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
{ Gestione form -------------------------------------------------------------- }
// OpenGL initialization
procedure TfrmMain.FormCreate(Sender: TObject);
var
pfd: TPixelFormatDescriptor;
formatIndex: Integer;
begin
FillChar(pfd, SizeOf(pfd), 0);
with pfd do
begin
nSize := SizeOf(pfd);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL;
iPixelType := PFD_TYPE_RGBA;
cColorBits := 24;
cDepthBits := 32;
iLayerType := PFD_MAIN_PLANE;
end;
glDC := GetDC(Handle);
formatIndex := ChoosePixelFormat(glDC, @pfd);
if formatIndex = 0 then
raise Exception.Create('Choose pixel format failed ' + IntToStr(GetLastError));
if not SetPixelFormat(glDC, formatIndex, @pfd) then
raise Exception.Create('Set pixel forma failed ' + IntToStr(GetLastError));
glContext := wglCreateContext(glDC);
if not glContext = 0 then
raise Exception.Create('Create context failed ' + IntToStr(GetLastError));
if not wglMakeCurrent(glDC, glContext) then
raise Exception.Create('Make current failsed ' + IntToStr(GetLastError));
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0.0, ClientWidth, 0.0, ClientHeight, 0.0, 1.0);
oldW := ClientWidth;
oldH := ClientHeight;
openGLReady := True;
end;
// OpenGL destruction
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(Canvas.Handle, 0);
wglDeleteContext(glContext);
end;
// Form resize
procedure TfrmMain.FormResize(Sender: TObject);
begin
if not openGLReady then
exit;
glViewport(0, 0, ClientWidth, ClientHeight);
errorCode := glGetError;
if errorCode <> GL_NO_ERROR then
raise Exception.Create('Form resize: ' + gluErrorString(errorCode));
if (ClientWidth <> oldW) or (ClientHeight <> oldH) then
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0.0, ClientWidth, 0.0, ClientHeight, 0.0, 1.0);
DisegnaTabellone(10, 10);
end;
oldW := ClientWidth;
oldH := ClientHeight;
end;
// Menu option grid drawing
procedure TfrmMain.mnuDrawGridClick(Sender: TObject);
begin
DisegnaTabellone(10, 10);
end;
// OpenGL ---------------------------------------------------------------------
// Draw a line at aX1, aY1 to aX2, aY2 coordinates
procedure TfrmMain.DisegnaLinea(const aX1, aY1, aX2, aY2: Double; aSpessore,
aOffSet: Integer);
begin
glEnable(GL_LINE_SMOOTH);
glLineWidth(aSpessore);
glBegin(GL_LINES);
glVertex2f(aX1, aY1);
glVertex2f(aX2, aY2);
glEnd;
end;
// Grid design
procedure TfrmMain.DisegnaTabellone(const aNumRighe, aNumColonne: SmallInt);
const
vOffSet = 20;
var
idx: SmallInt;
pX, pY, incX, incY, hPos, hWidth: Double;
widthArea, heightArea: Integer;
aspectRatio: Double;
begin
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
widthArea := ClientWidth;
heightArea := ClientHeight;
aspectRatio := widthArea / heightArea;
pY := vOffSet / 2;
incY := (heightArea - vOffSet) / aNumRighe;
pX := (widthArea - aNumColonne * incY) / 2;
hPos := pX;
hWidth := hPos + aNumColonne * incY;
incX := incY;
// Draw vertical lines
for idx := 0 to aNumColonne do begin
DisegnaLinea(pX, vOffSet / 2, pX, heightArea - vOffSet / 2, 3, 0);
pX := pX + incX;
end;
// Draw horizontal lines
for idx := 0 to aNumRighe do begin
DisegnaLinea(hPos, pY, hWidth, pY, 3, 0);
pY := pY + incY;
end;
glFlush;
end;
end.
В этом примере, в процедуре FormResize, мы пересчитываем матрицу проекции при изменении размера окна, чтобы сохранить правильное соотношение сторон таблицы. Кроме того, в процедуре DisegnaTabellone, мы рассчитываем ширину и высоту ячеек таблицы на основе соотношения сторон окна, чтобы сохранить правильное соотношение сторон таблицы.
Вопрос: Как нарисовать таблицу с фиксированным соотношением сторон в OpenGL с помощью Delphi?
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.