Radar's picture

OGL3 VBO question

Hi all,

i was looking at the tutorial of flopoloco called "Triangle + Shader + Uniform" .
First i copied it and it worked.
Then i tried to add other stuff and it does still work... kinda.
Since i really don't (yet) understand the big picture of openGL3+ iam not so sure what i did was right. Here is the code to init and then render my VBO.
Is the following code correct???

public void SetUpVBO(Vertex[] vertices)
        {
            GL.GenBuffers(1, out this.vboID);
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.vboID);
            GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(vertices.Length * Vertex.Stride), vertices, BufferUsageHint.StaticDraw);
            this.vboSize = vertices.Length;
        }
 
        public void RenderVBO()
        {
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.vboID);
 
            GL.EnableVertexAttribArray(0);
            GL.BindAttribLocation(1, 0, "VertexPosition");
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.Stride, 0);//position
 
            GL.EnableVertexAttribArray(1);
            GL.BindAttribLocation(1, 1, "VertexNormal");
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes);//normal
 
            GL.EnableVertexAttribArray(2);
            GL.BindAttribLocation(1, 2, "VertexTangent");
            GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes + Vec3.SizeInBytes);//tangent
 
            GL.EnableVertexAttribArray(3);
            GL.BindAttribLocation(1, 3, "VertexTexCoord");
            GL.VertexAttribPointer(3, 2, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes + Vec3.SizeInBytes + Vec4.SizeInBytes);//TexCoord
 
            GL.DrawArrays(BeginMode.Triangles, 0, this.vboSize);
 
            GL.DisableVertexAttribArray(0);
            GL.DisableVertexAttribArray(1);
            GL.DisableVertexAttribArray(2);
            GL.DisableVertexAttribArray(3);
        }

And another thing. The triangle shows just in black... like the fragment shader is never called. Except for when i comment out the texture stuff above. Then it turns white. I mean... WTF? And Why??? I don't use any light or textures at all.

Thanks in advance!


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
elaverick's picture

Can you post the structure of the Vertex Array you're using as well please.

Radar's picture

Sure
The vertex struct is just a small container keeping the data together.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct Vertex
        {
            public Vec3 Position;
            public Vec3 Normal;
            public Vec4 Tangent;
            public Vec2 TexCoord;
            public static readonly int Stride = Marshal.SizeOf(default(Vertex));
 
            public static explicit operator IntPtr(Vertex v)
            {
                unsafe
                {
                    return (IntPtr)(&v.Position);
                }
            }
        }

The VecX structs are more or less the same as the OpenTK Vectors.
Heres an example Vec3. I removed the functions and the operator overloads for posting here.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct Vec3
        {
            public float X, Y, Z;
 
            unsafe public static explicit operator float*(Vec3 v)
            {
                return &v.X;
            }
 
            public static explicit operator IntPtr(Vec3 v)
            {
                unsafe
                {
                    return (IntPtr)(&v.X);
                }
            }
        }
Radar's picture

Still getting nowhere. Most tutorials are more confusing than helping actually. I just get an empty screen.
I really don't know what is wrong with this code.

Please can someone explain to me why it does not work?

Vertex[] v = new Vertex[3];
v[0].Position = new Vec3(-1f, -1f, 0f);
v[0].Normal = new Vec3(1f,0f,0f);
v[0].Tangent = new Vec4();
v[0].TexCoord = new Vec2();
 
v[1].Position = new Vec3(1f, -1f, 0f);
v[1].Normal = new Vec3(0f, 1f, 0f);
v[1].Tangent = new Vec4();
v[1].TexCoord = new Vec2();
 
v[2].Position = new Vec3(0f, 1f, 0f);
v[2].Normal = new Vec3(0f, 0f, 1f);
v[2].Tangent = new Vec4();
v[2].TexCoord = new Vec2();
ms.SetUpVAO(v);
 
---
//set up the data
        public void SetUpVAO(Vertex[] vertices)
        {
            this.vboSize = vertices.Length;
            GL.GenVertexArrays(1, out this.vaoID);
            GL.BindVertexArray(this.vaoID);
            {
                GL.GenBuffers(1, out this.vboID);
                GL.BindBuffer(BufferTarget.ArrayBuffer, this.vboID);
                {
                    GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(vertices.Length * Vertex.Stride), vertices, BufferUsageHint.StaticDraw);
                    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.Stride, 0);//position
                    GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes);//normal
                    GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes + Vec3.SizeInBytes);//tangent
                    GL.VertexAttribPointer(3, 2, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes + Vec3.SizeInBytes + Vec4.SizeInBytes);//TexCoord
                }
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 
            }
            GL.BindVertexArray(0);
        }
---
//Rendering method
        public void RenderVAO()
        {
            GL.BindVertexArray(this.vaoID);
            {
                GL.DrawArrays(BeginMode.Triangles, 0, this.vboSize);
            }
            GL.BindVertexArray(0);
        }
---
 
//On render frame
protected override void OnRenderFrame(FrameEventArgs e)
        {
            GL.Viewport(0, 0, Width, Height);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            time = (time >= Math.PI) ? 0.0 : time + e.Time;
            variableScale = (float)(Math.Sin(time));
 
            basicShader.Bind();
            basicShader.SendUniform("scale", variableScale);
            ms.RenderVAO();
            basicShader.Unbind();
 
            SwapBuffers();
        }

BasicShaders:

#version 330
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec4 VertexTangent;
layout (location = 3) in vec2 VertexTexCoord;
 
uniform float scale;
smooth out vec4 theColor;
 
void main()
{
	gl_Position = vec4(scale * VertexPosition.x, scale * VertexPosition.y, VertexPosition.z, 1.0);
	theColor = vec4(VertexNormal, 1.0);
}
 
 
#version 330 
out vec4 FragColor;
 
 smooth in vec4 theColor;
 
void main()
{
	FragColor = theColor; //vec4(0.5, 0.8, 1.0, 1.0);
}

Thanks!

Radar's picture

Okay, got it to render something. I just don't know if that is the correct way.

public void SetUpVAO(Vertex[] vertices)
        {
            this.vboSize = vertices.Length;
            GL.GenVertexArrays(1, out this.vaoID);
            GL.BindVertexArray(this.vaoID);
            {
                GL.GenBuffers(1, out this.vboID);
 
                GL.BindBuffer(BufferTarget.ArrayBuffer, this.vboID);
                {
                    GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(vertices.Length * Vertex.Stride), vertices, BufferUsageHint.StaticDraw);
                    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.Stride, 0);//position
                    GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes);//normal
                    GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes + Vec3.SizeInBytes);//tangent
                    GL.VertexAttribPointer(3, 2, VertexAttribPointerType.Float, false, Vertex.Stride, Vec3.SizeInBytes + Vec3.SizeInBytes + Vec4.SizeInBytes);//TexCoord
                }
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 
            }
            GL.BindVertexArray(0);
        }
 
        public void RenderVAO()
        {
            GL.BindVertexArray(this.vaoID);
            {
                GL.EnableVertexAttribArray(0);
                GL.EnableVertexAttribArray(1);
                GL.EnableVertexAttribArray(2);
                GL.EnableVertexAttribArray(3);
                GL.DrawArrays(BeginMode.Triangles, 0, this.vboSize);
                GL.DisableVertexAttribArray(0);
                GL.DisableVertexAttribArray(1);
                GL.DisableVertexAttribArray(2);
                GL.DisableVertexAttribArray(3);
            }
            GL.BindVertexArray(0);
        }