Ir para conteúdo

Todas Atividades

Atualizada automaticamente

  1. Recentemente
  2. Hoje
  3. Gabriel

    Devocional | 26/08/2026

    Lugares desertos Deuteronômio 2.1-7 Pois o SENHOR [...] tem cuidado de cada um de seus passos por este grande deserto. v.7 Quando eu conhecia meu Salvador há pouco tempo, achava que encontraria Jesus nas experiências cheias de emoção. Mas esses pontos altos raramente duravam ou traziam crescimento. A autora Lina AbuJamra afirma que encontramos Deus e crescemos nos lugares desertos. Em um de seus estudos bíblicos, diz que: "O objetivo de Deus é usar os desertos de nossa vida para nos fortalecer". E continua: "A bondade de Deus deve ser recebida em meio à sua dor, e não é comprovada pela ausência de dor". Em lugares difíceis de tristeza, perda e dor, Deus nos ajuda a crescer em nossa fé e a nos aproximarmos dele. Lina já aprendeu que "o deserto não é um descuido no plano de Deus, mas uma parte integral de nosso processo de crescimento". Deus levou muitos patriarcas do Antigo Testamento ao deserto. Abraão, Isaque e Jacó tiveram experiências no deserto. Foi no deserto que Deus preparou o coração de Moisés e o chamou para conduzir Seu povo para livrá-lo da escravidão (Êxodo 3.1-2,9-10). E foi também no deserto que Deus cuidou da jornada dos israelitas por 40 anos com Sua ajuda e orientação (Deuteronômio 2.7). Deus estava com Moisés e com os israelitas a cada passo do caminho deles pelo deserto, e Ele está com você e comigo em nossa jornada. No deserto, aprendemos a confiar em Deus. No deserto, Ele nos encontra, e nele nós crescemos. — Alyson Kieda Deus já o encontrou num lugar deserto? Qual foi o resultado? Deus, Tu és fiel e compassivo. Sou grato por Tua presença nos momentos difíceis do deserto da vida.
  4. -Ink-

    resolvido Ajuda

    Tópico Resolvido! Ficamos felizes que seu tópico tenha sido resolvido!🙂 Devido a isso, estaremos fechando este tópico... Atenciosamente,Web Cheats
  5. Bacana, da pra ancorar no "timer" do dia nativo, assim a sombra anda conforme o dia passa... int nTime = (dwServerTime / 600000) % 12; // fase do dia: 0..11 e trocando o 12 por 600000 fica progressivo, vc ve literalmente a sombra andando.
  6. -Ink-

    resolvido Ajuda

    Repassei aos superiores, se notar no perfil próximo a Seguidores, também contém esse número 2. Assim que tiver uma resposta referente a resolução, estarei em contato! O problema foi resolvido @Gabriel Seguimos à disposição!
  7. Ontem
  8. Gabriel

    resolvido Ajuda

    Boa noite a todos. Bom, tô com um problema já faz um tempo, todo tópico que entro aparece "2 quem está por aqui", mas só eu estou por lá.
  9. MEUS CANAIS DE VÍDEOS HC CURSOS E TUTORIAIS 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️ VEICARECA GAMES 🎬 ▶️ PLAYLIST DO MEU CANAL NO YOUTUBE 🎬 ▶️
  10. Parabéns pelo projeto! Testei o jogo e ele é idle literalmente 😂 Aproveitei para fuçar um pouco mais a parte técnica também. Fiz alguns testes interceptando requisições, explorando os endpoints da API e tentando algumas manipulações client-side para ver se dava para contornar alguma validação ou alterar o comportamento do jogo. Até cheguei a usar snippets para automatizar alguns testes. A ideia foi apenas avaliar a estrutura e a segurança da aplicação; caso encontrasse alguma vulnerabilidade real, a intenção seria reportá-la. No fim, as validações do backend seguraram tudo que tentei. Achei bem interessante a estrutura e a forma como algumas regras estão sendo validadas no servidor. Parabéns pelo projeto! 👏
  11. Somos o primeiro servidor do Genero Idle, inpirado no no jogo RPG: With Your Destiny ! Site: [Hidden Content] WhatsApp: [Hidden Content] - Equipamentos Padrão - Mercado Global - Arena PVP - Sistema de GUILD - Sistema de Montaria - Guerras: Torre, Cidades e Noatun - Quests (Em Breve) - Crafts Padrão (Em Breve) Projeto em Desenvolvimento
  12. Bom dia pessoal.

  13. gnib

    Fim do WYD KR?

    Não é falta de gente pra dar ctrl c + ctrl v no claude, são devs de verdade, que contamos nos dedos na comunidade
  14. Se eles soubesse como a comunidade br esta, não faltaria gente para equipe,
  15. Gabriel

    Devocional | 25/08/2026

    Corrida espacial 1 Coríntios 3.3-9 Pois nós somos colaboradores de Deus, e vocês são lavoura de Deus e edifício de Deus. v.9 Em 29 de julho de 1955, os EUA anunciaram sua intenção de colocar satélites no espaço. Logo após, a União Soviética declarou seus planos de fazer o mesmo. Teve início a corrida espacial! Os soviéticos lançaram o primeiro satélite (Sputnik) e colocaram Yuri Gagarin como o primeiro homem que orbitou no espaço. A corrida continuou e em 20 de julho de 1969, Neil Armstrong deu o "salto gigantesco para a humanidade" na superfície da Lua, extraoficialmente encerrando a competição. Iniciou-se um tempo de colaboração, que levou à criação da Estação Espacial Internacional. Às vezes, a concorrência pode ser saudável, levando-nos a fazer mais, o que talvez não fizéssemos de outra forma. Em outros momentos, a competição é destrutiva. Esse era um problema na igreja de Corinto, pois diferentes grupos se apegavam a vários líderes como seus faróis de esperança. Paulo buscou abordar esse problema quando escreveu: "Não importa quem planta ou quem rega, mas sim Deus, que faz crescer" (1 Coríntios 3.7), e concluiu: "Pois nós somos colaboradores" (v.9). Colaboradores, não concorrentes. E não apenas uns com os outros, mas com o próprio Deus! Por meio de Sua capacitação e orientação, podemos servir juntos, como colegas de trabalho, promovendo a mensagem de Jesus, para Sua honra e não a nossa. — Bill Crowder Você já participou de uma competição doentia? Como Jesus o ajuda a servir aos outros humildemente? Deus amoroso, ensina-me o valor de trabalhar para honrar-te e ajudar os outros.
  16. Estou tentando "abrir" faz uns 10 minutos... E só depois de um bom tempo apareceu o BG, fiquei em um loop de recarregamentos... [Hidden Content]
  17. Última semana
  18. 🚀 PATCH DE ATUALIZAÇÃO — WAR OF DESTINY ✅ Ampliação e melhorias na área jogável ✅ Sistema de múltiplas instâncias ✅ Novo Modo Economia de recursos ✅ Otimização geral de até 80% ⚔️ Mais desempenho, estabilidade e liberdade para jogar diretamente pelo navegador!
  19. Hello Guys Download link: [Hidden Content] __________________ Selling combo high quality with guarantee➖ Selling: EMAIL: PASS USER: PASS MAILLIST AOL, YAHOO, HOTMAIL, OUTLOOK, FRANCE, UK, GERMANY, USA, ESPAIN, ITALY, CANADA, AUSTRALIA… To buy msg me TELEGRAM: @KOCsupport
  20. 🌑 SISTEMA DE SOMBRAS PARA TMPROJECT – WYD Código desenvolvido e compartilhado por mim para melhorar o visual do WYD, adicionando sombras ao projeto e deixando o ambiente mais bonito e moderno. Também criei um arquivo .md com as instruções necessárias para implementar corretamente o sistema no TMProject. ✅ Código completo ✅ Guia de implementação em .md ✅ Compatível com TMProject ✅ Melhoria visual para o cliente WYD 💻 compartilhado por João Frango ShadowProjectorMesh.cpp #include "pch.h" #include "ShadowProjectorMesh.h" #include "TMHuman.h" #include "TMGlobal.h" #include "RenderDevice.h" // ============================================================ // MANUAL SHADOW TUNING (AJUSTE MANUAL DA SOMBRA PROJETADA) // // 1) ROTACAO DA SOMBRA (direcao): // g_ShadowLightDir.x / y / z // // 2) ALTURA/ENCOSTE NO CHAO: // g_ShadowPlaneBias // // 3) INTENSIDADE: // g_ShadowAlphaMax // // Dica: ajuste primeiro a direcao (x/z), depois bias, depois alpha. // ============================================================ static D3DXVECTOR3 g_ShadowLightDir = D3DXVECTOR3(1.20f, -0.70f, 0.60f); static float g_ShadowPlaneBias = 0.005f; static float g_ShadowDirOffset = 2.80f; static DWORD g_ShadowAlphaMax = 120; static bool g_ShadowLockAtFeet = false; // false = projeta para o lado D3DXVECTOR3 ShadowProjectorMesh::s_vLightDir = D3DXVECTOR3(1.20f, -0.70f, 0.60f); DWORD ShadowProjectorMesh::s_sAlphaBlend, ShadowProjectorMesh::s_sSrcBlend, ShadowProjectorMesh::s_sDestBlend; DWORD ShadowProjectorMesh::s_sAlphaRef, ShadowProjectorMesh::s_sAlphaFunc, ShadowProjectorMesh::s_sAlphaTest; DWORD ShadowProjectorMesh::s_sZWrite, ShadowProjectorMesh::s_sZEnable, ShadowProjectorMesh::s_sZFunc, ShadowProjectorMesh::s_sDepthBias, ShadowProjectorMesh::s_sSlopeBias, ShadowProjectorMesh::s_sLighting; DWORD ShadowProjectorMesh::s_sFogEnable, ShadowProjectorMesh::s_sFogVertex, ShadowProjectorMesh::s_sCull; DWORD ShadowProjectorMesh::s_sTexFactor, ShadowProjectorMesh::s_sColorVertex; DWORD ShadowProjectorMesh::s_sTs0ColorOp, ShadowProjectorMesh::s_sTs0ColorArg1, ShadowProjectorMesh::s_sTs0ColorArg2; DWORD ShadowProjectorMesh::s_sTs0AlphaOp, ShadowProjectorMesh::s_sTs0AlphaArg1, ShadowProjectorMesh::s_sTs0AlphaArg2; DWORD ShadowProjectorMesh::s_sTs1ColorOp, ShadowProjectorMesh::s_sTs1ColorArg1, ShadowProjectorMesh::s_sTs1ColorArg2; DWORD ShadowProjectorMesh::s_sTs1AlphaOp, ShadowProjectorMesh::s_sTs1AlphaArg1, ShadowProjectorMesh::s_sTs1AlphaArg2; DWORD ShadowProjectorMesh::s_sStencilEnable, ShadowProjectorMesh::s_sStencilFunc, ShadowProjectorMesh::s_sStencilRef, ShadowProjectorMesh::s_sStencilMask; DWORD ShadowProjectorMesh::s_sStencilWriteMask, ShadowProjectorMesh::s_sStencilPass, ShadowProjectorMesh::s_sStencilFail, ShadowProjectorMesh::s_sStencilZFail; void ShadowProjectorMesh::SetupShadowMatrix(TMHuman* pHuman, float groundY) { if (!pHuman) return; if (groundY < -9000.0f) groundY = 0.0f; if (g_ShadowLockAtFeet) { D3DXMatrixIdentity(&pHuman->m_matShadow); pHuman->m_matShadow._22 = 0.0f; pHuman->m_matShadow._42 = groundY + g_ShadowPlaneBias; return; } D3DXVECTOR3 L = g_ShadowLightDir; D3DXVec3Normalize(&L, &L); // D3DXMatrixShadow com luz direcional rasante — projeta o mesh real no plano do chao // Quanto mais rasante o Y da luz, mais longa/deitada fica a sombra D3DXPLANE plane(0.0f, 1.0f, 0.0f, -(groundY + g_ShadowPlaneBias)); D3DXVECTOR4 lightDir(-L.x, -L.y, -L.z, 0.0f); // w=0 = luz direcional D3DXMatrixShadow(&pHuman->m_matShadow, &lightDir, &plane); } bool ShadowProjectorMesh::BeginShadow(IDirect3DDevice9* dev, float alpha) { if (!dev || !g_pDevice) return false; auto FloatToDWORD = [](float v) -> DWORD { DWORD out = 0; memcpy(&out, &v, sizeof(DWORD)); return out; }; // Salva via dev direto — estado real do device, sem cache dev->GetRenderState(D3DRS_ALPHABLENDENABLE, &s_sAlphaBlend); dev->GetRenderState(D3DRS_SRCBLEND, &s_sSrcBlend); dev->GetRenderState(D3DRS_DESTBLEND, &s_sDestBlend); dev->GetRenderState(D3DRS_ALPHAREF, &s_sAlphaRef); dev->GetRenderState(D3DRS_ALPHAFUNC, &s_sAlphaFunc); dev->GetRenderState(D3DRS_ALPHATESTENABLE, &s_sAlphaTest); dev->GetRenderState(D3DRS_ZWRITEENABLE, &s_sZWrite); dev->GetRenderState(D3DRS_ZENABLE, &s_sZEnable); dev->GetRenderState(D3DRS_ZFUNC, &s_sZFunc); dev->GetRenderState(D3DRS_DEPTHBIAS, &s_sDepthBias); dev->GetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, &s_sSlopeBias); dev->GetRenderState(D3DRS_LIGHTING, &s_sLighting); dev->GetRenderState(D3DRS_FOGENABLE, &s_sFogEnable); dev->GetRenderState(D3DRS_FOGVERTEXMODE, &s_sFogVertex); dev->GetRenderState(D3DRS_CULLMODE, &s_sCull); dev->GetRenderState(D3DRS_TEXTUREFACTOR, &s_sTexFactor); dev->GetRenderState(D3DRS_COLORVERTEX, &s_sColorVertex); dev->GetTextureStageState(0, D3DTSS_COLOROP, &s_sTs0ColorOp); dev->GetTextureStageState(0, D3DTSS_COLORARG1, &s_sTs0ColorArg1); dev->GetTextureStageState(0, D3DTSS_COLORARG2, &s_sTs0ColorArg2); dev->GetTextureStageState(0, D3DTSS_ALPHAOP, &s_sTs0AlphaOp); dev->GetTextureStageState(0, D3DTSS_ALPHAARG1, &s_sTs0AlphaArg1); dev->GetTextureStageState(0, D3DTSS_ALPHAARG2, &s_sTs0AlphaArg2); dev->GetTextureStageState(1, D3DTSS_COLOROP, &s_sTs1ColorOp); dev->GetTextureStageState(1, D3DTSS_COLORARG1, &s_sTs1ColorArg1); dev->GetTextureStageState(1, D3DTSS_COLORARG2, &s_sTs1ColorArg2); dev->GetTextureStageState(1, D3DTSS_ALPHAOP, &s_sTs1AlphaOp); dev->GetTextureStageState(1, D3DTSS_ALPHAARG1, &s_sTs1AlphaArg1); dev->GetTextureStageState(1, D3DTSS_ALPHAARG2, &s_sTs1AlphaArg2); dev->GetRenderState(D3DRS_STENCILENABLE, &s_sStencilEnable); dev->GetRenderState(D3DRS_STENCILFUNC, &s_sStencilFunc); dev->GetRenderState(D3DRS_STENCILREF, &s_sStencilRef); dev->GetRenderState(D3DRS_STENCILMASK, &s_sStencilMask); dev->GetRenderState(D3DRS_STENCILWRITEMASK,&s_sStencilWriteMask); dev->GetRenderState(D3DRS_STENCILPASS, &s_sStencilPass); dev->GetRenderState(D3DRS_STENCILFAIL, &s_sStencilFail); dev->GetRenderState(D3DRS_STENCILZFAIL, &s_sStencilZFail); DWORD a = (DWORD)(alpha * 255.0f); if (a > g_ShadowAlphaMax) a = g_ShadowAlphaMax; DWORD shadowColor = D3DCOLOR_ARGB(a, 0, 0, 0); // Configura via g_pDevice para manter cache sincronizado g_pDevice->SetTexture(0, nullptr); g_pDevice->SetTexture(1, nullptr); g_pDevice->SetRenderState(D3DRS_TEXTUREFACTOR, shadowColor); g_pDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); g_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); g_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); g_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); g_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); g_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); g_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS); g_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); g_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE); g_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); g_pDevice->SetRenderState(D3DRS_DEPTHBIAS, FloatToDWORD(-0.00005f)); g_pDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FloatToDWORD(-0.5f)); g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); g_pDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); g_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); g_pDevice->SetRenderState(D3DRS_ALPHAREF, 0); g_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); g_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); // so pinta onde stencil=0 (sem personagem) g_pDevice->SetRenderState(D3DRS_STENCILREF, 0x00); g_pDevice->SetRenderState(D3DRS_STENCILMASK, 0xFF); g_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xFF); g_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); g_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); g_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); return true; } void ShadowProjectorMesh::EndShadow(IDirect3DDevice9* dev) { if (!dev || !g_pDevice) return; // Restaura via g_pDevice para manter cache sincronizado // Textura null para limpar estado da sombra g_pDevice->SetTexture(0, nullptr); g_pDevice->SetTexture(1, nullptr); // Restaura render states via g_pDevice (atualiza cache + device) g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, s_sAlphaBlend); g_pDevice->SetRenderState(D3DRS_SRCBLEND, s_sSrcBlend); g_pDevice->SetRenderState(D3DRS_DESTBLEND, s_sDestBlend); g_pDevice->SetRenderState(D3DRS_ALPHAREF, s_sAlphaRef); g_pDevice->SetRenderState(D3DRS_ALPHAFUNC, s_sAlphaFunc); g_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, s_sAlphaTest); g_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, s_sZWrite); g_pDevice->SetRenderState(D3DRS_ZENABLE, s_sZEnable); g_pDevice->SetRenderState(D3DRS_ZFUNC, s_sZFunc); g_pDevice->SetRenderState(D3DRS_DEPTHBIAS, s_sDepthBias); g_pDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, s_sSlopeBias); g_pDevice->SetRenderState(D3DRS_LIGHTING, s_sLighting); g_pDevice->SetRenderState(D3DRS_FOGENABLE, s_sFogEnable); g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, s_sFogVertex); g_pDevice->SetRenderState(D3DRS_CULLMODE, s_sCull); g_pDevice->SetRenderState(D3DRS_TEXTUREFACTOR, s_sTexFactor); g_pDevice->SetRenderState(D3DRS_COLORVERTEX, s_sColorVertex); g_pDevice->SetRenderState(D3DRS_STENCILENABLE, s_sStencilEnable); g_pDevice->SetRenderState(D3DRS_STENCILFUNC, s_sStencilFunc); g_pDevice->SetRenderState(D3DRS_STENCILREF, s_sStencilRef); g_pDevice->SetRenderState(D3DRS_STENCILMASK, s_sStencilMask); g_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, s_sStencilWriteMask); g_pDevice->SetRenderState(D3DRS_STENCILPASS, s_sStencilPass); g_pDevice->SetRenderState(D3DRS_STENCILFAIL, s_sStencilFail); g_pDevice->SetRenderState(D3DRS_STENCILZFAIL, s_sStencilZFail); g_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, s_sTs0ColorOp); g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, s_sTs0ColorArg1); g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, s_sTs0ColorArg2); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, s_sTs0AlphaOp); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, s_sTs0AlphaArg1); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, s_sTs0AlphaArg2); g_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, s_sTs1ColorOp); g_pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, s_sTs1ColorArg1); g_pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, s_sTs1ColorArg2); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, s_sTs1AlphaOp); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, s_sTs1AlphaArg1); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, s_sTs1AlphaArg2); // Força cache de textura a refletir nullptr — próximo render vai rebindar // Invalida cache para forçar rebind no próximo SetTexture g_pDevice->m_pTexture[0] = nullptr; g_pDevice->m_pTexture[1] = nullptr; } ShadowProjectorMesh.h #pragma once #include <d3d9.h> #include <d3dx9.h> class TMHuman; class ShadowProjectorMesh { public: static D3DXVECTOR3 s_vLightDir; static void SetupShadowMatrix(TMHuman* pHuman, float groundY); static bool BeginShadow(IDirect3DDevice9* dev, float alpha = 0.38f); static void EndShadow(IDirect3DDevice9* dev); private: // render states static DWORD s_sAlphaBlend, s_sSrcBlend, s_sDestBlend; static DWORD s_sAlphaRef, s_sAlphaFunc, s_sAlphaTest; static DWORD s_sZWrite, s_sZEnable, s_sZFunc, s_sDepthBias, s_sSlopeBias, s_sLighting; static DWORD s_sFogEnable, s_sFogVertex, s_sCull; static DWORD s_sTexFactor, s_sColorVertex; // stage 0 static DWORD s_sTs0ColorOp, s_sTs0ColorArg1, s_sTs0ColorArg2; static DWORD s_sTs0AlphaOp, s_sTs0AlphaArg1, s_sTs0AlphaArg2; // stage 1 static DWORD s_sTs1ColorOp, s_sTs1ColorArg1, s_sTs1ColorArg2; static DWORD s_sTs1AlphaOp, s_sTs1AlphaArg1, s_sTs1AlphaArg2; static DWORD s_sStencilEnable, s_sStencilFunc, s_sStencilRef, s_sStencilMask; static DWORD s_sStencilWriteMask, s_sStencilPass, s_sStencilFail, s_sStencilZFail; }; Implementação .md # ShadowProjectorMesh — Documentação Completa de Implementação ## Visão Geral O `ShadowProjectorMesh` é um sistema de sombras projetadas (planar shadow) usando DirectX 9. Ele projeta a geometria dos personagens e objetos no plano do chão como silhuetas escuras, utilizando **stencil buffer** para evitar sobreposição de sombras. --- ## Arquivos do Sistema | Arquivo | Descrição | |---|---| | `ShadowProjectorMesh.h` | Header com declaração da classe | | `ShadowProjectorMesh.cpp` | Implementação dos 3 métodos principais | | `TMHuman.cpp` | Integração com personagens (queue + render) | | `TMObject.cpp` | Integração com objetos estáticos (queue + render) | | `ObjectManager.cpp` | Pipeline de renderização (flush das filas) | | `TMProject.vcxproj` | Registro no projeto Visual Studio | | `TMProject.vcxproj.filters` | Filtro: `Source Files\Effects` / `Header Files\Effects` | --- ## 1. ShadowProjectorMesh.h ```cpp #pragma once #include <d3d9.h> #include <d3dx9.h> class TMHuman; class ShadowProjectorMesh { public: static D3DXVECTOR3 s_vLightDir; static void SetupShadowMatrix(TMHuman* pHuman, float groundY); static bool BeginShadow(IDirect3DDevice9* dev, float alpha = 0.38f); static void EndShadow(IDirect3DDevice9* dev); private: // render states static DWORD s_sAlphaBlend, s_sSrcBlend, s_sDestBlend; static DWORD s_sAlphaRef, s_sAlphaFunc, s_sAlphaTest; static DWORD s_sZWrite, s_sZEnable, s_sZFunc, s_sDepthBias, s_sSlopeBias, s_sLighting; static DWORD s_sFogEnable, s_sFogVertex, s_sCull; static DWORD s_sTexFactor, s_sColorVertex; // stage 0 static DWORD s_sTs0ColorOp, s_sTs0ColorArg1, s_sTs0ColorArg2; static DWORD s_sTs0AlphaOp, s_sTs0AlphaArg1, s_sTs0AlphaArg2; // stage 1 static DWORD s_sTs1ColorOp, s_sTs1ColorArg1, s_sTs1ColorArg2; static DWORD s_sTs1AlphaOp, s_sTs1AlphaArg1, s_sTs1AlphaArg2; static DWORD s_sStencilEnable, s_sStencilFunc, s_sStencilRef, s_sStencilMask; static DWORD s_sStencilWriteMask, s_sStencilPass, s_sStencilFail, s_sStencilZFail; }; ``` --- ## 2. ShadowProjectorMesh.cpp ```cpp #include "pch.h" #include "ShadowProjectorMesh.h" #include "TMHuman.h" #include "TMGlobal.h" #include "RenderDevice.h" // ============================================================ // MANUAL SHADOW TUNING (AJUSTE MANUAL DA SOMBRA PROJETADA) // // 1) ROTACAO DA SOMBRA (direcao): // g_ShadowLightDir.x / y / z // // 2) ALTURA/ENCOSTE NO CHAO: // g_ShadowPlaneBias // // 3) INTENSIDADE: // g_ShadowAlphaMax // // Dica: ajuste primeiro a direcao (x/z), depois bias, depois alpha. // ============================================================ static D3DXVECTOR3 g_ShadowLightDir = D3DXVECTOR3(1.20f, -0.70f, 0.60f); static float g_ShadowPlaneBias = 0.005f; static float g_ShadowDirOffset = 2.80f; static DWORD g_ShadowAlphaMax = 120; static bool g_ShadowLockAtFeet = false; // false = projeta para o lado D3DXVECTOR3 ShadowProjectorMesh::s_vLightDir = D3DXVECTOR3(1.20f, -0.70f, 0.60f); DWORD ShadowProjectorMesh::s_sAlphaBlend, ShadowProjectorMesh::s_sSrcBlend, ShadowProjectorMesh::s_sDestBlend; DWORD ShadowProjectorMesh::s_sAlphaRef, ShadowProjectorMesh::s_sAlphaFunc, ShadowProjectorMesh::s_sAlphaTest; DWORD ShadowProjectorMesh::s_sZWrite, ShadowProjectorMesh::s_sZEnable, ShadowProjectorMesh::s_sZFunc, ShadowProjectorMesh::s_sDepthBias, ShadowProjectorMesh::s_sSlopeBias, ShadowProjectorMesh::s_sLighting; DWORD ShadowProjectorMesh::s_sFogEnable, ShadowProjectorMesh::s_sFogVertex, ShadowProjectorMesh::s_sCull; DWORD ShadowProjectorMesh::s_sTexFactor, ShadowProjectorMesh::s_sColorVertex; DWORD ShadowProjectorMesh::s_sTs0ColorOp, ShadowProjectorMesh::s_sTs0ColorArg1, ShadowProjectorMesh::s_sTs0ColorArg2; DWORD ShadowProjectorMesh::s_sTs0AlphaOp, ShadowProjectorMesh::s_sTs0AlphaArg1, ShadowProjectorMesh::s_sTs0AlphaArg2; DWORD ShadowProjectorMesh::s_sTs1ColorOp, ShadowProjectorMesh::s_sTs1ColorArg1, ShadowProjectorMesh::s_sTs1ColorArg2; DWORD ShadowProjectorMesh::s_sTs1AlphaOp, ShadowProjectorMesh::s_sTs1AlphaArg1, ShadowProjectorMesh::s_sTs1AlphaArg2; DWORD ShadowProjectorMesh::s_sStencilEnable, ShadowProjectorMesh::s_sStencilFunc, ShadowProjectorMesh::s_sStencilRef, ShadowProjectorMesh::s_sStencilMask; DWORD ShadowProjectorMesh::s_sStencilWriteMask, ShadowProjectorMesh::s_sStencilPass, ShadowProjectorMesh::s_sStencilFail, ShadowProjectorMesh::s_sStencilZFail; void ShadowProjectorMesh::SetupShadowMatrix(TMHuman* pHuman, float groundY) { if (!pHuman) return; if (groundY < -9000.0f) groundY = 0.0f; if (g_ShadowLockAtFeet) { D3DXMatrixIdentity(&pHuman->m_matShadow); pHuman->m_matShadow._22 = 0.0f; pHuman->m_matShadow._42 = groundY + g_ShadowPlaneBias; return; } D3DXVECTOR3 L = g_ShadowLightDir; D3DXVec3Normalize(&L, &L); // D3DXMatrixShadow com luz direcional rasante D3DXPLANE plane(0.0f, 1.0f, 0.0f, -(groundY + g_ShadowPlaneBias)); D3DXVECTOR4 lightDir(-L.x, -L.y, -L.z, 0.0f); // w=0 = luz direcional D3DXMatrixShadow(&pHuman->m_matShadow, &lightDir, &plane); } bool ShadowProjectorMesh::BeginShadow(IDirect3DDevice9* dev, float alpha) { if (!dev || !g_pDevice) return false; auto FloatToDWORD = [](float v) -> DWORD { DWORD out = 0; memcpy(&out, &v, sizeof(DWORD)); return out; }; // Salva render states originais dev->GetRenderState(D3DRS_ALPHABLENDENABLE, &s_sAlphaBlend); dev->GetRenderState(D3DRS_SRCBLEND, &s_sSrcBlend); dev->GetRenderState(D3DRS_DESTBLEND, &s_sDestBlend); dev->GetRenderState(D3DRS_ALPHAREF, &s_sAlphaRef); dev->GetRenderState(D3DRS_ALPHAFUNC, &s_sAlphaFunc); dev->GetRenderState(D3DRS_ALPHATESTENABLE, &s_sAlphaTest); dev->GetRenderState(D3DRS_ZWRITEENABLE, &s_sZWrite); dev->GetRenderState(D3DRS_ZENABLE, &s_sZEnable); dev->GetRenderState(D3DRS_ZFUNC, &s_sZFunc); dev->GetRenderState(D3DRS_DEPTHBIAS, &s_sDepthBias); dev->GetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, &s_sSlopeBias); dev->GetRenderState(D3DRS_LIGHTING, &s_sLighting); dev->GetRenderState(D3DRS_FOGENABLE, &s_sFogEnable); dev->GetRenderState(D3DRS_FOGVERTEXMODE, &s_sFogVertex); dev->GetRenderState(D3DRS_CULLMODE, &s_sCull); dev->GetRenderState(D3DRS_TEXTUREFACTOR, &s_sTexFactor); dev->GetRenderState(D3DRS_COLORVERTEX, &s_sColorVertex); dev->GetTextureStageState(0, D3DTSS_COLOROP, &s_sTs0ColorOp); dev->GetTextureStageState(0, D3DTSS_COLORARG1, &s_sTs0ColorArg1); dev->GetTextureStageState(0, D3DTSS_COLORARG2, &s_sTs0ColorArg2); dev->GetTextureStageState(0, D3DTSS_ALPHAOP, &s_sTs0AlphaOp); dev->GetTextureStageState(0, D3DTSS_ALPHAARG1, &s_sTs0AlphaArg1); dev->GetTextureStageState(0, D3DTSS_ALPHAARG2, &s_sTs0AlphaArg2); dev->GetTextureStageState(1, D3DTSS_COLOROP, &s_sTs1ColorOp); dev->GetTextureStageState(1, D3DTSS_COLORARG1, &s_sTs1ColorArg1); dev->GetTextureStageState(1, D3DTSS_COLORARG2, &s_sTs1ColorArg2); dev->GetTextureStageState(1, D3DTSS_ALPHAOP, &s_sTs1AlphaOp); dev->GetTextureStageState(1, D3DTSS_ALPHAARG1, &s_sTs1AlphaArg1); dev->GetTextureStageState(1, D3DTSS_ALPHAARG2, &s_sTs1AlphaArg2); dev->GetRenderState(D3DRS_STENCILENABLE, &s_sStencilEnable); dev->GetRenderState(D3DRS_STENCILFUNC, &s_sStencilFunc); dev->GetRenderState(D3DRS_STENCILREF, &s_sStencilRef); dev->GetRenderState(D3DRS_STENCILMASK, &s_sStencilMask); dev->GetRenderState(D3DRS_STENCILWRITEMASK,&s_sStencilWriteMask); dev->GetRenderState(D3DRS_STENCILPASS, &s_sStencilPass); dev->GetRenderState(D3DRS_STENCILFAIL, &s_sStencilFail); dev->GetRenderState(D3DRS_STENCILZFAIL, &s_sStencilZFail); DWORD a = (DWORD)(alpha * 255.0f); if (a > g_ShadowAlphaMax) a = g_ShadowAlphaMax; DWORD shadowColor = D3DCOLOR_ARGB(a, 0, 0, 0); // Configura via g_pDevice para manter cache sincronizado g_pDevice->SetTexture(0, nullptr); g_pDevice->SetTexture(1, nullptr); g_pDevice->SetRenderState(D3DRS_TEXTUREFACTOR, shadowColor); g_pDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); g_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); g_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); g_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); g_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); g_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); g_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS); g_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); g_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE); g_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); g_pDevice->SetRenderState(D3DRS_DEPTHBIAS, FloatToDWORD(-0.00005f)); g_pDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FloatToDWORD(-0.5f)); g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); g_pDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); g_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); g_pDevice->SetRenderState(D3DRS_ALPHAREF, 0); g_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); g_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); g_pDevice->SetRenderState(D3DRS_STENCILREF, 0x00); g_pDevice->SetRenderState(D3DRS_STENCILMASK, 0xFF); g_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xFF); g_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); g_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); g_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); return true; } void ShadowProjectorMesh::EndShadow(IDirect3DDevice9* dev) { if (!dev || !g_pDevice) return; g_pDevice->SetTexture(0, nullptr); g_pDevice->SetTexture(1, nullptr); // Restaura todos os render states salvos g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, s_sAlphaBlend); g_pDevice->SetRenderState(D3DRS_SRCBLEND, s_sSrcBlend); g_pDevice->SetRenderState(D3DRS_DESTBLEND, s_sDestBlend); g_pDevice->SetRenderState(D3DRS_ALPHAREF, s_sAlphaRef); g_pDevice->SetRenderState(D3DRS_ALPHAFUNC, s_sAlphaFunc); g_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, s_sAlphaTest); g_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, s_sZWrite); g_pDevice->SetRenderState(D3DRS_ZENABLE, s_sZEnable); g_pDevice->SetRenderState(D3DRS_ZFUNC, s_sZFunc); g_pDevice->SetRenderState(D3DRS_DEPTHBIAS, s_sDepthBias); g_pDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, s_sSlopeBias); g_pDevice->SetRenderState(D3DRS_LIGHTING, s_sLighting); g_pDevice->SetRenderState(D3DRS_FOGENABLE, s_sFogEnable); g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, s_sFogVertex); g_pDevice->SetRenderState(D3DRS_CULLMODE, s_sCull); g_pDevice->SetRenderState(D3DRS_TEXTUREFACTOR, s_sTexFactor); g_pDevice->SetRenderState(D3DRS_COLORVERTEX, s_sColorVertex); g_pDevice->SetRenderState(D3DRS_STENCILENABLE, s_sStencilEnable); g_pDevice->SetRenderState(D3DRS_STENCILFUNC, s_sStencilFunc); g_pDevice->SetRenderState(D3DRS_STENCILREF, s_sStencilRef); g_pDevice->SetRenderState(D3DRS_STENCILMASK, s_sStencilMask); g_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, s_sStencilWriteMask); g_pDevice->SetRenderState(D3DRS_STENCILPASS, s_sStencilPass); g_pDevice->SetRenderState(D3DRS_STENCILFAIL, s_sStencilFail); g_pDevice->SetRenderState(D3DRS_STENCILZFAIL, s_sStencilZFail); g_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, s_sTs0ColorOp); g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, s_sTs0ColorArg1); g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, s_sTs0ColorArg2); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, s_sTs0AlphaOp); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, s_sTs0AlphaArg1); g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, s_sTs0AlphaArg2); g_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, s_sTs1ColorOp); g_pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, s_sTs1ColorArg1); g_pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, s_sTs1ColorArg2); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, s_sTs1AlphaOp); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, s_sTs1AlphaArg1); g_pDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, s_sTs1AlphaArg2); // Invalida cache para forcar rebind g_pDevice->m_pTexture[0] = nullptr; g_pDevice->m_pTexture[1] = nullptr; } ``` --- ## 3. Membros adicionados ao TMHuman.h Na classe `TMHuman`, os seguintes membros sao necessarios: ```cpp // TMHuman.h (dentro da classe TMHuman) int m_bShadowPass; // Flag: 1 durante render de sombra, 0 normal D3DXMATRIX m_matShadow; // Matriz de projecao da sombra no chao void QueueProjectedShadow(); void RenderProjectedShadowPass(); static void ClearProjectedShadowQueue(); static void FlushProjectedShadowQueue(); ``` Inicializado no construtor: ```cpp // TMHuman::TMHuman(TMScene* pParentScene) m_bShadowPass = 0; ``` --- ## 4. Codigo em TMHuman.cpp ### 4.1 Fila de sombras ```cpp // TMHuman.cpp — topo do arquivo #include "ShadowProjectorMesh.h" #include <vector> static std::vector<TMHuman*>& ProjectedShadowQueue() { static std::vector<TMHuman*> queue; return queue; } ``` ### 4.2 Queue / Clear / Flush ```cpp void TMHuman::QueueProjectedShadow() { auto& queue = ProjectedShadowQueue(); queue.push_back(this); } void TMHuman::ClearProjectedShadowQueue() { ProjectedShadowQueue().clear(); } void TMHuman::FlushProjectedShadowQueue() { auto& queue = ProjectedShadowQueue(); if (queue.empty()) return; // Um unico Begin/End por frame para humanos if (!ShadowProjectorMesh::BeginShadow(g_pDevice->m_pd3dDevice, 0.47f)) { queue.clear(); return; } for (TMHuman* pHuman : queue) { if (!pHuman || pHuman->m_cDeleted || pHuman->m_dwDelayDel || !pHuman->m_bVisible) continue; pHuman->RenderProjectedShadowPass(); } ShadowProjectorMesh::EndShadow(g_pDevice->m_pd3dDevice); queue.clear(); } ``` ### 4.3 RenderProjectedShadowPass (TMHuman) ```cpp void TMHuman::RenderProjectedShadowPass() { if (!g_pCurrentScene) return; bool isPlayerHuman = (g_pCurrentScene && g_pCurrentScene->m_pMyHuman == this); bool hideProjectedShadow = isPlayerHuman ? (g_bHidePlayerShadow != 0) : (g_bHideObjectShadow != 0); if (hideProjectedShadow || m_cHide || m_cShadow == 1) { return; } float groundY = g_pCurrentScene->GroundGetHeight( TMVector2(m_pSkinMesh->m_vPosition.x, m_pSkinMesh->m_vPosition.z)); // Sem montaria if (m_cMount <= 0) { if (!m_pSkinMesh || !m_pSkinMesh->m_pRoot) return; ShadowProjectorMesh::SetupShadowMatrix(this, groundY); m_bShadowPass = 1; m_pSkinMesh->m_pRoot->Render(); if (m_cMantua > 0 && m_pMantua) { TMHuman* prevOwner = m_pMantua->m_pOwner; m_pMantua->m_pOwner = this; m_pMantua->m_BaseMatrix = m_pSkinMesh->m_OutMatrix; m_pMantua->Render(0.0f, 1.0f, 0.0f); m_pMantua->m_pOwner = prevOwner; } m_bShadowPass = 0; return; } // Com montaria if (!m_pMount || !m_pMount->m_pRoot || !m_pSkinMesh || !m_pSkinMesh->m_pRoot) return; ShadowProjectorMesh::SetupShadowMatrix(this, groundY); m_bShadowPass = 1; m_pMount->m_pRoot->Render(); m_pSkinMesh->m_pRoot->Render(); if (m_cMantua > 0 && m_pMantua) { TMHuman* prevOwner = m_pMantua->m_pOwner; m_pMantua->m_pOwner = this; m_pMantua->m_BaseMatrix = m_pSkinMesh->m_OutMatrix; m_pMantua->Render(0.0f, 1.0f, 0.0f); m_pMantua->m_pOwner = prevOwner; } m_bShadowPass = 0; } ``` ### 4.4 Enfileiramento no Render() do TMHuman Dentro de `TMHuman::Render()`, apos preparar o mesh e antes de renderizar efeitos: ```cpp // Condicao para enfileirar a sombra projetada (dentro de TMHuman::Render) bool isPlayerHuman = (g_pCurrentScene && g_pCurrentScene->m_pMyHuman == this); bool hideProjectedShadow = isPlayerHuman ? (g_bHidePlayerShadow != 0) : (g_bHideObjectShadow != 0); bool canRenderProjectedShadow = (!hideProjectedShadow && !m_cHide && m_cShadow == 0); // Desativa sombra circular antiga if (m_pShade) m_pShade->m_bShow = 0; // Sem montaria: if (canRenderProjectedShadow && m_pSkinMesh->m_pRoot) QueueProjectedShadow(); // Com montaria: if (canRenderProjectedShadow && m_pMount->m_pRoot) QueueProjectedShadow(); ``` --- ## 5. Codigo em TMObject.cpp ### 5.1 Fila de sombras ```cpp // TMObject.cpp — topo do arquivo #include "ShadowProjectorMesh.h" #include <vector> static std::vector<TMObject*>& ProjectedObjectShadowQueue() { static std::vector<TMObject*> queue; return queue; } ``` ### 5.2 Declaracoes em TMObject.h ```cpp // TMObject.h (dentro da classe TMObject) void QueueProjectedShadow(); void RenderProjectedShadowPass(); static void ClearProjectedShadowQueue(); static void FlushProjectedShadowQueue(); ``` ### 5.3 Queue / Clear / Flush (TMObject) ```cpp void TMObject::QueueProjectedShadow() { ProjectedObjectShadowQueue().push_back(this); } void TMObject::ClearProjectedShadowQueue() { ProjectedObjectShadowQueue().clear(); } void TMObject::FlushProjectedShadowQueue() { auto& queue = ProjectedObjectShadowQueue(); // Modo otimizado: limpa fila sem processar sombras if (g_bModoOtimizado || g_bHideObjectShadow) { queue.clear(); return; } if (queue.empty()) return; // Um unico BeginShadow para todos os objetos if (!ShadowProjectorMesh::BeginShadow(g_pDevice->m_pd3dDevice, 0.47f)) { queue.clear(); return; } for (TMObject* pObj : queue) { if (!pObj || pObj->m_cDeleted || !pObj->m_bVisible) continue; pObj->RenderProjectedShadowPass(); } ShadowProjectorMesh::EndShadow(g_pDevice->m_pd3dDevice); queue.clear(); } ``` ### 5.4 RenderProjectedShadowPass (TMObject) ```cpp void TMObject::RenderProjectedShadowPass() { if (!g_pCurrentScene || g_pCurrentScene->m_eSceneType != ESCENE_TYPE::ESCENE_FIELD || g_bHideObjectShadow) return; TMMesh* pMesh = g_pMeshManager->GetCommonMesh(m_dwObjType, 0, 3_min); if (!pMesh) return; float groundY = g_pCurrentScene->GroundGetHeight(m_vecPosition); if (groundY <= -9000.0f) groundY = m_fHeight; D3DXVECTOR3 L = ShadowProjectorMesh::s_vLightDir; D3DXVec3Normalize(&L, &L); if (L.y > -0.01f) L.y = -0.01f; D3DXMATRIX mat{}, matPosition{}, matScale{}; D3DXMatrixScaling(&matScale, pMesh->m_fScaleH, pMesh->m_fScaleV, pMesh->m_fScaleH); D3DXMatrixTranslation(&matPosition, m_vecPosition.x, m_fHeight, m_vecPosition.y); D3DXMatrixRotationYawPitchRoll(&mat, m_fAngle, -D3DXToRadian(90), 0.0f); D3DXMatrixMultiply(&mat, &g_pDevice->m_matWorld, &mat); D3DXMatrixMultiply(&mat, &mat, &matScale); D3DXMatrixMultiply(&mat, &mat, &matPosition); D3DXMATRIX matProjected; D3DXPLANE plane(0.0f, 1.0f, 0.0f, -(groundY + 0.005f)); D3DXVECTOR4 lightDir(-L.x, -L.y, -L.z, 0.0f); // w=0 = luz direcional D3DXMATRIX matShadow{}; D3DXMatrixShadow(&matShadow, &lightDir, &plane); D3DXMatrixMultiply(&matProjected, &mat, &matShadow); // Begin/End e feito pelo FlushProjectedShadowQueue — apenas faz o draw aqui g_pDevice->m_pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(0), &matProjected); pMesh->RenderDrawShadow(); } ``` --- ## 6. Pipeline de Renderizacao — ObjectManager.cpp ```cpp // ObjectManager::RenderObject() void ObjectManager::RenderObject() { if (g_pCurrentScene != nullptr) { // 1. Limpa filas e stencil buffer TMHuman::ClearProjectedShadowQueue(); TMObject::ClearProjectedShadowQueue(); if (g_pDevice && g_pDevice->m_pd3dDevice) g_pDevice->m_pd3dDevice->Clear(0, nullptr, D3DCLEAR_STENCIL, 0, 1.0f, 0); // 2. Renderiza cena principal (cada Render() enfileira sombras via QueueProjectedShadow) // ... (tree traversal renderizando todos os nodos exceto containers de efeito/extra) // 3. Flush das sombras projetadas (renderiza todas de uma vez) TMHuman::FlushProjectedShadowQueue(); TMObject::FlushProjectedShadowQueue(); if (g_pDevice) g_pDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); // 4. Renderiza Danos e Efeitos por ultimo (sobre as sombras) // ... (containers de efeito e extras) } } ``` --- ## 7. Registro no Projeto Visual Studio ### TMProject.vcxproj ```xml <ClInclude Include="ShadowProjectorMesh.h" /> <ClCompile Include="ShadowProjectorMesh.cpp" /> ``` ### TMProject.vcxproj.filters ```xml <ClInclude Include="ShadowProjectorMesh.h"> <Filter>Header Files\Effects</Filter> </ClInclude> <ClCompile Include="ShadowProjectorMesh.cpp"> <Filter>Source Files\Effects</Filter> </ClCompile> ``` --- ## 8. Dependencias / Includes | Arquivo | Includes necessarios | |---|---| | `ShadowProjectorMesh.h` | `<d3d9.h>`, `<d3dx9.h>` | | `ShadowProjectorMesh.cpp` | `"pch.h"`, `"ShadowProjectorMesh.h"`, `"TMHuman.h"`, `"TMGlobal.h"`, `"RenderDevice.h"` | | `TMHuman.cpp` | `"ShadowProjectorMesh.h"`, `<vector>` | | `TMObject.cpp` | `"ShadowProjectorMesh.h"`, `"OptimizationConfig.h"`, `<vector>` | --- ## 9. Variaveis Globais Utilizadas | Variavel | Tipo | Descricao | |---|---|---| | `g_pDevice` | `RenderDevice*` | Device wrapper com cache de estados | | `g_pCurrentScene` | `TMScene*` | Cena ativa (acessa `GroundGetHeight`, `m_pMyHuman`) | | `g_bModoOtimizado` | `bool` | Modo otimizado — pula sombras de objetos | | `g_bHideObjectShadow` | `DWORD/bool` | Esconde sombras de mobs/objetos | | `g_bHidePlayerShadow` | `DWORD/bool` | Esconde sombra do jogador | | `g_pMeshManager` | `MeshManager*` | Gerenciador de meshes estáticos | --- ## 10. Fluxo de Execucao Resumido ``` ObjectManager::RenderObject() | +-- TMHuman::ClearProjectedShadowQueue() +-- TMObject::ClearProjectedShadowQueue() +-- Clear(STENCIL) | +-- [Render cena] --> cada TMHuman::Render() chama QueueProjectedShadow() | --> cada TMObject::Render() chama QueueProjectedShadow() | +-- TMHuman::FlushProjectedShadowQueue() | +-- BeginShadow(alpha=0.47) // configura estados + stencil | +-- loop: RenderProjectedShadowPass() | | +-- SetupShadowMatrix() // calcula m_matShadow | | +-- m_bShadowPass = 1 | | +-- m_pSkinMesh->Render() // mesh usa m_matShadow quando m_bShadowPass=1 | | +-- m_bShadowPass = 0 | +-- EndShadow() // restaura todos os estados | +-- TMObject::FlushProjectedShadowQueue() | +-- BeginShadow(alpha=0.47) | +-- loop: RenderProjectedShadowPass() | | +-- D3DXMatrixShadow() // calcula matriz inline | | +-- SetTransform + RenderDrawShadow() | +-- EndShadow() | +-- SetRenderState(STENCILENABLE, FALSE) +-- [Render efeitos/danos] ``` --- ## 11. Parametros de Ajuste (Tuning) Definidos como `static` no topo de `ShadowProjectorMesh.cpp`: | Variavel | Valor Padrao | Descricao | |---|---|---| | `g_ShadowLightDir` | `(1.20, -0.70, 0.60)` | Direcao da luz (rotacao da sombra) | | `g_ShadowPlaneBias` | `0.005f` | Bias do plano (evita z-fighting) | | `g_ShadowDirOffset` | `2.80f` | Offset direcional (nao utilizado ativamente) | | `g_ShadowAlphaMax` | `120` | Alpha maximo da sombra (0-255) | | `g_ShadowLockAtFeet` | `false` | `true` = sombra direto embaixo; `false` = projecao lateral |
  21. NEW BOTS!: @qoihfuoa_bot @hydralog_bot @octoberslog_bot @perimeterlog_bot
  1. Mais Resultados
×
×
  • Criar Novo...

Informação Importante

Nós fazemos uso de cookies no seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies , caso contrário, vamos supor que você está bem para continuar.