mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:27:33 +00:00
Move wideband OpenGL background to primitives
This commit is contained in:
+196
-40
@@ -24,6 +24,7 @@ type
|
|||||||
TWidebandView = class
|
TWidebandView = class
|
||||||
private
|
private
|
||||||
FBitmap: TBitmap;
|
FBitmap: TBitmap;
|
||||||
|
FLabelBitmap: TBitmap;
|
||||||
FRulerBitmap: TBitmap;
|
FRulerBitmap: TBitmap;
|
||||||
FTheme: TAppTheme;
|
FTheme: TAppTheme;
|
||||||
FData: array of Single;
|
FData: array of Single;
|
||||||
@@ -57,6 +58,8 @@ type
|
|||||||
procedure PaintCPU(C: TCanvas);
|
procedure PaintCPU(C: TCanvas);
|
||||||
procedure PaintGL(C: TOpenGLControl);
|
procedure PaintGL(C: TOpenGLControl);
|
||||||
procedure ColorToGL(AColor: TColor; out R, G, B: GLFloat);
|
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 DrawSpectrumGL(PlotW, H: Integer);
|
||||||
procedure DrawHamBandGL(PlotW, H: Integer; F1, F2: Double; AColor: TColor);
|
procedure DrawHamBandGL(PlotW, H: Integer; F1, F2: Double; AColor: TColor);
|
||||||
procedure DrawHamBandsGL(PlotW, H: Integer);
|
procedure DrawHamBandsGL(PlotW, H: Integer);
|
||||||
@@ -71,7 +74,9 @@ type
|
|||||||
const Name: string; AColor: TColor);
|
const Name: string; AColor: TColor);
|
||||||
procedure DrawFrequencyMarker(C: TCanvas; PlotW, H: Integer);
|
procedure DrawFrequencyMarker(C: TCanvas; PlotW, H: Integer);
|
||||||
procedure DrawSpectrumGradient(const SpPts: array of TPoint; 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
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@@ -107,6 +112,8 @@ begin
|
|||||||
inherited Create;
|
inherited Create;
|
||||||
FBitmap := TBitmap.Create;
|
FBitmap := TBitmap.Create;
|
||||||
FBitmap.PixelFormat := pf32bit;
|
FBitmap.PixelFormat := pf32bit;
|
||||||
|
FLabelBitmap := TBitmap.Create;
|
||||||
|
FLabelBitmap.PixelFormat := pf32bit;
|
||||||
FRulerBitmap := TBitmap.Create;
|
FRulerBitmap := TBitmap.Create;
|
||||||
FRulerBitmap.PixelFormat := pf32bit;
|
FRulerBitmap.PixelFormat := pf32bit;
|
||||||
FTheme := DarkTheme;
|
FTheme := DarkTheme;
|
||||||
@@ -137,6 +144,7 @@ begin
|
|||||||
if FGLTex <> 0 then
|
if FGLTex <> 0 then
|
||||||
glDeleteTextures(1, @FGLTex);
|
glDeleteTextures(1, @FGLTex);
|
||||||
FRulerBitmap.Free;
|
FRulerBitmap.Free;
|
||||||
|
FLabelBitmap.Free;
|
||||||
FBitmap.Free;
|
FBitmap.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
@@ -230,6 +238,11 @@ begin
|
|||||||
FBitmap.SetSize(W, H);
|
FBitmap.SetSize(W, H);
|
||||||
FGLBackgroundDirty := True;
|
FGLBackgroundDirty := True;
|
||||||
end;
|
end;
|
||||||
|
if (FLabelBitmap.Width <> W) or (FLabelBitmap.Height <> H) then
|
||||||
|
begin
|
||||||
|
FLabelBitmap.SetSize(W, H);
|
||||||
|
FGLBackgroundDirty := True;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWidebandView.SetBitmapSize(W, H: Integer);
|
procedure TWidebandView.SetBitmapSize(W, H: Integer);
|
||||||
@@ -666,8 +679,6 @@ begin
|
|||||||
|
|
||||||
DrawHamBands(C, PlotW, H);
|
DrawHamBands(C, PlotW, H);
|
||||||
|
|
||||||
C.Font.Color := FTheme.Text;
|
|
||||||
C.TextOut(6, 4, 'Wideband');
|
|
||||||
if IncludeSpectrum then
|
if IncludeSpectrum then
|
||||||
FDirty := False
|
FDirty := False
|
||||||
else
|
else
|
||||||
@@ -742,6 +753,67 @@ begin
|
|||||||
B := ((AColor shr 16) and $FF) / 255.0;
|
B := ((AColor shr 16) and $FF) / 255.0;
|
||||||
end;
|
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);
|
procedure TWidebandView.DrawSpectrumGL(PlotW, H: Integer);
|
||||||
var
|
var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
@@ -826,66 +898,158 @@ begin
|
|||||||
DrawHamBandGL(PlotW, H, 50000000, 51990000, TColor($003C729A));
|
DrawHamBandGL(PlotW, H, 50000000, 51990000, TColor($003C729A));
|
||||||
end;
|
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
|
var
|
||||||
X, Y, I: Integer;
|
X, Y, I: Integer;
|
||||||
Src: PByte;
|
Src: PByte;
|
||||||
Buf: array of Byte;
|
Buf: array of Byte;
|
||||||
|
A: Byte;
|
||||||
begin
|
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
|
if FGLTex = 0 then
|
||||||
glGenTextures(1, @FGLTex);
|
glGenTextures(1, @FGLTex);
|
||||||
SetLength(Buf, FBitmap.Width * FBitmap.Height * 4);
|
SetLength(Buf, FLabelBitmap.Width * FLabelBitmap.Height * 4);
|
||||||
FBitmap.BeginUpdate(False);
|
FLabelBitmap.BeginUpdate(False);
|
||||||
try
|
try
|
||||||
I := 0;
|
I := 0;
|
||||||
for Y := 0 to FBitmap.Height - 1 do
|
for Y := 0 to FLabelBitmap.Height - 1 do
|
||||||
begin
|
begin
|
||||||
Src := PByte(FBitmap.ScanLine[Y]);
|
Src := PByte(FLabelBitmap.ScanLine[Y]);
|
||||||
for X := 0 to FBitmap.Width - 1 do
|
for X := 0 to FLabelBitmap.Width - 1 do
|
||||||
begin
|
begin
|
||||||
Buf[I] := Src[2];
|
A := Max(Src[0], Max(Src[1], Src[2]));
|
||||||
Buf[I + 1] := Src[1];
|
if A < 6 then A := 0;
|
||||||
Buf[I + 2] := Src[0];
|
if A > 0 then
|
||||||
Buf[I + 3] := $FF;
|
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(Src, 4);
|
||||||
Inc(I, 4);
|
Inc(I, 4);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
FBitmap.EndUpdate(False);
|
FLabelBitmap.EndUpdate(False);
|
||||||
end;
|
end;
|
||||||
glBindTexture(GL_TEXTURE_2D, FGLTex);
|
glBindTexture(GL_TEXTURE_2D, FGLTex);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FBitmap.Width, FBitmap.Height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FLabelBitmap.Width, FLabelBitmap.Height, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, @Buf[0]);
|
GL_RGBA, GL_UNSIGNED_BYTE, @Buf[0]);
|
||||||
end;
|
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);
|
procedure TWidebandView.PaintGL(C: TOpenGLControl);
|
||||||
var
|
var
|
||||||
W, H, PlotW, X: Integer;
|
W, H, PlotW, X: Integer;
|
||||||
NeedUpload: Boolean;
|
|
||||||
begin
|
begin
|
||||||
if C = nil then Exit;
|
if C = nil then Exit;
|
||||||
W := Max(1, C.Width);
|
W := Max(1, C.Width);
|
||||||
H := Max(1, C.Height);
|
H := Max(1, C.Height);
|
||||||
if not C.MakeCurrent then Exit;
|
if not C.MakeCurrent then Exit;
|
||||||
NeedUpload := False;
|
|
||||||
if (FBitmap.Width <> W) or (FBitmap.Height <> H) then
|
if (FBitmap.Width <> W) or (FBitmap.Height <> H) then
|
||||||
begin
|
|
||||||
SetBitmapSize(W, H);
|
SetBitmapSize(W, H);
|
||||||
NeedUpload := True;
|
|
||||||
end;
|
|
||||||
if FGLBackgroundDirty then
|
if FGLBackgroundDirty then
|
||||||
begin
|
begin
|
||||||
DrawCPU(W, H, False);
|
PlotW := Max(1, W - WB_DB_SCALE_W);
|
||||||
NeedUpload := True;
|
DrawGLLabels(W, H, PlotW);
|
||||||
|
UploadLabelTextureToGL;
|
||||||
|
FGLBackgroundDirty := False;
|
||||||
end;
|
end;
|
||||||
if FGLTex = 0 then
|
|
||||||
NeedUpload := True;
|
|
||||||
if NeedUpload then
|
|
||||||
UploadBitmapToGL;
|
|
||||||
glViewport(0, 0, W, H);
|
glViewport(0, 0, W, H);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity;
|
glLoadIdentity;
|
||||||
@@ -895,21 +1059,13 @@ begin
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glClearColor(0, 0, 0, 1.0);
|
glClearColor(0, 0, 0, 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
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);
|
PlotW := Max(1, W - WB_DB_SCALE_W);
|
||||||
|
DrawBackgroundGL(W, H, PlotW);
|
||||||
|
DrawGridGL(W, H, PlotW);
|
||||||
DrawSpectrumGL(PlotW, H);
|
DrawSpectrumGL(PlotW, H);
|
||||||
DrawHamBandsGL(PlotW, H);
|
DrawHamBandsGL(PlotW, H);
|
||||||
|
DrawLabelTextureGL(W, H);
|
||||||
FDirty := False;
|
FDirty := False;
|
||||||
|
|
||||||
if (FMarkerHz >= FViewStartHz) and (FMarkerHz <= FViewEndHz) then
|
if (FMarkerHz >= FViewStartHz) and (FMarkerHz <= FViewEndHz) then
|
||||||
|
|||||||
Reference in New Issue
Block a user