Ejemplo n.º 1
0
void
HdSt_TestDriver::Draw(HdRenderPassSharedPtr const &renderPass)
{
    HdTaskSharedPtrVector tasks = {
        boost::make_shared<HdSt_DrawTask>(renderPass, _renderPassState)
    };
    _engine.Execute(_sceneDelegate->GetRenderIndex(), tasks);

    GLF_POST_PENDING_GL_ERRORS();
}
bool
HdxColorCorrectionTask::_CreateShaderResources()
{
    if (_shaderProgram) {
        return true;
    }

    // Client can choose to use Hydra's build-in sRGB color correction or use
    // OpenColorIO for color correction in which case we insert extra OCIO code.
    #ifdef PXR_OCIO_PLUGIN_ENABLED
        bool useOCIO = 
            _colorCorrectionMode == HdxColorCorrectionTokens->openColorIO;
    #else
        bool useOCIO = false;
    #endif

    _shaderProgram.reset(new HdStGLSLProgram(_tokens->colorCorrectionShader));

    HioGlslfx glslfx(HdxPackageColorCorrectionShader());

    std::string fragCode = "#version 120\n";

    if (useOCIO) {
        fragCode += "#define GLSLFX_USE_OCIO\n";
    }

    fragCode += glslfx.GetSource(_tokens->colorCorrectionFragment);

    if (useOCIO) {
        std::string ocioGpuShaderText = _CreateOpenColorIOResources();
        fragCode += ocioGpuShaderText;
    }

    if (!_shaderProgram->CompileShader(GL_VERTEX_SHADER,
            glslfx.GetSource(_tokens->colorCorrectionVertex)) ||
        !_shaderProgram->CompileShader(GL_FRAGMENT_SHADER, fragCode) ||
        !_shaderProgram->Link()) {
        TF_CODING_ERROR("Failed to load color correction shader");
        _shaderProgram.reset();
        return false;
    }

    GLuint programId = _shaderProgram->GetProgram().GetId();
    _locations[COLOR_IN]  = glGetUniformLocation(programId, "colorIn");
    _locations[POSITION] = glGetAttribLocation(programId, "position");
    _locations[UV_IN]     = glGetAttribLocation(programId, "uvIn");
    
    if (useOCIO) {
        _locations[LUT3D_IN] = glGetUniformLocation(programId, "LUT3dIn");
    }

    GLF_POST_PENDING_GL_ERRORS();
    return true;
}
Ejemplo n.º 3
0
HdxCompositor::~HdxCompositor()
{
    if (_colorTexture != 0) {
        glDeleteTextures(1, &_colorTexture);
    }
    if (_depthTexture != 0) {
        glDeleteTextures(1, &_depthTexture);
    }
    if (_vertexBuffer != 0) {
        glDeleteBuffers(1, &_vertexBuffer);
    }
    if (_compositorProgram) {
        _compositorProgram.reset();
    }
    GLF_POST_PENDING_GL_ERRORS();
}
bool
HdxColorCorrectionTask::_CreateBufferResources()
{
    if (_vertexBuffer) {
        return true;
    }

    // A larger-than screen triangle with UVs made to fit the screen.
    //                                 positions          |   uvs
    static const float vertices[] = { -1,  3, -1, 1,        0, 2,
                                      -1, -1, -1, 1,        0, 0,
                                       3, -1, -1, 1,        2, 0 };

    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
                 &vertices[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    GLF_POST_PENDING_GL_ERRORS();
    return true;
}
HdxColorCorrectionTask::~HdxColorCorrectionTask()
{
    if (_texture != 0) {
        glDeleteTextures(1, &_texture);
    }

    if (_texture3dLUT != 0) {
        glDeleteTextures(1, &_texture3dLUT);
    }

    if (_vertexBuffer != 0) {
        glDeleteBuffers(1, &_vertexBuffer);
    }

    if (_shaderProgram) {
        _shaderProgram.reset();
    }

    if (_framebuffer != 0) {
        glDeleteFramebuffers(1, &_framebuffer);
    }

    GLF_POST_PENDING_GL_ERRORS();
}
void
HdxColorCorrectionTask::_CopyTexture()
{
    GLint restoreReadFB, restoreDrawFB;
    glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &restoreReadFB);
    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &restoreDrawFB);

    // The read framebuffer will be the client's FBO (viewer backbuffer).
    // The write framebuffer will be ours.
    glBindFramebuffer(GL_READ_FRAMEBUFFER, restoreDrawFB);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _framebuffer);

    int width = _textureSize[0];
    int height = _textureSize[1];

    glBlitFramebuffer(0, 0, width, height,
                      0, 0, width, height,
                      GL_COLOR_BUFFER_BIT, GL_NEAREST);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, restoreReadFB);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFB);
    
    GLF_POST_PENDING_GL_ERRORS();
}
Ejemplo n.º 7
0
void
HdxCompositor::UpdateDepth(int width, int height, uint8_t *data)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    if (width == 0 || height == 0) {
        if (_depthTexture != 0) {
            glDeleteTextures(1, &_depthTexture);
            _depthTexture = 0;
        }
        return;
    }

    if (_depthTexture == 0) {
        _CreateTextureResources(&_depthTexture);
    }
    glBindTexture(GL_TEXTURE_2D, _depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED,
                 GL_FLOAT, data);
    glBindTexture(GL_TEXTURE_2D, 0);

    GLF_POST_PENDING_GL_ERRORS();
}
Ejemplo n.º 8
0
void
HdxCompositor::UpdateColor(int width, int height, uint8_t *data)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    if (width == 0 || height == 0) {
        if (_colorTexture != 0) {
            glDeleteTextures(1, &_colorTexture);
            _colorTexture = 0;
        }
        return;
    }

    if (_colorTexture == 0) {
        _CreateTextureResources(&_colorTexture);
    }
    glBindTexture(GL_TEXTURE_2D, _colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, data);
    glBindTexture(GL_TEXTURE_2D, 0);

    GLF_POST_PENDING_GL_ERRORS();
}
void
HdxColorCorrectionTask::_ApplyColorCorrection()
{
    // Client can choose to use Hydra's build-in sRGB color correction or use
    // OpenColorIO for color correction in which case we insert extra OCIO code.
    #ifdef PXR_OCIO_PLUGIN_ENABLED
        bool useOCIO = 
            _colorCorrectionMode == HdxColorCorrectionTokens->openColorIO;
    #else
        bool useOCIO = false;
    #endif

    // A note here: colorCorrection is used for all of our plugins and has to be
    // robust to poor GL support.  OSX compatibility profile provides a
    // GL 2.1 API, slightly restricting our choice of API and heavily
    // restricting our shader syntax. See also HdxCompositor.

    // Read from the texture-copy we made of the clients FBO and output the
    // color-corrected pixels into the clients FBO.

    GLuint programId = _shaderProgram->GetProgram().GetId();
    glUseProgram(programId);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _texture);
    glUniform1i(_locations[COLOR_IN], 0);

    if (useOCIO) {
        glEnable(GL_TEXTURE_3D);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_3D, _texture3dLUT);
        glUniform1i(_locations[LUT3D_IN], 1);
    }

    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glVertexAttribPointer(_locations[POSITION], 4, GL_FLOAT, GL_FALSE,
                          sizeof(float)*6, 0);
    glEnableVertexAttribArray(_locations[POSITION]);
    glVertexAttribPointer(_locations[UV_IN], 2, GL_FLOAT, GL_FALSE,
            sizeof(float)*6, reinterpret_cast<void*>(sizeof(float)*4));
    glEnableVertexAttribArray(_locations[UV_IN]);

    // Since we are rendering a full-screen triangle, we want to disable the
    // depth and stencil writes. We need to preserve the depth and stencil,
    // because they are copied back to the clients framebuffer so they can do
    // additional compositing of e.g. bounding boxes.
    GLboolean restoreDepthWriteMask;
    GLboolean restoreStencilWriteMask;
    glGetBooleanv(GL_DEPTH_WRITEMASK, &restoreDepthWriteMask);
    glGetBooleanv(GL_STENCIL_WRITEMASK, &restoreStencilWriteMask);
    glDepthMask(GL_FALSE);
    glStencilMask(GL_FALSE);

    // Depth test must be ALWAYS instead of disabling the depth_test because
    // we still want to write to the depth buffer. Disabling depth_test disables
    // depth_buffer writes.
    GLint restoreDepthFunc;
    glGetIntegerv(GL_DEPTH_FUNC, &restoreDepthFunc);
    glDepthFunc(GL_ALWAYS);

    GLint restoreViewport[4] = {0};
    glGetIntegerv(GL_VIEWPORT, restoreViewport);
    glViewport(0, 0, _framebufferSize[0], _framebufferSize[1]);

    // The app may have alpha blending enabled.
    // We want to pass-through the alpha values, not alpha-blend on top of dest.
    GLboolean restoreblendEnabled;
    glGetBooleanv(GL_BLEND, &restoreblendEnabled);
    glDisable(GL_BLEND);

    // Alpha to coverage would prevent any pixels that have an alpha of 0.0 from
    // being written. We want to color correct all pixels. Even background
    // pixels that were set with a clearColor alpha of 0.0
    GLboolean restoreAlphaToCoverage;
    glGetBooleanv(GL_SAMPLE_ALPHA_TO_COVERAGE, &restoreAlphaToCoverage);
    glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    if (restoreAlphaToCoverage) {
        glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
    }

    if (restoreblendEnabled) {
        glEnable(GL_BLEND);
    }

    glViewport(restoreViewport[0], restoreViewport[1],
               restoreViewport[2], restoreViewport[3]);

    glDepthFunc(restoreDepthFunc);
    glDepthMask(restoreDepthWriteMask);
    glStencilMask(restoreStencilWriteMask);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(_locations[POSITION]);
    glDisableVertexAttribArray(_locations[UV_IN]);

    glUseProgram(0);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, 0);

    if (useOCIO) {
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_3D, 0);
        glDisable(GL_TEXTURE_3D);
    }

    GLF_POST_PENDING_GL_ERRORS();
}
bool
HdxColorCorrectionTask::_CreateFramebufferResources(GLuint *texture)
{
    // If framebufferSize is not provided we use the viewport size.
    // This can be incorrect if the client/app has changed the viewport to
    // be different then the render window size. (E.g. UsdView CameraMask mode)
    GfVec2i fboSize = _framebufferSize;
    if (fboSize[0] <= 0 || fboSize[1] <= 0) {
        GLint res[4] = {0};
        glGetIntegerv(GL_VIEWPORT, res);
        fboSize = GfVec2i(res[2], res[3]);
    }

    bool createTexture = (_texture == 0 || fboSize != _textureSize);

    if (createTexture) {
        if (_texture != 0) {
            glDeleteTextures(1, &_texture);
            _texture = 0;
        }

        _textureSize = fboSize;

        GLint restoreTexture;
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &restoreTexture);

        glGenTextures(1, texture);
        glBindTexture(GL_TEXTURE_2D, *texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // XXX For step 1 we copy the client FBO texture, apply gamma to the
        // copy and write it back to the client texture.
        // A future step will likely create a 16F texture at the start of 
        // hydra rendering and use color-correction to render the results back
        // into the client FBO texture.

        // XXX For now we assume we always want R16F. We could perhaps expose
        //     this as client-API in HdxColorCorrectionTaskParams.
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, _textureSize[0], 
                     _textureSize[1], 0, GL_RGBA, GL_FLOAT, 0);

        glBindTexture(GL_TEXTURE_2D, restoreTexture);
    }

    bool switchedGLContext = !_owningContext || !_owningContext->IsCurrent();

    if (switchedGLContext) {
        // If we're rendering with a different context than the render pass
        // was created with, recreate the FBO because FB is not shared.
        // XXX we need this since we use a FBO in _CopyTexture(). Ideally we
        // use HdxCompositor to do the copy, but for that we need to know the
        // textureId currently bound to the default framebuffer. However
        // glGetFramebufferAttachmentParameteriv will return and error when
        // trying to query the texture name bound to GL_BACK_LEFT.
        if (_owningContext && _owningContext->IsValid()) {
            GlfGLContextScopeHolder contextHolder(_owningContext);
            glDeleteFramebuffers(1, &_framebuffer);
        }

        _owningContext = GlfGLContext::GetCurrentGLContext();
        if (!TF_VERIFY(_owningContext, "No valid GL context")) {
            return false;
        }

        if (_framebuffer == 0) {
            glGenFramebuffers(1, &_framebuffer);
        }
    }

    if (createTexture || switchedGLContext) {
        GLint restoreReadFB, restoreDrawFB;
        glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &restoreReadFB);
        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &restoreDrawFB);
        glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                               GL_TEXTURE_2D, _texture, 0);

        glBindFramebuffer(GL_READ_FRAMEBUFFER, restoreReadFB);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFB);
    }

    GLF_POST_PENDING_GL_ERRORS();
    return true;
}
std::string
HdxColorCorrectionTask::_CreateOpenColorIOResources()
{
    #ifdef PXR_OCIO_PLUGIN_ENABLED
        // Use client provided OCIO values, or use default fallback values
        OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();

        const char* display = _displayOCIO.empty() ? 
                              config->getDefaultDisplay() : 
                              _displayOCIO.c_str();

        const char* view = _viewOCIO.empty() ? 
                           config->getDefaultView(display) :
                           _viewOCIO.c_str();

        std::string inputColorSpace = _colorspaceOCIO;
        if (inputColorSpace.empty()) {
            OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace("default");
            if (cs) {
                inputColorSpace = cs->getName();
            } else {
                inputColorSpace = OCIO::ROLE_SCENE_LINEAR;
            }
        }

        // Setup the transformation we need to apply
        OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
        transform->setDisplay(display);
        transform->setView(view);
        transform->setInputColorSpaceName(inputColorSpace.c_str());
        if (!_looksOCIO.empty()) {
            transform->setLooksOverride(_looksOCIO.c_str());
            transform->setLooksOverrideEnabled(true);
        } else {
            transform->setLooksOverrideEnabled(false);
        }

        OCIO::ConstProcessorRcPtr processor = config->getProcessor(transform);

        // Create a GPU Shader Description
        OCIO::GpuShaderDesc shaderDesc;
        shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
        shaderDesc.setFunctionName("OCIODisplay");
        shaderDesc.setLut3DEdgeLen(_lut3dSizeOCIO);

        // Compute and the 3D LUT
        int num3Dentries = 3 * _lut3dSizeOCIO*_lut3dSizeOCIO*_lut3dSizeOCIO;
        std::vector<float> lut3d;
        lut3d.resize(num3Dentries);
        processor->getGpuLut3D(&lut3d[0], shaderDesc);

        // Load the data into an OpenGL 3D Texture
        if (_texture3dLUT != 0) {
            glDeleteTextures(1, &_texture3dLUT);
        }
        GLint restoreTexture;
        glGetIntegerv(GL_TEXTURE_BINDING_3D, &restoreTexture);
        glGenTextures(1, &_texture3dLUT);
        glBindTexture(GL_TEXTURE_3D, _texture3dLUT);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
        glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F,
                     _lut3dSizeOCIO, _lut3dSizeOCIO, _lut3dSizeOCIO,
                     0, GL_RGB, GL_FLOAT, &lut3d[0]);
        glBindTexture(GL_TEXTURE_3D, restoreTexture);

        const char* gpuShaderText = processor->getGpuShaderText(shaderDesc);

        GLF_POST_PENDING_GL_ERRORS();
        return std::string(gpuShaderText);
    #else
        return std::string();
    #endif
}
Ejemplo n.º 12
0
bool
HdxIntersector::Query(HdxIntersector::Params const& params,
                      HdRprimCollection const& col,
                      HdEngine* engine,
                      HdxIntersector::Result* result)
{
    TRACE_FUNCTION();

    // Make sure we're in a sane GL state before attempting anything.
    if (GlfHasLegacyGraphics()) {
        TF_RUNTIME_ERROR("framebuffer object not supported");
        return false;
    }
    GlfGLContextSharedPtr context = GlfGLContext::GetCurrentGLContext();
    if (!TF_VERIFY(context)) {
        TF_RUNTIME_ERROR("Invalid GL context");
        return false;
    }
    if (!_drawTarget) {
        // Initialize the shared draw target late to ensure there is a valid GL
        // context, which may not be the case at constructon time.
        _Init(GfVec2i(128,128));
    }

    GfVec2i size(_drawTarget->GetSize());
    GfVec4i viewport(0, 0, size[0], size[1]);

    if (!TF_VERIFY(_renderPass)) {
        return false;
    }
    _renderPass->SetRprimCollection(col);

    // Setup state based on incoming params.
    _renderPassState->SetAlphaThreshold(params.alphaThreshold);
    _renderPassState->SetClipPlanes(params.clipPlanes);
    _renderPassState->SetCullStyle(params.cullStyle);
    _renderPassState->SetCamera(params.viewMatrix, params.projectionMatrix, viewport);
    _renderPassState->SetLightingEnabled(false);

    // Use a separate drawTarget (framebuffer object) for each GL context
    // that uses this renderer, but the drawTargets share attachments/textures.
    GlfDrawTargetRefPtr drawTarget = GlfDrawTarget::New(size);

    // Clone attachments into this context. Note that this will do a
    // light-weight copy of the textures, it does not produce a full copy of the
    // underlying images.
    drawTarget->Bind();
    drawTarget->CloneAttachments(_drawTarget);

    //
    // Setup GL raster state
    //

    GLenum drawBuffers[3] = { GL_COLOR_ATTACHMENT0,
                              GL_COLOR_ATTACHMENT1,
                              GL_COLOR_ATTACHMENT2 };
    glDrawBuffers(3, drawBuffers);
    
    glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
    glDisable(GL_BLEND);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);  

    glClearColor(0,0,0,0);
    glClearStencil(0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

    glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);

    GLF_POST_PENDING_GL_ERRORS();
    
    //
    // Execute the picking pass
    //
    {
        GLuint vao;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
        // Setup stencil state and prevent writes to color buffer.
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_ALWAYS, 1, 1);
        glStencilOp(GL_KEEP,     // stencil failed
                    GL_KEEP,     // stencil passed, depth failed
                    GL_REPLACE); // stencil passed, depth passed

        //
        // Condition the stencil buffer.
        //
        params.depthMaskCallback();
        // we expect any GL state changes are restored.

        // Disable stencil updates and setup the stencil test.
        glStencilFunc(GL_LESS, 0, 1);
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        // Clear depth incase the depthMaskCallback pollutes the depth buffer.
        glClear(GL_DEPTH_BUFFER_BIT);
        // Restore color outputs & setup state for rendering
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glDisable(GL_CULL_FACE);
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        glFrontFace(GL_CCW);

        //
        // Enable conservative rasterization, if available.
        //
        // XXX: This wont work until it's in the Glew build.
        bool convRstr = glewIsSupported("GL_NV_conservative_raster");
        if (convRstr) {
            // XXX: this should come from Glew
            #define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
            glEnable(GL_CONSERVATIVE_RASTERIZATION_NV);
        }

        // 
        // Execute
        //
        // XXX: make intersector a Task
        HdTaskSharedPtrVector tasks;
        tasks.push_back(boost::make_shared<HdxIntersector_DrawTask>(_renderPass,
                                                               _renderPassState,
                                                            params.renderTags));
        engine->Execute(*_index, tasks);

        glDisable(GL_STENCIL_TEST);

        if (convRstr) {
            // XXX: this should come from Glew
            #define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
            glDisable(GL_CONSERVATIVE_RASTERIZATION_NV);
        }

        // Restore
        glBindVertexArray(0);
        glDeleteVertexArrays(1, &vao);
    }

    GLF_POST_PENDING_GL_ERRORS();

    //
    // Capture the result buffers to be resolved later.
    //
    size_t len = size[0] * size[1];
    std::unique_ptr<unsigned char[]> primId(new unsigned char[len*4]);
    std::unique_ptr<unsigned char[]> instanceId(new unsigned char[len*4]);
    std::unique_ptr<unsigned char[]> elementId(new unsigned char[len*4]);
    std::unique_ptr<float[]> depths(new float[len]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("primId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &primId[0]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("instanceId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &instanceId[0]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("elementId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &elementId[0]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("depth")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
                    &depths[0]);

    glBindTexture(GL_TEXTURE_2D, 0);

    GLF_POST_PENDING_GL_ERRORS();

    if (result) {
        *result = HdxIntersector::Result(
            std::move(primId), std::move(instanceId), std::move(elementId),
            std::move(depths), _index, params, viewport);
    }

    drawTarget->Unbind();
    GLF_POST_PENDING_GL_ERRORS();

    return true;
}
Ejemplo n.º 13
0
void 
HdxCompositor::Draw(GLuint colorId, GLuint depthId, bool remapDepth)
{
    // No-op if no color data was specified.
    if (colorId == 0) {
        return;
    }

    // Create draw buffers if they haven't been created yet.
    if (_vertexBuffer == 0) {
        _CreateBufferResources();
    }

    bool useDepthProgram = (depthId != 0);

    // Load the shader if it hasn't been loaded, or we're changing modes.
    if (!_compositorProgram || _useDepthProgram != useDepthProgram) {
        _CreateShaderResources(useDepthProgram);
        _useDepthProgram = useDepthProgram;
    }

    // No-op if the shader failed to compile.
    if (!_compositorProgram) {
        return;
    }

    // A note here: HdxCompositor is used for all of our plugins and has to be
    // robust to poor GL support.  OSX compatibility profile provides a
    // GL 2.1 API, slightly restricting our choice of API and heavily
    // restricting our shader syntax.

    GLuint programId = _compositorProgram->GetProgram().GetId();
    glUseProgram(programId);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, colorId);
    glUniform1i(_locations[colorIn], 0);

    if (depthId != 0) {
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, depthId);
        glUniform1i(_locations[depthIn], 1);
    }

    glUniform1i(_locations[remapDepthIn], (GLint)remapDepth);

    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glVertexAttribPointer(_locations[position], 4, GL_FLOAT, GL_FALSE,
            sizeof(float)*6, 0);
    glEnableVertexAttribArray(_locations[position]);
    glVertexAttribPointer(_locations[uvIn], 2, GL_FLOAT, GL_FALSE,
            sizeof(float)*6, reinterpret_cast<void*>(sizeof(float)*4));
    glEnableVertexAttribArray(_locations[uvIn]);

    GLboolean restoreAlphaToCoverage;
    glGetBooleanv(GL_SAMPLE_ALPHA_TO_COVERAGE, &restoreAlphaToCoverage);
    glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    if (restoreAlphaToCoverage) {
        glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
    }
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(_locations[position]);
    glDisableVertexAttribArray(_locations[uvIn]);

    glUseProgram(0);

    if (depthId != 0) {
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, 0);
    }

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, 0);

    GLF_POST_PENDING_GL_ERRORS();
}