diff --git a/CMakeLists.txt b/CMakeLists.txt index e0e0db1..340b728 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,7 +259,6 @@ SET (cubicsdr_sources src/visual/ScopeCanvas.cpp src/visual/ScopeContext.cpp src/visual/SpectrumCanvas.cpp - src/visual/SpectrumContext.cpp src/visual/WaterfallCanvas.cpp src/process/VisualProcessor.cpp src/process/ScopeVisualProcessor.cpp @@ -313,7 +312,6 @@ SET (cubicsdr_headers src/visual/ScopeCanvas.h src/visual/ScopeContext.h src/visual/SpectrumCanvas.h - src/visual/SpectrumContext.h src/visual/WaterfallCanvas.h src/process/VisualProcessor.h src/process/ScopeVisualProcessor.h diff --git a/src/panel/ScopePanel.h b/src/panel/ScopePanel.h index 2907448..7d72756 100644 --- a/src/panel/ScopePanel.h +++ b/src/panel/ScopePanel.h @@ -11,8 +11,11 @@ public: void setMode(ScopeMode scopeMode); void setPoints(std::vector &points); - void drawPanelContents(); +protected: + void drawPanelContents(); + +private: std::vector points; ScopeMode scopeMode; GLPanel bgPanel; diff --git a/src/panel/SpectrumPanel.cpp b/src/panel/SpectrumPanel.cpp index 853a805..4e33087 100644 --- a/src/panel/SpectrumPanel.cpp +++ b/src/panel/SpectrumPanel.cpp @@ -1,2 +1,160 @@ #include "SpectrumPanel.h" +#include +#include +#include "ColorTheme.h" + +SpectrumPanel::SpectrumPanel() : floorValue(0), ceilValue(1) { + setFill(GLPANEL_FILL_GRAD_Y); + setFillColor(ThemeMgr::mgr.currentTheme->fftBackground * 2.0, ThemeMgr::mgr.currentTheme->fftBackground); +} + + +float SpectrumPanel::getFloorValue() const { + return floorValue; +} + +void SpectrumPanel::setFloorValue(float floorValue) { + this->floorValue = floorValue; +} + +float SpectrumPanel::getCeilValue() const { + return ceilValue; +} + +void SpectrumPanel::setCeilValue(float ceilValue) { + this->ceilValue = ceilValue; +} + +void SpectrumPanel::setFreq(long long freq) { + this->freq = freq; +} + +long long SpectrumPanel::getFreq() { + return freq; +} + +void SpectrumPanel::setBandwidth(long long bandwidth) { + this->bandwidth = bandwidth; +} + +long long SpectrumPanel::getBandwidth() { + return bandwidth; +} + +void SpectrumPanel::setPoints(std::vector &points) { + this->points.assign(points.begin(), points.end()); +} + + +void SpectrumPanel::drawPanelContents() { + glDisable(GL_TEXTURE_2D); + + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); + + glLoadMatrixf(transform * (CubicVR::mat4::translate(-1.0f, -0.75f, 0.0f) * CubicVR::mat4::scale(2.0f, 1.5f, 1.0f))); + + if (points.size()) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + float range = ceilValue-floorValue; + float ranges[3][4] = { { 90.0, 5000.0, 10.0, 100.0 }, { 20.0, 150.0, 10.0, 10.0 }, { -20.0, 30.0, 10.0, 1.0 } }; + + for (int i = 0; i < 3; i++) { + float p = 0; + float rangeMin = ranges[i][0]; + float rangeMax = ranges[i][1]; + float rangeTrans = ranges[i][2]; + float rangeStep = ranges[i][3]; + + if (range >= rangeMin && range <= rangeMax) { + float a = 1.0; + + if (range <= rangeMin+rangeTrans) { + a *= (range-rangeMin)/rangeTrans; + } + if (range >= rangeMax-rangeTrans) { + a *= (rangeTrans-(range-(rangeMax-rangeTrans)))/rangeTrans; + } + + glColor4f(0.12, 0.12, 0.12, a); + glBegin(GL_LINES); + for (float l = floorValue; l<=ceilValue+rangeStep; l+=rangeStep) { + p += rangeStep/range; + glVertex2f(0,p); glVertex2f(1,p); + } + glEnd(); + } + } + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor3f(ThemeMgr::mgr.currentTheme->fftLine.r, ThemeMgr::mgr.currentTheme->fftLine.g, ThemeMgr::mgr.currentTheme->fftLine.b); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, &points[0]); + glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2); + glDisableClientState(GL_VERTEX_ARRAY); + } + + glLoadMatrixf(transform); + + GLint vp[4]; + glGetIntegerv( GL_VIEWPORT, vp); + + float viewHeight = (float) vp[3]; + float viewWidth = (float) vp[2]; + + long long leftFreq = (float) freq - ((float) bandwidth / 2.0); + long long rightFreq = leftFreq + (float) bandwidth; + + long long firstMhz = (leftFreq / 1000000) * 1000000; + long double mhzStart = ((long double) (firstMhz - leftFreq) / (long double) (rightFreq - leftFreq)) * 2.0; + + long double mhzStep = (100000.0 / (long double) (rightFreq - leftFreq)) * 2.0; + float mhzVisualStep = 0.1f; + + if (mhzStep * 0.5 * viewWidth > 400) { + mhzStep = (10000.0 / (long double) (rightFreq - leftFreq)) * 2.0; + mhzVisualStep = 0.01f; + } + + long double currentMhz = trunc(floor(firstMhz / 1000000.0)); + + std::stringstream label; + label.precision(2); + + float hPos = 1.0 - (16.0 / viewHeight); + float lMhzPos = 1.0 - (5.0 / viewHeight); + + for (float m = -1.0 + mhzStart, mMax = 1.0 + ((mhzStart>0)?mhzStart:-mhzStart); m <= mMax; m += mhzStep) { + label << std::fixed << currentMhz; + + double fractpart, intpart; + + fractpart = modf(currentMhz, &intpart); + + if (fractpart < 0.001) { + glLineWidth(4.0); + glColor3f(ThemeMgr::mgr.currentTheme->freqLine.r, ThemeMgr::mgr.currentTheme->freqLine.g, ThemeMgr::mgr.currentTheme->freqLine.b); + } else { + glLineWidth(1.0); + glColor3f(ThemeMgr::mgr.currentTheme->freqLine.r * 0.65, ThemeMgr::mgr.currentTheme->freqLine.g * 0.65, + ThemeMgr::mgr.currentTheme->freqLine.b * 0.65); + } + + glDisable(GL_TEXTURE_2D); + glBegin(GL_LINES); + glVertex2f(m, lMhzPos); + glVertex2f(m, 1); + glEnd(); + + glColor4f(ThemeMgr::mgr.currentTheme->text.r, ThemeMgr::mgr.currentTheme->text.g, ThemeMgr::mgr.currentTheme->text.b,1.0); + GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(label.str(), m, hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); + + label.str(std::string()); + + currentMhz += mhzVisualStep; + } + + glLineWidth(1.0); +} diff --git a/src/panel/SpectrumPanel.h b/src/panel/SpectrumPanel.h index a72c79f..af2d2f7 100644 --- a/src/panel/SpectrumPanel.h +++ b/src/panel/SpectrumPanel.h @@ -3,5 +3,29 @@ #include "GLPanel.h" class SpectrumPanel : public GLPanel { +public: + SpectrumPanel(); + void setPoints(std::vector &points); + + float getFloorValue() const; + void setFloorValue(float floorValue); + + float getCeilValue() const; + void setCeilValue(float ceilValue); + + void setFreq(long long freq); + long long getFreq(); + + void setBandwidth(long long bandwidth); + long long getBandwidth(); + +protected: + void drawPanelContents(); + +private: + float floorValue, ceilValue; + long long freq; + long long bandwidth; + std::vector points; }; \ No newline at end of file diff --git a/src/panel/WaterfallPanel.h b/src/panel/WaterfallPanel.h index b172635..3d44d6b 100644 --- a/src/panel/WaterfallPanel.h +++ b/src/panel/WaterfallPanel.h @@ -9,11 +9,13 @@ public: void refreshTheme(); void setPoints(std::vector &points); void step(); - void drawPanelContents(); std::vector points; bool needsUpdate; +protected: + void drawPanelContents(); + private: GLuint waterfall[2]; int waterfall_ofs[2]; diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index f27d355..1063c16 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -57,21 +57,14 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { ScopeRenderData *avData; inputData.pop(avData); - if (!avData) { - return; - } - - int iMax = avData->waveform_points.size(); - - if (!iMax) { + if (avData) { + if (avData->waveform_points.size()) { + scopePanel.setPoints(avData->waveform_points); + setStereo(avData->channels == 2); + } + avData->decRefCount(); - return; } - - scopePanel.setPoints(avData->waveform_points); - setStereo(avData->channels == 2); - - avData->decRefCount(); } glContext->SetCurrent(*this); diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index 5052f24..c9df1f0 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -29,7 +29,7 @@ wxEND_EVENT_TABLE() SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) : InteractiveCanvas(parent, attribList), waterfallCanvas(NULL) { - glContext = new SpectrumContext(this, &wxGetApp().GetContext(this)); + glContext = new PrimaryGLContext(this, &wxGetApp().GetContext(this)); mouseTracker.setVertDragLock(true); @@ -49,13 +49,12 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { visualDataQueue.pop(vData); - if (!vData) { - return; + if (vData) { + spectrumPanel.setPoints(vData->spectrum_points); + spectrumPanel.setFloorValue(vData->fft_floor); + spectrumPanel.setCeilValue(vData->fft_ceiling); + vData->decRefCount(); } - - spectrum_points.assign(vData->spectrum_points.begin(),vData->spectrum_points.end()); - - vData->decRefCount(); } @@ -64,9 +63,14 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glViewport(0, 0, ClientSize.x, ClientSize.y); - glContext->BeginDraw(ThemeMgr::mgr.currentTheme->fftBackground.r, ThemeMgr::mgr.currentTheme->fftBackground.g, ThemeMgr::mgr.currentTheme->fftBackground.b); - glContext->Draw(spectrum_points, getCenterFrequency(), getBandwidth()); + glContext->BeginDraw(0,0,0); + spectrumPanel.setFreq(getCenterFrequency()); + spectrumPanel.setBandwidth(getBandwidth()); + + spectrumPanel.calcTransform(CubicVR::mat4::identity()); + spectrumPanel.draw(); + std::vector &demods = wxGetApp().getDemodMgr().getDemodulators(); for (int i = 0, iMax = demods.size(); i < iMax; i++) { @@ -155,10 +159,6 @@ void SpectrumCanvas::attachWaterfallCanvas(WaterfallCanvas* canvas_in) { waterfallCanvas = canvas_in; } -SpectrumContext* SpectrumCanvas::getSpectrumContext() { - return glContext; -} - SpectrumVisualDataQueue *SpectrumCanvas::getVisualDataQueue() { return &visualDataQueue; } \ No newline at end of file diff --git a/src/visual/SpectrumCanvas.h b/src/visual/SpectrumCanvas.h index eb05e79..6c891ae 100644 --- a/src/visual/SpectrumCanvas.h +++ b/src/visual/SpectrumCanvas.h @@ -1,31 +1,24 @@ #pragma once -#include "wx/glcanvas.h" -#include "wx/timer.h" - #include #include #include "InteractiveCanvas.h" -#include "SpectrumContext.h" - -#include "fftw3.h" +#include "PrimaryGLContext.h" #include "MouseTracker.h" #include "SpectrumVisualProcessor.h" +#include "SpectrumPanel.h" class WaterfallCanvas; class SpectrumCanvas: public InteractiveCanvas { public: - std::vector spectrum_points; - SpectrumCanvas(wxWindow *parent, int *attribList = NULL); ~SpectrumCanvas(); void attachWaterfallCanvas(WaterfallCanvas *canvas_in); void moveCenterFrequency(long long freqChange); - SpectrumContext* getSpectrumContext(); SpectrumVisualDataQueue *getVisualDataQueue(); private: @@ -39,8 +32,9 @@ private: void OnMouseReleased(wxMouseEvent& event); void OnMouseLeftWindow(wxMouseEvent& event); - SpectrumContext *glContext; + PrimaryGLContext *glContext; WaterfallCanvas *waterfallCanvas; + SpectrumPanel spectrumPanel; SpectrumVisualDataQueue visualDataQueue; diff --git a/src/visual/SpectrumContext.cpp b/src/visual/SpectrumContext.cpp deleted file mode 100644 index 22b78b7..0000000 --- a/src/visual/SpectrumContext.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include "SpectrumContext.h" - -#include "SpectrumCanvas.h" -#include "CubicSDR.h" -#include -#include -#include "ColorTheme.h" - -SpectrumContext::SpectrumContext(SpectrumCanvas *canvas, wxGLContext *sharedContext) : - PrimaryGLContext(canvas, sharedContext), floorValue(0), ceilValue(1) { - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - -} - - -float SpectrumContext::getFloorValue() const { - return floorValue; -} - -void SpectrumContext::setFloorValue(float floorValue) { - this->floorValue = floorValue; -} - -float SpectrumContext::getCeilValue() const { - return ceilValue; -} - -void SpectrumContext::setCeilValue(float ceilValue) { - this->ceilValue = ceilValue; -} - -void SpectrumContext::Draw(std::vector &points, long long freq, int bandwidth) { - - glBegin(GL_QUADS); - glColor3f(ThemeMgr::mgr.currentTheme->fftBackground.r, ThemeMgr::mgr.currentTheme->fftBackground.g, ThemeMgr::mgr.currentTheme->fftBackground.b); - glVertex2f(1, 0.5); - glVertex2f(-1, 0.5); - glColor3f(ThemeMgr::mgr.currentTheme->fftBackground.r*2.0, ThemeMgr::mgr.currentTheme->fftBackground.g*2.0, ThemeMgr::mgr.currentTheme->fftBackground.b*2.0); - glVertex2f(-1, -1); - glVertex2f(1, -1); - glEnd(); - - - glDisable(GL_TEXTURE_2D); - - glEnable(GL_BLEND); - glEnable(GL_LINE_SMOOTH); - glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); - if (points.size()) { - glPushMatrix(); - glTranslatef(-1.0f, -0.75f, 0.0f); - glScalef(2.0f, 1.5f, 1.0f); - - - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - float range = ceilValue-floorValue; - float ranges[3][4] = { { 90.0, 5000.0, 10.0, 100.0 }, { 20.0, 150.0, 10.0, 10.0 }, { -20.0, 30.0, 10.0, 1.0 } }; - - for (int i = 0; i < 3; i++) { - float p = 0; - float rangeMin = ranges[i][0]; - float rangeMax = ranges[i][1]; - float rangeTrans = ranges[i][2]; - float rangeStep = ranges[i][3]; - - if (range >= rangeMin && range <= rangeMax) { - float a = 1.0; - - if (range <= rangeMin+rangeTrans) { - a *= (range-rangeMin)/rangeTrans; - } - if (range >= rangeMax-rangeTrans) { - a *= (rangeTrans-(range-(rangeMax-rangeTrans)))/rangeTrans; - } - - glColor4f(0.12, 0.12, 0.12, a); - glBegin(GL_LINES); - for (float l = floorValue; l<=ceilValue+rangeStep; l+=rangeStep) { - p += rangeStep/range; - glVertex2f(0,p); glVertex2f(1,p); - } - glEnd(); - } - } - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor3f(ThemeMgr::mgr.currentTheme->fftLine.r, ThemeMgr::mgr.currentTheme->fftLine.g, ThemeMgr::mgr.currentTheme->fftLine.b); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, &points[0]); - glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2); - glDisableClientState(GL_VERTEX_ARRAY); - glPopMatrix(); - } - - GLint vp[4]; - glGetIntegerv( GL_VIEWPORT, vp); - - float viewHeight = (float) vp[3]; - float viewWidth = (float) vp[2]; - - long long leftFreq = (float) freq - ((float) bandwidth / 2.0); - long long rightFreq = leftFreq + (float) bandwidth; - - long long firstMhz = (leftFreq / 1000000) * 1000000; - long double mhzStart = ((long double) (firstMhz - leftFreq) / (long double) (rightFreq - leftFreq)) * 2.0; - - long double mhzStep = (100000.0 / (long double) (rightFreq - leftFreq)) * 2.0; - float mhzVisualStep = 0.1f; - - if (mhzStep * 0.5 * viewWidth > 400) { - mhzStep = (10000.0 / (long double) (rightFreq - leftFreq)) * 2.0; - mhzVisualStep = 0.01f; - } - - long double currentMhz = trunc(floor(firstMhz / 1000000.0)); - - std::stringstream label; - label.precision(2); - - float hPos = 1.0 - (16.0 / viewHeight); - float lMhzPos = 1.0 - (5.0 / viewHeight); - - for (float m = -1.0 + mhzStart, mMax = 1.0 + fabs(mhzStart); m <= mMax; m += mhzStep) { - label << std::fixed << currentMhz; - - double fractpart, intpart; - - fractpart = modf(currentMhz, &intpart); - - if (fractpart < 0.001) { - glLineWidth(4.0); - glColor3f(ThemeMgr::mgr.currentTheme->freqLine.r, ThemeMgr::mgr.currentTheme->freqLine.g, ThemeMgr::mgr.currentTheme->freqLine.b); - } else { - glLineWidth(1.0); - glColor3f(ThemeMgr::mgr.currentTheme->freqLine.r * 0.65, ThemeMgr::mgr.currentTheme->freqLine.g * 0.65, - ThemeMgr::mgr.currentTheme->freqLine.b * 0.65); - } - - glDisable(GL_TEXTURE_2D); - glBegin(GL_LINES); - glVertex2f(m, lMhzPos); - glVertex2f(m, 1); - glEnd(); - - glColor4f(ThemeMgr::mgr.currentTheme->text.r, ThemeMgr::mgr.currentTheme->text.g, ThemeMgr::mgr.currentTheme->text.b,1.0); - GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(label.str(), m, hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); - - label.str(std::string()); - - currentMhz += mhzVisualStep; - } - - glLineWidth(1.0); - -// getFont(PrimaryGLContext::GLFONT_SIZE16).drawString("Welcome to CubicSDR -- This is a test string. 01234567890!@#$%^&*()_[]",0.0,0.0,16,GLFont::GLFONT_ALIGN_CENTER,GLFont::GLFONT_ALIGN_CENTER); - CheckGLError(); -} diff --git a/src/visual/SpectrumContext.h b/src/visual/SpectrumContext.h deleted file mode 100644 index 03cc82a..0000000 --- a/src/visual/SpectrumContext.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "PrimaryGLContext.h" -#include "Gradient.h" - -#define NUM_WATERFALL_LINES 512 - -class SpectrumCanvas; - -class SpectrumContext: public PrimaryGLContext { -public: - SpectrumContext(SpectrumCanvas *canvas, wxGLContext *sharedContext); - - void Draw(std::vector &points, long long freq, int bandwidth); - - float getFloorValue() const; - void setFloorValue(float floorValue); - float getCeilValue() const; - void setCeilValue(float ceilValue); - -private: - float floorValue, ceilValue; -}; diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index e9a93ff..3f13d9b 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -139,7 +139,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glContext->SetCurrent(*this); initGLExtensions(); glViewport(0, 0, ClientSize.x, ClientSize.y); - + if (!visualDataQueue.empty()) { SpectrumVisualData *vData; @@ -148,9 +148,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { if (vData) { waterfallPanel.setPoints(vData->spectrum_points); waterfallPanel.step(); + vData->decRefCount(); } - - vData->decRefCount(); } glContext->BeginDraw(0,0,0);