dwmkerr / sharpgl

Use OpenGL in .NET applications. SharpGL wraps all modern OpenGL features and offers a powerful scene graph to aid development.
MIT License
753 stars 300 forks source link

glUseProgram not supported #138

Open TKmolibso opened 6 years ago

TKmolibso commented 6 years ago

Hello,

I try to write a parabola using a heightmap. I use SharpGL and WPF. I 've oriented at

http://www.learnopengles.com/tag/index-buffer-object/

I am really sorry about posting that much code but I get the following Exception: System.Exception: Extension function glUseProgram not supported So I think I use SharpGL maybe in wrong order? It appears black screen but my FPS goes down to 10-12FPS so something he's doing.

My shaders:

Vertex Shader

#version 330

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec4 color;

void main()
{
    gl_Position = vec4(position,1.0);
    gl_Normal = vec4(normal,1.0)
    gl_Color = vec4(color);
}

Fragment Shader:

#version 330

in vec4 color;

out vec4 frag_color;

void main()
{
   frag_color=vec4(color);
}

First of all I just want to create my ShaderProgram and link my ShaderSource In openGLControl_OpenGLInitialized() I initialize following:

 public void openGLControl_OpenGLInitialized(object sender, OpenGLEventArgs args)
        {

            OpenGL gl = args.OpenGL;
            try
            {
                InitializeProgram(gl);
                InitializeVertexBuffer(gl);

                gl.Enable(OpenGL.GL_LIGHTING);
            }
            catch (Exception e)
            {
                Debug.WriteLine("Failed_OpenGLInitialized: " + e);
            }
        }
private void InitializeProgram(OpenGL gl)
        {
            List<uint> shaderList = new List<uint>();

            shaderList.Add(CreateShader(OpenGL.GL_VERTEX_SHADER, pathVertexShader,gl));
            shaderList.Add(CreateShader(OpenGL.GL_FRAGMENT_SHADER, pathFragmentShader,gl));
            ShaderProgram = CreateProgram(shaderList,gl);
            foreach (uint shader in shaderList)
                gl.DeleteShader(shader);
        }
        private uint CreateShader(uint eShaderType, string strShaderFile, OpenGL gl)
        {
            uint shader = gl.CreateShader(eShaderType);
            string[] strFileData = { File.ReadAllText(strShaderFile) };
            gl.ShaderSource(shader, strFileData[0]);
            gl.CompileShader(shader);
            ShaderErrorInfo(shader,gl);
            return shader;
        }
        private uint CreateProgram(List<uint> shaderList, OpenGL gl)
        {
            uint program = gl.CreateProgram();
            foreach (uint shader in shaderList)
                gl.AttachShader(program, shader);
            //gl.BindAttribLocation(ShaderProgram, 0, "position");
            //gl.BindAttribLocation(ShaderProgram, 1, "normal");
            //gl.BindAttribLocation(ShaderProgram, 2, "color");
            Console.WriteLine("program: " + program.ToString());
            gl.LinkProgram(program);
            ProgramErrorInfo(program,gl);
            foreach (uint shader in shaderList)
                gl.DetachShader(program, shader);
            return program;
        }
        private bool ProgramErrorInfo(uint programId, OpenGL gl)
        {
            StringBuilder builder = new StringBuilder(2048);
            gl.GetProgramInfoLog(programId, 2048, IntPtr.Zero, builder);
            string res = builder.ToString();
            if (!res.Equals(""))
            {
                System.Console.WriteLine(res);
                return false;
            }
            return true;
        }
        private bool ShaderErrorInfo(uint shaderId, OpenGL gl)
        {
            StringBuilder builder = new StringBuilder(2048);
            gl.GetShaderInfoLog(shaderId, 2048, IntPtr.Zero, builder);
            string res = builder.ToString();
            if (!res.Equals(""))
            {
                System.Console.WriteLine(res);
                return false;
            }
            return true;
        }

Step 2: I create my vertices and indices: for each Vertex I fill a float array with position(x,yz), normal(x,y,z) and color(r,g,b,a). Then I fill a short array with indices to link all vertices together.

Step 3: I create a VertexBufferObject and IndexBufferObject:

 private void CreateVBO(OpenGL gl)
        {
            verticesPtr = GCHandle.Alloc(vertices, GCHandleType.Pinned).AddrOfPinnedObject();
            gl.GenBuffers(0, vbo);
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, vbo[0]);
            gl.BufferData(OpenGL.GL_ARRAY_BUFFER, vertices.Length * sizeof(float), verticesPtr, OpenGL.GL_STATIC_DRAW);
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, 0);
        }
        private void CreateIBO(OpenGL gl)
        {
            indicesPtr = GCHandle.Alloc(indices, GCHandleType.Pinned).AddrOfPinnedObject();
            gl.GenBuffers(0, ibo);
            gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
            gl.BufferData(OpenGL.GL_ELEMENT_ARRAY_BUFFER, indices.Length * sizeof(short), indicesPtr, OpenGL.GL_STATIC_DRAW);
            gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, 0);
        }

In my Draw Function openGLControl_OpenGLDraw I want to point and enable my attributes.

public void openGLControl_OpenGLDraw(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            try
            {

                OpenGL gl = args.OpenGL;

                gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

                gl.UseProgram(ShaderProgram);

                //gl.BindVertexArray(vao[0]);
                gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER,vbo[0]);

                //Bind Attributes
                gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero);
                gl.EnableVertexAttribArray(0);

                gl.VertexAttribPointer(1, 3, OpenGL.GL_FLOAT, false, 3 * 4, IntPtr.Zero);
                gl.EnableVertexAttribArray(1);

                gl.VertexAttribPointer(2, 4, OpenGL.GL_FLOAT, false, (3 + 3) * 4, IntPtr.Zero);
                gl.EnableVertexAttribArray(2);

                //DRAW
                gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
                gl.DrawElements(OpenGL.GL_TRIANGLE_STRIP, indexCount, OpenGL.GL_UNSIGNED_SHORT, IntPtr.Zero);

                gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, 0);
                gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, 0);

                gl.DisableVertexAttribArray(0);
                gl.DisableVertexAttribArray(1);
                gl.DisableVertexAttribArray(2);

                gl.UseProgram(0);

                gl.Flush();

            }
            catch(Exception e)
            {
                Debug.WriteLine(e.ToString());
            }
        }
bukshuk commented 3 years ago

Hi @TKmolibso,

Try setting the following property for the SharpGL control (in XAML)

RenderContextType="FBO"