Czy ktoś może pomógł w następujących?

Za pomocą Visual Studio 2019 Projekt Xamarin Forms Próbuję wyświetlić obrotowy plac czerwony w Emulatorze Android. Mam to działać, ale mój plac jest czarny:

enter image description here

Oto kod mojej mainePage.xaml.cs (stosując ES20, jak ES10 nie posiada funkcji OpenGL):

using OpenTK.Graphics.ES20;
using System;
using Xamarin.Forms;

namespace OGLMobile
{
    public partial class MainPage : ContentPage
    {
        private float red = 1.0f;
        private float green = 0.0f;
        private float blue = 0.0f;

        private const float halfWidth = 0.2f;
        private float[] m_vertex_buffer_data = { 0.5f - halfWidth, 0.5f - halfWidth, 0.0f,
                                                 0.5f + halfWidth, 0.5f - halfWidth, 0.0f,
                                                 0.5f + halfWidth, 0.5f + halfWidth, 0.0f,
                                                 0.5f - halfWidth, 0.5f + halfWidth, 0.0f };

        private string[] m_szVertexShader = null;
        private string[] m_szFragmentShader = null;

        private int m_nProgram = -1;
        private int m_nVertexShaderHandle = -1;
        private int m_nFragmentShaderHandle = -1;

        private uint[] indices = { 0, 1, 2, 0, 2, 3 };

        private int m_nVertexBuffer = -1;

        bool m_bOGLParametersSet = false;

        private void RotateSquare(float radians, float xRotationCentre, float yRotationCentre)
        {
            int[] nBaseIndices = { 0, 3, 6, 9 };

            for (int nVertex = 0; nVertex <= 3 ; nVertex++)
            {
                int nIndex1 = nBaseIndices[nVertex];
                int nIndex2 = nIndex1 + 1;

                float offsetX = m_vertex_buffer_data[nIndex1] - xRotationCentre;
                float offsetY = m_vertex_buffer_data[nIndex2] - yRotationCentre;

                double xRotated = offsetX * Math.Cos(radians) - offsetY * Math.Sin(radians);
                double yRotated = offsetX * Math.Sin(radians) + offsetY * Math.Cos(radians);

                m_vertex_buffer_data[nIndex1] = (float)xRotated + xRotationCentre;
                m_vertex_buffer_data[nIndex2] = (float)yRotated + yRotationCentre;
            }

            GL.BindBuffer(BufferTarget.ArrayBuffer, m_nVertexBuffer);
            GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, new IntPtr(m_vertex_buffer_data.Length * sizeof(float)), m_vertex_buffer_data);
        }

        public MainPage()
        {
            Title = "OpenGL";
            var view = new OpenGLView { HasRenderLoop = true };
            var toggle = new Switch { IsToggled = true };

            m_szVertexShader = new string[1];
            m_szFragmentShader = new string[1];

            view.HeightRequest = 300;
            view.WidthRequest = 300;
            
            GL.Viewport(0, 0, 300, 300);

            view.OnDisplay = r =>
            {
                if(!m_bOGLParametersSet) // Do this only on first rendering
                {
                    CreateShader();

                    m_bOGLParametersSet = true;

                    GL.UseProgram(m_nProgram);

                    GL.GenBuffers(1, out m_nVertexBuffer);

                    GL.BindBuffer(BufferTarget.ArrayBuffer, m_nVertexBuffer);

                    GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(m_vertex_buffer_data.Length * sizeof(float)), m_vertex_buffer_data, BufferUsage.StaticDraw);
                }

                GL.ClearColor(0.0f, 0.0f, 1.0f, 1.0f);
                GL.Clear((ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit));

                RotateSquare(0.0174533f, 0.5f, 0.5f);

                GL.EnableVertexAttribArray(0);
                GL.BindBuffer(BufferTarget.ArrayBuffer, m_nVertexBuffer);


                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);

                GL.DrawElements(BeginMode.Triangles, indices.Length, DrawElementsType.UnsignedInt, indices);

