//====================================================================== //====================================================================== 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); }
//====================================================================== //====================================================================== 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); }