aybe's picture

[Solved] Trying to extend HelloGL3.cs shader with coloring

Hello,

I am getting the following issue, tried nearly everything but I can't get color for my shader...
In the vertex shader code, I add the following, right below in_position and in_normal :

in vec3 in_color;

Then I try to retrieve the location of in_color:

int attribLocation = GL.GetAttribLocation(shaderProgramHandle, "in_position");
int attribLocation1 = GL.GetAttribLocation(shaderProgramHandle, "in_normal");
int attribLocation2 = GL.GetAttribLocation(shaderProgramHandle, "in_color");

Its location is always -1, no matter what name I give to it ... my drawing is now all black.
I have of course created an extra VBO that holds color vectors, I checked the upload status, it's been uploaded successfully.
Tried vec4, tried to change fragment, but always -1 ... Any ideas ??

Thanks a lot :-)

UPDATE :
When running it, it does work, even though it's -1 ... but now, in_normal location becomes -1 !!!
In the end I should have just ran it, and not trust OpenTK 100% ... but is this normal ?

Thank you !

Here is my code for those who might encounter a similar issue ...

using System;
using System.Diagnostics;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
 
namespace GLSL
{
    public class HelloGL3 : GameWindow
    {
        private const string FragmentShaderSource =
            @"
#version 130
 
precision highp float;
 
const vec3 ambient = vec3(0.1, 0.1, 0.1);
const vec3 lightVecNormalized = normalize(vec3(0.5, 0.5, 2.0));
const vec3 lightColor = vec3(0.9, 0.9, 0.7);
 
in vec3 normal;
in vec3 mycolor;
 
out vec4 out_frag_color;
 
void main(void)
{
  float diffuse = clamp(dot(lightVecNormalized, normalize(normal)), 0.0, 1.0);
  out_frag_color = vec4(mycolor, 1); // vec4(ambient + diffuse * lightColor, 1.0);
}";
 
        private const string VertexShaderSource =
            @"
#version 130
 
precision highp float;
 
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
 
in vec3 in_position;
in vec3 in_normal;
in vec3 in_color;
 
out vec3 normal;
out vec3 mycolor;
 
void main(void)
{
  //works only for orthogonal modelview
  normal = (modelview_matrix * vec4(in_normal, 0)).xyz;
  mycolor = in_color;
  gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1);
}";
 
        private readonly Vector3[] _colorVboData = new[]
                                                       {
                                                           new Vector3(0.0f, 0.0f, 1.0f),
                                                           new Vector3(1.0f, 0.0f, 1.0f),
                                                           new Vector3(1.0f, 1.0f, 1.0f),
                                                           new Vector3(0.0f, 1.0f, 1.0f),
                                                           new Vector3(0.0f, 0.0f, 0.0f),
                                                           new Vector3(1.0f, 0.0f, 0.0f),
                                                           new Vector3(1.0f, 1.0f, 0.0f),
                                                           new Vector3(0.0f, 1.0f, 0.0f)
                                                       };
 
        private readonly int[] _indicesVboData = new[]
                                                     {
                                                         // front face
                                                         0, 1, 2, 2, 3, 0,
                                                         // top face
                                                         3, 2, 6, 6, 7, 3,
                                                         // back face
                                                         7, 6, 5, 5, 4, 7,
                                                         // left face
                                                         4, 0, 3, 3, 7, 4,
                                                         // bottom face
                                                         0, 1, 5, 5, 4, 0,
                                                         // right face
                                                         1, 5, 6, 6, 2, 1
                                                     };
 
        private readonly Vector3[] _positionVboData = new[]
                                                          {
                                                              new Vector3(-1.0f, -1.0f, 1.0f),
                                                              new Vector3(1.0f, -1.0f, 1.0f),
                                                              new Vector3(1.0f, 1.0f, 1.0f),
                                                              new Vector3(-1.0f, 1.0f, 1.0f),
                                                              new Vector3(-1.0f, -1.0f, -1.0f),
                                                              new Vector3(1.0f, -1.0f, -1.0f),
                                                              new Vector3(1.0f, 1.0f, -1.0f),
                                                              new Vector3(-1.0f, 1.0f, -1.0f)
                                                          };
 
        private int _colorVboHandle;
 
        private int _eboHandle;
 
        private int _fragmentShaderHandle;
 
        private Matrix4 _modelviewMatrix;
 
        private int _modelviewMatrixLocation;
 
        private int _normalVboHandle;
 
        private int _positionVboHandle;
 
        private Matrix4 _projectionMatrix;
        private int _projectionMatrixLocation;
        private int _shaderProgramHandle;
        private int _vaoHandle;
        private int _vertexShaderHandle;
 
        public HelloGL3()
            : base(640, 480,
                   new GraphicsMode(), "OpenGL 3 Example", 0,
                   DisplayDevice.Default, 3, 0,
                   GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug)
        {
        }
 
        protected override void OnLoad(EventArgs e)
        {
            VSync = VSyncMode.On;
 
            CreateShaders();
            CreateVBOs();
            CreateVAOs();
 
            // Other state
            GL.Enable(EnableCap.DepthTest);
            GL.ClearColor(Color.MidnightBlue);
        }
 
