mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
Move wideband OpenGL background to primitives
This commit is contained in:
+196
-40
@@ -24,6 +24,7 @@ type
|
||||
TWidebandView = class
|
||||
private
|
||||
FBitmap: TBitmap;
|
||||
FLabelBitmap: TBitmap;
|
||||
FRulerBitmap: TBitmap;
|
||||
FTheme: TAppTheme;
|
||||
FData: array of Single;
|
||||
@@ -57,6 +58,8 @@ type
|
||||
procedure PaintCPU(C: TCanvas);
|
||||
procedure PaintGL(C: TOpenGLControl);
|
||||
procedure ColorToGL(AColor: TColor; out R, G, B: GLFloat);
|
||||
procedure DrawBackgroundGL(W, H, PlotW: Integer);
|
||||
procedure DrawGridGL(W, H, PlotW: Integer);
|
||||
procedure DrawSpectrumGL(PlotW, H: Integer);
|
||||
procedure DrawHamBandGL(PlotW, H: Integer; F1, F2: Double; AColor: TColor);
|
||||
procedure DrawHamBandsGL(PlotW, H: Integer);
|
||||
@@ -71,7 +74,9 @@ type
|
||||
const Name: string; AColor: TColor);
|
||||
procedure DrawFrequencyMarker(C: TCanvas; PlotW, H: Integer);
|
||||
procedure DrawSpectrumGradient(const SpPts: array of TPoint; PlotW, H: Integer);
|
||||
procedure UploadBitmapToGL;
|
||||
procedure DrawGLLabels(W, H, PlotW: Integer);
|
||||
procedure UploadLabelTextureToGL;
|
||||
procedure DrawLabelTextureGL(W, H: Integer);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@@ -107,6 +112,8 @@ begin
|
||||
inherited Create;
|
||||
FBitmap := TBitmap.Create;
|
||||
FBitmap.PixelFormat := pf32bit;
|
||||
FLabelBitmap := TBitmap.Create;
|
||||
FLabelBitmap.PixelFormat := pf32bit;
|
||||
FRulerBitmap := TBitmap.Create;
|
||||
FRulerBitmap.PixelFormat := pf32bit;
|
||||
FTheme := DarkTheme;
|
||||
@@ -137,6 +144,7 @@ begin
|
||||
if FGLTex <> 0 then
|
||||
glDeleteTextures(1, @FGLTex);
|
||||
FRulerBitmap.Free;
|
||||
FLabelBitmap.Free;
|
||||
FBitmap.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
@@ -230,6 +238,11 @@ begin
|
||||
FBitmap.SetSize(W, H);
|
||||
FGLBackgroundDirty := True;
|
||||
end;
|
||||
if (FLabelBitmap.Width <> W) or (FLabelBitmap.Height <> H) then
|
||||
begin
|
||||
FLabelBitmap.SetSize(W, H);
|
||||
FGLBackgroundDirty := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.SetBitmapSize(W, H: Integer);
|
||||
@@ -666,8 +679,6 @@ begin
|
||||
|
||||
DrawHamBands(C, PlotW, H);
|
||||
|
||||
C.Font.Color := FTheme.Text;
|
||||
C.TextOut(6, 4, 'Wideband');
|
||||
if IncludeSpectrum then
|
||||
FDirty := False
|
||||
else
|
||||
@@ -742,6 +753,67 @@ begin
|
||||
B := ((AColor shr 16) and $FF) / 255.0;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawBackgroundGL(W, H, PlotW: Integer);
|
||||
var
|
||||
R1, G1, B1, R2, G2, B2: GLFloat;
|
||||
begin
|
||||
ColorToGL(FTheme.SpecGradTop, R1, G1, B1);
|
||||
ColorToGL(FTheme.SpecGradBot, R2, G2, B2);
|
||||
glBegin(GL_QUADS);
|
||||
glColor3f(R1, G1, B1); glVertex2f(0, H);
|
||||
glColor3f(R1, G1, B1); glVertex2f(W, H);
|
||||
glColor3f(R2, G2, B2); glVertex2f(W, 0);
|
||||
glColor3f(R2, G2, B2); glVertex2f(0, 0);
|
||||
glEnd;
|
||||
|
||||
ColorToGL(FTheme.SpecLabelBand, R1, G1, B1);
|
||||
glColor3f(R1, G1, B1);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(PlotW, 0);
|
||||
glVertex2f(W, 0);
|
||||
glVertex2f(W, H);
|
||||
glVertex2f(PlotW, H);
|
||||
glEnd;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawGridGL(W, H, PlotW: Integer);
|
||||
var
|
||||
X, Y, TopH: Integer;
|
||||
DB, DBMin, InvRange, StepHz, FreqHz: Double;
|
||||
R, G, B: GLFloat;
|
||||
begin
|
||||
DBMin := FRefLevel - FRange;
|
||||
InvRange := 1.0 / Max(1.0, FRange);
|
||||
TopH := Max(1, H - 1);
|
||||
ColorToGL(FTheme.SpecGrid, R, G, B);
|
||||
glColor4f(R, G, B, 0.78);
|
||||
glBegin(GL_LINES);
|
||||
FLabelBitmap.Canvas.Font.Name := 'Courier New';
|
||||
FLabelBitmap.Canvas.Font.Size := 7;
|
||||
StepHz := RulerGridStepHz(FLabelBitmap.Canvas, PlotW);
|
||||
FreqHz := Ceil(FViewStartHz / StepHz) * StepHz;
|
||||
while FreqHz <= FViewEndHz + 0.5 do
|
||||
begin
|
||||
X := FreqToX(FreqHz, PlotW);
|
||||
glVertex2f(X, 0);
|
||||
glVertex2f(X, H);
|
||||
FreqHz := FreqHz + StepHz;
|
||||
end;
|
||||
|
||||
DB := FRefLevel - 20.0;
|
||||
while DB >= DBMin do
|
||||
begin
|
||||
Y := Round((FRefLevel - DB) * InvRange * TopH);
|
||||
glVertex2f(0, H - Y);
|
||||
glVertex2f(W, H - Y);
|
||||
DB := DB - 20.0;
|
||||
end;
|
||||
|
||||
glVertex2f(PlotW, 0);
|
||||
glVertex2f(PlotW, H);
|
||||
glEnd;
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawSpectrumGL(PlotW, H: Integer);
|
||||
var
|
||||
I: Integer;
|
||||
@@ -826,66 +898,158 @@ begin
|
||||
DrawHamBandGL(PlotW, H, 50000000, 51990000, TColor($003C729A));
|
||||
end;
|
||||
|
||||
procedure TWidebandView.UploadBitmapToGL;
|
||||
procedure TWidebandView.DrawGLLabels(W, H, PlotW: Integer);
|
||||
var
|
||||
C: TCanvas;
|
||||
X1, X2, LabelX, LabelY, TW, TH, Y, TopH, ScaleX: Integer;
|
||||
DB, DBMin, InvRange: Double;
|
||||
|
||||
procedure BandLabel(F1, F2: Double; const Name: string);
|
||||
begin
|
||||
X1 := FreqToX(F1, PlotW);
|
||||
X2 := FreqToX(F2, PlotW);
|
||||
if (X2 <= 0) or (X1 >= PlotW) then Exit;
|
||||
X1 := EnsureRange(X1, 0, PlotW - 1);
|
||||
X2 := EnsureRange(X2, 0, PlotW - 1);
|
||||
if X2 <= X1 then Exit;
|
||||
TW := C.TextWidth(Name);
|
||||
TH := C.TextHeight(Name);
|
||||
LabelX := EnsureRange(((X1 + X2) div 2) - TW div 2, 2, Max(2, PlotW - TW - 5));
|
||||
LabelY := Max(1, Min(H - TH - 1, 2));
|
||||
C.TextOut(LabelX, LabelY, Name);
|
||||
end;
|
||||
|
||||
begin
|
||||
if (W <= 0) or (H <= 0) then Exit;
|
||||
if (FLabelBitmap.Width <> W) or (FLabelBitmap.Height <> H) then
|
||||
FLabelBitmap.SetSize(W, H);
|
||||
|
||||
C := FLabelBitmap.Canvas;
|
||||
C.Brush.Style := bsSolid;
|
||||
C.Brush.Color := clBlack;
|
||||
C.FillRect(Rect(0, 0, W, H));
|
||||
C.Brush.Style := bsClear;
|
||||
|
||||
DBMin := FRefLevel - FRange;
|
||||
InvRange := 1.0 / Max(1.0, FRange);
|
||||
TopH := Max(1, H - 1);
|
||||
ScaleX := PlotW;
|
||||
|
||||
C.Font.Name := 'Courier New';
|
||||
C.Font.Quality := fqDefault;
|
||||
C.Font.Size := 7;
|
||||
C.Font.Color := FTheme.SpecLabelText;
|
||||
DB := FRefLevel - 20.0;
|
||||
while DB >= DBMin do
|
||||
begin
|
||||
Y := Round((FRefLevel - DB) * InvRange * TopH);
|
||||
C.TextOut(ScaleX + 2, Y - 9, Format('%4.0f', [DB]));
|
||||
DB := DB - 20.0;
|
||||
end;
|
||||
|
||||
C.Font.Name := 'Sans';
|
||||
C.Font.Quality := fqDefault;
|
||||
C.Font.Size := 7;
|
||||
C.Font.Color := TColor($00EAF7D7);
|
||||
BandLabel(1810000, 2000000, '160m');
|
||||
BandLabel(3500000, 3800000, '80m');
|
||||
BandLabel(5258500, 5403500, '60m');
|
||||
BandLabel(7000000, 7300000, '40m');
|
||||
BandLabel(10100000, 10150000, '30m');
|
||||
BandLabel(14000000, 14350000, '20m');
|
||||
BandLabel(18068000, 18168000, '17m');
|
||||
BandLabel(21000000, 21450000, '15m');
|
||||
BandLabel(24890000, 24990000, '12m');
|
||||
BandLabel(28000000, 29700000, '10m');
|
||||
BandLabel(50000000, 51990000, '6m');
|
||||
|
||||
end;
|
||||
|
||||
procedure TWidebandView.UploadLabelTextureToGL;
|
||||
var
|
||||
X, Y, I: Integer;
|
||||
Src: PByte;
|
||||
Buf: array of Byte;
|
||||
A: Byte;
|
||||
begin
|
||||
if (FBitmap.Width <= 0) or (FBitmap.Height <= 0) then Exit;
|
||||
if (FLabelBitmap.Width <= 0) or (FLabelBitmap.Height <= 0) then Exit;
|
||||
if FGLTex = 0 then
|
||||
glGenTextures(1, @FGLTex);
|
||||
SetLength(Buf, FBitmap.Width * FBitmap.Height * 4);
|
||||
FBitmap.BeginUpdate(False);
|
||||
SetLength(Buf, FLabelBitmap.Width * FLabelBitmap.Height * 4);
|
||||
FLabelBitmap.BeginUpdate(False);
|
||||
try
|
||||
I := 0;
|
||||
for Y := 0 to FBitmap.Height - 1 do
|
||||
for Y := 0 to FLabelBitmap.Height - 1 do
|
||||
begin
|
||||
Src := PByte(FBitmap.ScanLine[Y]);
|
||||
for X := 0 to FBitmap.Width - 1 do
|
||||
Src := PByte(FLabelBitmap.ScanLine[Y]);
|
||||
for X := 0 to FLabelBitmap.Width - 1 do
|
||||
begin
|
||||
Buf[I] := Src[2];
|
||||
Buf[I + 1] := Src[1];
|
||||
Buf[I + 2] := Src[0];
|
||||
Buf[I + 3] := $FF;
|
||||
A := Max(Src[0], Max(Src[1], Src[2]));
|
||||
if A < 6 then A := 0;
|
||||
if A > 0 then
|
||||
begin
|
||||
Buf[I] := Byte(Min(255, Src[2] * 255 div A));
|
||||
Buf[I + 1] := Byte(Min(255, Src[1] * 255 div A));
|
||||
Buf[I + 2] := Byte(Min(255, Src[0] * 255 div A));
|
||||
A := Byte(Min(255, A + (255 - A) div 3));
|
||||
end
|
||||
else
|
||||
begin
|
||||
Buf[I] := 0;
|
||||
Buf[I + 1] := 0;
|
||||
Buf[I + 2] := 0;
|
||||
end;
|
||||
Buf[I + 3] := A;
|
||||
Inc(Src, 4);
|
||||
Inc(I, 4);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
FBitmap.EndUpdate(False);
|
||||
FLabelBitmap.EndUpdate(False);
|
||||
end;
|
||||
glBindTexture(GL_TEXTURE_2D, FGLTex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FBitmap.Width, FBitmap.Height, 0,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FLabelBitmap.Width, FLabelBitmap.Height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, @Buf[0]);
|
||||
end;
|
||||
|
||||
procedure TWidebandView.DrawLabelTextureGL(W, H: Integer);
|
||||
begin
|
||||
if FGLTex = 0 then Exit;
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, FGLTex);
|
||||
glColor4f(1, 1, 1, 1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 1); glVertex2f(0, 0);
|
||||
glTexCoord2f(1, 1); glVertex2f(W, 0);
|
||||
glTexCoord2f(1, 0); glVertex2f(W, H);
|
||||
glTexCoord2f(0, 0); glVertex2f(0, H);
|
||||
glEnd;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
end;
|
||||
|
||||
procedure TWidebandView.PaintGL(C: TOpenGLControl);
|
||||
var
|
||||
W, H, PlotW, X: Integer;
|
||||
NeedUpload: Boolean;
|
||||
begin
|
||||
if C = nil then Exit;
|
||||
W := Max(1, C.Width);
|
||||
H := Max(1, C.Height);
|
||||
if not C.MakeCurrent then Exit;
|
||||
NeedUpload := False;
|
||||
if (FBitmap.Width <> W) or (FBitmap.Height <> H) then
|
||||
begin
|
||||
SetBitmapSize(W, H);
|
||||
NeedUpload := True;
|
||||
end;
|
||||
if FGLBackgroundDirty then
|
||||
begin
|
||||
DrawCPU(W, H, False);
|
||||
NeedUpload := True;
|
||||
PlotW := Max(1, W - WB_DB_SCALE_W);
|
||||
DrawGLLabels(W, H, PlotW);
|
||||
UploadLabelTextureToGL;
|
||||
FGLBackgroundDirty := False;
|
||||
end;
|
||||
if FGLTex = 0 then
|
||||
NeedUpload := True;
|
||||
if NeedUpload then
|
||||
UploadBitmapToGL;
|
||||
glViewport(0, 0, W, H);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity;
|
||||
@@ -895,21 +1059,13 @@ begin
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor(0, 0, 0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, FGLTex);
|
||||
glColor3f(1, 1, 1);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 1); glVertex2f(0, 0);
|
||||
glTexCoord2f(1, 1); glVertex2f(W, 0);
|
||||
glTexCoord2f(1, 0); glVertex2f(W, H);
|
||||
glTexCoord2f(0, 0); glVertex2f(0, H);
|
||||
glEnd;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
PlotW := Max(1, W - WB_DB_SCALE_W);
|
||||
DrawBackgroundGL(W, H, PlotW);
|
||||
DrawGridGL(W, H, PlotW);
|
||||
DrawSpectrumGL(PlotW, H);
|
||||
DrawHamBandsGL(PlotW, H);
|
||||
DrawLabelTextureGL(W, H);
|
||||
FDirty := False;
|
||||
|
||||
if (FMarkerHz >= FViewStartHz) and (FMarkerHz <= FViewEndHz) then
|
||||
|
||||
Reference in New Issue
Block a user