GML Drawing a vertex buffer in different colors

Erik Leppen

Member
Hi all, I have another question about vertex buffers (that I couldn't find in the manual).

I have a vertex format using position (xy) and color (ca) and I want to use it to draw a line segment (as a minimal example):
GML:
    vertex_format_begin();
        vertex_format_add_position();
        vertex_format_add_color();
    global.vf_xy_ca = vertex_format_end();

    var vbuff = vertex_create_buffer();
            vertex_begin(vbuff, global.vf_xy_ca);
                vertex_position(vbuff, 100, 100); vertex_color(vbuff, c_red, 1);
                vertex_position(vbuff, 200, 150); vertex_color(vbuff, c_red, 1);
            vertex_end(vbuff);
        vertex_freeze(vbuff);
        vertex_submit(vbuff, pr_linelist, -1);
    vertex_delete_buffer(vbuff);
This all works well.

Now, I want to reuse the vertexbuffer, but change the color, i.e. have different colors for different draws of the same vertex buffer.

So I thought: remove the color information from the vertex buffer (and format), and it will use the current active color (set by draw_set_color). Sounds sensible to me :)

So, create a format with only xy and remove the vertex_color calls, but add draw_set_color before the draw call.
GML:
    vertex_format_begin();
        vertex_format_add_position();
    global.vf_xy = vertex_format_end();

    var vbuff = vertex_create_buffer();
            vertex_begin(vbuff, global.vf_xy);
                vertex_position(vbuff, 100, 200);
                vertex_position(vbuff, 200, 250);
            vertex_end(vbuff);
        vertex_freeze(vbuff);
        draw_set_color(c_yellow); draw_set_alpha(1);
        vertex_submit(vbuff, pr_linelist, -1);
    vertex_delete_buffer(vbuff);
But it doesn't work. I don't see it on screen. Why? I provide the vertex position, I have a color anda alpha set, which should be enough information.

Why does this not work? And how can I make it work, that is: how to store vertex position (xy) data in a vertex buffer and then draw the same vertex buffer multiple times with a different color each time?
 

hippyman

Member
Are you using a custom shader that only uses position? If so then draw_set_color won't work.

Off the top of my head you may be able to add the colors back to the vertices but make them all white. Then try draw_set_color again.
 
Use a uniform vairiable in a fragment shader to supply the color.

uniform vec3 my_color;

...

gl_FragColor = vec4( my_color, 1.0);

...

shader_set_uniform_f(shader_get_uniform(my_shader,"my_color"), 0, 0.6, 1); //green-ish blue
 

Erik Leppen

Member
Are you using a custom shader that only uses position? If so then draw_set_color won't work.

Off the top of my head you may be able to add the colors back to the vertices but make them all white. Then try draw_set_color again.
I wasn't using a shader. Also, as far as I know, as soon as I add color information, it overrides the "draw_set_color" color :)

Use a uniform vairiable in a fragment shader to supply the color.

uniform vec3 my_color;
gl_FragColor = vec4( my_color, 1.0);
shader_set_uniform_f(shader_get_uniform(my_shader,"my_color"), 0, 0.6, 1); //green-ish blue
I tried this method and it seems it works! Thanks! It does make drawing the stuff more complicated, but if it's needed, it's needed. For now, I made a little function for it.
GML:
function vertex_submit_color (vertexbuffer, primitive, color) {
    var rpart = color_get_red(color) / 255;
    var gpart = color_get_green(color) / 255;
    var bpart = color_get_blue(color) / 255;
    shader_set(sh_recolor);
        shader_set_uniform_f(shader_get_uniform(sh_recolor, "recolor_color"), rpart, gpart, bpart);
        vertex_submit(vertexbuffer, primitive, -1);
    shader_reset();
}
I had to use this other question about shaders to find out I had to remove the texture information from the shader if my vertex format doesn't have texture coordinates.

But I believe that solves it, so thanks! :D
 
Top