DECLINLINE(GLfloat*) crBltVtRectsTFNormalized(const RTRECT *paRects, uint32_t cRects, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height) { for (uint32_t i = 0; i < cRects; ++i) { pBuff = crBltVtRectTFNormalized(&paRects[i], normalX, normalY, pBuff, height); } return pBuff; }
/* Indexed GL_TRIANGLES */ DECLINLINE(GLfloat*) crBltVtRectITNormalized(const RTRECT *pRect, uint32_t normalX, uint32_t normalY, GLfloat* pBuff, uint32_t height) { GLfloat* ret = crBltVtRectTFNormalized(pRect, normalX, normalY, pBuff, height); return ret; }
static DECLCALLBACK(int) crBltBlitTexBufImplDraw2D(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags) { GLuint normalX, normalY; uint32_t srcHeight = (fFlags & CRBLT_F_INVERT_SRC_YCOORDS) ? pSrc->height : 0; uint32_t dstHeight = (fFlags & CRBLT_F_INVERT_DST_YCOORDS) ? pDstSize->cy : 0; Assert(srcHeight == dstHeight); switch (pSrc->target) { case GL_TEXTURE_2D: { normalX = pSrc->width; normalY = pSrc->height; break; } case GL_TEXTURE_RECTANGLE_ARB: { normalX = 1; normalY = 1; break; } default: { crWarning("Unsupported texture target 0x%x", pSrc->target); return VERR_INVALID_PARAMETER; } } Assert(pSrc->hwid); pBlitter->pDispatch->BindTexture(pSrc->target, pSrc->hwid); if (cRects == 1) { /* just optimizatino to draw a single rect with GL_TRIANGLE_FAN */ bool bUseSameVerticies = paSrcRect == paDstRect && normalX == 1 && normalY == 1 && srcHeight == dstHeight; GLfloat *pVerticies; GLfloat *pTexCoords; GLuint cElements = crBltVtGetNumVerticiesTF(1); if (bUseSameVerticies) { pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * sizeof (*pVerticies)); crBltVtRectTFNormalized(paDstRect, normalX, normalY, pVerticies, dstHeight); pTexCoords = pVerticies; } else { pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * 2 * sizeof (*pVerticies)); pTexCoords = crBltVtRectTFNormalized(paDstRect, 1, 1, pVerticies, dstHeight); crBltVtRectTFNormalized(paSrcRect, normalX, normalY, pTexCoords, srcHeight); } pBlitter->pDispatch->EnableClientState(GL_VERTEX_ARRAY); pBlitter->pDispatch->VertexPointer(2, GL_FLOAT, 0, pVerticies); pBlitter->pDispatch->EnableClientState(GL_TEXTURE_COORD_ARRAY); pBlitter->pDispatch->TexCoordPointer(2, GL_FLOAT, 0, pTexCoords); pBlitter->pDispatch->Enable(pSrc->target); pBlitter->pDispatch->DrawArrays(GL_TRIANGLE_FAN, 0, cElements); pBlitter->pDispatch->Disable(pSrc->target); pBlitter->pDispatch->DisableClientState(GL_TEXTURE_COORD_ARRAY); pBlitter->pDispatch->DisableClientState(GL_VERTEX_ARRAY); } else { bool bUseSameVerticies = paSrcRect == paDstRect && normalX == 1 && normalY == 1 && srcHeight == dstHeight; GLfloat *pVerticies; GLfloat *pTexCoords; GLubyte *pIndicies; GLuint cElements = crBltVtGetNumVerticiesIT(cRects); GLuint cIndicies = crBltVtGetNumIndiciesIT(cRects); GLubyte iIdxBase = 0; if (bUseSameVerticies) { pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * sizeof (*pVerticies) + cIndicies * sizeof (*pIndicies)); crBltVtRectsITNormalized(paDstRect, cRects, normalX, normalY, pVerticies, &pIndicies, &iIdxBase, dstHeight); pTexCoords = pVerticies; } else { pVerticies = (GLfloat*)crBltBufGet(&pBlitter->Verticies, cElements * 2 * 2 * sizeof (*pVerticies) + cIndicies * sizeof (*pIndicies)); pTexCoords = crBltVtRectsITNormalized(paDstRect, cRects, 1, 1, pVerticies, &pIndicies, &iIdxBase, dstHeight); crBltVtRectsITNormalized(paSrcRect, cRects, normalX, normalY, pTexCoords, NULL, NULL, srcHeight); } pBlitter->pDispatch->EnableClientState(GL_VERTEX_ARRAY); pBlitter->pDispatch->VertexPointer(2, GL_FLOAT, 0, pVerticies); pBlitter->pDispatch->EnableClientState(GL_TEXTURE_COORD_ARRAY); pBlitter->pDispatch->TexCoordPointer(2, GL_FLOAT, 0, pTexCoords); pBlitter->pDispatch->Enable(pSrc->target); pBlitter->pDispatch->DrawElements(GL_TRIANGLES, cIndicies, GL_UNSIGNED_BYTE, pIndicies); pBlitter->pDispatch->Disable(pSrc->target); pBlitter->pDispatch->DisableClientState(GL_TEXTURE_COORD_ARRAY); pBlitter->pDispatch->DisableClientState(GL_VERTEX_ARRAY); } pBlitter->pDispatch->BindTexture(pSrc->target, 0); return VINF_SUCCESS; }