void OpenGL2Common::testGLInternal() { int glMajor = 0, glMinor = 0; #ifndef OPENGL_ES2 glGetIntegerv(GL_MAJOR_VERSION, &glMajor); glGetIntegerv(GL_MINOR_VERSION, &glMinor); #endif if (!glMajor) { const QString glVersionStr = (const char *)glGetString(GL_VERSION); const int dotIdx = glVersionStr.indexOf('.'); if (dotIdx > 0) { const int vIdx = glVersionStr.lastIndexOf(' ', dotIdx); if (sscanf(glVersionStr.mid(vIdx < 0 ? 0 : vIdx).toLatin1().data(), "%d.%d", &glMajor, &glMinor) != 2) glMajor = glMinor = 0; } } if (glMajor) glVer = glMajor * 10 + glMinor; #ifndef OPENGL_ES2 initGLProc(); if (!canCreateNonPowerOfTwoTextures || !supportsShaders || !glActiveTexture) { showOpenGLMissingFeaturesMessage(); isOK = false; } /* Reset variables */ supportsShaders = canCreateNonPowerOfTwoTextures = false; glActiveTexture = NULL; #endif QWidget *w = widget(); w->grabGesture(Qt::PinchGesture); w->setMouseTracking(true); #ifdef Q_OS_WIN /* * This property is read by QMPlay2 and it ensures that toolbar will be visible * on fullscreen in Windows Vista and newer on nVidia and AMD drivers. */ if (preventFullscreen && QSysInfo::windowsVersion() >= QSysInfo::WV_6_0) w->setProperty("PreventFullscreen", true); #endif }
void OpenGL2Common::testGLInternal() { int glMajor = 0, glMinor = 0; #ifndef OPENGL_ES2 glGetIntegerv(GL_MAJOR_VERSION, &glMajor); glGetIntegerv(GL_MINOR_VERSION, &glMinor); #endif #ifndef Q_OS_MACOS //On macOS I have always OpenGL 2.1... if (!glMajor) { const QString glVersionStr = (const char *)glGetString(GL_VERSION); const int dotIdx = glVersionStr.indexOf('.'); if (dotIdx > 0) { const int vIdx = glVersionStr.lastIndexOf(' ', dotIdx); if (sscanf(glVersionStr.mid(vIdx < 0 ? 0 : vIdx).toLatin1().constData(), "%d.%d", &glMajor, &glMinor) != 2) glMajor = glMinor = 0; } } if (glMajor) glVer = glMajor * 10 + glMinor; canUseHueSharpness = (glVer >= 30); #endif #ifndef OPENGL_ES2 initGLProc(); //No need to call it here for OpenGL|ES if (!canCreateNonPowerOfTwoTextures || !supportsShaders || !glActiveTexture) { showOpenGLMissingFeaturesMessage(); isOK = false; } /* Reset variables */ supportsShaders = canCreateNonPowerOfTwoTextures = false; glActiveTexture = nullptr; #endif numPlanes = 3; target = GL_TEXTURE_2D; if (hwAccellnterface) { switch (hwAccellnterface->getFormat()) { case HWAccelInterface::NV12: numPlanes = 2; break; case HWAccelInterface::RGB32: numPlanes = 1; break; } if (hwAccellnterface->isTextureRectangle()) { target = GL_TEXTURE_RECTANGLE_ARB; if (numPlanes == 1) isOK = false; // Not used and not supported hqScaling = false; // Not yet supported } if (isOK) { quint32 textures[numPlanes]; memset(textures, 0, sizeof textures); glGenTextures(numPlanes, textures); if (hwAccellnterface->canInitializeTextures()) { for (int p = 0; p < numPlanes; ++p) { glBindTexture(target, textures[p]); if (numPlanes == 2) glTexImage2D(target, 0, !p ? GL_R8 : GL_RG8, 1, 1, 0, !p ? GL_RED : GL_RG, GL_UNSIGNED_BYTE, nullptr); else if (numPlanes == 1) glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); } } if (!hwAccellnterface->lock()) isOK = false; else { if (!hwAccellnterface->init(textures)) isOK = false; if (numPlanes == 1) //For RGB32 format, HWAccel should be able to adjust the video { VideoAdjustment videoAdjustmentCap; hwAccellnterface->getVideAdjustmentCap(videoAdjustmentCap); if (videoAdjustmentCap.brightness) videoAdjustmentKeys += "Brightness"; if (videoAdjustmentCap.contrast) videoAdjustmentKeys += "Contrast"; if (videoAdjustmentCap.saturation) videoAdjustmentKeys += "Saturation"; if (videoAdjustmentCap.hue) videoAdjustmentKeys += "Hue"; if (videoAdjustmentCap.sharpness) videoAdjustmentKeys += "Sharpness"; } hwAccellnterface->clear(true); hwAccellnterface->unlock(); } glDeleteTextures(numPlanes, textures); } } QWidget *w = widget(); w->grabGesture(Qt::PinchGesture); w->setMouseTracking(true); #ifdef Q_OS_WIN /* * This property is read by QMPlay2 and it ensures that toolbar will be visible * on fullscreen in Windows Vista and newer on nVidia and AMD drivers. */ const bool canPreventFullScreen = (qstrcmp(w->metaObject()->className(), "QOpenGLWidget") != 0); const QSysInfo::WinVersion winVer = QSysInfo::windowsVersion(); if (canPreventFullScreen && winVer >= QSysInfo::WV_6_0) { Qt::CheckState compositionEnabled; if (!preventFullScreen) compositionEnabled = Qt::PartiallyChecked; else { compositionEnabled = Qt::Checked; if (winVer <= QSysInfo::WV_6_1) //Windows 8 and 10 can't disable DWM composition { using DwmIsCompositionEnabledProc = HRESULT (WINAPI *)(BOOL *pfEnabled); DwmIsCompositionEnabledProc DwmIsCompositionEnabled = (DwmIsCompositionEnabledProc)GetProcAddress(GetModuleHandleA("dwmapi.dll"), "DwmIsCompositionEnabled"); if (DwmIsCompositionEnabled) { BOOL enabled = false; if (DwmIsCompositionEnabled(&enabled) == S_OK && !enabled) compositionEnabled = Qt::PartiallyChecked; } } } w->setProperty("preventFullScreen", (int)compositionEnabled); } #endif }
void OpenGL2Common::initializeGL() { initGLProc(); #ifndef OPENGL_ES2 if (!glActiveTexture) //Be sure that "glActiveTexture" has valid pointer (don't check "supportsShaders" here)! { showOpenGLMissingFeaturesMessage(); isOK = false; return; } #endif delete shaderProgramVideo; delete shaderProgramOSD; shaderProgramVideo = new QOpenGLShaderProgram; shaderProgramOSD = new QOpenGLShaderProgram; /* YCbCr shader */ shaderProgramVideo->addShaderFromSourceCode(QOpenGLShader::Vertex, readShader(":/Video.vert")); QByteArray videoFrag; if (numPlanes == 1) { videoFrag = readShader(":/VideoRGB.frag"); if (canUseHueSharpness) { //Use sharpness only when OpenGL/OpenGL|ES version >= 3.0, because it can be slow on old hardware and/or buggy drivers and may increase CPU usage! videoFrag.prepend("#define Sharpness\n"); } } else { videoFrag = readShader(":/VideoYCbCr.frag"); if (canUseHueSharpness) { //Use hue and sharpness only when OpenGL/OpenGL|ES version >= 3.0, because it can be slow on old hardware and/or buggy drivers and may increase CPU usage! videoFrag.prepend("#define HueAndSharpness\n"); } if (numPlanes == 2) videoFrag.prepend("#define NV12\n"); } if (target == GL_TEXTURE_RECTANGLE_ARB) videoFrag.prepend("#define TEXTURE_RECTANGLE\n"); if (hqScaling) { constexpr const char *getTexelDefine = "#define getTexel texture\n"; Q_ASSERT(videoFrag.contains(getTexelDefine)); videoFrag.replace(getTexelDefine, readShader(":/Bicubic.frag", true)); } shaderProgramVideo->addShaderFromSourceCode(QOpenGLShader::Fragment, videoFrag); if (shaderProgramVideo->bind()) { texCoordYCbCrLoc = shaderProgramVideo->attributeLocation("aTexCoord"); positionYCbCrLoc = shaderProgramVideo->attributeLocation("aPosition"); shaderProgramVideo->setUniformValue((numPlanes == 1) ? "uRGB" : "uY" , 0); if (numPlanes == 2) shaderProgramVideo->setUniformValue("uCbCr", 1); else if (numPlanes == 3) { shaderProgramVideo->setUniformValue("uCb", 1); shaderProgramVideo->setUniformValue("uCr", 2); } shaderProgramVideo->release(); } else { QMPlay2Core.logError(tr("Shader compile/link error")); isOK = false; return; } /* OSD shader */ shaderProgramOSD->addShaderFromSourceCode(QOpenGLShader::Vertex, readShader(":/OSD.vert")); shaderProgramOSD->addShaderFromSourceCode(QOpenGLShader::Fragment, readShader(":/OSD.frag")); if (shaderProgramOSD->bind()) { texCoordOSDLoc = shaderProgramOSD->attributeLocation("aTexCoord"); positionOSDLoc = shaderProgramOSD->attributeLocation("aPosition"); shaderProgramOSD->setUniformValue("uTex", 3); shaderProgramOSD->release(); } else { QMPlay2Core.logError(tr("Shader compile/link error")); isOK = false; return; } /* Set OpenGL parameters */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); glDisable(GL_DITHER); /* Prepare textures */ glGenTextures(numPlanes + 1, textures); for (int i = 0; i < numPlanes + 1; ++i) { const quint32 tmpTarget = (i == 0) ? GL_TEXTURE_2D : target; qint32 tmpParam = (i == 0) ? GL_NEAREST : GL_LINEAR; glBindTexture(tmpTarget, textures[i]); glTexParameteri(tmpTarget, GL_TEXTURE_MIN_FILTER, tmpParam); glTexParameteri(tmpTarget, GL_TEXTURE_MAG_FILTER, tmpParam); glTexParameteri(tmpTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(tmpTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } if (hasPbo) { glGenBuffers(1 + (hwAccellnterface ? 0 : numPlanes), pbo); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } setVSync(vSync); doReset = true; resetSphereVbo(); }
void OpenGL2Common::initializeGL() { #ifndef OPENGL_ES2 initGLProc(); if (!glActiveTexture) //Be sure that "glActiveTexture" has valid pointer (don't check "supportsShaders" here)! { showOpenGLMissingFeaturesMessage(); isOK = false; return; } #endif #ifndef DONT_RECREATE_SHADERS delete shaderProgramYCbCr; delete shaderProgramOSD; shaderProgramYCbCr = shaderProgramOSD = NULL; #endif if (!shaderProgramYCbCr) shaderProgramYCbCr = new QOpenGLShaderProgram; if (!shaderProgramOSD) shaderProgramOSD = new QOpenGLShaderProgram; /* YCbCr shader */ if (shaderProgramYCbCr->shaders().isEmpty()) { shaderProgramYCbCr->addShaderFromSourceCode(QOpenGLShader::Vertex, vShaderYCbCrSrc); /* Use hue only when OpenGL/OpenGL|ES version >= 3.0, because it can be slow on old hardware and/or buggy drivers and may increase CPU usage! */ shaderProgramYCbCr->addShaderFromSourceCode(QOpenGLShader::Fragment, QString(fShaderYCbCrSrc).arg((glVer >= 30) ? fShaderYCbCrHueSrc : "")); } if (shaderProgramYCbCr->bind()) { const qint32 newTexCoordLoc = shaderProgramYCbCr->attributeLocation("aTexCoord"); const qint32 newPositionLoc = shaderProgramYCbCr->attributeLocation("vPosition"); if (newTexCoordLoc != newPositionLoc) //If new locations are invalid, just leave them untouched... { texCoordYCbCrLoc = newTexCoordLoc; positionYCbCrLoc = newPositionLoc; } shaderProgramYCbCr->setUniformValue("Ytex", 0); shaderProgramYCbCr->setUniformValue("Utex", 1); shaderProgramYCbCr->setUniformValue("Vtex", 2); shaderProgramYCbCr->release(); } else { QMPlay2Core.logError(tr("Shader compile/link error")); isOK = false; return; } /* OSD shader */ if (shaderProgramOSD->shaders().isEmpty()) { shaderProgramOSD->addShaderFromSourceCode(QOpenGLShader::Vertex, vShaderOSDSrc); shaderProgramOSD->addShaderFromSourceCode(QOpenGLShader::Fragment, fShaderOSDSrc); } if (shaderProgramOSD->bind()) { const qint32 newTexCoordLoc = shaderProgramOSD->attributeLocation("aTexCoord"); const qint32 newPositionLoc = shaderProgramOSD->attributeLocation("vPosition"); if (newTexCoordLoc != newPositionLoc) //If new locations are invalid, just leave them untouched... { texCoordOSDLoc = newTexCoordLoc; positionOSDLoc = newPositionLoc; } shaderProgramOSD->setUniformValue("tex", 3); shaderProgramOSD->release(); } else { QMPlay2Core.logError(tr("Shader compile/link error")); isOK = false; return; } /* Set OpenGL parameters */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); glDisable(GL_DITHER); /* Prepare textures */ for (int i = 1; i <= 4; ++i) { glBindTexture(GL_TEXTURE_2D, i); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, i == 1 ? GL_NEAREST : GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, i == 1 ? GL_NEAREST : GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } doReset = true; }