| 105 | } |
| 106 | |
| 107 | bool EnsureTarget(int res) |
| 108 | { |
| 109 | if (s_fbo && s_res == res) |
| 110 | return true; |
| 111 | if (s_tex) |
| 112 | { |
| 113 | GL33Bind::OnTexDeleted(s_tex); |
| 114 | glDeleteTextures(1, &s_tex); |
| 115 | s_tex = 0; |
| 116 | } |
| 117 | if (s_fbo) |
| 118 | { |
| 119 | glDeleteFramebuffers(1, &s_fbo); |
| 120 | s_fbo = 0; |
| 121 | } |
| 122 | |
| 123 | glGenTextures(1, &s_tex); |
| 124 | glBindTexture(GL_TEXTURE_2D, s_tex); |
| 125 | GL33Bind::Invalidate(); // raw init-path bind on an unknown unit |
| 126 | glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, res, res, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); |
| 127 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 128 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 129 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 130 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 131 | |
| 132 | glGenFramebuffers(1, &s_fbo); |
| 133 | glBindFramebuffer(GL_FRAMEBUFFER, s_fbo); |
| 134 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, s_tex, 0); |
| 135 | glDrawBuffer(GL_NONE); |
| 136 | glReadBuffer(GL_NONE); |
| 137 | GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
| 138 | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
| 139 | if (status != GL_FRAMEBUFFER_COMPLETE) |
| 140 | { |
| 141 | LOG_ERROR(Graphics, "GL33 shadow-depth FBO incomplete: {}", static_cast<unsigned>(status)); |
| 142 | return false; |
| 143 | } |
| 144 | s_res = res; |
| 145 | return true; |
| 146 | } |
| 147 | |
| 148 | bool EnsureArrayTarget(int res, int layers) |
| 149 | { |
no test coverage detected