bool ShaderLibrary::setTextureVariable(QString const& shader, QString const& variable, Texture const& texture) { QSizeF size(1.0/texture.size.width(), 1.0/texture.size.height()); setUniformVariable(shader, variable+"_delta", size); setUniformVariable(shader, variable, texture); return true; }
void ShaderLibrary::bindNormalMap(GLfloat near0, GLfloat far0) { bindShader("Normal Map"); s_normalBuffer->bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); setUniformVariable("Normal Map", "Near", near0); setUniformVariable("Normal Map", "Far", far0); }
void KisOpenGLHDRExposureProgram::setExposureUniformVariable() { Q_ASSERT(active()); float exposure = pow(2, m_exposure + 2.47393); setUniformVariable("exposure", exposure, exposure, exposure, 1.0); }
void ShaderLibrary::initializeTextures() { int nSamples = 16; // This is set in the shader too GLfloat* angles = new GLfloat[2*nSamples]; GLfloat angle = (GLfloat)M_PI_4; GLfloat radius = 0.415f; // This is the maximum length of the vector for (int i = 0; i < nSamples; ++i) { angles[2*i+0] = radius * cos(angle) * (i+1.0)/16.0f; angles[2*i+1] = radius * sin(angle) * (i+1.0)/16.0f; angle += (float)M_PI_2; if (((i + 1) % 4) == 0) angle += 0.375*M_PI; } GLFloatArray array; array.type = GLfloat2v; array.size = nSamples; array.ptr = angles; setUniformVariable("Filters", "SamplingVectors", array); delete angles; // generate a 64 x 64 rotation texture for rotating the sampling vectors srand(time(0)); int n(s_rotationTextureSize); s_rotationTextureData = new GLfloat[4*n*n]; angle = (2.0*M_PI) * rand() / RAND_MAX; for (int i = 0; i < n*n; ++i) { s_rotationTextureData[4*i+0] = 0.5f*cos(angle) + 0.5f; s_rotationTextureData[4*i+1] = 0.5f*sin(angle) + 0.5f; s_rotationTextureData[4*i+2] = -0.5f*sin(angle) + 0.5f; s_rotationTextureData[4*i+3] = 0.5f*cos(angle) + 0.5f; angle += (2.0*M_PI) * rand() / RAND_MAX; } for (int i = 0; i < n*n; ++i) { s_rotationTextureData[4*i+0] = 1.0; s_rotationTextureData[4*i+1] = 0.0; s_rotationTextureData[4*i+2] = 0.0; s_rotationTextureData[4*i+3] = 1.0; } glGenTextures(1, &s_rotationTextureId); Texture texture; texture.id = s_rotationTextureId; texture.size = QSize(n, n); texture.slot = RotationTexture; texture.data = s_rotationTextureData; setTextureVariable("Filters", "RotationTexture", texture); }
void ShaderLibrary::resizeScreenBuffers(QSize const& windowSize, double* projectionMatrix) { if (!filtersAvailable()) return; if (s_normalBuffer) delete s_normalBuffer; if (s_filterBuffer) delete s_filterBuffer; s_normalBuffer = new QGLFramebufferObject(windowSize, QGLFramebufferObject::Depth); s_filterBuffer = new QGLFramebufferObject(windowSize, QGLFramebufferObject::Depth); GLfloat width(s_normalBuffer->size().width()); GLfloat height(s_normalBuffer->size().height()); mat4x4 projection, projectionInverse, projectionBiasInverse; for (int i = 0; i < 15; ++i) { projection[i] = (GLfloat)projectionMatrix[i]; } projectionInverse = PerspectiveProjectionMatrixInverse(projection); projectionBiasInverse = projectionInverse * BiasMatrixInverse(); QSizeF size(width/s_rotationTextureSize, height/s_rotationTextureSize); setUniformVariable("Filters", "Scale_xy", size); setUniformVariable("Filters", "ProjectionInverse", projectionBiasInverse); }
bool ShaderLibrary::setUniformVariables(QString const& shaderName, QVariantMap const& map) { // If there is no shader, the parameters affect the material if (shaderName == NoShader) return setMaterialParameters(map); bool ok; double val; QColor color; QString name; for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) { name = iter.key(); switch (iter.value().type()) { // case QVariant::QColor: // color = iter.value().value<QColor>(); // if (!color.isValid() || !setUniformVariable(shaderName, name, color)) { // return false; // } // break; case QVariant::Bool: ok = iter.value().toBool(); if (!setUniformVariable(shaderName, name, ok)) return false; break; case QVariant::Double: val = iter.value().toDouble(&ok); if (!ok || !setUniformVariable(shaderName, name, val)) return false; break; default: QLOG_DEBUG() << "Unsupported QVariant type in ShaderLibrary"; break; } } return true; }
bool ShaderLibrary::setUniformVariable(QString const& shaderName, QString const& variable, T const& value) { if (!s_shaders.contains(shaderName)) return false; unsigned program(s_shaders.value(shaderName)); glUseProgram(program); QByteArray raw(variable.toLocal8Bit()); const char* c_str(raw.data()); GLint location(glGetUniformLocation(program, c_str)); if (location < 0) return false; setUniformVariable(program, location, value); return true; }
void ShaderLibrary::setFilterVariables(QVariantMap const& map) { if (!filtersAvailable()) return; bool aa(map.contains("Antialias") && map.value("Antialias").toBool()); bool bd(map.contains("Border") && map.value("Border").toBool()); bool ao(map.contains("AmbientOcclusion") && map.value("AmbientOcclusion").toBool()); m_filtersActive = aa || bd || ao; // Let the shaders know whether or not the Mask texture is valid QStringList shaders(availableShaders()); QStringList::const_iterator iter; for (iter = shaders.begin(); iter != shaders.end(); ++iter) { setUniformVariable(*iter, "FiltersAreValid", m_filtersActive); } // Ambient Occlusion parameters if (ao) { setUniformVariables("Filters", map); } }
void KisOpenGLHDRExposureProgram::activate() { KisOpenGLProgram::activate(); setExposureUniformVariable(); setUniformVariable("image", ImageTextureUnit); }