Я пытаюсь сделать текст в OpenGL, это то, как я это делаю:Странное поведение в OpenGL
- чтения пикселов растрового изображения с помощью
glReadPixels
иSetDIBits
; - нарисовать текст на растровом изображении с использованием холста;
- рисовать пиксели в буфер основной рамки, используя
GetDIBits
иglDrawPixels
.
Это то, что я получаю, когда оказываю Sample text
(81x21).
растровое изображение.
Это то, что я получаю, когда я вынести Sample text.
(84x21) (с точкой в конце).
Он работает. Он всегда работает, когда результирующая ширина текста равна двум! Strange ...
Это код.
procedure TMainForm.RenderBtnClick(Sender: TObject);
var
DC, RC: HDC;
BMP: TBitmap;
Pixels: Pointer;
X, Y, W, H: Integer;
Header: PBitmapInfo;
Result, Error: Integer;
Str: String;
begin
// Initialize OpenGL
if InitOpenGL = False then
Application.Terminate;
DC := GetDC(Handle);
RC := CreateRenderingContext(DC,
[OpDoubleBuffered],
32,
24,
0,
0,
0,
0);
ActivateRenderingContext(DC, RC);
Caption :=
'OpenGL version: ' + glGetString(GL_VERSION) + ' | ' +
'vendor: ' + glGetString(GL_VENDOR) + ' | ' +
'renderer: ' + glGetString(GL_RENDERER);
// Setup OpenGL
glClearColor(0.27, 0.4, 0.7, 0.0); // Light blue
glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, ClientWidth, 0, ClientHeight, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glClear(GL_COLOR_BUFFER_BIT);
BMP := TBitmap.Create;
BMP.PixelFormat := pf24bit;
BMP.Canvas.Font.Name := 'Segoe UI';
BMP.Canvas.Font.Size := 12;
BMP.Canvas.Font.Color := clWhite;
BMP.Canvas.Brush.Style := bsClear;
Str := Edit.Text;
W := BMP.Canvas.TextWidth(Str);
H := BMP.Canvas.TextHeight(Str);
X := (ClientWidth - W) div 2;
Y := (ClientHeight - H) div 2;
BMP.Width := W;
BMP.Height := H;
GetMem(Pixels, W * H * 3);
GetMem(Header, SizeOf(TBitmapInfoHeader));
with Header^.bmiHeader do
begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := W;
biHeight := H;
biCompression := BI_RGB;
biPlanes := 1;
biBitCount := 24;
biSizeImage := W * H * 3;
end;
glReadPixels(X, Y, W, H, GL_BGR, GL_UNSIGNED_BYTE, Pixels);
Result := SetDIBits(BMP.Canvas.Handle, BMP.Handle, 0, H, Pixels,
TBitmapInfo(Header^), DIB_RGB_COLORS);
if Result = 0 then
begin
Error := GetLastError;
raise Exception.Create('"SetDIBits" error ' + IntToStr(Error) + ': ' + SysErrorMessage(Error));
end;
BMP.Canvas.TextOut(0, 0, Str);
BMP.SaveToFile('C:/TextOut.bmp'); // for debugging purposes of course
Result := GetDIBits(BMP.Canvas.Handle, BMP.Handle, 0, H, Pixels, TBitmapInfo(Header^), DIB_RGB_COLORS);
if Result = 0 then
begin
Error := GetLastError;
raise Exception.Create('"GetDIBits" error ' + IntToStr(Error) + ': ' + SysErrorMessage(Error));
end;
glRasterPos2i(X, Y);
glDrawPixels(W, H, GL_BGR, GL_UNSIGNED_BYTE, Pixels);
SwapBuffers(DC);
// Free memory
DeactivateRenderingContext;
wglDeleteContext(RC);
ReleaseDC(Handle, DC);
FreeMem(Header);
FreeMem(Pixels);
BMP.Free;
end;
я дважды проверил код с glGetError
- без ошибок. Я видел много сообщений о нечетном поведении с SetDIBits и его производными. Некоторые утверждают, что странность имеет отношение к управлению памятью Delphi, но у меня есть сомнения. Любые идеи, что я могу попробовать дальше?
Редактировать: он работает, если я использую альфа.