Load times are probably only slightly better than the regular client, since it's the same approach. The ground mesh is built on the main thread and must be completed before the map is displayed, while model loading runs on a separate thread and finishes later. On mobile phones it takes a couple of seconds to load a map, and on my PC a typical map loads in under one second. I believe map loading is mostly bound by I/O. No problems with FPS so far and so I haven't bothered to measure it. As mentioned I have both Direct3D or OpenGL implementations to support the renderer. I believe OpenGL is the most performant one since I've made some adjustments to heavily batch render calls.
Effects are for the most part identical to their originals effect. I can't quite copy-paste from the original client, but I can borrow the approach. Here's an example of how a simple effect is implemented:
void CRagEffect::IncAgility(void)
{
matrix vtm;
tlvertex3d vert;
vector3d src;
src = m_master->m_pos;
vtm = g_modeMgr.GetGameMode()->m_view->m_viewMatrix;
g_renderer->ProjectVertex(src, vtm, &vert);
m_tlvertX = vert.x;
m_tlvertY = vert.y;
m_pos = m_master->m_pos;
if (m_stateCnt == 0)
{
auto player = g_modeMgr.GetGameMode()->m_world->m_player;
float z = m_pos.z - player->m_pos.z;
float x = m_pos.x - player->m_pos.x;
PlayWave("effect\\EF_IncAgility.wav", x, 0.0f, z, 250, 40, 1.0f);
g_prim = LaunchEffectPrim(PP_2DTEXTURE, { 0, 0, 0 });
g_prim->m_duration = m_duration;
g_prim->m_longitude = 0;
g_prim->m_speed = 1.5f;
g_prim->m_accel = g_prim->m_speed / g_prim->m_duration * -1.2f;
g_prim->m_widthSize = 40.0f;
g_prim->m_heightSize = 20.0f;
g_prim->m_alpha = 0;
g_prim->m_maxAlpha = 200.0f;
g_prim->m_alphaSpeed = g_prim->m_maxAlpha * 0.06666667f;
g_prim->m_fadeOutCnt = g_prim->m_duration - 15;
g_prim->m_texture = new CTexture*[g_prim->m_totalTexture]();
g_prim->m_texture[0] = g_texMgr.GetTexture("effect\\agi_up.bmp", false);
}
if ((m_stateCnt % 2) == 0)
{
g_prim = LaunchEffectPrim(PP_3DCROSSTEXTURE, { 0, 0, 0 });
g_prim->m_duration = 50;
g_prim->m_matrix.MakeYRotation(GetRadian(rand() % 360));
g_prim->m_deltaPos2 = vector3d(0.0f, 0.0f, (float)(rand() % 7 + 2)) * g_prim->m_matrix;
g_prim->m_matrix.MakeXRotation(GetRadian(90));
g_prim->m_speed = (rand() % 50 + 20) * 0.01f;
g_prim->m_widthSize = (rand() % 60 + 30) * 0.1f;
g_prim->m_heightSize = 0.18f;
g_prim->m_alpha = 0;
g_prim->m_maxAlpha = 200.0f;
g_prim->m_alphaSpeed = g_prim->m_maxAlpha * 0.05f;
g_prim->m_fadeOutCnt = g_prim->m_duration - 20;
g_prim->m_texture = new CTexture*[g_prim->m_totalTexture]();
g_prim->m_texture[0] = g_texMgr.GetTexture("effect\\ac_center2.tga", false);
}
}