[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" );  
        glEnableVertexAttribArray(color);  
        glVertexAttribPointer(color,4,GL_FLOAT,0,0,colors);  
  
  

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:

  
  
  
        glVertexAttribPointer(color,3,GL_FLOAT,0,0,colors);  
  

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”?

Cheers
D

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.

HI!
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:

shader.end();
GLint idPosition = shader.getAttributeLocation( "positionNew" );
glEnableVertexAttribArray(idPosition);
glVertexAttribPointer(idPosition, 4, GL_FLOAT, 0,0, positions);
myMesh.draw();
shader.begin();

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");
vbomesh.getVbo().setAttributeData(location,&positionNew[0],4,positionNew.size(),GL_DRAW_STATIC,sizeof(ofVec4f));
vboMesh.draw();

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.setMode(OF_PRIMITIVE_POINTS);
  
  myMesh.addVertex(ofVec3f(100,10));
  myMesh.addVertex(ofVec3f(ofGetWindowWidth() - 500,10));
  myMesh.addVertex(ofVec3f(ofGetWindowWidth() - 500,ofGetWindowHeight() - 100));
  
  myMesh.addIndex(0);
  myMesh.addIndex(1);
  myMesh.addIndex(2);

  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;
positionNew.push_back(ofVec4f(10,11,15,0));
 positionNew.push_back(ofVec4f(50,11,15,0));
 positionNew.push_back(ofVec4f(100,11,15,0));

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!