Пример #1
0
//
//  Load shader
//
void Ex07opengl::Shader(QGLShaderProgram& shader,QString vert,QString frag)
{
    //  Vertex shader
    if (vert.length() && !shader.addShaderFromSourceFile(QGLShader::Vertex,vert))
        Fatal("Error compiling "+vert+"\n"+shader.log());
    //  Fragment shader
    if (frag.length() && !shader.addShaderFromSourceFile(QGLShader::Fragment,frag))
        Fatal("Error compiling "+frag+"\n"+shader.log());
    //  Link
    if (!shader.link())
        Fatal("Error linking shader\n"+shader.log());
}
Пример #2
0
// See programCache doc comments to see how caching works here.
bool StelQGLGLSLShader::build()
{
	// Unlocked - i.e. not Modified
	if(state == State_Unlocked && program != NULL)
	{
		state = State_Built;
		return true;
	}

	QGLShaderProgram* cached = getProgramFromCache();
	// No matching program in cache, need to link a new program.
	if(cached == NULL)
	{
		uintptr_t id = 0;
		QGLShaderProgram* newProgram = new QGLShaderProgram(renderer->getGLContext());

		// Add all the shaders to the program.
		foreach(QGLShader* shader, defaultVertexShaders)
		{
			if(!newProgram->addShader(shader)) {goto FAILED;}
			id += reinterpret_cast<uintptr_t>(shader);
		}
		foreach(OptionalShader shader, namedVertexShaders)
		{
			if(shader.enabled)
			{
				if(!newProgram->addShader(shader.shader)) {goto FAILED;}
				id += reinterpret_cast<uintptr_t>(shader.shader);
			}
		}
		foreach(QGLShader* shader, defaultFragmentShaders)
		{
			if(!newProgram->addShader(shader)) {goto FAILED;}
			id += reinterpret_cast<uintptr_t>(shader);
		}
		Q_ASSERT_X(id > 0, Q_FUNC_INFO, "Trying to build() a StelQGLGLSLShader "
		           "but no vertex or fragment shaders were added");

		// Link the program.
		if(!newProgram->link()) {goto FAILED;}

		aggregatedLog += "Built successfully";
		// Add the program to the cache, and set the current program to it.
		programCache.insert(id, newProgram);
		program = newProgram;
		state = State_Built;
		return true;

		// And here I present to you a viable application of the fabled GOTO statement and a label.
		// (good way to do error recovery in plan C and when using return codes, BTW)
FAILED:
		aggregatedLog += newProgram->log();
		delete newProgram;
		return false;
	}
Пример #3
0
bool prepareShaderProgram( QGLShaderProgram& program,
                           const QString& vertexShaderPath,
                           const QString& fragmentShaderPath )
{
    // First we load and compile the vertex shader...
    bool result = program.addShaderFromSourceFile( QGLShader::Vertex, vertexShaderPath );
    if ( !result )
        qWarning() << program.log();

    // ...now the fragment shader...
    result = program.addShaderFromSourceFile( QGLShader::Fragment, fragmentShaderPath );
    if ( !result )
        qWarning() << program.log();

    // ...and finally we link them to resolve any references.
    result = program.link();
    if ( !result )
        qWarning() << "Could not link shader program:" << program.log();

    return result;
}
Пример #4
0
bool GLWidgetRendererPrivate::prepareShaderProgram(const VideoFormat &fmt, ColorTransform::ColorSpace cs)
{
    // isSupported(pixfmt)
    if (!fmt.isValid())
        return false;
    releaseShaderProgram();
    video_format.setPixelFormatFFmpeg(fmt.pixelFormatFFmpeg());
    colorTransform.setInputColorSpace(cs);
    // TODO: only to kinds, packed.glsl, planar.glsl
    QString frag;
    if (fmt.isPlanar()) {
        frag = getShaderFromFile("shaders/planar.f.glsl");
    } else {
        frag = getShaderFromFile("shaders/rgb.f.glsl");
    }
    if (frag.isEmpty())
        return false;
    if (fmt.isRGB()) {
        frag.prepend("#define INPUT_RGB\n");
    } else {
        frag.prepend(QString("#define YUV%1P\n").arg(fmt.bitsPerPixel(0)));
    }
    if (fmt.isPlanar() && fmt.bytesPerPixel(0) == 2) {
        if (fmt.isBigEndian())
            frag.prepend("#define LA_16BITS_BE\n");
        else
            frag.prepend("#define LA_16BITS_LE\n");
    }
    if (cs == ColorTransform::BT601) {
        frag.prepend("#define CS_BT601\n");
    } else if (cs == ColorTransform::BT709) {
        frag.prepend("#define CS_BT709\n");
    }
#if NO_QGL_SHADER
    program = createProgram(kVertexShader, frag.toUtf8().constData());
    if (!program) {
        qWarning("Could not create shader program.");
        return false;
    }
    // vertex shader. we can set attribute locations calling glBindAttribLocation
    a_Position = glGetAttribLocation(program, "a_Position");
    a_TexCoords = glGetAttribLocation(program, "a_TexCoords");
    u_matrix = glGetUniformLocation(program, "u_MVP_matrix");
    u_bpp = glGetUniformLocation(program, "u_bpp");
    u_opacity = glGetUniformLocation(program, "u_opacity");
    // fragment shader
    u_colorMatrix = glGetUniformLocation(program, "u_colorMatrix");
#else
    if (!shader_program->addShaderFromSourceCode(QGLShader::Vertex, kVertexShader)) {
        qWarning("Failed to add vertex shader: %s", shader_program->log().toUtf8().constData());
        return false;
    }
    if (!shader_program->addShaderFromSourceCode(QGLShader::Fragment, frag)) {
        qWarning("Failed to add fragment shader: %s", shader_program->log().toUtf8().constData());
        return false;
    }
    if (!shader_program->link()) {
        qWarning("Failed to link shader program...%s", shader_program->log().toUtf8().constData());
        return false;
    }
    // vertex shader
    a_Position = shader_program->attributeLocation("a_Position");
    a_TexCoords = shader_program->attributeLocation("a_TexCoords");
    u_matrix = shader_program->uniformLocation("u_MVP_matrix");
    u_bpp = shader_program->uniformLocation("u_bpp");
    u_opacity = shader_program->uniformLocation("u_opacity");
    // fragment shader
    u_colorMatrix = shader_program->uniformLocation("u_colorMatrix");
#endif //NO_QGL_SHADER
    qDebug("glGetAttribLocation(\"a_Position\") = %d\n", a_Position);
    qDebug("glGetAttribLocation(\"a_TexCoords\") = %d\n", a_TexCoords);
    qDebug("glGetUniformLocation(\"u_MVP_matrix\") = %d\n", u_matrix);
    qDebug("glGetUniformLocation(\"u_bpp\") = %d\n", u_bpp);
    qDebug("glGetUniformLocation(\"u_opacity\") = %d\n", u_opacity);
    qDebug("glGetUniformLocation(\"u_colorMatrix\") = %d\n", u_colorMatrix);

    if (fmt.isRGB())
        u_Texture.resize(1);
    else
        u_Texture.resize(fmt.channels());
    for (int i = 0; i < u_Texture.size(); ++i) {
        QString tex_var = QString("u_Texture%1").arg(i);
#if NO_QGL_SHADER
        u_Texture[i] = glGetUniformLocation(program, tex_var.toUtf8().constData());
#else
        u_Texture[i] = shader_program->uniformLocation(tex_var);
#endif
        qDebug("glGetUniformLocation(\"%s\") = %d\n", tex_var.toUtf8().constData(), u_Texture[i]);
    }
    return true;
}
Пример #5
0
QGLPEXShaderManager::QGLPEXShaderManager(const QGLContext* context)
{
    ctx = const_cast<QGLContext*>(context);

    defaultVertexShader= new QGLShader(QGLShader::VertexShader, context);
    defaultVertexShader->addSource(QLatin1String(qglslDefaultVertexShader));
    if (!defaultVertexShader->compile())
        qWarning() << "Default vertex shader failed to compile: " << defaultVertexShader->log();

    noBrushShader = new QGLShader(QGLShader::FragmentShader, context);
    noBrushShader->addSource(QLatin1String(qglslFragmentShaderMain));
    noBrushShader->addSource(QLatin1String(qglslNoBrushFragmentShader));
    if (!noBrushShader->compile())
        qWarning() << "No brush shader failed to compile:" << noBrushShader->log();


    // Create a program for noBrush:
    QGLShaderProgram* noBrushProg = new QGLShaderProgram(ctx);
    noBrushProg->addShader(defaultVertexShader);
    noBrushProg->addShader(noBrushShader);
    if (!noBrushProg->link())
        qWarning() << "NoBrush shader program failed to link:" << noBrushProg->log();

    // Add noBrush Program to cache:
    QGLCachedShaderProg cachedProg;
    cachedProg.vertexShader = defaultVertexShader;
    cachedProg.brushShader = noBrushShader;
    cachedProg.compositionShader = 0;
    cachedProg.shader = noBrushProg;
    cachedPrograms.append(cachedProg);


    // Set state
    useGlobalOpacity = true;
    currentBrushStyle = Qt::NoBrush;
    currentTransformType = FullTransform;
    shaderProgNeedsChanging = false;
    activeProgram = noBrushProg;

    solidBrushShader    = 0;

    conicalBrushVertexShader = 0;
    conicalBrushFragmentShader = 0;

    radialBrushVertexShader   = 0;
    radialBrushFragmentShader   = 0;

    linearBrushVertexShader = 0;
    linearBrushFragmentShader = 0;

    patternBrushVertexShader  = 0;
    patternBrushFragmentShader  = 0;

    textureBrushFragmentShader  = 0;
    textureBrushVertexShader  = 0;

    simpleFragmentShader = 0;
    simpleShaderProgram  = 0;

    imageVertexShader = 0;
    imageFragmentShader = 0;
    imageShaderProgram = 0;

    textVertexShader = 0;
    textFragmentShader = 0;
    textShaderProgram = 0;
}
Пример #6
0
bool QGLPEXShaderManager::useCorrectShaderProg()
{
    if (!shaderProgNeedsChanging) {
        activeProgram->use();
        return false;
    }

    const char* fragmentShaderMainSrc = qglslFragmentShaderMain;
    QGLShader* vertexShader = defaultVertexShader;
    QGLShader* fragmentShader = noBrushShader;

    // Make sure we compile up the correct brush shader
    switch (currentBrushStyle) {
    case Qt::NoBrush:
        break;
    case Qt::SolidPattern:
        if (!solidBrushShader) {
            qDebug("Compiling qglslSolidBrushFragmentShader");
            solidBrushShader = new QGLShader(QGLShader::FragmentShader, ctx);
            solidBrushShader->addSource(QLatin1String(qglslNoOpacityFragmentShaderMain));
            solidBrushShader->addSource(QLatin1String(qglslSolidBrushFragmentShader));
            if (!solidBrushShader->compile())
                qWarning() << "qglslSolidBrush failed to compile:" << solidBrushShader->log();
        }
        fragmentShader = solidBrushShader;
        break;
    case Qt::TexturePattern:
        if (!textureBrushVertexShader) {
            qDebug("Compiling qglslTextureBrushVertexShader");
            textureBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx);
            textureBrushVertexShader->addSource(QLatin1String(qglslTextureBrushVertexShader));
            if (!textureBrushVertexShader->compile()) {
                qWarning() << "qglslTextureBrushVertexShader failed to compile: "
                           << textureBrushVertexShader->log();
            }
        }
        vertexShader = textureBrushVertexShader;

        if (!textureBrushFragmentShader) {
            qDebug("Compiling qglslTextureBrushFragmentShader");
            textureBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx);
            textureBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc));
            textureBrushFragmentShader->addSource(QLatin1String(qglslTextureBrushFragmentShader));
            if (!textureBrushFragmentShader->compile()) {
                qWarning() << "qglslTextureBrushFragmentShader failed to compile:"
                           << textureBrushFragmentShader->log();
            }
        }
        fragmentShader = textureBrushFragmentShader;
        break;
    case Qt::LinearGradientPattern:
        if (!linearBrushVertexShader) {
            qDebug("Compiling qglslLinearGradientBrushVertexShader");
            linearBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx);
            linearBrushVertexShader->addSource(QLatin1String(qglslLinearGradientBrushVertexShader));
            if (!linearBrushVertexShader->compile()) {
                qWarning() << "qglslLinearGradientBrushVertexShader failed to compile: "
                           << linearBrushVertexShader->log();
            }
        }
        vertexShader = linearBrushVertexShader;

        if (!linearBrushFragmentShader) {
            qDebug("Compiling qglslLinearGradientBrushFragmentShader");
            linearBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx);
            linearBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc));
            linearBrushFragmentShader->addSource(QLatin1String(qglslLinearGradientBrushFragmentShader));
            if (!linearBrushFragmentShader->compile()) {
                qWarning() << "qglslLinearGradientBrushFragmentShader failed to compile:"
                           << linearBrushFragmentShader->log();
            }
        }
        fragmentShader = linearBrushFragmentShader;
        break;
    case Qt::RadialGradientPattern:
        if (!radialBrushVertexShader) {
            qDebug("Compiling qglslRadialGradientBrushVertexShader");
            radialBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx);
            radialBrushVertexShader->addSource(QLatin1String(qglslRadialGradientBrushVertexShader));
            if (!radialBrushVertexShader->compile()) {
                qWarning() << "qglslRadialGradientBrushVertexShader failed to compile: "
                           << radialBrushVertexShader->log();
            }
        }
        vertexShader = radialBrushVertexShader;

        if (!radialBrushFragmentShader) {
            qDebug("Compiling qglslRadialGradientBrushFragmentShader");
            radialBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx);
            radialBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc));
            radialBrushFragmentShader->addSource(QLatin1String(qglslRadialGradientBrushFragmentShader));
            if (!radialBrushFragmentShader->compile()) {
                qWarning() << "qglslRadialGradientBrushFragmentShader failed to compile:"
                           << radialBrushFragmentShader->log();
            }
        }
        fragmentShader = radialBrushFragmentShader;
        break;
    case Qt::ConicalGradientPattern:
        // FIXME: We currently use the same vertex shader as radial brush
        if (!conicalBrushVertexShader) {
            qDebug("Compiling qglslConicalGradientBrushVertexShader");
            conicalBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx);
            conicalBrushVertexShader->addSource(QLatin1String(qglslConicalGradientBrushVertexShader));
            if (!conicalBrushVertexShader->compile()) {
                qWarning() << "qglslConicalGradientBrushVertexShader failed to compile: "
                           << conicalBrushVertexShader->log();
            }
        }
        vertexShader = conicalBrushVertexShader;

        if (!conicalBrushFragmentShader) {
            qDebug("Compiling qglslConicalGradientBrushFragmentShader");
            conicalBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx);
            conicalBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc));
            conicalBrushFragmentShader->addSource(QLatin1String(qglslConicalGradientBrushFragmentShader));
            if (!conicalBrushFragmentShader->compile()) {
                qWarning() << "qglslConicalGradientBrushFragmentShader failed to compile:"
                           << conicalBrushFragmentShader->log();
            }
        }
        fragmentShader = conicalBrushFragmentShader;
        break;
    case Qt::Dense1Pattern:
    case Qt::Dense2Pattern:
    case Qt::Dense3Pattern:
    case Qt::Dense4Pattern:
    case Qt::Dense5Pattern:
    case Qt::Dense6Pattern:
    case Qt::Dense7Pattern:
    case Qt::HorPattern:
    case Qt::VerPattern:
    case Qt::CrossPattern:
    case Qt::BDiagPattern:
    case Qt::FDiagPattern:
    case Qt::DiagCrossPattern:
        if (!patternBrushVertexShader) {
            qDebug("Compiling qglslPatternBrushVertexShader");
            patternBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx);
            patternBrushVertexShader->addSource(QLatin1String(qglslPatternBrushVertexShader));
            if (!patternBrushVertexShader->compile()) {
                qWarning() << "qglslPatternBrushVertexShader failed to compile: "
                           << patternBrushVertexShader->log();
            }
        }
        vertexShader = patternBrushVertexShader;

        if (!patternBrushFragmentShader) {
            qDebug("Compiling qglslPatternBrushFragmentShader");
            patternBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx);
            patternBrushFragmentShader->addSource(QLatin1String(qglslNoOpacityFragmentShaderMain));
            patternBrushFragmentShader->addSource(QLatin1String(qglslPatternBrushFragmentShader));
            if (!patternBrushFragmentShader->compile()) {
                qWarning() << "qglslPatternBrushFragmentShader failed to compile:"
                           << patternBrushFragmentShader->log();
            }
        }
        fragmentShader = patternBrushFragmentShader;
        break;
    default:
        qWarning("Unimplemented brush style (%d)", currentBrushStyle);
    }

    // Now newBrushShader is set correctly, check to see if we already have the program
    // already linked and ready to go in the cache:
    bool foundProgram = false;
    foreach (QGLCachedShaderProg cachedProg, cachedPrograms) {
        if ((cachedProg.vertexShader == vertexShader) &&
            (cachedProg.brushShader == fragmentShader) &&
            (cachedProg.compositionShader == 0) ) {

            activeProgram = cachedProg.shader;
            foundProgram = true;
            break;
        }
    }

    if (!foundProgram) {
        qDebug() << "Linking shader program for " << currentBrushStyle;
        // Required program not found - create it.
        QGLShaderProgram* newProg = new QGLShaderProgram(ctx);

        newProg->addShader(vertexShader);
        newProg->addShader(fragmentShader);

        if (!newProg->link())
            qWarning() << "Shader program for " << currentBrushStyle << "failed to link:" << newProg->log();

        QGLCachedShaderProg cachedProg;
        cachedProg.vertexShader = vertexShader;
        cachedProg.brushShader = fragmentShader;
        cachedProg.compositionShader = 0;
        cachedProg.shader = newProg;

        cachedPrograms.append(cachedProg);
        activeProgram = newProg;
    }

    activeProgram->use();
    shaderProgNeedsChanging = false;
    return true;
}
Пример #7
0
//
//  Initialize
//
void Hw1opengl::initializeGL()
{
   if (init) return;
   init = true;

   //  Enable Z-buffer depth testing
   glEnable(GL_DEPTH_TEST);

   //  Build shaders
   QGLShaderProgram* shader = new QGLShaderProgram();
   if (!shader->addShaderFromSourceFile(QGLShader::Vertex,":/ex01.vert"))
      Fatal("Error compiling ex01.vert\n"+shader->log());
   if (!shader->addShaderFromSourceFile(QGLShader::Fragment,":/ex01.frag"))
      Fatal("Error compiling ex01.frag\n"+shader->log());
   if (!shader->link())
      Fatal("Error linking shader\n"+shader->log());
   shaders.push_back(shader);

   shader = new QGLShaderProgram();
   if (!shader->addShaderFromSourceFile(QGLShader::Vertex,":/hw1.vert"))
      Fatal("Error compiling hw1.vert\n"+shader->log());
   if (!shader->addShaderFromSourceFile(QGLShader::Fragment,":/hw1.frag"))
      Fatal("Error compiling hw1.frag\n"+shader->log());
   if (!shader->link())
      Fatal("Error linking shader\n"+shader->log());
   shaders.push_back(shader);

   // Cube
   objects.push_back(new Cube());

   // Teapot
   Teapot* pot = new Teapot(8);
   pot->scale(0.5);
   pot->color(0,1,1);
   objects.push_back(pot);

   // Tyra
   WaveOBJ* tyra=0;
   try
   {
      tyra = new WaveOBJ(":/tyra.obj");
   }
   catch (QString err)
   {
      Fatal("Error loading object\n"+err);
   }
   if (tyra)
   {
      tyra->color(1,1,0);
      objects.push_back(tyra);
   }

   //  Set initial object
   obj = objects[0];

   //  Start 100 fps timer connected to updateGL
   timer.setInterval(10);
   connect(&timer,SIGNAL(timeout()),this,SLOT(updateGL()));
   timer.start();
   time.start();
}