Exemplo n.º 1
0
bool GrGLShaderBuilder::finish() {
    SkASSERT(0 == fOutput.fProgramID);
    GL_CALL_RET(fOutput.fProgramID, CreateProgram());
    if (!fOutput.fProgramID) {
        return false;
    }

    SkTDArray<GrGLuint> shadersToDelete;

    if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) {
        GL_CALL(DeleteProgram(fOutput.fProgramID));
        return false;
    }

    this->bindProgramLocations(fOutput.fProgramID);
    if (fUniformManager->isUsingBindUniform()) {
        fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
    }

    GL_CALL(LinkProgram(fOutput.fProgramID));

    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
    bool checkLinked = !fGpu->ctxInfo().isChromium();
#ifdef SK_DEBUG
    checkLinked = true;
#endif
    if (checkLinked) {
        GrGLint linked = GR_GL_INIT_ZERO;
        GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked));
        if (!linked) {
            GrGLint infoLen = GR_GL_INIT_ZERO;
            GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
            SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
            if (infoLen > 0) {
                // retrieve length even though we don't need it to workaround
                // bug in chrome cmd buffer param validation.
                GrGLsizei length = GR_GL_INIT_ZERO;
                GL_CALL(GetProgramInfoLog(fOutput.fProgramID,
                                          infoLen+1,
                                          &length,
                                          (char*)log.get()));
                GrPrintf((char*)log.get());
            }
            SkDEBUGFAIL("Error linking program");
            GL_CALL(DeleteProgram(fOutput.fProgramID));
            fOutput.fProgramID = 0;
            return false;
        }
    }

    if (!fUniformManager->isUsingBindUniform()) {
        fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
    }

    for (int i = 0; i < shadersToDelete.count(); ++i) {
      GL_CALL(DeleteShader(shadersToDelete[i]));
    }

    return true;
}
Exemplo n.º 2
0
bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) {
    SK_TRACE_EVENT0("GrGLShaderBuilder::finish");

    GrGLuint programId = 0;
    GL_CALL_RET(programId, CreateProgram());
    if (!programId) {
        return false;
    }

    if (!this->compileAndAttachShaders(programId)) {
        GL_CALL(DeleteProgram(programId));
        return false;
    }

    this->bindProgramLocations(programId);

    GL_CALL(LinkProgram(programId));

    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
    bool checkLinked = !fGpu->ctxInfo().isChromium();
#ifdef SK_DEBUG
    checkLinked = true;
#endif
    if (checkLinked) {
        GrGLint linked = GR_GL_INIT_ZERO;
        GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked));
        if (!linked) {
            GrGLint infoLen = GR_GL_INIT_ZERO;
            GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen));
            SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
            if (infoLen > 0) {
                // retrieve length even though we don't need it to workaround
                // bug in chrome cmd buffer param validation.
                GrGLsizei length = GR_GL_INIT_ZERO;
                GL_CALL(GetProgramInfoLog(programId,
                                          infoLen+1,
                                          &length,
                                          (char*)log.get()));
                GrPrintf((char*)log.get());
            }
            SkDEBUGFAIL("Error linking program");
            GL_CALL(DeleteProgram(programId));
            return false;
        }
    }

    fUniformManager.getUniformLocations(programId, fUniforms);
    *outProgramId = programId;
    return true;
}
Exemplo n.º 3
0
GLuint LinkShaders3(GLuint vertShader, GLuint geomShader, GLuint fragShader) {
  GLuint program = CreateProgram();

  assert(vertShader || fragShader);

  if (vertShader) AttachShader(program, vertShader);
  if (geomShader) AttachShader(program, geomShader);
  if (fragShader) AttachShader(program, fragShader);

  LinkProgram(program);

  /* check link */
  {
    GLint stat;
    GetProgramiv(program, GL_LINK_STATUS, &stat);
    if (!stat) {
      GLchar log[1000];
      GLsizei len;
      GetProgramInfoLog(program, 1000, &len, log);
      wxLogError(wxT("BR24radar_pi: problem linking program: %s"), log);
      return 0;
    }
  }

  return program;
}
Exemplo n.º 4
0
JS::Value
WebGLProgram::GetProgramParameter(GLenum pname) const
{
    gl::GLContext* gl = mContext->gl;
    gl->MakeCurrent();

    if (mContext->IsWebGL2()) {
        switch (pname) {
        case LOCAL_GL_ACTIVE_UNIFORM_BLOCKS:
            return JS::Int32Value(GetProgramiv(gl, mGLName, pname));

        case LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS:
            return JS::Int32Value(mNextLink_TransformFeedbackVaryings.size());

        case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
            return JS::Int32Value(mNextLink_TransformFeedbackBufferMode);
       }
    }

    switch (pname) {
    case LOCAL_GL_ATTACHED_SHADERS:
    case LOCAL_GL_ACTIVE_UNIFORMS:
    case LOCAL_GL_ACTIVE_ATTRIBUTES:
        return JS::Int32Value(GetProgramiv(gl, mGLName, pname));

    case LOCAL_GL_DELETE_STATUS:
        return JS::BooleanValue(IsDeleteRequested());

    case LOCAL_GL_LINK_STATUS:
        return JS::BooleanValue(IsLinked());

    case LOCAL_GL_VALIDATE_STATUS:
#ifdef XP_MACOSX
        // See comment in ValidateProgram.
        if (gl->WorkAroundDriverBugs())
            return JS::BooleanValue(true);
#endif
        return JS::BooleanValue(bool(GetProgramiv(gl, mGLName, pname)));

    default:
        mContext->ErrorInvalidEnumInfo("getProgramParameter: `pname`",
                                       pname);
        return JS::NullValue();
    }
}
Exemplo n.º 5
0
bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
    GrGLint linked = GR_GL_INIT_ZERO;
    GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
    if (!linked) {
        SkDebugf("Program linking failed.\n");
        GrGLint infoLen = GR_GL_INIT_ZERO;
        GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
        SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
        if (infoLen > 0) {
            // retrieve length even though we don't need it to workaround
            // bug in chrome cmd buffer param validation.
            GrGLsizei length = GR_GL_INIT_ZERO;
            GL_CALL(GetProgramInfoLog(programID,
                                      infoLen+1,
                                      &length,
                                      (char*)log.get()));
            SkDebugf("%s", (char*)log.get());
        }
        GL_CALL(DeleteProgram(programID));
        programID = 0;
    }
    return SkToBool(linked);
}
Exemplo n.º 6
0
GLboolean ValidateShaderProgram(GLuint program) {
  GLint stat;
  ValidateProgram(program);
  GetProgramiv(program, GL_VALIDATE_STATUS, &stat);

  if (!stat) {
    GLchar log[1000];
    GLsizei len;
    GetProgramInfoLog(program, 1000, &len, log);
    wxLogError(wxT("BR24radar_pi: program validation error: %s"), log);
    return 0;
  }

  return (GLboolean)stat;
}
Exemplo n.º 7
0
int
rb_get_uniforms
  (struct rb_context* ctxt,
   struct rb_program* prog,
   size_t* out_nb_uniforms,
   struct rb_uniform* dst_uniform_list[])
{
  GLchar* uniform_buffer = NULL;
  int uniform_buflen = 0;
  int nb_uniforms = 0;
  int uniform_id = 0;
  int err = 0;

