| 455 | } |
| 456 | |
| 457 | void EngineGL33::Init3DState() |
| 458 | { |
| 459 | if (!_glContext) |
| 460 | return; |
| 461 | |
| 462 | _bias = 0; |
| 463 | _clipANearEnabled = false; |
| 464 | _clipAFarEnabled = false; |
| 465 | _texLoc = TexLocalVidMem; |
| 466 | // Capability bits (_can*, _dxtFormats, _hasStencilBuffer, _canDetailTex, |
| 467 | // _canZBias) are static constexpr in EngineGL33.hpp — nothing to set here. |
| 468 | |
| 469 | // Guard band: OpenGL has no hardware guard band (unlike D3D9/D3D11). |
| 470 | // Use a modest guard band — vertices outside NDC [-1,1] are clipped by OpenGL's |
| 471 | // fixed-function pipeline, but small overflows are safe with depth clamping. |
| 472 | float maxBand = 1024 * 4; |
| 473 | _minGuardX = static_cast<int>(-maxBand); |
| 474 | _maxGuardX = static_cast<int>(_w + maxBand); |
| 475 | _minGuardY = static_cast<int>(-maxBand); |
| 476 | _maxGuardY = static_cast<int>(_h + maxBand); |
| 477 | |
| 478 | _nightEye = 0; |
| 479 | _pixelSize = 32; |
| 480 | _depthBpp = 32; |
| 481 | |
| 482 | int viewportW, viewportH; |
| 483 | RenderTargetSize(viewportW, viewportH); |
| 484 | |
| 485 | // Set viewport |
| 486 | glViewport(0, 0, viewportW, viewportH); |
| 487 | |
| 488 | // Use D3D-compatible clip space: Z ∈ [0, 1] instead of OpenGL's default [-1, 1]. |
| 489 | // This matches the projection matrix convention used by D3D11 and avoids |
| 490 | // halving the depth buffer precision. |
| 491 | if (GLAD_GL_ARB_clip_control) |
| 492 | { |
| 493 | glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); |
| 494 | LOG_DEBUG(Graphics, "GL33: glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE) enabled"); |
| 495 | } |
| 496 | else |
| 497 | { |
| 498 | LOG_WARN(Graphics, "GL33: GL_ARB_clip_control not available — depth precision will be reduced"); |
| 499 | } |
| 500 | |
| 501 | // Apply default state |
| 502 | InvalidatePipelineCache(); |
| 503 | ApplyDepthMode(DepthMode::Normal); |
| 504 | ApplyBlendMode(BlendMode::AlphaBlend); |
| 505 | |
| 506 | // Default rasterizer: backface cull |
| 507 | // D3D convention: CW = front face. With glClipControl(GL_LOWER_LEFT), |
| 508 | // no viewport Y-flip occurs, so mesh winding is preserved from NDC to window. |
| 509 | Poseidon::render::cull::Back(); |
| 510 | Poseidon::render::cull::FrontFaceCW(); |
| 511 | |
| 512 | _pointSampling = false; |
| 513 | _lastClampU = false; |
| 514 | _lastClampV = false; |
nothing calls this directly
no test coverage detected