0

I'm trying to update some old-style OpenGL code to modern OpenGL4.

I have a huge textured and pre-tessellated cube model to render.

Instead of that, I'm now getting this:

Failure

That's a field of semi-arbitrary black triangles on a white background.

My VAO/VBO build code:

        // Normal buffer
        GL.GenBuffers(1, out VBONormals);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Normals.Length * Vector3.SizeInBytes),
        Normals, BufferUsageHint.StaticDraw);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        // TexCoord buffer
        GL.GenBuffers(1, out VBOTexCoords);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(TexCoords.Length * Vector3.SizeInBytes),
        TexCoords, BufferUsageHint.StaticDraw);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        // Vertex buffer
        GL.GenBuffers(1, out VBO);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Positions.Length * Vector3.SizeInBytes),
        Positions, BufferUsageHint.StaticDraw);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        // Index buffer
        GL.GenBuffers(1, out VBOIndices);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
        GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(Indices.Length * sizeof(uint)),
        Indices, BufferUsageHint.StaticDraw);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
        GL.GenVertexArrays(1, out VAO);
        GL.BindVertexArray(VAO);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
        GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
        GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, 0, 0);
        GL.EnableVertexAttribArray(0);
        GL.EnableVertexAttribArray(1);
        GL.EnableVertexAttribArray(2);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
        // Clean up
        GL.BindVertexArray(0);
        GL.DisableVertexAttribArray(0);
        GL.DisableVertexAttribArray(1);
        GL.DisableVertexAttribArray(2);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

and the render code:

        VBOTexture.Bind();
        GL.BindVertexArray(VAO);
        //GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
        GL.DrawArrays(PrimitiveType.Triangles, 0, Indices.Length);

Vertex shader:

#version 430 core

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

layout (location = 1) uniform mat4 projection;

layout (location = 0) out vec3 f_color;

void main()
{
    f_color = normal;
    gl_Position = projection * vec4(position, 1.0);
}

fragment shader:

#version 430 core

layout (binding = 0) uniform sampler2D tex;

layout (location = 0) in vec3 f_color;

out vec4 color;

void main()
{
    vec4 tcolor = texture2D(tex, gl_TexCoord[0].st);
    float dist = 0.0;
    if (gl_TexCoord[0].x < 0.5)
    {
        dist = gl_TexCoord[0].x;
    }
    else
    {
        dist = 1.0 - gl_TexCoord[0].x;
    }
    if (gl_TexCoord[0].y < 0.5)
    {
        dist *= gl_TexCoord[0].y;
    }
    else
    {
        dist *= 1.0 - gl_TexCoord[0].y;
    }
    dist *= 32;
    dist = min(1, dist);
    color = vec4(tcolor[0] * dist, tcolor[1] * dist, tcolor[2] * dist, tcolor[3]);
}

Note that switching the draw call to the commented-out one produces the same results.

Also note: the original code was exactly the same, minus the VAO chunk, and rendering with this:

        GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
        GL.NormalPointer(NormalPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
        GL.EnableClientState(ArrayCap.NormalArray);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
        GL.TexCoordPointer(2, TexCoordPointerType.Float, Vector2.SizeInBytes, IntPtr.Zero);
        GL.EnableClientState(ArrayCap.TextureCoordArray);
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
        GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
        GL.EnableClientState(ArrayCap.VertexArray);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
        GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
        GL.PopClientAttrib();

(except I also switched the texcoords from Vector2 to Vector3 for unrelated reasons)

Where have I gone wrong?

Community
  • 1
  • 1
mcmonkey4eva
  • 1,359
  • 7
  • 19
  • Off-topic, but generally you want to avoid `conditionals` in shaders due to performance hit –  Feb 07 '15 at 07:27
  • That code was a temporary proof-of-concept, it's not optimized in the slightest. – mcmonkey4eva Feb 07 '15 at 07:54
  • Well, the `glDrawArrays()` call is conceptually totally wrong, especially with `Indices.Leght` as count. The `glDrawRangeElements()` one should work in principle. When both calls produce the same result, your index array is either the trivial case of the first n integers (including zero), or something is screwed up with your data somewhere.just – derhass Feb 07 '15 at 14:37

1 Answers1

1

Your old code uses drawElements but your new code uses drawArrays.

    VBOTexture.Bind();
    GL.BindVertexArray(VAO);
    //GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
    GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • 1
    Is `PrimitiveType.Quads` a typo? Looks like the index buffer stores triangles, and there's no quads in core GL. – Colonel Thirty Two Feb 07 '15 at 16:36
  • @ColonelThirtyTwo it's what he used in his original code – ratchet freak Feb 07 '15 at 17:02
  • ... Please tell me I didn't accidentally switch from triangles to quads or vice-versa, because that would pretty well explain everything... – mcmonkey4eva Feb 07 '15 at 19:34
  • Yup. Triangles -> quads were the extent of the differences. I amaze myself. Thank you for spotting that! Now I just need to find out why the texture is pitch black... probably my shader not passing the texcoords or somethin', I can handle it. If not, I have this wonderful site to ask for more help :D for now, You definitely answered my main question. Accepting... (Also, I should probably be using triangles here, why do I have quads? That's problem two for me) – mcmonkey4eva Feb 07 '15 at 19:37