Beispiel #1
0
 void State::useProgram(ProgramPtr prog)
 {
   if (prog)
     glRun(glUseProgram(prog->id()));
   else
     glRun(glUseProgram(0));
   m_data.back().m_prog = prog;
 }
Beispiel #2
0
 void State::pop()
 {
   glRun(glPopClientAttrib());
   glRun(glPopAttrib());
   if (m_data.size() <= 1) {
     Log::error("State push/pop mismatch");
   } else {
     m_data.pop_back();
   }
 }
Beispiel #3
0
 unsigned int State::pickingQuery()
 {
   /// @todo is static so great idea? not
   static unsigned int s_picking_query = 0;
   if (s_picking_query == 0) {
     glRun(glGenQueries(1, &s_picking_query));
   }
   return s_picking_query;
 }
Beispiel #4
0
  AttributeVar::List GLProgram::getAttributeList()
  {
    glCheck("GLProgram::getAttributeList");
    AttributeVar::List list;

    GLint num = 0, buffer_size = 0;
    glRun(glGetProgramiv(m_prog, GL_ACTIVE_ATTRIBUTES, &num));
    glRun(glGetProgramiv(m_prog, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &buffer_size));

    std::vector<GLchar> name(buffer_size);
    for (GLint i = 0; i < num; i++) {
      GLsizei length;
      GLint size;
      GLenum type;
      glRun(glGetActiveAttrib(m_prog, i, buffer_size,
                              &length, &size, &type, name.data()));

      list.push_back(AttributeVar(shared_from_this(), name.data(), type));
    }
    return list;
  }
Beispiel #5
0
 bool GLProgram::removeShader(ShaderPtr shader)
 {
   if (!m_shaders.contains(shader)) return false;
   disconnect(shader.get(), SIGNAL(changed(ShaderPtr)), this, SIGNAL(shaderChanged(ShaderPtr)));
   m_shaders.remove(shader);
   if (m_prog) glRun(glDetachShader(m_prog, shader->id()));
   shader->setProgram(ProgramPtr());
   m_compiled = false;
   m_relink = true;
   emit changed();
   return true;
 }
Beispiel #6
0
  Shader::CompileStatus Shader::compile(ShaderErrorList& errors)
  {
    glCheck("Shader::compile");
    if (m_needCompile) {
      m_needCompile = false;
      if (!m_shader) {
        m_shader = glRun2(glCreateShader(m_type));
        if (!m_shader) {
          Log::error("Shader: could not create shader");
          return ERRORS;
        }
      }

      QByteArray src_ = m_src.toUtf8();

#ifndef _WIN32
      if (s_sandbox_compile && !SandboxCompiler::check(shared_from_this(), src_, errors)) {
        return ERRORS;
      }
#endif

      const char* src = src_.data();
      GLint len = src_.length();
      glRun(glShaderSource(m_shader, 1, &src, &len));
      glRun(glCompileShader(m_shader));

      GLint ok = 0;
      glRun(glGetShaderiv(m_shader, GL_COMPILE_STATUS, &ok));
      glRun(glGetShaderiv(m_shader, GL_INFO_LOG_LENGTH, &len));
      int error_count = errors.size();
      // len may include the zero byte
      if (len > 1 && !handleCompilerOutput(errors)) {
        Log::error("Failed to parse GLSL compiler output");
      }
      error_count = errors.size() - error_count;
      return ok ? error_count ? WARNINGS : OK : ERRORS;
    } else {
      return NONE;
    }
  }
Beispiel #7
0
  void GLProgram::link(State* state)
  {
    glCheck("GLProgram::link");
    m_relink = false;
    GLint prog = 0;
    glRun(glGetIntegerv(GL_CURRENT_PROGRAM, &prog));
    if (isLinked()) {
      glRun(glUseProgram(m_prog)); /// @todo Do we need this?
      m_uniformList = getUniformList();
    }

    ShaderErrorList errors(state ? state->material() : MaterialPtr(), name());

    if (!m_transformFeedback.isEmpty()) {
      const char* names[10];
      int m = std::min(m_transformFeedback.size(), 10);
      for (int i = 0; i < m; ++i) {
        names[i] = m_transformFeedback[i].data();
      }
      glRun(glTransformFeedbackVaryings(m_prog, m, names, GL_SEPARATE_ATTRIBS));
    }

    glRun(glLinkProgram(m_prog));
    GLint ok = 0;
    glRun(glGetProgramiv(m_prog, GL_LINK_STATUS, &ok));

    GLint len = 0;
    glRun(glGetProgramiv(m_prog, GL_INFO_LOG_LENGTH, &len));
    // len may include the zero byte
    if (len > 1) {
      std::vector<GLchar> log(len);
      GLsizei size = len;
      glRun(glGetProgramInfoLog(m_prog, size, &size, &log[0]));
      ShaderCompilerOutputParser::instance().parse(QString::fromUtf8(&log[0], size),
          errors);
    }

    if (ok) {
      glRun(glUseProgram(m_prog)); /// @todo Do we need this?
      setUniform(m_uniformList);
    }
    emit linked(errors);

    glRun(glUseProgram(prog));
  }