  if(!ctxt || !prog || !out_nb_uniforms)
    goto error;

  if(!prog->is_linked)
    goto error;

  OGL(GetProgramiv(prog->name, GL_ACTIVE_UNIFORMS, &nb_uniforms));
  assert(nb_uniforms >= 0);

  if(dst_uniform_list) {
      OGL(GetProgramiv
        (prog->name, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_buflen));
    uniform_buffer = MEM_ALLOC
      (ctxt->allocator, sizeof(GLchar) * uniform_buflen);
    if(!uniform_buffer)
      goto error;

    for(uniform_id = 0; uniform_id < nb_uniforms; ++uniform_id) {
      struct rb_uniform* uniform = NULL;

      err = get_active_uniform
        (ctxt, prog, uniform_id, uniform_buflen, uniform_buffer, &uniform);
      if(err != 0)
        goto error;

      dst_uniform_list[uniform_id] = uniform;
    }
  }

exit:
  if(uniform_buffer)
    MEM_FREE(ctxt->allocator, uniform_buffer);
  if(out_nb_uniforms)
    *out_nb_uniforms = nb_uniforms;
  return err;

error:
  if(dst_uniform_list) {
    /* NOTE: uniform_id <=> nb uniforms in dst_uniform_list; */
    int i = 0;
    for(i = 0; i < uniform_id; ++i) {
      RB(uniform_ref_put(dst_uniform_list[i]));
      dst_uniform_list[i] = NULL;
    }
  }
  nb_uniforms = 0;
  err = -1;
  goto exit;
}
Exemplo n.º 8
0
static GrGLuint compile_shader(const GrGLContext* ctx) {
    const char* version = GrGLGetGLSLVersionDecl(*ctx);

    // setup vertex shader
    GrGLShaderVar aPosition("a_position", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
    GrGLShaderVar aColor("a_color", kVec3f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
    GrGLShaderVar oColor("o_color", kVec3f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier);

    SkString vshaderTxt(version);
    aPosition.appendDecl(*ctx, &vshaderTxt);
    vshaderTxt.append(";\n");
    aColor.appendDecl(*ctx, &vshaderTxt);
    vshaderTxt.append(";\n");
    oColor.appendDecl(*ctx, &vshaderTxt);
    vshaderTxt.append(";\n");

    vshaderTxt.append(
            "void main()\n"
            "{\n"
                "gl_Position = vec4(a_position, 0.f, 1.f);\n"
                "o_color = a_color;\n"
            "}\n");

    const GrGLInterface* gl = ctx->interface();
    GrGLuint vertexShader = load_shader(gl, vshaderTxt.c_str(), GR_GL_VERTEX_SHADER);

    // setup fragment shader
    GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
    SkString fshaderTxt(version);
    GrGLAppendGLSLDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, gl->fStandard,
                                                   &fshaderTxt);
    oColor.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
    oColor.appendDecl(*ctx, &fshaderTxt);
    fshaderTxt.append(";\n");

    const char* fsOutName;
    if (ctx->caps()->glslCaps()->mustDeclareFragmentShaderOutput()) {
        oFragColor.appendDecl(*ctx, &fshaderTxt);
        fshaderTxt.append(";\n");
        fsOutName = oFragColor.c_str();
    } else {
        fsOutName = "gl_FragColor";
    }

    fshaderTxt.appendf(
            "void main()\n"
            "{\n"
                "%s = vec4(o_color, 1.0f);\n"
            "}\n", fsOutName);

    GrGLuint fragmentShader = load_shader(gl, fshaderTxt.c_str(), GR_GL_FRAGMENT_SHADER);

    GrGLint shaderProgram;
    GR_GL_CALL_RET(gl, shaderProgram, CreateProgram());
    GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader));
    GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader));
    GR_GL_CALL(gl, LinkProgram(shaderProgram));

    // Check for linking errors
    GrGLint success;
    GrGLchar infoLog[512];
    GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success));
    if (!success) {
        GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, NULL, infoLog));
        SkDebugf("Linker Error: %s\n", infoLog);
    }
    GR_GL_CALL(gl, DeleteShader(vertexShader));
    GR_GL_CALL(gl, DeleteShader(fragmentShader));

    return shaderProgram;
}
Exemplo n.º 9
0
GrGLProgram* GrGLProgramBuilder::finalize() {
    TRACE_EVENT0("skia", TRACE_FUNC);

    // verify we can get a program id
    GrGLuint programID;
    GL_CALL_RET(programID, CreateProgram());
    if (0 == programID) {
        this->cleanupFragmentProcessors();
        return nullptr;
    }

    if (this->gpu()->glCaps().programBinarySupport() &&
        this->gpu()->getContext()->contextPriv().getPersistentCache()) {
        GL_CALL(ProgramParameteri(programID, GR_GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GR_GL_TRUE));
    }

    this->finalizeShaders();

    // compile shaders and bind attributes / uniforms
    const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
    SkSL::Program::Settings settings;
    settings.fCaps = this->gpu()->glCaps().shaderCaps();
    settings.fFlipY = this->pipeline().proxy()->origin() != kTopLeft_GrSurfaceOrigin;
    settings.fSharpenTextures = this->gpu()->getContext()->contextPriv().sharpenMipmappedTextures();
    SkSL::Program::Inputs inputs;
    SkTDArray<GrGLuint> shadersToDelete;
    bool cached = fGpu->glCaps().programBinarySupport() && nullptr != fCached.get();
    if (cached) {
        this->bindProgramResourceLocations(programID);
        // cache hit, just hand the binary to GL
        const uint8_t* bytes = fCached->bytes();
        size_t offset = 0;
        memcpy(&inputs, bytes + offset, sizeof(inputs));
        offset += sizeof(inputs);
        int binaryFormat;
        memcpy(&binaryFormat, bytes + offset, sizeof(binaryFormat));
        offset += sizeof(binaryFormat);
        GrGLClearErr(this->gpu()->glInterface());
        GR_GL_CALL_NOERRCHECK(this->gpu()->glInterface(),
                              ProgramBinary(programID, binaryFormat, (void*) (bytes + offset),
                                            fCached->size() - offset));
        if (GR_GL_GET_ERROR(this->gpu()->glInterface()) == GR_GL_NO_ERROR) {
            if (inputs.fRTHeight) {
                this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
            }
            cached = this->checkLinkStatus(programID);
        } else {
            cached = false;
        }
    }
    if (!cached) {
        // cache miss, compile shaders
        if (fFS.fForceHighPrecision) {
            settings.fForceHighPrecision = true;
        }
        SkSL::String glsl;
        std::unique_ptr<SkSL::Program> fs = GrSkSLtoGLSL(gpu()->glContext(),
                                                         GR_GL_FRAGMENT_SHADER,
                                                         fFS.fCompilerStrings.begin(),
                                                         fFS.fCompilerStringLengths.begin(),
                                                         fFS.fCompilerStrings.count(),
                                                         settings,
                                                         &glsl);
        inputs = fs->fInputs;
        if (inputs.fRTHeight) {
            this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
        }
        if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
                                           GR_GL_FRAGMENT_SHADER, &shadersToDelete, settings,
                                           inputs)) {
            this->cleanupProgram(programID, shadersToDelete);
            return nullptr;
        }

        std::unique_ptr<SkSL::Program> vs = GrSkSLtoGLSL(gpu()->glContext(),
                                                         GR_GL_VERTEX_SHADER,
                                                         fVS.fCompilerStrings.begin(),
                                                         fVS.fCompilerStringLengths.begin(),
                                                         fVS.fCompilerStrings.count(),
                                                         settings,
                                                         &glsl);
        if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
                                           GR_GL_VERTEX_SHADER, &shadersToDelete, settings,
                                           inputs)) {
            this->cleanupProgram(programID, shadersToDelete);
            return nullptr;
        }

        // NVPR actually requires a vertex shader to compile
        bool useNvpr = primProc.isPathRendering();
        if (!useNvpr) {
            int vaCount = primProc.numAttribs();
            for (int i = 0; i < vaCount; i++) {
                GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName));
            }
        }

        if (primProc.willUseGeoShader()) {
            std::unique_ptr<SkSL::Program> gs;
            gs = GrSkSLtoGLSL(gpu()->glContext(),
                              GR_GL_GEOMETRY_SHADER,
                              fGS.fCompilerStrings.begin(),
                              fGS.fCompilerStringLengths.begin(),
                              fGS.fCompilerStrings.count(),
                              settings,
                              &glsl);
            if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
                                               GR_GL_GEOMETRY_SHADER, &shadersToDelete, settings,
                                               inputs)) {
                this->cleanupProgram(programID, shadersToDelete);
                return nullptr;
            }

        }
        this->bindProgramResourceLocations(programID);

        GL_CALL(LinkProgram(programID));
    }
    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
    bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver();
