@@ -1517,12 +1517,41 @@ void plGLPipeline::IDrawPlate(plPlate* plate)
15171517
15181518struct plAVTexVert
15191519{
1520- float fPos [3 ];
1520+ float fPos [2 ];
15211521 float fUv [2 ];
15221522};
15231523
1524+ static const char * AVATAR_VERTEX_SHADER_STRING = R"( #version 430
1525+
1526+ layout(location = 0) in vec2 aVtxPosition;
1527+ layout(location = 1) in vec2 aVtxUV;
1528+
1529+ out vec2 vVtxUV;
1530+
1531+ void main() {
1532+ vVtxUV = aVtxUV;
1533+ gl_Position = vec4(aVtxPosition, 0.0, 1.0);
1534+ })" ;
1535+
1536+ static const char * AVATAR_FRAGMENT_SHADER_STRING = R"( #version 430
1537+ precision mediump float;
1538+
1539+ layout(location = 0) uniform sampler2D uTex;
1540+ layout(location = 1) uniform vec4 uColor;
1541+
1542+ in highp vec2 vVtxUV;
1543+ out vec4 fragColor;
1544+
1545+ void main() {
1546+ fragColor = texture(uTex, vVtxUV.xy) * uColor;
1547+ })" ;
1548+
15241549void plGLPipeline::IPreprocessAvatarTextures ()
15251550{
1551+ static GLuint sVertShader = 0 ;
1552+ static GLuint sFragShader = 0 ;
1553+ static GLuint sProgram = 0 ;
1554+
15261555 plProfile_Set (AvRTPoolUsed, fClothingOutfits .size ());
15271556 plProfile_Set (AvRTPoolCount, fAvRTPool .size ());
15281557 plProfile_Set (AvRTPoolRes, fAvRTWidth );
@@ -1534,51 +1563,200 @@ void plGLPipeline::IPreprocessAvatarTextures()
15341563 if (fClothingOutfits .empty ())
15351564 return ;
15361565
1537- static float kIdentityMatrix [16 ] = {
1538- 1 .0f , 0 .0f , 0 .0f , 0 .0f ,
1539- 0 .0f , 1 .0f , 0 .0f , 0 .0f ,
1540- 0 .0f , 0 .0f , 1 .0f , 0 .0f ,
1541- 0 .0f , 0 .0f , 0 .0f , 1 .0f
1542- };
1566+ // Set up the shaders the first time to go through here
1567+ if (!sVertShader ) {
1568+ GLuint vshader = glCreateShader (GL_VERTEX_SHADER);
1569+ glShaderSource (vshader, 1 , &AVATAR_VERTEX_SHADER_STRING, nullptr );
1570+ glCompileShader (vshader);
1571+ LOG_GL_ERROR_CHECK (" Vertex Shader compile failed" );
1572+
1573+ sVertShader = vshader;
1574+ }
1575+
1576+ if (!sFragShader ) {
1577+ GLuint fshader = glCreateShader (GL_FRAGMENT_SHADER);
1578+ glShaderSource (fshader, 1 , &AVATAR_FRAGMENT_SHADER_STRING, nullptr );
1579+ glCompileShader (fshader);
1580+ LOG_GL_ERROR_CHECK (" Vertex Shader compile failed" );
15431581
1544- // glUniformMatrix4fv(mRef->uMatrixProj, 1, GL_TRUE, kIdentityMatrix);
1545- // glUniformMatrix4fv(mRef->uMatrixW2C, 1, GL_TRUE, kIdentityMatrix);
1546- // glUniformMatrix4fv(mRef->uMatrixC2W, 1, GL_TRUE, kIdentityMatrix);
1547- // glUniformMatrix4fv(mRef->uMatrixL2W, 1, GL_TRUE, kIdentityMatrix);
1582+ sFragShader = fshader;
1583+ }
1584+
1585+ if (!sProgram ) {
1586+ GLuint program = glCreateProgram ();
1587+ LOG_GL_ERROR_CHECK (" Create Program failed" );
1588+
1589+ if (plGLVersion () >= 43 ) {
1590+ const char * name = " AvatarClothing" ;
1591+ glObjectLabel (GL_PROGRAM, program, strlen (name), name);
1592+ }
1593+
1594+ glAttachShader (program, sVertShader );
1595+ LOG_GL_ERROR_CHECK (" Attach Vertex Shader failed" );
1596+
1597+ glAttachShader (program, sFragShader );
1598+ LOG_GL_ERROR_CHECK (" Attach Fragment Shader failed" );
1599+
1600+ glLinkProgram (program);
1601+ LOG_GL_ERROR_CHECK (" Program Link failed" );
1602+
1603+ GLint isLinked = 0 ;
1604+ glGetProgramiv (program, GL_LINK_STATUS, &isLinked);
1605+ if (isLinked == GL_FALSE)
1606+ {
1607+ GLint maxLength = 0 ;
1608+ glGetProgramiv (program, GL_INFO_LOG_LENGTH, &maxLength);
1609+
1610+ // The maxLength includes the NULL character
1611+ char * log = new char [maxLength];
1612+ glGetProgramInfoLog (program, maxLength, &maxLength, log);
1613+
1614+ hsStatusMessage (log);
1615+ delete[] log;
1616+ }
1617+
1618+ sProgram = program;
1619+ }
15481620
15491621 for (size_t oIdx = 0 ; oIdx < fClothingOutfits .size (); oIdx++) {
15501622 plClothingOutfit* co = fClothingOutfits [oIdx];
15511623 if (co->fBase == nullptr || co->fBase ->fBaseTexture == nullptr )
15521624 continue ;
15531625
1554- #if 0
15551626 plRenderTarget* rt = plRenderTarget::ConvertNoRef (co->fTargetLayer ->GetTexture ());
15561627 if (rt != nullptr && co->fDirtyItems .Empty ())
15571628 // we've still got our valid RT from last frame and we have nothing to do.
15581629 continue ;
15591630
15601631 if (rt == nullptr ) {
15611632 rt = IGetNextAvRT ();
1633+
1634+ plGLMaterialShaderRef* mRef = static_cast <plGLMaterialShaderRef*>(co->fMaterial ->GetDeviceRef ());
1635+ if (mRef )
1636+ mRef ->SetDirty (true );
1637+
15621638 co->fTargetLayer ->SetTexture (rt);
15631639 }
1564- #endif
15651640
1566- // PushRenderTarget(rt);
1641+ PushRenderTarget (rt);
1642+ glViewport (0 , 0 , rt->GetWidth (), rt->GetHeight ());
1643+ glDepthRange (0.0 , 1.0 );
15671644
1568- // HACK HACK HACK
1569- co->fTargetLayer ->SetTexture (co->fBase ->fBaseTexture );
1645+ glUseProgram (sProgram );
1646+ LOG_GL_ERROR_CHECK (" Use Program failed" );
1647+ fDevice .fCurrentProgram = sProgram ;
1648+
1649+ glUniform1i (0 , 0 );
1650+ glUniform4f (1 , 1 .f , 1 .f , 1 .f , 1 .f );
1651+ glDepthFunc (GL_LEQUAL);
1652+ glDepthMask (GL_TRUE);
15701653
1571- // TODO: Actually render to the render target
1654+ float uOff = 0 .5f / rt->GetWidth ();
1655+ float vOff = 0 .5f / rt->GetHeight ();
15721656
1573- // PopRenderTarget();
1574- // co->fDirtyItems.Clear();
1657+ IDrawClothingQuad (-1 .f , -1 .f , 2 .f , 2 .f , uOff, vOff, co->fBase ->fBaseTexture );
1658+ plClothingLayout *layout = plClothingMgr::GetClothingMgr ()->GetLayout (co->fBase ->fLayoutName );
1659+
1660+ for (plClothingItem *item : co->fItems ) {
1661+ for (size_t j = 0 ; j < item->fElements .size (); j++) {
1662+ for (int k = 0 ; k < plClothingElement::kLayerMax ; k++) {
1663+ if (item->fTextures [j][k] == nullptr )
1664+ continue ;
1665+
1666+ plMipmap* itemBufferTex = item->fTextures [j][k];
1667+ hsColorRGBA tint = co->GetItemTint (item, k);
1668+ if (k >= plClothingElement::kLayerSkinBlend1 && k <= plClothingElement::kLayerSkinLast )
1669+ tint.a = co->fSkinBlends [k - plClothingElement::kLayerSkinBlend1 ];
1670+
1671+ if (k == plClothingElement::kLayerBase ) {
1672+ glBlendFunc (GL_ONE, GL_ZERO);
1673+ } else {
1674+ glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
1675+ }
1676+
1677+ glUniform4f (1 , tint.r , tint.g , tint.b , tint.a );
1678+
1679+ float screenW = (float )item->fElements [j]->fWidth / layout->fOrigWidth * 2 .f ;
1680+ float screenH = (float )item->fElements [j]->fHeight / layout->fOrigWidth * 2 .f ;
1681+ float screenX = (float )item->fElements [j]->fXPos / layout->fOrigWidth * 2 .f - 1 .f ;
1682+ float screenY = (1 .f - (float )item->fElements [j]->fYPos / layout->fOrigWidth ) * 2 .f - 1 .f - screenH;
1683+
1684+ IDrawClothingQuad (screenX, screenY, screenW, screenH, uOff, vOff, itemBufferTex);
1685+ }
1686+ }
1687+ }
1688+
1689+ PopRenderTarget ();
1690+ co->fDirtyItems .Clear ();
15751691 }
15761692
15771693 fView .fXformResetFlags = fView .kResetAll ;
15781694
15791695 fClothingOutfits .swap (fPrevClothingOutfits );
15801696}
15811697
1698+ void plGLPipeline::IDrawClothingQuad (float x, float y, float w, float h, float uOff, float vOff, plMipmap *tex)
1699+ {
1700+ const uint32_t kVSize = sizeof (plAVTexVert);
1701+
1702+ plGLTextureRef* ref = static_cast <plGLTextureRef*>(tex->GetDeviceRef ());
1703+ if (!ref || ref->IsDirty ())
1704+ {
1705+ CheckTextureRef (tex);
1706+ ref = (plGLTextureRef*)tex->GetDeviceRef ();
1707+ }
1708+
1709+ glActiveTexture (GL_TEXTURE0);
1710+ LOG_GL_ERROR_CHECK (" Active Texture failed" )
1711+
1712+ glBindTexture (GL_TEXTURE_2D, ref->fRef );
1713+ LOG_GL_ERROR_CHECK (" Bind Texture failed" );
1714+
1715+ plAVTexVert ptr[4 ];
1716+ plAVTexVert vert;
1717+ vert.fPos [0 ] = x;
1718+ vert.fPos [1 ] = y;
1719+ vert.fUv [0 ] = uOff;
1720+ vert.fUv [1 ] = 1 .f + vOff;
1721+
1722+ // P0
1723+ ptr[2 ] = vert;
1724+
1725+ // P1
1726+ ptr[0 ] = vert;
1727+ ptr[0 ].fPos [0 ] += w;
1728+ ptr[0 ].fUv [0 ] += 1 .f ;
1729+
1730+ // P2
1731+ ptr[1 ] = vert;
1732+ ptr[1 ].fPos [0 ] += w;
1733+ ptr[1 ].fUv [0 ] += 1 .f ;
1734+ ptr[1 ].fPos [1 ] += h;
1735+ ptr[1 ].fUv [1 ] -= 1 .f ;
1736+
1737+ // P3
1738+ ptr[3 ] = vert;
1739+ ptr[3 ].fPos [1 ] += h;
1740+ ptr[3 ].fUv [1 ] -= 1 .f ;
1741+
1742+ GLuint vbo;
1743+ glGenBuffers (1 , &vbo);
1744+ glBindBuffer (GL_ARRAY_BUFFER, vbo);
1745+ glBufferData (GL_ARRAY_BUFFER, sizeof (ptr), ptr, GL_STATIC_DRAW);
1746+
1747+ glVertexAttribPointer (0 , 2 , GL_FLOAT, GL_FALSE, kVSize , (void *)(sizeof (float ) * 0 ));
1748+ glEnableVertexAttribArray (0 );
1749+
1750+ glVertexAttribPointer (1 , 2 , GL_FLOAT, GL_FALSE, kVSize , (void *)(sizeof (float ) * 2 ));
1751+ glEnableVertexAttribArray (1 );
1752+
1753+ glDrawArrays (GL_TRIANGLE_STRIP, 0 , 6 );
1754+
1755+ LOG_GL_ERROR_CHECK (" Render failed" )
1756+
1757+ glDeleteBuffers (1 , &vbo);
1758+ }
1759+
15821760
15831761bool plGLPipeline::ISoftwareVertexBlend (plDrawableSpans* drawable, const std::vector<int16_t >& visList)
15841762{
0 commit comments