ifan's picture

VBO (on Windows) vs (on Ubuntu)

Hello Folks,
My problem is the following:

I have a struct, which is a base of each vertices, which looks something like this.

public struct VertexPositionNormalTangentTexture
    {
        public Vector3 point;
        public Vector3 normal;
        public Vector3 tangent;
        public Vector2 texCoord;
   }

at some point of my code i use

VertexPositionNormalTangentTexture[] array = .....
GL.BufferData(.., .., .., array, ..)

My experience on Windows:
My stuff drawn looks fancy

My experience on Ubuntu:
The points are misaligned (like Point and Tangent or Normal or even Texture bits were swapped for SOME of the points)
(Or the Stride is bad somehow)
No correct triangles formed! A pile of mess displayed.

Then i tried using the same code with a slightly smaller VBO, based ONLY on Position and Normal
This worked correctly, all points and triangles were rendered

So i figured, i can solve my problem if i use "smaller" values,
But is still makes me no sence, and looks really like that the STRIDE of GL.VertexAttribPointer "works somehow badly".

Do you know a solution for this problem?

Thanks,
Ifan

----------------------------------------------------------
Edit:

I use this piece of code to map attributes after binding the buffer:

            // Position
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, TypeSize, 0);
            GL.EnableVertexAttribArray(0);
 
            // Normal
            GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, TypeSize, 12); //+ 3x4 bytes
            GL.EnableVertexAttribArray(2); //Normals are attrib 2
 
            // Tangent
            GL.VertexAttribPointer(5, 3, VertexAttribPointerType.Float, false, TypeSize, 24); //+ 3x4 bytes
            GL.EnableVertexAttribArray(5);
 
            // Texture
            GL.VertexAttribPointer(8, 2, VertexAttribPointerType.Float, false, TypeSize, 36);
            GL.EnableVertexAttribArray(8);

Comments

Comment viewing options

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

so I ended up using less attributes

            // Position
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, TypeSize, 0);
            GL.EnableVertexAttribArray(0);
 
            // Normal
            GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, TypeSize, 12);
            GL.EnableVertexAttribArray(2); //Normals are attrib 2
 
            // Texture
            GL.VertexAttribPointer(8, 2, VertexAttribPointerType.Float, false, TypeSize, 24);
            GL.EnableVertexAttribArray(8);

In the shader i use the tangent needed can be calculated from crossing normal and local y axis' unit vector

BUT i'm still curious about why my code (with the extra Tangent) did work on Windows, but on Ubuntu...
I didnt enable any arraycap, or messed with interleaved arrays, just what i described previously.

Robmaister's picture

The issue could just be Mono padding out parts of your struct for alignment. I had the same issue where MS .NET wouldn't pad, but Mono would. The solution is in the StructLayout attribute:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct VertexPositionNormalTangentTexture
{
//...
}

Pack = 1 forces the struct to only be padded to the nearest byte, meaning the layout of your struct in memory will be the same as what you define it to be.