[ofxShader] set color in shader via attribute float array

Hey I can’t figure out how to color my point sprites individually. after a lot of googling I have this:

my float array:

        // defined like this:  
        float    colors[30000*4];  
        // when particles get created, allparticles is a vector with all particles in  
        int i=allparticles.size()*4;  
        colors[i] = ofRandom(1);  
        colors[i++] = ofRandom(1);  
        colors[i++] = ofRandom(1);  
        colors[i++] = 255.0;  

in my draw loop

        GLint color = shader.getAttributeLocation( "color" );  

in my vertex shader

attribute vec4 col;  
varying vec4 mycol;  
void main()  
    // other stuff ....  
    // then I pass it on:  
    mycol = col;  

in fragment shader

#version 120  
uniform sampler2D texture;  
varying vec4 mycol;  
void main(void)  
    gl_FragColor = texture2D(texture,gl_PointCoord) * mycol;  

just discovered if I write:


and limit the original array to 3 it works… but how do I take the alpha in account then?

Hi Thomas

Check your call to getAttributeLocation – shouldn’t it be “col” rather than “color”?


Hi Damian,

yes thanks I spotted that error later too. I settled for having the the RGB values and not worry about the Alpha value anymore. Pretty cool the shader stuff IF it works :slight_smile:

Colors in GLSL are 0 - 1.0, so doing this:

colors[i] = ofRandom(1);    
colors[i++] = ofRandom(1);    
colors[i++] = ofRandom(1);    
// this might throw things off, should be 'colors[i++] = 1.0;' for full alpha   
colors[i++] = 255.0;    

could cause problems depending on your card and drivers.

I have to do something similar. I have a array of 16 float and i want to pass like attribute to change vertex position of my ofMesh with 4 vertex.
I wrote this on my draw method:

GLint idPosition = shader.getAttributeLocation( "positionNew" );
glVertexAttribPointer(idPosition, 4, GL_FLOAT, 0,0, positions);

And this is my vertex shader:

#version 150

uniform mat4 modelViewProjectionMatrix;
in vec4 positionNew;
in vec4 position;

void main(){
	gl_Position = modelViewProjectionMatrix * positionNew;

I don’t receive any error but my vertex remain in the original position of my mesh.
Any idea?
Really i’m not super sure about this way to pass the attribute values. :-\

Maybe i have to use ofVbo… i try to study that

yes, check ofVbo, it has methods to add custom attributes, you can actually combine an ofVboMesh + an external vector to pass the additional attribute using:

vector<ofVec4f> positionNew;
int location = shader.getAttributeLocation("positionNew");

Thanks Arturo, but i still have some problems. Before i seen your post i tried in this way:
in setup:

  shader.load( "shader.vert", "shader.frag");
  myMesh.addVertex(ofVec3f(ofGetWindowWidth() - 500,10));
  myMesh.addVertex(ofVec3f(ofGetWindowWidth() - 500,ofGetWindowHeight() - 100));

  positions[0] = 100;   // x
  positions[1] = 0;     // y
  positions[2] = 0;     // z
  positions[3] = 1;     // w
  positions[4] = 1000;
  positions[5] = 100;
  positions[6] = 0;
  positions[7] = 1;
  positions[8] = 500;
  positions[9] = 200;
  positions[10] = 0;
  positions[11] = 1;
  GLint idPosition = shader.getAttributeLocation( "positionNew" );
  GLuint tangentsAttribLocation = 4;
  myVbo.setMesh(myMesh, GL_DYNAMIC_DRAW);
  myVbo.setAttributeData(idPosition, &positions[0], 4, 3*4, GL_STATIC_DRAW, sizeof(float) );

and positions is

float positions[16];

and this is my vertex shader:

#version 150

uniform mat4 modelViewProjectionMatrix;
in vec4 positionNew;
in vec4 position;

void main(){
	gl_Position = modelViewProjectionMatrix * vec4(positionNew.x, positionNew.y, positionNew.z, position.w);

But when i try… i don’t see anything.
I also tried with your code, but i have some errors passing the address of vector lke this:

     myVbo.setAttributeData(location, &positionNew[0], 3 ,positionNew.size(), GL_STATIC_DRAW, sizeof(ofVec4f));

so i tried in this way (and i’m not sure if it’s right):

  myVbo.setAttributeData(location, &positionNew[0][0],4,positionNew.size()*4,GL_STATIC_DRAW,sizeof(float));

And in this case positionNew is a vector of ofVec4f:

vector<ofVec4f> positionNew;

But in the output i still see nothing.

i think the problem is the stride that should be sizeof(float)*4 since you are passing 4 coordinates

1 Like

Argh!!! Thanks Arturo, you are right! I thought the same thing and i I thought that i had already tried but probably i didn’t… because now i tried and works! Maybe it’s because i was working in train and i wasn’t super concentrated!! :slight_smile:
Now i try to resolve the solution with vector.
Thanks a lot!