Версия: OpenGL ES 3.0.0 (ANGLE 2.1.25606 git hash: cb8b4e1307a9)"
Моя цель — реализовать следующий алгоритм (из этого поста Reddit) на C# с помощью Avalonia Framework OpenGlControlBase: Исходный код. Идея состоит в том, чтобы разместить 3D-объект в левой половине экрана, который я могу вращать и панорамировать. Существует также ползунок, который управляет разрезающей плоскостью. Поперечное сечение объекта, определенное этой плоскостью, должно отображаться с правой стороны, причем область сечения каким-то образом окрашена, а окружающие биты должны быть черными. Результат должен выглядеть примерно так: Результат Видео
Итак, вот моя проблема: левая сторона отображается нормально, но правая сторона представляет для меня проблему. Она не только отображает замаскированное сечение, но и отображает всю область сплошным цветом:
Я предполагаю, что буфера трафарета нет, потому что я пишу в него, но при попытке чтения из него я получаю только нули или когда говорю рендереру использовать GL_NEVER в качестве функции трафарета. он по-прежнему отображает все, как будто никакого трафарета не было...
Вот мой код:
Теперь я не понимаю, почему буфер трафарета не применяется и все нормально отображается с правой стороны. Как видите, как только я ожидал, что это будет какая-то проблема с трафаретным буфером, я добавил эти две строки в метод DrawRegular:
Насколько я понимаю, это должно привести к тому, что последующие вызовы элемента рисования ничего не отрисуют и что экран должен быть просто черным/пустым с правой стороны. Поскольку я думаю, что буфер трафарета либо не существует, либо он каким-то образом деактивирован, я провел небольшое исследование, как активировать/добавить его снова. Именно там я наткнулся на этот сайт о FBO: Учебное пособие по объектам фреймбуфера. Я не до конца это понял, но все равно попробовал реализовать. Вот что представляют собой закомментированные строки в методе OnOpenGlRender. Сначала я попытался поместить строки в метод Init, но это тоже не сработало. Когда они в текущем состоянии раскомментированы, экран становится только серым. Я чувствую, что подход с ПФ – это правильный путь для дальнейшего развития, но я действительно не понимаю, что там на самом деле должно произойти. Я думаю, что мне нужно определить новый FBO, который включает трафаретный буфер, в который я могу писать, затем привязаться к этому новому FBO и использовать этот новый кадровый буфер вместо кадрового буфера, предоставляемого системой. Есть какие-нибудь подсказки, почему это не работает?
Информация о версии и оборудовании: [list] [*]Средство рендеринга: ANGLE (Intel, Intel(R) Iris(R) Xe Graphics (0x00009A49) Direct3D11 vs_5_0 ps_5_0, D3D11-31.0.101.5333) [*]Версия: OpenGL ES 3.0.0 (ANGLE 2.1.25606 git hash: cb8b4e1307a9)" [/list] Моя цель — реализовать следующий алгоритм (из этого поста Reddit) на C# с помощью Avalonia Framework OpenGlControlBase: Исходный код. Идея состоит в том, чтобы разместить 3D-объект в левой половине экрана, который я могу вращать и панорамировать. Существует также ползунок, который управляет разрезающей плоскостью. Поперечное сечение объекта, определенное этой плоскостью, должно отображаться с правой стороны, причем область сечения каким-то образом окрашена, а окружающие биты должны быть черными. Результат должен выглядеть примерно так: Результат Видео Итак, вот моя проблема: левая сторона отображается нормально, но правая сторона представляет для меня проблему. Она не только отображает замаскированное сечение, но и отображает всю область сплошным цветом: [img]https://i.sstatic.net/wi9URgZY.png[/img]
Я предполагаю, что буфера трафарета нет, потому что я пишу в него, но при попытке чтения из него я получаю только нули или когда говорю рендереру использовать GL_NEVER в качестве функции трафарета. он по-прежнему отображает все, как будто никакого трафарета не было... Вот мой код: [code]public override unsafe void OnOpenGlRender(GlInterface GL, int fb, PixelSize size, Vector3 cameraPos, Quaternion quaternion, Vector3 pan, Vector3 cameraUpVector, float scale ) { //int rboId; //GL.GenRenderbuffers(1, &rboId); //GL.BindRenderbuffer(GL_RENDERBUFFER, rboId); //GL.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, 100, 100); //GL.BindRenderbuffer(GL_RENDERBUFFER, 0);
var model = Matrix4x4.CreateFromQuaternion(quaternion); model *= Matrix4x4.CreateTranslation(pan); model *= Matrix4x4.CreateScale(scale); var modelLoc = GL.GetUniformLocationString(_shaderProgram, "uModel"); GL.UniformMatrix4fv(modelLoc, 1, false, &model);
var view = Matrix4x4.CreateLookAt(cameraPos, new Vector3(), cameraUpVector); var viewLoc = GL.GetUniformLocationString(_shaderProgram, "uView"); GL.UniformMatrix4fv(viewLoc, 1, false, &view);
var model = Matrix4x4.Identity; model *= Matrix4x4.CreateScale(10); var modelLoc = GL.GetUniformLocationString(_shaderProgram, "uModel"); GL.UniformMatrix4fv(modelLoc, 1, false, &model);
var view = Matrix4x4.Identity; var viewLoc = GL.GetUniformLocationString(_shaderProgram, "uView"); GL.UniformMatrix4fv(viewLoc, 1, false, &view);
GL.Disable(GL_STENCIL_TEST); GL.Disable(GL_CULL_FACE); } [/code] Теперь я не понимаю, почему буфер трафарета не применяется и все нормально отображается с правой стороны. Как видите, как только я ожидал, что это будет какая-то проблема с трафаретным буфером, я добавил эти две строки в метод DrawRegular: [code]GL.Enable(GL_STENCIL_TEST); glUnsafeHelper.StencilFunc(GL_NEVER, 0, 0); [/code] Насколько я понимаю, это должно привести к тому, что последующие вызовы элемента рисования ничего не отрисуют и что экран должен быть просто черным/пустым с правой стороны. Поскольку я думаю, что буфер трафарета либо не существует, либо он каким-то образом деактивирован, я провел небольшое исследование, как активировать/добавить его снова. Именно там я наткнулся на этот сайт о FBO: Учебное пособие по объектам фреймбуфера. Я не до конца это понял, но все равно попробовал реализовать. Вот что представляют собой закомментированные строки в методе OnOpenGlRender. Сначала я попытался поместить строки в метод Init, но это тоже не сработало. Когда они в текущем состоянии раскомментированы, экран становится только серым. Я чувствую, что подход с ПФ – это правильный путь для дальнейшего развития, но я действительно не понимаю, что там на самом деле должно произойти. Я думаю, что мне нужно определить новый FBO, который включает трафаретный буфер, в который я могу писать, затем привязаться к этому новому FBO и использовать этот новый кадровый буфер вместо кадрового буфера, предоставляемого системой. Есть какие-нибудь подсказки, почему это не работает?