Opengl vertex color always leads to a black triangle

1

My first triangle works well if the color is specified in the fragment shader. When I add a vertex color to the buffer the triangle is always black.

A minimal code with the issue:

type 
    OGLfloat = float32
    OGLuint = uint32
    OGLint = int32

const
    GLFW_CONTEXT_VERSION_MAJOR = 0x00022002
    GLFW_CONTEXT_VERSION_MINOR = 0x00022003
    GLFW_OPENGL_PROFILE = 0x00022008
    GLFW_OPENGL_CORE_PROFILE = 0x00032001

const 
    GL_COLOR_BUFFER_BIT = 0x00004000
    GL_DEPTH_BUFFER_BIT = 0x00000100
    GL_ACCUM_BUFFER_BIT = 0x00000200
    GL_STENCIL_BUFFER_BIT = 0x00000400
    GL_ARRAY_BUFFER = 0x8892
    GL_ELEMENT_ARRAY_BUFFER = 0x8893
    GL_FALSE = 0.char
    GL_STATIC_DRAW = 0x88E4
    GL_FLOAT = 0x1406
    GL_VERTEX_SHADER = 0x8B31
    GL_COMPILE_STATUS = 0x8B81
    GL_INFO_LOG_LENGTH = 0x8B84
    GL_FRAGMENT_SHADER = 0x8B30
    GL_LINK_STATUS = 0x8B82
    GL_TRIANGLES = 0x0004
    GL_UNSIGNED_INT= 0x1405
    GL_VERSION = 0x1F02

const 
    POSITION_LENGTH = 3
    COLOR_LENGTH = 3

const
    WINDOW_W = 640
    WINDOW_H = 480

var
    colorDataOffset = 3 * sizeof(OGLfloat)

    vertices = @[OGLfloat(0.0), 0.5, 0, 1, 1, 1,
                         0.5, -0.5, 0,  0, 0, 0,
                         -0.5, -0.5, 0,  0, 0, 0]

    indices = @[OGLuint(0), 1 , 2]

# initialisation using glfw and glew
var glfwErr = glfwInit()
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
var winHandle = glfwCreateWindow(WINDOW_W, WINDOW_H)
glfwMakeContextCurrent(winHandle)
var glewErr = glewInit()

# shaders sources
var 
    shadID:OGLuint
    vertSrc:cstring = """
        #version 330 core
        layout (location = 0) in vec3 aPos;
        layout (location = 1) in vec3 aColor;

        out vec3 inColor;

        void main()
        {
            gl_Position = vec4(aPos, 1.0f);
            inColor = aColor;

        }
        """
    fragSrc:cstring = """
        #version 330 core
        out vec4 FragColor;        
        in vec3 inColor;

        void main()
        {
            FragColor = vec4(inColor, 1.0f);
        }

        """
# create the shader program
proc send_src(vert:var cstring, frag:var cstring):OGLuint =
    var success:OGLint
    # vertex
    var vertexShader = glCreateShader(GL_VERTEX_SHADER)
    glShaderSource(vertexShader, 1, addr vert, nil)
    glCompileShader(vertexShader)
    # Check compilation errors.
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, addr success)
    if bool(success) == false:
        echo(" vertex shader compilation failed (send_src)")
    else:
        echo("vertexShader compiled (send_src)")

    # fragment
    var fragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
    glShaderSource(fragmentShader, 1, addr frag, nil)
    glCompileShader(fragmentShader)
    # Check compilation errors.
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, addr success)
    if bool(success) == false:
        echo("fragment shader compilation failed (send_src)"
    else:
        echo("fragmentShader compiled (send_src)")

    # Shader program
    result = glCreateProgram()
    glAttachShader(result, vertexShader)
    glAttachShader(result, fragmentShader)
    glLinkProgram(result)
    # Check for linkage errors.
    glGetProgramiv(result, GL_LINK_STATUS, addr success)
    if success == 0:
        echo ("program linking failed (send_src)")
    else:
        echo ("shader linked (send_src)")

    glDeleteShader(vertexShader)
    glDeleteShader(fragmentShader)


glViewport(0, 0, WINDOW_W, WINDOW_H)
shadID = send_src(vertSrc, fragSrc)

var VAO, VBO, EBO:OGLuint
glGenVertexArrays(1, addr VAO)
glGenBuffers(1, addr VBO)
glGenBuffers(1, addr EBO)
glBindVertexArray(VAO)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, vertices.len * sizeof(OGLfloat), 
             addr vertices[0], GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.len * sizeof(OGLuint), 
             addr indices[0], GL_STATIC_DRAW)
# Position layout
glVertexAttribPointer(0, POSITION_LENGTH, GL_FLOAT, GL_FALSE, 6 * sizeof(OGLfloat), 
                      nil)
glEnableVertexAttribArray(0)
# Color layout
glVertexAttribPointer(1, COLOR_LENGTH, GL_FLOAT, GL_FALSE, 6 * sizeof(OGLfloat), 
                      addr colorDataOffset)
glEnableVertexAttribArray(1)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
glUseProgram(shadID)

while bool(glfwWindowShouldClose(winHandle)) == false:
    glClearColor(0.2, 0.3, 0.3, 1.0)
    glClear(GL_COLOR_BUFFER_BIT)
    glBindVertexArray(VAO)
    glDrawElements(GL_TRIANGLES, OGLint(indices.len), GL_UNSIGNED_INT, nil)
    glfwSwapBuffers(winHandle)
    glfwPollEvents()

glDeleteVertexArrays(1, addr VAO)
glDeleteBuffers(1, addr VBO)
glDeleteBuffers(1, addr EBO)
glfwDestroyWindow(winHandle)
glfwTerminate()
opengl
nim-lang
asked on Stack Overflow Nov 17, 2018 by Ploumploum • edited Nov 18, 2018 by genpfault

1 Answer

1

First see OpenGL 4.6 API Compatibility Profile Specification; 10.3.9 Vertex Arrays in Buffer Objects; page 409

... When an array is sourced from a buffer object for a vertex attribute, [...] the offset set for the vertex buffer [...] is used as the offset in basic machine units of the first element in that buffer’s data store.

This means that the 6th parameter of glVertexAttribPointer has to be the offset of the color attribute, encoded to a pointer.

When you do addr colorDataOffset in

glVertexAttribPointer(1, COLOR_LENGTH, GL_FLOAT, GL_FALSE, 6 * sizeof(OGLfloat),
                      addr colorDataOffset)

then you create a pointer, but the value of the pointer is the address of colorDataOffset - see The addr operator.

What you have to do is to cast colorDataOffset to an pointer type by cast[pointer](colorDataOffset), the value of the pointer has to be the value of colorDataOffset - see Type casts and Types:

glVertexAttribPointer(1, COLOR_LENGTH, GL_FLOAT, GL_FALSE, 6 * sizeof(OGLfloat), 
                      cast[pointer](colorDataOffset))
answered on Stack Overflow Nov 18, 2018 by Rabbid76

User contributions licensed under CC BY-SA 3.0