#ifdef SK_DEBUG
    checkLinked = true;
#endif
    if (checkLinked) {
        if (!this->checkLinkStatus(programID)) {
            SkDebugf("VS:\n");
            GrGLPrintShader(fGpu->glContext(), GR_GL_VERTEX_SHADER, fVS.fCompilerStrings.begin(),
                            fVS.fCompilerStringLengths.begin(), fVS.fCompilerStrings.count(),
                            settings);
            if (primProc.willUseGeoShader()) {
                SkDebugf("\nGS:\n");
                GrGLPrintShader(fGpu->glContext(), GR_GL_GEOMETRY_SHADER,
                                fGS.fCompilerStrings.begin(), fGS.fCompilerStringLengths.begin(),
                                fGS.fCompilerStrings.count(), settings);
            }
            SkDebugf("\nFS:\n");
            GrGLPrintShader(fGpu->glContext(), GR_GL_FRAGMENT_SHADER, fFS.fCompilerStrings.begin(),
                            fFS.fCompilerStringLengths.begin(), fFS.fCompilerStrings.count(),
                            settings);
            SkDEBUGFAIL("");
            return nullptr;
        }
    }
    this->resolveProgramResourceLocations(programID);

    this->cleanupShaders(shadersToDelete);
    if (!cached && this->gpu()->getContext()->contextPriv().getPersistentCache() &&
        fGpu->glCaps().programBinarySupport()) {
        GrGLsizei length = 0;
        GL_CALL(GetProgramiv(programID, GL_PROGRAM_BINARY_LENGTH, &length));
        if (length > 0) {
            // store shader in cache
            sk_sp<SkData> key = SkData::MakeWithoutCopy(desc()->asKey(), desc()->keyLength());
            GrGLenum binaryFormat;
            std::unique_ptr<char[]> binary(new char[length]);
            GL_CALL(GetProgramBinary(programID, length, &length, &binaryFormat, binary.get()));
            size_t dataLength = sizeof(inputs) + sizeof(binaryFormat) + length;
            std::unique_ptr<uint8_t[]> data(new uint8_t[dataLength]);
            size_t offset = 0;
            memcpy(data.get() + offset, &inputs, sizeof(inputs));
            offset += sizeof(inputs);
            memcpy(data.get() + offset, &binaryFormat, sizeof(binaryFormat));
            offset += sizeof(binaryFormat);
            memcpy(data.get() + offset, binary.get(), length);
            this->gpu()->getContext()->contextPriv().getPersistentCache()->store(
                                            *key, *SkData::MakeWithoutCopy(data.get(), dataLength));
        }
    }
    return this->createProgram(programID);
}
Exemplo n.º 10
0
GLint GLInterfaceWrapper::GetProgramParameter( GLuint program, GLenum pname ) const {
  GLint parameter = 0;
  GetProgramiv( program, pname, &parameter );
  return parameter;
}
Exemplo n.º 11
0
GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params)
{
	CONTEXT_EXEC(GetProgramiv(program, pname, params));
}
Exemplo n.º 12
0
void GrGLProgram::genProgram(GrGLProgram::CachedData* programData, 
                             const GrDrawTarget* target) const {

    ShaderCodeSegments segments;
    const uint32_t& layout = fProgramDesc.fVertexLayout;

    memset(&programData->fUniLocations, 0, sizeof(UniLocations));

    bool haveColor = !(ProgramDesc::kVertexColorAllOnes_OptFlagBit &
                       fProgramDesc.fOptFlags);

#if ATTRIBUTE_MATRIX
    segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n";
#else
    segments.fVSUnis  = "uniform mat3 " VIEW_MATRIX_NAME ";\n";
    segments.fVSAttrs = "";
#endif
    segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";
    if (haveColor) {
        segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
        segments.fVaryings = "varying vec4 vColor;\n";
    } else {
        segments.fVaryings = "";
    }

    segments.fVSCode   = "void main() {\n"
                         "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n"
                         "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n";
    if (haveColor) {
        segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n";
    }

    if (!(fProgramDesc.fOptFlags & ProgramDesc::kNotPoints_OptFlagBit)) {
        segments.fVSCode += "\tgl_PointSize = 1.0;\n";
    }
    segments.fFSCode   = "void main() {\n";

    // add texture coordinates that are used to the list of vertex attr decls
    GrTokenString texCoordAttrs[GrDrawTarget::kMaxTexCoords];
    for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
        if (target->VertexUsesTexCoordIdx(t, layout)) {
            tex_attr_name(t, texCoordAttrs + t);

            segments.fVSAttrs += "attribute vec2 ";
            segments.fVSAttrs += texCoordAttrs[t];
            segments.fVSAttrs += ";\n";
        }
    }

    // for each enabled stage figure out what the input coordinates are
    // and count the number of stages in use.
    const char* stageInCoords[GrDrawTarget::kNumStages];
    int numActiveStages = 0;

    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
        if (fProgramDesc.fStages[s].fEnabled) {
            if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) & layout) {
                stageInCoords[s] = POS_ATTR_NAME;
            } else {
                int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout);
                 // we better have input tex coordinates if stage is enabled.
                GrAssert(tcIdx >= 0);
                GrAssert(texCoordAttrs[tcIdx].length());
                stageInCoords[s] = texCoordAttrs[tcIdx].cstr();
            }
            ++numActiveStages;
        }
    }

    GrTokenString inColor = "vColor";

    // if we have active stages string them together, feeding the output color
    // of each to the next and generating code for each stage.
    if (numActiveStages) {
        int currActiveStage = 0;
        for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
            if (fProgramDesc.fStages[s].fEnabled) {
                GrTokenString outColor;
                if (currActiveStage < (numActiveStages - 1)) {
                    outColor = "color";
                    outColor.appendInt(currActiveStage);
                    segments.fFSCode += "\tvec4 ";
                    segments.fFSCode += outColor;
                    segments.fFSCode += ";\n";
                } else {
                    outColor = "gl_FragColor";
                }

                genStageCode(s,
                             fProgramDesc.fStages[s],
                             haveColor ? inColor.cstr() : NULL,
                             outColor.cstr(),
                             stageInCoords[s],
                             &segments,
                             &programData->fUniLocations.fStages[s]);
                ++currActiveStage;
                inColor = outColor;
                haveColor = true;
            }
        }
    } else {
        segments.fFSCode += "\tgl_FragColor = ";
        if (haveColor) {
            segments.fFSCode += inColor;
        } else {
            segments.fFSCode += "vec4(1,1,1,1)";
        }
        segments.fFSCode += ";\n";
    }
    segments.fFSCode += "}\n";
    segments.fVSCode += "}\n";


    const char* strings[4];
    int lengths[4];
    int stringCnt = 0;

    if (segments.fVSUnis.length()) {
        strings[stringCnt] = segments.fVSUnis.cstr();
        lengths[stringCnt] = segments.fVSUnis.length();
        ++stringCnt;
    }
    if (segments.fVSAttrs.length()) {
        strings[stringCnt] = segments.fVSAttrs.cstr();
        lengths[stringCnt] = segments.fVSAttrs.length();
        ++stringCnt;
    }
    if (segments.fVaryings.length()) {
        strings[stringCnt] = segments.fVaryings.cstr();
        lengths[stringCnt] = segments.fVaryings.length();
        ++stringCnt;
    }

    GrAssert(segments.fVSCode.length());
    strings[stringCnt] = segments.fVSCode.cstr();
    lengths[stringCnt] = segments.fVSCode.length();
    ++stringCnt;

