| 639 | } |
| 640 | |
| 641 | void EngineGL33::SetTexture(const TextureGL33* tex, const Poseidon::render::LegacySpec& spec) |
| 642 | { |
| 643 | // P3D model faces may legitimately have no texture (the original D3D9 |
| 644 | // fixed-function pipeline rendered them via SELECTARG2(DIFFUSE) — vertex |
| 645 | // color only). GLSL has no fixed-function fallback: any sampler the |
| 646 | // shader reads from must point at a texture with a defined base level, |
| 647 | // or the driver returns undefined data (NVIDIA: garbage from previously |
| 648 | // bound texture's residue, plus a LOW id=131204 warning). Bind a 1x1 |
| 649 | // opaque-white sentinel instead — `tex.rgb * vertColor.rgb` with |
| 650 | // tex=white yields vertColor, exactly matching the FF semantics. |
| 651 | unsigned int handle = tex ? tex->GetHandle() : _fallbackWhiteTex; |
| 652 | // Snapshot the GL handle into the next TL draw's record so |
| 653 | // the frame layer's `EmitDraw` can rebind without crossing the GL33 layering. |
| 654 | _currentDrawItem.backendTextureHandle = handle; |
| 655 | |
| 656 | GL33Bind::Tex2D(0, handle); |
| 657 | |
| 658 | const Poseidon::render::Backend backend = spec.backend; |
| 659 | constexpr Poseidon::render::Backend mtMask = Poseidon::render::Backend::DetailTexture | |
| 660 | Poseidon::render::Backend::SpecularTexture | |
| 661 | Poseidon::render::Backend::GrassTexture; |
| 662 | VFormatSet format = SingleTex; |
| 663 | if (tex) |
| 664 | { |
| 665 | if ((backend & mtMask) != Poseidon::render::Backend::None) |
| 666 | { |
| 667 | if (Poseidon::render::Has(backend, Poseidon::render::Backend::GrassTexture)) |
| 668 | format = GrassTex; |
| 669 | else if (Poseidon::render::Has(backend, Poseidon::render::Backend::DetailTexture)) |
| 670 | format = DetailTex; |
| 671 | else |
| 672 | format = SpecularTex; |
| 673 | } |
| 674 | } |
| 675 | SetMultiTexturing(format); |
| 676 | } |
| 677 | |
| 678 | void EngineGL33::SetMultiTexturing(VFormatSet format) |
| 679 | { |
no test coverage detected