Все работает так, как мне хотелось, и попытался добавить ко всему этому отображение теней (следуя руководству LearnOpenGL) . Если я привязываю фреймбуфер, текстуру и все остальное, но ничего с этим не делаю, шейдер и рендеринг все равно работают нормально. Но если я даже просто вызову Clear(), экран останется черным (я обнаружил, что неустановленная текстура в моем шейдере AlphaTexture по какой-то причине возвращает полные значения 1.0, а также некоторые вычисления просто прерываются). Я потратил на это кучу времени и постепенно начинаю сходить с ума. Пожалуйста, помогите, вот соответствующий код, а также весь репозиторий:
Создание фреймбуфера и его вложения (в Light.cs):
Код: Выделить всё
public unsafe void InitShadowMap(GL gl)
{
// Generate framebuffer
_shadowMapFbo = gl.GenFramebuffer();
gl.BindFramebuffer(FramebufferTarget.Framebuffer, _shadowMapFbo);
// Generate depth texture
ShadowMap = gl.GenTexture();
gl.BindTexture(TextureTarget.Texture2D, ShadowMap);
gl.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.DepthComponent, ShadowWidth, ShadowHeight, 0, PixelFormat.DepthComponent, PixelType.Float, null);
// Set texture parameters
gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
// Set border color
float[] borderColor = { 1.0f, 1.0f, 1.0f, 1.0f };
gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, borderColor);
// Attach depth texture as FBO's depth buffer
gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, ShadowMap, 0);
gl.DrawBuffer(DrawBufferMode.None);
gl.ReadBuffer(ReadBufferMode.None);
// Check if framebuffer is complete
if (gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != GLEnum.FramebufferComplete)
{
Console.WriteLine("Framebuffer not complete");
}
// Unbind framebuffer
gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}
Код: Выделить всё
public void BindFramebuffer(GL gl)
{
gl.BindFramebuffer(FramebufferTarget.Framebuffer, _shadowMapFbo);
gl.Viewport(0, 0, ShadowWidth, ShadowHeight);
gl.Clear(ClearBufferMask.DepthBufferBit); // even just this breaks everything
}
Код: Выделить всё
public unsafe void Draw(GL gl, Shader shader)
{
int[] oldViewport = new int[4];
gl.GetInteger(GetPName.Viewport, (Span)oldViewport);
Lights[0].BindFramebuffer(gl);
_shadowShader!.Use(gl);
var lightSpaceMatrix = Lights[0].GetLightSpaceMatrix();
gl.UniformMatrix4(_shadowShader.GetUniformLocation(gl, ViewMatrixVariableName), 1, false, (float*)&lightSpaceMatrix);
// Program.CheckError();
// // Program.CheckError();
// foreach (var obj in Objects)
// {
// obj.Draw(gl, _shadowShader, false);
// }
gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
// Program.CheckError();
shader.Use(gl);
// Program.CheckError();
gl.UniformMatrix4(shader.GetUniformLocation(gl, LightSpaceMatrixVariableName), 1, false, (float*)&lightSpaceMatrix);
// Program.CheckError();
gl.Viewport(oldViewport[0], oldViewport[1], (uint)oldViewport[2], (uint)oldViewport[3]);
// Program.CheckError();
//
gl.ActiveTexture(TextureUnit.Texture15);
// Program.CheckError();
gl.BindTexture(TextureTarget.Texture2D, Lights[0].ShadowMap);
// Program.CheckError();
gl.Uniform1(shader.GetUniformLocation(gl, ShadowMapVariableName), 15);
// Program.CheckError();
//
gl.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
SetViewerPosition(gl, shader);
SetViewMatrix(gl, shader);
SkyBox?.Draw(gl, shader);
foreach (var obj in Objects)
{
obj.Draw(gl, shader);
}
}
Подробнее здесь: https://stackoverflow.com/questions/785 ... -behaviour