                GL.DisableVertexAttribArray(0);

                
            };

            toggle.Toggled += (s, a) =>
            {
                view.HasRenderLoop = toggle.IsToggled;
            };

            var stack = new StackLayout
            {
                Padding = new Size(20, 20),
                Children = { view, toggle}
            };

            Content = stack;
        }

        private void SetShaderSource()
        {
            m_szVertexShader[0] = "void main()" +
                                  "{" +
                                    "gl_Position = ftransform();" +
                                  "}";

            m_szFragmentShader[0] = "void main()" +
                                    "{" +
                                        "gl_FragColor = vec4(1.0,0.0,0.0,1.0);" +
                                    "}";
        }


        private void CreateShader()
        {
            SetShaderSource();

            int nVertexShaderSourceLength = m_szVertexShader[0].Length;
            int nFragmentShaderLength = m_szFragmentShader[0].Length;

            m_nVertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);
            m_nFragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader);

            GL.ShaderSource(m_nVertexShaderHandle, 1, m_szVertexShader, new int[] { nVertexShaderSourceLength });
            GL.ShaderSource(m_nFragmentShaderHandle, 1, m_szFragmentShader, new int[] { nVertexShaderSourceLength });

            GL.CompileShader(m_nVertexShaderHandle);
            GL.CompileShader(m_nFragmentShaderHandle);

            string szVertexShaderLog = GL.GetShaderInfoLog(m_nVertexShaderHandle);
            string szFragmentShaderLog = GL.GetShaderInfoLog(m_nFragmentShaderHandle);

            m_nProgram = GL.CreateProgram();

            GL.AttachShader(m_nProgram, m_nVertexShaderHandle);
            GL.AttachShader(m_nProgram, m_nFragmentShaderHandle);

            GL.LinkProgram(m_nProgram);
        }
    }
}

Moje cieniowanie muszą być nieprawidłowe, otrzymuję ten sam wyjście, jeśli zastąpię je z sznurkami, więc system musi być domyślny do czegoś.

Mam skompilować błędy, gdy dzwonię do GetShaderinfologa, ale moje cienie są takie trywialne, że nie widzę problemu:

enter image description here

Bardzo dziękuję za wszelką pomoc (utknął na tym na chwilę

Dodawanie: bardzo dziękuję za ciebie odpowiedzi. Zastąpiłem Shaders z komplementami, niestety nadal mam czarny plac:

(Na obrazie mówi Mediump, próbowałem także nadmiaru i Lowp, ale nadal dostaję te same wyniki).

enter image description here

Teraz otrzymuję inny błąd na kompilacji cieniowania wierzchołka i brak błędu dla fragmentu Shader - chociaż mam jedno ostrzeżenie na ten ostatni:

enter image description here

Dziękujemy za dalsze porady, które możesz zaoferować.

1
user3738290 14 październik 2020, 19:20

1 odpowiedź

Najlepsza odpowiedź

Te cienie nie spełniają żadnej specyfikacji GLSL ES. Patrz OpenGL ES Język ocieniowy 1,00 Specyfikacja. OpenGL ES Język Cieniowanie 3.00 Specyfikacja.

Zobacz shader roboczy z cieniowaniem VEREX:

attribute vec3 a_position;

void main()
{
    gl_Position = vec4(a_position, 1.0);
}

I fragment Shader.

precision mediump float;

void main()
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Polecam weryfikację, czy shader skompiluje się bez błędów:

GL.CompileShader(m_nVertexShaderHandle);
string infoLogFrag = GL.GetShaderInfoLog(m_nVertexShaderHandle);
if (infoLogFrag != System.String.Empty)
{
    System.Console.WriteLine(infoLogFrag);
}

GL.CompileShader(m_nFragmentShaderHandle);
string infoLogVert = GL.GetShaderInfoLog(m_nFragmentShaderHandle);
if (infoLogVert != System.String.Empty)
{
    System.Console.WriteLine(infoLogVert);
}

A Program Linki bez błędów:

GL.LinkProgram(m_nProgram);
string infoLogProg = GL.GetProgramInfoLog(m_nProgram );
if (infoLogProg != System.String.Empty)
{
    System.Console.WriteLine(infoLogProg);
}
0
Rabbid76 15 październik 2020, 08:58