Accessing Color in vertex shader

I feel like this should be blindingly obvious, but I’m really struggling. I can’t work out how to get color into my shaders.

I’ve reduced my problem down to a very simple shader and draw statement

vertex shader

#version 150

uniform mat4 modelViewProjectionMatrix;

in vec4 position;
in vec4 color;
out vec4 oCol;

void main(){
	gl_Position = modelViewProjectionMatrix * position;
	oCol = color;
	//oCol = vec4(100, 100, 100, 100);
}

fragment shader

#version 150

in vec4 oCol;
out vec4 outputColor;

void main()
{

	outputColor = oCol;
}

Draw loop:

void ofApp::draw(){
    ofBackground(0);

    shader.begin();

    ofSetColor(ofColor::blue);
    ofDrawLine(ofVec2f(0, 0), ofVec2f(1000, 1000));
    ofDrawLine(ofVec2f(1000, 0), ofVec2f(0, 1000));

    shader.end();
}

As shown this results in a totally black screen.
But if I comment out the penultimate line of the vertex shader and uncomment the last line (so that the outgoing color that is passed onto the fragment shader is set manually) then the manually set color displays, so I’m fairly sure my problem is in getting the color into the vertex shader.

I thought color was a built in OF attribute and assumed it would be picked up from the ofSetColor method. But obviously that isn’t happening. Any advice?

Ok I think I understand now. Drawline is not working the same way as ofMesh. I guess I’m going to have to work via ofMesh?

Hey @Daniel_Bennett1 ,

You can also directly send the color to the shader using a uniform variable.

As you’ve pointed out, ofDrawLine doesn’t send along vertex colors in the way that ofMesh does.

#version 150

uniform mat4 modelViewProjectionMatrix;
uniform vec4 color;
in vec4 position;
out vec4 oCol;

void main(){
	gl_Position = modelViewProjectionMatrix * position;
	oCol = color;
}



void ofApp::draw(){
    ofBackground(0);

    shader.begin();
    shader.setUniform4f( 0.0, 0.0, 1.0, 1.0);
    ofDrawLine(ofVec2f(0, 0), ofVec2f(1000, 1000));
    ofDrawLine(ofVec2f(1000, 0), ofVec2f(0, 1000));

    shader.end();
}

thanks for the help - I did think about uniforms but so far as I understand it uniforms are per-shader-pass, so I’d have to do a new shader pass for each color. For this project I think better to move to drawing with ofMesh.

I think the attribute is named globalColor

try changing
in vec4 color;

to

in vec4 globalColor;

Thanks - I think you’re right.
I’ve more or less rewritten all the draw methods I need in order to work with ofMesh now though, so I think I’m going to stick with that approach. I’m beginning to think that after a small outlay, using ofMesh makes it easier to build more complex structures, and to organise the code sensibly than using the drawArc, drawLine etc. functions. It’s also easier to separate setup and draw that way - I can move calcs that don’t need to be in the shader passes outside of the shader passes.

in vec4 color in the vertex shader is for color coordinates which ofDrawLine doesn’t produce if you want to get the color set using ofSetColor, you need to use the uniform:

uniform vec4 globalColor

which is directly accesible from the fragment shader so no need to right to a varying in the vertex

but yes you are right with:

using ofMesh makes it easier to build more complex structures,