diff --git a/CMakeLists.txt b/CMakeLists.txt index ced47f1..63c4ae2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,6 +200,7 @@ SET (cubicsdr_sources src/util/Gradient.cpp src/util/Timer.cpp src/util/MouseTracker.cpp + src/util/GLExt.cpp src/util/GLFont.cpp src/util/DataTree.cpp src/visual/ColorTheme.cpp @@ -242,6 +243,7 @@ SET (cubicsdr_headers src/util/Timer.h src/util/ThreadQueue.h src/util/MouseTracker.h + src/util/GLExt.h src/util/GLFont.h src/util/DataTree.h src/visual/ColorTheme.h diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 9a68285..51c98d9 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -42,7 +42,15 @@ wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(NULL) { wxBoxSizer *demodTray = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *demodScopeTray = new wxBoxSizer(wxVERTICAL); - demodModeSelector = new ModeSelectorCanvas(this, NULL); + int attribList[] = { + WX_GL_RGBA, + WX_GL_STENCIL_SIZE, 8, + WX_GL_BUFFER_SIZE, 24, + WX_GL_DOUBLEBUFFER, + 0 + }; + + demodModeSelector = new ModeSelectorCanvas(this, attribList); demodModeSelector->addChoice(DEMOD_TYPE_FM, "FM"); demodModeSelector->addChoice(DEMOD_TYPE_AM, "AM"); demodModeSelector->addChoice(DEMOD_TYPE_LSB, "LSB"); @@ -53,14 +61,14 @@ wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(NULL) { // demodTray->AddSpacer(2); - demodSpectrumCanvas = new SpectrumCanvas(this, NULL); + demodSpectrumCanvas = new SpectrumCanvas(this, attribList); demodSpectrumCanvas->setup(1024); demodSpectrumCanvas->setView(DEFAULT_FREQ, 300000); demodVisuals->Add(demodSpectrumCanvas, 3, wxEXPAND | wxALL, 0); demodVisuals->AddSpacer(1); - demodWaterfallCanvas = new WaterfallCanvas(this, NULL); + demodWaterfallCanvas = new WaterfallCanvas(this, attribList); demodWaterfallCanvas->setup(1024, 128); demodWaterfallCanvas->setView(DEFAULT_FREQ, 300000); demodWaterfallCanvas->attachSpectrumCanvas(demodSpectrumCanvas); @@ -71,19 +79,19 @@ wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(NULL) { demodTray->AddSpacer(1); - demodSignalMeter = new MeterCanvas(this, NULL); + demodSignalMeter = new MeterCanvas(this, attribList); demodSignalMeter->setMax(0.5); demodSignalMeter->setHelpTip("Current Signal Level. Click / Drag to set Squelch level."); demodTray->Add(demodSignalMeter, 1, wxEXPAND | wxALL, 0); demodTray->AddSpacer(1); - scopeCanvas = new ScopeCanvas(this, NULL); + scopeCanvas = new ScopeCanvas(this, attribList); demodScopeTray->Add(scopeCanvas, 8, wxEXPAND | wxALL, 0); demodScopeTray->AddSpacer(1); - demodTuner = new TuningCanvas(this, NULL); + demodTuner = new TuningCanvas(this, attribList); demodTuner->setHelpTip("Testing tuner"); demodScopeTray->Add(demodTuner, 1, wxEXPAND | wxALL, 0); @@ -91,18 +99,18 @@ wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(NULL) { demodTray->AddSpacer(1); - demodGainMeter = new MeterCanvas(this, NULL); + demodGainMeter = new MeterCanvas(this, attribList); demodGainMeter->setMax(2.0); demodGainMeter->setHelpTip("Current Demodulator Gain Level. Click / Drag to set Gain level."); demodTray->Add(demodGainMeter, 1, wxEXPAND | wxALL, 0); vbox->Add(demodTray, 12, wxEXPAND | wxALL, 0); vbox->AddSpacer(1); - spectrumCanvas = new SpectrumCanvas(this, NULL); + spectrumCanvas = new SpectrumCanvas(this, attribList); spectrumCanvas->setup(2048); vbox->Add(spectrumCanvas, 5, wxEXPAND | wxALL, 0); vbox->AddSpacer(1); - waterfallCanvas = new WaterfallCanvas(this, NULL); + waterfallCanvas = new WaterfallCanvas(this, attribList); waterfallCanvas->setup(2048, 512); waterfallCanvas->attachSpectrumCanvas(spectrumCanvas); waterfallCanvas->attachWaterfallCanvas(demodWaterfallCanvas); diff --git a/src/CubicSDR.h b/src/CubicSDR.h index ec57720..d841ad7 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -6,7 +6,7 @@ #include -#include "wx/glcanvas.h" +#include "GLExt.h" #include "PrimaryGLContext.h" #include "ThreadQueue.h" diff --git a/src/util/GLExt.cpp b/src/util/GLExt.cpp new file mode 100644 index 0000000..7d01733 --- /dev/null +++ b/src/util/GLExt.cpp @@ -0,0 +1,66 @@ +#include "GLExt.h" +#include +#include + +#ifdef _WIN32 + +PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT = NULL; +PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL; +PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL; + +bool GLExtSupported(const char *extension_name) { + const GLubyte *extensions = glGetString(GL_EXTENSIONS); + + return (std::strstr((const char *)extensions, extension_name) != NULL); +} + +#endif + + +bool GLExt_initialized = false; + +void initGLExtensions() { + if (GLExt_initialized) { + return; + } + + const GLubyte *extensions = glGetString(GL_EXTENSIONS); + + std::cout << "Supported GL Extensions: " << extensions << std::endl; + + int interval = 2; + +#ifdef _WIN32 + if (GLExtSupported("WGL_EXT_swap_control")) { + std::cout << "Initializing WGL swap control extensions.." << std::endl; + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT"); + wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) wglGetProcAddress("wglGetSwapIntervalEXT"); + + wglSwapIntervalEXT(interval); + } +#endif + +#ifdef __APPLE__ + long l_interval= interval; + CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &l_interval); +#endif + +/* +#ifdef LINUX + char* pcDummy = NULL; + + glXSwapIntervalSGIFunc glXSwapIntervalSGI = 0; + glXSwapIntervalMESAFunc glXSwapIntervalMESA = 0; + + pcDummy = (char*)glXQueryExtensionsString (glXGetCurrentDisplay(), 0); + if (strstr (pcDummy, "GLX_SGI_swap_control") != NULL) { + glXSwapIntervalSGI = (glXSwapIntervalSGIFunc) dlsym(RTLD_DEFAULT,"glXSwapIntervalSGI") && glXSwapIntervalSGI (interval); + + } else if (strstr(pcDummy, "GLX_MESA_swap_control") != NULL) { + glXSwapIntervalMESA = (glXSwapIntervalMESAFunc) dlsym(RTLD_DEFAULT,"glXSwapIntervalMESA") && glXSwapIntervalMESA (interval); + } +#endif +*/ + + GLExt_initialized = true; +} diff --git a/src/util/GLExt.h b/src/util/GLExt.h new file mode 100644 index 0000000..86d6cf1 --- /dev/null +++ b/src/util/GLExt.h @@ -0,0 +1,20 @@ +#pragma once + +#include "wx/glcanvas.h" + +#ifdef _WIN32 +#include +#include + +extern PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT; +extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; +extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; + +bool GLExtSupported(const char *extension_name); + +#endif + +extern bool GLExt_initialized; + +void initGLExtensions(); + diff --git a/src/visual/MeterCanvas.cpp b/src/visual/MeterCanvas.cpp index 0dd0770..3014f8f 100644 --- a/src/visual/MeterCanvas.cpp +++ b/src/visual/MeterCanvas.cpp @@ -63,6 +63,8 @@ void MeterCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { const wxSize ClientSize = GetClientSize(); glContext->SetCurrent(*this); + initGLExtensions(); + glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->DrawBegin(); diff --git a/src/visual/ModeSelectorCanvas.cpp b/src/visual/ModeSelectorCanvas.cpp index 0a8904e..f067d6d 100644 --- a/src/visual/ModeSelectorCanvas.cpp +++ b/src/visual/ModeSelectorCanvas.cpp @@ -50,6 +50,8 @@ void ModeSelectorCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { const wxSize ClientSize = GetClientSize(); glContext->SetCurrent(*this); + initGLExtensions(); + glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->DrawBegin(); diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index ca6ae50..dc2a972 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -67,6 +67,8 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { } glContext->SetCurrent(*this); + initGLExtensions(); + glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->DrawBegin(); diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index 86f9873..f894f0f 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -70,6 +70,8 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { const wxSize ClientSize = GetClientSize(); glContext->SetCurrent(*this); + initGLExtensions(); + glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->BeginDraw(ThemeMgr::mgr.currentTheme->fftBackground.r, ThemeMgr::mgr.currentTheme->fftBackground.g, ThemeMgr::mgr.currentTheme->fftBackground.b); diff --git a/src/visual/TuningCanvas.cpp b/src/visual/TuningCanvas.cpp index 4996131..dab1aaf 100644 --- a/src/visual/TuningCanvas.cpp +++ b/src/visual/TuningCanvas.cpp @@ -39,6 +39,7 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { const wxSize ClientSize = GetClientSize(); glContext->SetCurrent(*this); + initGLExtensions(); glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->DrawBegin(); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 3f82261..10e0fcc 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -116,7 +116,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { } glContext->SetCurrent(*this); - glViewport(0, 0, ClientSize.x, ClientSize.y); + initGLExtensions(); + glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->BeginDraw(0,0,0); glContext->Draw(spectrum_points);