diff --git a/src/visual/PrimaryGLContext.cpp b/src/visual/PrimaryGLContext.cpp index 654b8e7..fab77ba 100644 --- a/src/visual/PrimaryGLContext.cpp +++ b/src/visual/PrimaryGLContext.cpp @@ -141,7 +141,7 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, float r, float glVertex3f(uxPos + ofs, hPos + labelHeight, 0.0); glEnd(); - glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); glColor4f(r, g, b, 0.2); glBegin(GL_QUADS); @@ -189,11 +189,10 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, float r, float g, f float uxPos = (float) (demod->getFrequency() - (center_freq - srate / 2)) / (float) srate; - glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); glColor4f(r, g, b, 0.6); glBegin(GL_LINES); @@ -210,7 +209,7 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, float r, float g, f glEnd(); - glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); glColor4f(r, g, b, 0.2); glBegin(GL_QUADS); glVertex3f((uxPos - 0.5) * 2.0 - ofs, 1.0, 0.0); @@ -267,7 +266,6 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, float r, float g, f getFont(PrimaryGLContext::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5), -1.0 + hPos, 16, demodAlign, GLFont::GLFONT_ALIGN_CENTER); glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); } @@ -286,11 +284,10 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, float r, float g, float b, srate = wxGetApp().getSampleRate(); } - glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); glColor4f(r, g, b, 0.6); glBegin(GL_LINES); @@ -313,7 +310,6 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, float r, float g, float b, glEnd(); glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); } diff --git a/src/visual/WaterfallContext.cpp b/src/visual/WaterfallContext.cpp index 031fd02..94fcbc8 100644 --- a/src/visual/WaterfallContext.cpp +++ b/src/visual/WaterfallContext.cpp @@ -3,91 +3,124 @@ #include "CubicSDR.h" WaterfallContext::WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext) : - PrimaryGLContext(canvas, sharedContext), waterfall(0), waterfall_tex(NULL), waterfall_lines(0), fft_size(0), activeTheme(NULL) { + PrimaryGLContext(canvas, sharedContext), waterfall_lines(0), fft_size(0), activeTheme(NULL) { + for (int i = 0; i < 2; i++) { + waterfall[i] = 0; + waterfall_tex[i] = 0; + } } void WaterfallContext::Setup(int fft_size_in, int num_waterfall_lines_in) { - if (waterfall) { - glDeleteTextures(1, &waterfall); - waterfall = 0; - } - if (waterfall_tex) { - delete waterfall_tex; - } - waterfall_lines = num_waterfall_lines_in; fft_size = fft_size_in; - waterfall_tex = new unsigned char[fft_size * waterfall_lines]; - memset(waterfall_tex, 0, fft_size * waterfall_lines); + int half_fft_size = fft_size / 2; + + for (int i = 0; i < 2; i++) { + if (waterfall[i]) { + glDeleteTextures(1, &waterfall[i]); + waterfall[i] = 0; + } + if (waterfall_tex[i]) { + delete waterfall_tex[i]; + } + + waterfall_tex[i] = new unsigned char[half_fft_size * waterfall_lines]; + memset(waterfall_tex[i], 0, half_fft_size * waterfall_lines); + } } void WaterfallContext::refreshTheme() { glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, waterfall); - glPixelTransferi(GL_MAP_COLOR, GL_TRUE); - glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 256, &(ThemeMgr::mgr.currentTheme->waterfallGradient.getRed())[0]); - glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 256, &(ThemeMgr::mgr.currentTheme->waterfallGradient.getGreen())[0]); - glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, &(ThemeMgr::mgr.currentTheme->waterfallGradient.getBlue())[0]); + for (int i = 0; i < 2; i++) { + glBindTexture(GL_TEXTURE_2D, waterfall[i]); + + glPixelTransferi(GL_MAP_COLOR, GL_TRUE); + glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 256, &(ThemeMgr::mgr.currentTheme->waterfallGradient.getRed())[0]); + glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 256, &(ThemeMgr::mgr.currentTheme->waterfallGradient.getGreen())[0]); + glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, &(ThemeMgr::mgr.currentTheme->waterfallGradient.getBlue())[0]); + } } void WaterfallContext::Draw(std::vector &points) { - if (!waterfall) { - glGenTextures(1, &waterfall); + glEnable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, waterfall); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (!waterfall[0]) { + glGenTextures(2, waterfall); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } + for (int i = 0; i < 2; i++) { + glBindTexture(GL_TEXTURE_2D, waterfall[i]); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + } if (activeTheme != ThemeMgr::mgr.currentTheme) { refreshTheme(); activeTheme = ThemeMgr::mgr.currentTheme; } - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + int half_fft_size = fft_size / 2; if (points.size()) { - memmove(waterfall_tex + fft_size, waterfall_tex, (waterfall_lines - 1) * fft_size); + for (int j = 0; j < 2; j++) { + memmove(waterfall_tex[j] + half_fft_size, waterfall_tex[j], (waterfall_lines - 1) * half_fft_size); - for (int i = 0, iMax = fft_size; i < iMax; i++) { - float v = points[i * 2 + 1]; + for (int i = 0, iMax = half_fft_size; i < iMax; i++) { + float v = points[(j * half_fft_size + i) * 2 + 1]; - float wv = v; - if (wv < 0.0) - wv = 0.0; - if (wv > 0.99) - wv = 0.99; - waterfall_tex[i] = (unsigned char) floor(wv * 255.0); + float wv = v; + if (wv < 0.0) + wv = 0.0; + if (wv > 0.99) + wv = 0.99; + waterfall_tex[j][i] = (unsigned char) floor(wv * 255.0); + } } + } - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, waterfall); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fft_size, waterfall_lines, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid *) waterfall_tex); + for (int i = 0; i < 2; i++) { + glBindTexture(GL_TEXTURE_2D, waterfall[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, half_fft_size, waterfall_lines, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid *) waterfall_tex[i]); + } glColor3f(1.0, 1.0, 1.0); - glBindTexture(GL_TEXTURE_2D, waterfall); + glBindTexture(GL_TEXTURE_2D, waterfall[0]); glBegin(GL_QUADS); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0); glTexCoord2f(1.0, 1.0); + glVertex3f(0.0, -1.0, 0.0); + glTexCoord2f(1.0, 0.0); + glVertex3f(0.0, 1.0, 0.0); + glTexCoord2f(0.0, 0.0); + glVertex3f(-1.0, 1.0, 0.0); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, waterfall[1]); + glBegin(GL_QUADS); + glTexCoord2f(0.0, 1.0); + glVertex3f(0.0, -1.0, 0.0); + glTexCoord2f(1.0, 1.0); glVertex3f(1.0, -1.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); - glVertex3f(-1.0, 1.0, 0.0); + glVertex3f(0.0, 1.0, 0.0); glEnd(); + glBindTexture(GL_TEXTURE_2D, 0); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_TEXTURE_2D); } diff --git a/src/visual/WaterfallContext.h b/src/visual/WaterfallContext.h index 507d338..18dfaca 100644 --- a/src/visual/WaterfallContext.h +++ b/src/visual/WaterfallContext.h @@ -15,8 +15,8 @@ public: void refreshTheme(); private: - GLuint waterfall; - unsigned char *waterfall_tex; + GLuint waterfall[2]; + unsigned char *waterfall_tex[2]; int fft_size; int waterfall_lines;