        private void CreateShaders()
        {
            _vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);
            _fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
 
            GL.ShaderSource(_vertexShaderHandle, VertexShaderSource);
            GL.ShaderSource(_fragmentShaderHandle, FragmentShaderSource);
 
            GL.CompileShader(_vertexShaderHandle);
            GL.CompileShader(_fragmentShaderHandle);
 
            Debug.WriteLine(GL.GetShaderInfoLog(_vertexShaderHandle));
            Debug.WriteLine(GL.GetShaderInfoLog(_fragmentShaderHandle));
 
            // Create program
            _shaderProgramHandle = GL.CreateProgram();
 
            GL.AttachShader(_shaderProgramHandle, _vertexShaderHandle);
            GL.AttachShader(_shaderProgramHandle, _fragmentShaderHandle);
 
            GL.LinkProgram(_shaderProgramHandle);
 
            Debug.WriteLine(GL.GetProgramInfoLog(_shaderProgramHandle));
 
            GL.UseProgram(_shaderProgramHandle);
 
            // Set uniforms
            _projectionMatrixLocation = GL.GetUniformLocation(_shaderProgramHandle, "projection_matrix");
            _modelviewMatrixLocation = GL.GetUniformLocation(_shaderProgramHandle, "modelview_matrix");
 
            float aspectRatio = ClientSize.Width / (float)(ClientSize.Height);
            Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspectRatio, 1, 100, out _projectionMatrix);
            _modelviewMatrix = Matrix4.LookAt(new Vector3(0, 3, 5), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
 
            GL.UniformMatrix4(_projectionMatrixLocation, false, ref _projectionMatrix);
            GL.UniformMatrix4(_modelviewMatrixLocation, false, ref _modelviewMatrix);
        }
 
        private void CreateVBOs()
        {
            GL.GenBuffers(1, out _positionVboHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _positionVboHandle);
            GL.BufferData(BufferTarget.ArrayBuffer,
                          new IntPtr(_positionVboData.Length * Vector3.SizeInBytes),
                          _positionVboData, BufferUsageHint.StaticDraw);
 
            GL.GenBuffers(1, out _normalVboHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _normalVboHandle);
            GL.BufferData(BufferTarget.ArrayBuffer,
                          new IntPtr(_positionVboData.Length * Vector3.SizeInBytes),
                          _positionVboData, BufferUsageHint.StaticDraw);
 
            GL.GenBuffers(1, out _colorVboHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _colorVboHandle);
            GL.BufferData(BufferTarget.ArrayBuffer,
                          new IntPtr(_colorVboData.Length * Vector3.SizeInBytes),
                          _colorVboData, BufferUsageHint.StaticDraw);
 
            GL.GenBuffers(1, out _eboHandle);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, _eboHandle);
            GL.BufferData(BufferTarget.ElementArrayBuffer,
                          new IntPtr(sizeof(uint) * _indicesVboData.Length),
                          _indicesVboData, BufferUsageHint.StaticDraw);
 
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
        }
 
        private void CreateVAOs()
        {
            // GL3 allows us to store the vertex layout in a "vertex array object" (VAO).
            // This means we do not have to re-issue VertexAttribPointer calls
            // every time we try to use a different vertex layout - these calls are
            // stored in the VAO so we simply need to bind the correct VAO.
            GL.GenVertexArrays(1, out _vaoHandle);
            GL.BindVertexArray(_vaoHandle);
 
            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _positionVboHandle);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
            GL.BindAttribLocation(_shaderProgramHandle, 0, "in_position");
 
            GL.EnableVertexAttribArray(1);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _normalVboHandle);
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
            GL.BindAttribLocation(_shaderProgramHandle, 1, "in_normal");
 
            GL.EnableVertexAttribArray(2);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _colorVboHandle);
            GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);
            GL.BindAttribLocation(_shaderProgramHandle, 2, "in_color");
 
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, _eboHandle);
 
            int attribLocation = GL.GetAttribLocation(_shaderProgramHandle, "in_position");
            int attribLocation1 = GL.GetAttribLocation(_shaderProgramHandle, "in_normal");
            int attribLocation2 = GL.GetAttribLocation(_shaderProgramHandle, "in_color");
            ErrorCode errorCode = GL.GetError();
 
            GL.BindVertexArray(0);
        }
 
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            Matrix4 rotation = Matrix4.CreateRotationY((float)e.Time);
            Matrix4.Mult(ref rotation, ref _modelviewMatrix, out _modelviewMatrix);
            GL.UniformMatrix4(_modelviewMatrixLocation, false, ref _modelviewMatrix);
 
            if (Keyboard[Key.Escape])
                Exit();
        }
 
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            GL.Viewport(0, 0, Width, Height);
 
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            GL.BindVertexArray(_vaoHandle);
            GL.DrawElements(BeginMode.Triangles, _indicesVboData.Length,
                            DrawElementsType.UnsignedInt, IntPtr.Zero);
 
            SwapBuffers();
        }
    }
}