#if PRINT_SHADERS
    GrPrintf("%s%s%s%s\n",
             segments.fVSUnis.cstr(),
             segments.fVSAttrs.cstr(),
             segments.fVaryings.cstr(),
             segments.fVSCode.cstr());
#endif
    programData->fVShaderID = CompileShader(GR_GL_VERTEX_SHADER,
                                        stringCnt,
                                        strings,
                                        lengths);

    stringCnt = 0;

    if (strlen(GrShaderPrecision()) > 1) {
        strings[stringCnt] = GrShaderPrecision();
        lengths[stringCnt] = strlen(GrShaderPrecision());
        ++stringCnt;
    }
    if (segments.fFSUnis.length()) {
        strings[stringCnt] = segments.fFSUnis.cstr();
        lengths[stringCnt] = segments.fFSUnis.length();
        ++stringCnt;
    }
    if (segments.fVaryings.length()) {
        strings[stringCnt] = segments.fVaryings.cstr();
        lengths[stringCnt] = segments.fVaryings.length();
        ++stringCnt;
    }

    GrAssert(segments.fFSCode.length());
    strings[stringCnt] = segments.fFSCode.cstr();
    lengths[stringCnt] = segments.fFSCode.length();
    ++stringCnt;

#if PRINT_SHADERS
    GrPrintf("%s%s%s%s\n",
             GR_SHADER_PRECISION,
             segments.fFSUnis.cstr(),
             segments.fVaryings.cstr(),
             segments.fFSCode.cstr());
