void CGraphicContext::ClipRect(CRect &vertex, CRect &texture, CRect *texture2) { // this is the software clipping routine. If the graphics hardware is set to do the clipping // (eg via SetClipPlane in D3D for instance) then this routine is unneeded. if (!m_clipRegions.empty()) { // take a copy of the vertex rectangle and intersect // it with our clip region (moved to the same coordinate system) CRect clipRegion(m_clipRegions.top()); if (!m_origins.empty()) clipRegion -= m_origins.top(); CRect original(vertex); vertex.Intersect(clipRegion); // and use the original to compute the texture coordinates if (original != vertex) { float scaleX = texture.Width() / original.Width(); float scaleY = texture.Height() / original.Height(); texture.x1 += (vertex.x1 - original.x1) * scaleX; texture.y1 += (vertex.y1 - original.y1) * scaleY; texture.x2 += (vertex.x2 - original.x2) * scaleX; texture.y2 += (vertex.y2 - original.y2) * scaleY; if (texture2) { scaleX = texture2->Width() / original.Width(); scaleY = texture2->Height() / original.Height(); texture2->x1 += (vertex.x1 - original.x1) * scaleX; texture2->y1 += (vertex.y1 - original.y1) * scaleY; texture2->x2 += (vertex.x2 - original.x2) * scaleX; texture2->y2 += (vertex.y2 - original.y2) * scaleY; } } } }
void CGUIBorderedImage::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) { if (!m_borderImage.GetFileName().IsEmpty() && m_texture.ReadyToRender()) { CRect rect = CRect(m_texture.GetXPosition(), m_texture.GetYPosition(), m_texture.GetXPosition() + m_texture.GetWidth(), m_texture.GetYPosition() + m_texture.GetHeight()); rect.Intersect(m_texture.GetRenderRect()); m_borderImage.SetPosition(rect.x1 - m_borderSize.x1, rect.y1 - m_borderSize.y1); m_borderImage.SetWidth(rect.Width() + m_borderSize.x1 + m_borderSize.x2); m_borderImage.SetHeight(rect.Height() + m_borderSize.y1 + m_borderSize.y2); m_borderImage.SetDiffuseColor(m_diffuseColor); if (m_borderImage.Process(currentTime)) MarkDirtyRegion(); } CGUIImage::Process(currentTime, dirtyregions); }
void CRenderUtils::ClipRect(const CRect &viewRect, CRect &sourceRect, CRect &destRect) { const float offsetX = viewRect.x1; const float offsetY = viewRect.y1; const float width = viewRect.Width(); const float height = viewRect.Height(); CRect original(destRect); destRect.Intersect(CRect(offsetX, offsetY, offsetX + width, offsetY + height)); if (destRect != original) { float scaleX = sourceRect.Width() / original.Width(); float scaleY = sourceRect.Height() / original.Height(); sourceRect.x1 += (destRect.x1 - original.x1) * scaleX; sourceRect.y1 += (destRect.y1 - original.y1) * scaleY; sourceRect.x2 += (destRect.x2 - original.x2) * scaleX; sourceRect.y2 += (destRect.y2 - original.y2) * scaleY; } }
void CGUIFontTTFGL::LastEnd() { #ifdef HAS_GL glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glColorPointer (4, GL_UNSIGNED_BYTE, sizeof(SVertex), (char*)&m_vertex[0] + offsetof(SVertex, r)); glVertexPointer (3, GL_FLOAT , sizeof(SVertex), (char*)&m_vertex[0] + offsetof(SVertex, x)); glTexCoordPointer(2, GL_FLOAT , sizeof(SVertex), (char*)&m_vertex[0] + offsetof(SVertex, u)); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_QUADS, 0, m_vertex.size()); glPopClientAttrib(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); #else // GLES 2.0 version. g_Windowing.EnableGUIShader(SM_FONTS); CreateStaticVertexBuffers(); GLint posLoc = g_Windowing.GUIShaderGetPos(); GLint colLoc = g_Windowing.GUIShaderGetCol(); GLint tex0Loc = g_Windowing.GUIShaderGetCoord0(); GLint modelLoc = g_Windowing.GUIShaderGetModel(); // Enable the attributes used by this shader glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(colLoc); glEnableVertexAttribArray(tex0Loc); if (m_vertex.size() > 0) { // Deal with vertices that had to use software clipping std::vector<SVertex> vecVertices( 6 * (m_vertex.size() / 4) ); SVertex *vertices = &vecVertices[0]; for (size_t i=0; i<m_vertex.size(); i+=4) { *vertices++ = m_vertex[i]; *vertices++ = m_vertex[i+1]; *vertices++ = m_vertex[i+2]; *vertices++ = m_vertex[i+1]; *vertices++ = m_vertex[i+3]; *vertices++ = m_vertex[i+2]; } vertices = &vecVertices[0]; glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, x)); // Normalize color values. Does not affect Performance at all. glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, r)); glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (char*)vertices + offsetof(SVertex, u)); glDrawArrays(GL_TRIANGLES, 0, vecVertices.size()); } if (m_vertexTrans.size() > 0) { // Deal with the vertices that can be hardware clipped and therefore translated // Bind our pre-calculated array to GL_ELEMENT_ARRAY_BUFFER glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementArrayHandle); // Store currect scissor CRect scissor = g_graphicsContext.StereoCorrection(g_graphicsContext.GetScissors()); for (size_t i = 0; i < m_vertexTrans.size(); i++) { // Apply the clip rectangle CRect clip = g_Windowing.ClipRectToScissorRect(m_vertexTrans[i].clip); if (!clip.IsEmpty()) { // intersect with current scissor clip.Intersect(scissor); // skip empty clip if (clip.IsEmpty()) continue; g_Windowing.SetScissors(clip); } // Apply the translation to the currently active (top-of-stack) model view matrix glMatrixModview.Push(); glMatrixModview.Get().Translatef(m_vertexTrans[i].translateX, m_vertexTrans[i].translateY, m_vertexTrans[i].translateZ); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get()); // Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point glBindBuffer(GL_ARRAY_BUFFER, (GLuint) m_vertexTrans[i].vertexBuffer->bufferHandle); // Do the actual drawing operation, split into groups of characters no // larger than the pre-determined size of the element array for (size_t character = 0; m_vertexTrans[i].vertexBuffer->size > character; character += ELEMENT_ARRAY_MAX_CHAR_INDEX) { size_t count = m_vertexTrans[i].vertexBuffer->size - character; count = std::min<size_t>(count, ELEMENT_ARRAY_MAX_CHAR_INDEX); // Set up the offsets of the various vertex attributes within the buffer // object bound to GL_ARRAY_BUFFER glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), (GLvoid *) (character*sizeof(SVertex)*4 + offsetof(SVertex, x))); glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), (GLvoid *) (character*sizeof(SVertex)*4 + offsetof(SVertex, r))); glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), (GLvoid *) (character*sizeof(SVertex)*4 + offsetof(SVertex, u))); glDrawElements(GL_TRIANGLES, 6 * count, GL_UNSIGNED_SHORT, 0); } glMatrixModview.Pop(); } // Restore the original scissor rectangle g_Windowing.SetScissors(scissor); // Restore the original model view matrix glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get()); // Unbind GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } // Disable the attributes used by this shader glDisableVertexAttribArray(posLoc); glDisableVertexAttribArray(colLoc); glDisableVertexAttribArray(tex0Loc); g_Windowing.DisableGUIShader(); #endif }
void CGUIFontTTFDX::LastEnd() { ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); if (!pContext) return; typedef CGUIFontTTFBase::CTranslatedVertices trans; bool transIsEmpty = std::all_of(m_vertexTrans.begin(), m_vertexTrans.end(), [](trans& _) { return _.vertexBuffer->size <= 0; }); // no chars to render if (m_vertex.empty() && transIsEmpty) return; CreateStaticIndexBuffer(); unsigned int offset = 0; unsigned int stride = sizeof(SVertex); CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader(); // Set font texture as shader resource ID3D11ShaderResourceView* resources[] = { m_speedupTexture->GetShaderResource() }; pGUIShader->SetShaderViews(1, resources); // Enable alpha blend g_Windowing.SetAlphaBlendEnable(true); // Set our static index buffer pContext->IASetIndexBuffer(m_staticIndexBuffer, DXGI_FORMAT_R16_UINT, 0); // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles. pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); if (!m_vertex.empty()) { // Deal with vertices that had to use software clipping if (!UpdateDynamicVertexBuffer(&m_vertex[0], m_vertex.size())) return; // Set the dynamic vertex buffer to active in the input assembler pContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset); // Do the actual drawing operation, split into groups of characters no // larger than the pre-determined size of the element array size_t size = m_vertex.size() / 4; for (size_t character = 0; size > character; character += ELEMENT_ARRAY_MAX_CHAR_INDEX) { size_t count = size - character; count = std::min<size_t>(count, ELEMENT_ARRAY_MAX_CHAR_INDEX); // 6 indices and 4 vertices per character pGUIShader->DrawIndexed(count * 6, 0, character * 4); } } if (!transIsEmpty) { // Deal with the vertices that can be hardware clipped and therefore translated // Store current GPU transform XMMATRIX view = pGUIShader->GetView(); // Store current scissor CRect scissor = g_graphicsContext.StereoCorrection(g_graphicsContext.GetScissors()); for (size_t i = 0; i < m_vertexTrans.size(); i++) { // ignore empty buffers if (m_vertexTrans[i].vertexBuffer->size == 0) continue; // Apply the clip rectangle CRect clip = g_Windowing.ClipRectToScissorRect(m_vertexTrans[i].clip); // Intersect with current scissors clip.Intersect(scissor); // skip empty clip, a little improvement to not render invisible text if (clip.IsEmpty()) continue; g_Windowing.SetScissors(clip); // Apply the translation to the model view matrix XMMATRIX translation = XMMatrixTranslation(m_vertexTrans[i].translateX, m_vertexTrans[i].translateY, m_vertexTrans[i].translateZ); pGUIShader->SetView(XMMatrixMultiply(translation, view)); CD3DBuffer* vbuffer = reinterpret_cast<CD3DBuffer*>(m_vertexTrans[i].vertexBuffer->bufferHandle); // Set the static vertex buffer to active in the input assembler ID3D11Buffer* buffers[1] = { vbuffer->Get() }; pContext->IASetVertexBuffers(0, 1, buffers, &stride, &offset); // Do the actual drawing operation, split into groups of characters no // larger than the pre-determined size of the element array for (size_t character = 0; m_vertexTrans[i].vertexBuffer->size > character; character += ELEMENT_ARRAY_MAX_CHAR_INDEX) { size_t count = m_vertexTrans[i].vertexBuffer->size - character; count = std::min<size_t>(count, ELEMENT_ARRAY_MAX_CHAR_INDEX); // 6 indices and 4 vertices per character pGUIShader->DrawIndexed(count * 6, 0, character * 4); } } // restore scissor g_Windowing.SetScissors(scissor); // Restore the original transform pGUIShader->SetView(view); } pGUIShader->RestoreBuffers(); }