Beispiel #8
0
  bool GLProgram::isLinked()
  {
    glCheck("GLProgram::isLinked");
    if (!m_prog) return false;

    /// for example i915_program_error: Exceeded max instructions etc can be
    /// checked with this
    if (!glRun2(glIsProgram(m_prog))) return false;

    GLint b = 0;
    glRun(glGetProgramiv(m_prog, GL_LINK_STATUS, &b));
    return b;
  }
Beispiel #9
0
  UniformVar::List GLProgram::getUniformList()
  {
    glCheck("GLProgram::getUniformList");
    UniformVar::List list;

    GLint num = 0, buffer_size = 0;
    glRun(glGetProgramiv(m_prog, GL_ACTIVE_UNIFORMS, &num));
    glRun(glGetProgramiv(m_prog, GL_ACTIVE_UNIFORM_MAX_LENGTH, &buffer_size));

    std::vector<GLchar> name(buffer_size);
    for (GLint i = 0; i < num; i++) {
      GLsizei length;
      GLint size;
      GLenum type;
      glRun(glGetActiveUniform(m_prog, i, buffer_size,
                               &length, &size, &type, &name[0]));

      // For now skip build-in uniforms, since those can't be changed the same way as others.
      if (strncmp(&name[0], "gl_", 3) != 0)
        list.push_back(UniformVar(shared_from_this(), &name[0], type));
    }
    return list;
  }
Beispiel #10
0
  bool Shader::getBuiltinMacro(QString name, float& out)
  {
    /// @todo use cleaned up version of the actual shader here
    QString src = "#version 150\n"
                  "out float x;\n"
                  "void main() {\n"
                  "  x = %1;\n"
                  "}\n";

    QueryShader& s = QueryShader::instance();
    bool ok = false;
    if (s.compile(Vertex, src.arg(name)) && s.bind("x")) {
      glRun(glDrawArrays(GL_POINTS, 0, 1));
      ok = s.unbind(out);
    }
    return ok;
  }
Beispiel #11
0
  bool QueryShader::compile(Shader::Type type, QString src)
  {
    if (!m_shader) {
      /// @todo handle different sets of shaders depending on the type
      m_shader = glRun2(glCreateShader(type));
      if (!m_shader) {
        Log::error("QueryShader: could not create shader object");
        return false;
      }
    }

    if (!m_prog) {
      m_prog = glRun2(glCreateProgram());
      if (!m_prog) {
        Log::error("QueryShader: could not create program object");
        return false;
      }
    }

    QByteArray bytes = src.toAscii();
    const char* data = bytes.data();
    GLint len = bytes.length();
    glRun(glShaderSource(m_shader, 1, &data, &len));
    glRun(glCompileShader(m_shader));

    GLint ok = 0;
    glRun(glGetShaderiv(m_shader, GL_COMPILE_STATUS, &ok));

    if (!ok) {
      glRun(glGetShaderiv(m_shader, GL_INFO_LOG_LENGTH, &len));
      std::vector<GLchar> log(len);
      glRun(glGetShaderInfoLog(m_shader, len, &len, &log[0]));
      Log::error("Compile log: %s", &log[0]);
      return false;
    }

    if (!m_attached) glRun(glAttachShader(m_prog, m_shader));
    m_attached = true;

    return true;
  }
Beispiel #12
0
  bool QueryShader::bind(const char* name)
  {
    GLint ok = 0;

    glRun(glTransformFeedbackVaryings(m_prog, 1, &name, GL_SEPARATE_ATTRIBS));

    glRun(glLinkProgram(m_prog));
    glRun(glGetProgramiv(m_prog, GL_LINK_STATUS, &ok));

    if (!ok) {
      GLint len = 0;
      glRun(glGetProgramiv(m_prog, GL_INFO_LOG_LENGTH, &len));
      std::vector<GLchar> log(len);
      GLsizei size = len;
      glRun(glGetProgramInfoLog(m_prog, size, &size, &log[0]));
      Log::error("Link log: %s", &log[0]);
      return false;
    }

    glRun(glUseProgram(m_prog));
    m_feedback.begin(GL_POINTS, 1);
    return true;
  }
Beispiel #13
0
 bool QueryShader::unbind(float& out)
 {
   bool ok = m_feedback.end(&out, 1);
   glRun(glUseProgram(0));
   return ok;
 }