#endif
    programData->fFShaderID = CompileShader(GR_GL_FRAGMENT_SHADER,
                                            stringCnt,
                                            strings,
                                            lengths);

    programData->fProgramID = GR_GL(CreateProgram());
    const GrGLint& progID = programData->fProgramID;

    GR_GL(AttachShader(progID, programData->fVShaderID));
    GR_GL(AttachShader(progID, programData->fFShaderID));

    // Bind the attrib locations to same values for all shaders
    GR_GL(BindAttribLocation(progID, POS_ATTR_LOCATION, POS_ATTR_NAME));
    for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
        if (texCoordAttrs[t].length()) {
            GR_GL(BindAttribLocation(progID,
                                     TEX_ATTR_LOCATION(t),
                                     texCoordAttrs[t].cstr()));
        }
    }

#if ATTRIBUTE_MATRIX
    // set unis to a bogus value so that checks against -1 before
    // flushing will pass.
    GR_GL(BindAttribLocation(progID,
                             VIEWMAT_ATTR_LOCATION,
                             VIEW_MATRIX_NAME));

    program->fUniLocations.fViewMatrixUni = BOGUS_MATRIX_UNI_LOCATION;

    for (int s = 0; s < kNumStages; ++s) {
        if (fProgramDesc.fStages[s].fEnabled) {
            GrStringBuilder matName;
            tex_matrix_name(s, &matName);
            GR_GL(BindAttribLocation(progID,
                                     TEXMAT_ATTR_LOCATION(s),
                                     matName.cstr()));
            program->fUniLocations.fStages[s].fTextureMatrixUni =
                                                    BOGUS_MATRIX_UNI_LOCATION;
        }
    }
