//======================================================================
//======================================================================
void NvUIGraphicFrameRenderVK::Draw(float alpha, const NvPackedColor& color, const float pixelToClipMatrix[4][4],
                            const nv::vec2<float>& thickness, const nv::vec2<float>& texBorder, bool drawCenter)
{
	NvVkContext& vk = *NvUIVKctx().mVk;
	VkCommandBuffer& cmd = NvUIVKctx().mCmd;

	// Set transform
	// pixelToClipMatrix
	memcpy(&(ms_ubo->pixelToClipMat), pixelToClipMatrix, 16 * sizeof(float));
	ms_ubo->pixelToClipMat(1, 1) *= -1.0f;
	ms_ubo->pixelToClipMat(1, 3) *= -1.0f;
	ms_ubo->alpha = alpha;
	ms_ubo->color = nv::vec4f(NV_PC_RED_FLOAT(color),
		NV_PC_GREEN_FLOAT(color), NV_PC_BLUE_FLOAT(color), 1.0f);

	NvUITexture* tex = m_graphic->GetTex();

	ms_ubo->thickness = thickness;
	ms_ubo->texBorder.x = texBorder.x / tex->GetWidth();
	ms_ubo->texBorder.y = texBorder.y / tex->GetHeight();
	ms_ubo.Update();
	m_uboOffset = ms_ubo.getDynamicOffset();

	VkViewport vp;
	VkRect2D sc;
	vp.x = 0;
	vp.y = 0;
	vp.height = (float)(vk.mainRenderTarget()->height());
	vp.width = (float)(vk.mainRenderTarget()->width());
	vp.minDepth = 0.0f;
	vp.maxDepth = 1.0f;

	sc.offset.x = 0;
	sc.offset.y = 0;
	sc.extent.width = vp.width;
	sc.extent.height = vp.height;

	vkCmdSetViewport(cmd, 0, 1, &vp);
	vkCmdSetScissor(cmd, 0, 1, &sc);

	if (m_graphic->GetTex()->GetHasAlpha() || (alpha < 1.0f)) {
		vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ms_pipelineAlpha);
	}
	else {
		vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ms_pipelineOpaque);
	}

	vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ms_pipelineLayout, 0, 1, &m_descriptorSet, 1, &m_uboOffset);

	// Bind the vertex and index buffers
	VkDeviceSize offsets[] = { 0 };
	vkCmdBindVertexBuffers(cmd, 0, 1, &ms_vbo(), offsets);
	vkCmdBindIndexBuffer(cmd, ms_ibo(), 0, VK_INDEX_TYPE_UINT16);

	// Draw the triangle
	vkCmdDrawIndexed(cmd, 30 + 6, 1, 0, 0, 0);
}
Example #2
0
//======================================================================
//======================================================================
void NvUIGraphic::Draw(const NvUIDrawState &drawState)
{
    if (!m_isVisible) return;
    if (!m_tex) return;

    // calculate internal alpha value...
    float myAlpha = m_alpha;
    if (drawState.alpha != 1.0f)
        myAlpha *= drawState.alpha;

    // pick correct shader based on alpha...
    ms_shader.m_program->enable();

    // then if alpha shader, set alpha uniform...
    if (ms_shader.m_alphaIndex >= 0)
        glUniform1f(ms_shader.m_alphaIndex, myAlpha);
    
    // then if colorizing shader, set color uniform...
    if (ms_shader.m_colorIndex >= 0)
    {   // optimize it a bit...  // !!!!TBD alpha in color not just sep value?
        if (NV_PC_IS_WHITE(m_color))
            glUniform4f(ms_shader.m_colorIndex, 1,1,1,1);
        else
            glUniform4f(ms_shader.m_colorIndex,
                            NV_PC_RED_FLOAT(m_color),
                            NV_PC_GREEN_FLOAT(m_color),
                            NV_PC_BLUE_FLOAT(m_color),
                            1); // !!!!TBD
    }
    
    // update the transform matrix.
    int32_t designWidth, designHeight;
    if (drawState.designWidth)
    {
        designWidth = drawState.designWidth;
        designHeight = drawState.designHeight;
    }
    else
    {
        designWidth = drawState.width;
        designHeight = drawState.height;
    }
    
    // update the scale factors ONLY IF cached design size changed.
    bool scaleFactorChanged = false;
    if (s_pixelXLast != designWidth)
    {
        s_pixelXLast = (int32_t)designWidth;
        s_pixelScaleFactorX = 2.0f / s_pixelXLast;
        scaleFactorChanged = true;
    }
    if (s_pixelYLast != designHeight)
    {
        s_pixelYLast = (int32_t)designHeight;
        s_pixelScaleFactorY = 2.0f / s_pixelYLast;
        scaleFactorChanged = true;
    }

    float rad = (float)(drawState.rotation / 180.0f * 3.14159f); // [-1,2]=>[-90,180] in radians...
    float cosf = cos(rad);
    float sinf = sin(rad);

    const float wNorm = s_pixelScaleFactorX;
    const float hNorm = s_pixelScaleFactorY;

    if (s_graphicWidth != m_rect.width)
    {
        s_graphicWidth = m_rect.width;
        scaleFactorChanged = true;
    }
    if (s_graphicHeight != m_rect.height)
    {
        s_graphicHeight = m_rect.height;
        scaleFactorChanged = true;
    }

    //if (1) //(scaleFactorChanged) // scale factor OR w/h is different this call
    {
        s_pixelToClipMatrix[0][0] = wNorm * m_rect.width  * cosf;
        s_pixelToClipMatrix[1][0] = hNorm * m_rect.height * -sinf;
        s_pixelToClipMatrix[0][1] = wNorm * m_rect.width  * sinf;
        s_pixelToClipMatrix[1][1] = hNorm * m_rect.height * cosf;
    }
    
    s_pixelToClipMatrix[3][0] = ( wNorm * m_rect.left - 1) * cosf
                              - ( 1 - hNorm * (m_rect.top + m_rect.height))  * sinf;
    s_pixelToClipMatrix[3][1] = ( wNorm * m_rect.left - 1 ) * sinf
                              + ( 1 - hNorm * (m_rect.top + m_rect.height))  * cosf;

    glUniformMatrix4fv(ms_shader.m_matrixIndex, 1, GL_FALSE, &(s_pixelToClipMatrix[0][0]));

    // set up texturing.
    bool ae = false;
    if (m_tex->GetHasAlpha() || (myAlpha<1.0f))
    {
        ae = true;
        glEnable(GL_BLEND);
        // Alpha sums in the destination channel to ensure that
        // partially-opaque items do not decrease the destination
        // alpha and thus "cut holes" in the backdrop
        glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
            GL_ONE, GL_ONE);
    }
    else
        glDisable(GL_BLEND);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_tex->GetGLTex());
    glBindBuffer(GL_ARRAY_BUFFER, m_vFlip?ms_vboFlip:ms_vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ms_ibo);

    glVertexAttribPointer(ms_shader.m_positionIndex, 2, GL_FLOAT, 0, sizeof(NvTexturedVertex), 0);
    glEnableVertexAttribArray(ms_shader.m_positionIndex);
    glVertexAttribPointer(ms_shader.m_uvIndex, 2, GL_FLOAT, 0, sizeof(NvTexturedVertex), (void*)sizeof(nv::vec2<float>));
    glEnableVertexAttribArray(ms_shader.m_uvIndex);

    // draw it already!
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

    //nv_flush_tracked_attribs();
    glDisableVertexAttribArray(ms_shader.m_positionIndex);
    glDisableVertexAttribArray(ms_shader.m_uvIndex);

    if (ae)
        glDisable(GL_BLEND);
}