#endif

    GR_GL(BindAttribLocation(progID, COL_ATTR_LOCATION, COL_ATTR_NAME));

    GR_GL(LinkProgram(progID));

    GrGLint linked = GR_GL_INIT_ZERO;
    GR_GL(GetProgramiv(progID, GR_GL_LINK_STATUS, &linked));
    if (!linked) {
        GrGLint infoLen = GR_GL_INIT_ZERO;
        GR_GL(GetProgramiv(progID, GR_GL_INFO_LOG_LENGTH, &infoLen));
        GrAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
        if (infoLen > 0) {
            GR_GL(GetProgramInfoLog(progID,
                                    infoLen+1,
                                    NULL,
                                    (char*)log.get()));
            GrPrintf((char*)log.get());
        }
        GrAssert(!"Error linking program");
        GR_GL(DeleteProgram(progID));
        programData->fProgramID = 0;
        return;
    }

    // Get uniform locations
#if !ATTRIBUTE_MATRIX
    programData->fUniLocations.fViewMatrixUni =
                    GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
    GrAssert(-1 != programData->fUniLocations.fViewMatrixUni);
#endif
    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
        StageUniLocations& locations = programData->fUniLocations.fStages[s];
        if (fProgramDesc.fStages[s].fEnabled) {
#if !ATTRIBUTE_MATRIX
            if (locations.fTextureMatrixUni) {
                GrTokenString texMName;
                tex_matrix_name(s, &texMName);
                locations.fTextureMatrixUni = GR_GL(GetUniformLocation(
                                                progID,
                                                texMName.cstr()));
                GrAssert(-1 != locations.fTextureMatrixUni);
            } else {
                locations.fTextureMatrixUni = -1;

            }
#endif

            if (locations.fSamplerUni) {
                GrTokenString samplerName;
                sampler_name(s, &samplerName);
                locations.fSamplerUni = GR_GL(GetUniformLocation(
                                                     progID,
                                                     samplerName.cstr()));
                GrAssert(-1 != locations.fSamplerUni);
            } else {
                locations.fSamplerUni = -1;
            }

            if (locations.fRadial2Uni) {
                GrTokenString radial2ParamName;
                radial2_param_name(s, &radial2ParamName);
                locations.fRadial2Uni = GR_GL(GetUniformLocation(
                                             progID,
                                             radial2ParamName.cstr()));
                GrAssert(-1 != locations.fRadial2Uni);
            } else {
                locations.fRadial2Uni = -1;
            }
        } else {
            locations.fSamplerUni = -1;
            locations.fRadial2Uni = -1;
            locations.fTextureMatrixUni = -1;
        }
    }
    GR_GL(UseProgram(progID));

    // init sampler unis and set bogus values for state tracking
    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
        if (-1 != programData->fUniLocations.fStages[s].fSamplerUni) {
            GR_GL(Uniform1i(programData->fUniLocations.fStages[s].fSamplerUni, s));
        }
        programData->fTextureMatrices[s] = GrMatrix::InvalidMatrix();
        programData->fRadial2CenterX1[s] = GR_ScalarMax;
        programData->fRadial2Radius0[s] = -GR_ScalarMax;
    }
    programData->fViewMatrix = GrMatrix::InvalidMatrix();
}
Exemplo n.º 13
0
static void
Init(void)
{
   static const char *fragShaderText =
      "uniform float StipplePattern[16]; \n"
      "varying float stippleCoord; \n"
      "void main() \n"
      "{ \n"
      "   // check the stipple pattern and discard if value is zero \n"
      "   // TODO: we should really undo the perspective interpolation here \n"
      "   // so that it's linear. \n"
      "   float stip = StipplePattern[int(fract(stippleCoord) * 16.0)]; \n"
      "   if (stip == 0.0) \n"
      "      discard; \n"
      "   gl_FragColor = gl_Color; \n"
      "} \n";
   static const char *vertShaderText =
      "void main() \n"
      "{ \n"
      "   gl_FrontColor = gl_Color; \n"
      "   gl_Position = ftransform(); \n"
      "} \n";
   static const char *geomShaderText =
      "#version 120 \n"
      "#extension GL_ARB_geometry_shader4: enable \n"
      "uniform vec2 ViewportSize; \n"
      "uniform float StippleFactor; \n"
      "varying float stippleCoord; \n"
      "void main() \n"
      "{ \n"
      "   vec4 pos0 = gl_PositionIn[0]; \n"
      "   vec4 pos1 = gl_PositionIn[1]; \n"
      "   // Convert eye coords to window coords \n"
      "   // Note: we're off by a factor of two here, make up for that below \n"
      "   vec2 p0 = pos0.xy / pos0.w * ViewportSize; \n"
      "   vec2 p1 = pos1.xy / pos1.w * ViewportSize; \n"
      "   float len = length(p0.xy - p1.xy); \n"
      "   // Emit first vertex \n"
      "   gl_FrontColor = gl_FrontColorIn[0]; \n"
      "   gl_Position = pos0; \n"
      "   stippleCoord = 0.0; \n"
      "   EmitVertex(); \n"
      "   // Emit second vertex \n"
      "   gl_FrontColor = gl_FrontColorIn[1]; \n"
      "   gl_Position = pos1; \n"
      "   stippleCoord = len / StippleFactor / 32.0; // Note: not 16, see above \n"
      "   EmitVertex(); \n"
      "} \n";

   if (!ShadersSupported())
      exit(1);

   if (!glutExtensionSupported("GL_ARB_geometry_shader4")) {
      fprintf(stderr, "Sorry, GL_ARB_geometry_shader4 is not supported.\n");
      exit(1);
   }

   VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
   FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
   GeomShader = CompileShaderText(GL_GEOMETRY_SHADER_ARB, geomShaderText);
   assert(GeomShader);

   Program = LinkShaders3(VertShader, GeomShader, FragShader);
   assert(Program);
   CheckError(__LINE__);

   /*
    * The geometry shader accepts lines and produces lines.
    */
   glProgramParameteriARB(Program, GL_GEOMETRY_INPUT_TYPE_ARB,
                          GL_LINES);
   glProgramParameteriARB(Program, GL_GEOMETRY_OUTPUT_TYPE_ARB,
                          GL_LINE_STRIP);
   glProgramParameteriARB(Program, GL_GEOMETRY_VERTICES_OUT_ARB, 4);
   CheckError(__LINE__);

   glLinkProgramARB(Program);

   /* check link */
   {
      GLint stat;
      GetProgramiv(Program, GL_LINK_STATUS, &stat);
      if (!stat) {
         GLchar log[1000];
         GLsizei len;
         GetProgramInfoLog(Program, 1000, &len, log);
         fprintf(stderr, "Shader link error:\n%s\n", log);
      }
   }

   glUseProgram(Program);

   uViewportSize = glGetUniformLocation(Program, "ViewportSize");
   uStippleFactor = glGetUniformLocation(Program, "StippleFactor");
   uStipplePattern = glGetUniformLocation(Program, "StipplePattern");

   glUniform1f(uStippleFactor, StippleFactor);

   glClearColor(0.3f, 0.3f, 0.3f, 0.0f);

   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));

   assert(glIsProgram(Program));
   assert(glIsShader(FragShader));
   assert(glIsShader(VertShader));
   assert(glIsShader(GeomShader));


   glLineStipple(StippleFactor, StipplePattern);
   SetStippleUniform(StippleFactor, StipplePattern);

   MakePointsVBO();
}
Exemplo n.º 14
0
static void
Init(void)
{
   static const char *fragShaderText =
      "void main() \n"
      "{ \n"
      "   gl_FragColor = gl_Color; \n"
      "} \n";
   static const char *vertShaderText =
      "void main() \n"
      "{ \n"
      "   gl_FrontColor = gl_Color; \n"
      "   gl_Position = ftransform(); \n"
      "} \n";
   static const char *geomShaderText =
      "#version 120 \n"
      "#extension GL_ARB_geometry_shader4: enable \n"
      "uniform vec2 InverseViewportSize; \n"
      "uniform float LineWidth; \n"
      "void main() \n"
      "{ \n"
      "   vec4 pos0 = gl_PositionIn[0]; \n"
      "   vec4 pos1 = gl_PositionIn[1]; \n"
      "   vec4 dir = abs(pos1 - pos0); \n"
      "   vec2 d0 = vec2(LineWidth * pos0.w) * InverseViewportSize; \n"
      "   vec2 d1 = vec2(LineWidth * pos1.w) * InverseViewportSize; \n"
      "   // this conditional could be avoided \n"
      "   if (dir.x > dir.y) { \n"
      "      // X-major line \n"
      "      d0.x = 0.0; \n"
      "      d1.x = 0.0; \n"
      "   } \n"
      "   else { \n"
      "      // Y-major line \n"
      "      d0.y = 0.0; \n"
      "      d1.y = 0.0; \n"
      "   } \n"
      "   gl_FrontColor = gl_FrontColorIn[0]; \n"
      "   gl_TexCoord[0] = vec4(0, 0, 0, 1); \n"
      "   gl_Position = pos0 + vec4( d0.x, -d0.y, 0, 0); \n"
      "   EmitVertex(); \n"
      "   gl_FrontColor = gl_FrontColorIn[1]; \n"
      "   gl_TexCoord[0] = vec4(1, 0, 0, 1); \n"
      "   gl_Position = pos1 + vec4( d1.x, -d1.y, 0, 0); \n"
      "   EmitVertex(); \n"
      "   gl_FrontColor = gl_FrontColorIn[0]; \n"
      "   gl_TexCoord[0] = vec4(0, 1, 0, 1); \n"
      "   gl_Position = pos0 + vec4(-d0.x,  d0.y, 0, 0); \n"
      "   EmitVertex(); \n"
      "   gl_FrontColor = gl_FrontColorIn[1]; \n"
      "   gl_TexCoord[0] = vec4(1, 1, 0, 1); \n"
      "   gl_Position = pos1 + vec4(-d1.x,  d1.y, 0, 0); \n"
      "   EmitVertex(); \n"
      "} \n";

   if (!ShadersSupported())
      exit(1);

   if (!glutExtensionSupported("GL_ARB_geometry_shader4")) {
      fprintf(stderr, "Sorry, GL_ARB_geometry_shader4 is not supported.\n");
      exit(1);
   }

   VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
   FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
   GeomShader = CompileShaderText(GL_GEOMETRY_SHADER_ARB, geomShaderText);
   assert(GeomShader);

   Program = LinkShaders3(VertShader, GeomShader, FragShader);
   assert(Program);
   CheckError(__LINE__);

   /*
    * The geometry shader will convert incoming lines to quads (4-vertex
    * triangle strips).
    */
   glProgramParameteriARB(Program, GL_GEOMETRY_INPUT_TYPE_ARB,
                          GL_LINES);
   glProgramParameteriARB(Program, GL_GEOMETRY_OUTPUT_TYPE_ARB,
                          GL_TRIANGLE_STRIP);
   glProgramParameteriARB(Program,GL_GEOMETRY_VERTICES_OUT_ARB, 4);
   CheckError(__LINE__);

   glLinkProgramARB(Program);

   /* check link */
   {
      GLint stat;
      GetProgramiv(Program, GL_LINK_STATUS, &stat);
      if (!stat) {
         GLchar log[1000];
         GLsizei len;
         GetProgramInfoLog(Program, 1000, &len, log);
         fprintf(stderr, "Shader link error:\n%s\n", log);
      }
   }

   CheckError(__LINE__);

   glUseProgram(Program);
   CheckError(__LINE__);

   uInverseViewportSize = glGetUniformLocation(Program, "InverseViewportSize");
   uLineWidth = glGetUniformLocation(Program, "LineWidth");

   glClearColor(0.3f, 0.3f, 0.3f, 0.0f);

   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));

   assert(glIsProgram(Program));
   assert(glIsShader(FragShader));
   assert(glIsShader(VertShader));
   assert(glIsShader(GeomShader));

   glEnable(GL_DEPTH_TEST);

   {
      GLfloat r[2];
      glGetFloatv(GL_LINE_WIDTH_RANGE, r);
      MaxLineWidth = r[1];
   }

   MakePointsVBO();
}